已经有 4 个晚上了,我一直在努力反编译这个。这是我通过 IDA 运行以获取 C 代码的 Android 本地库。
Java签名:
byte[] resultArray = new byte[-2 + dataArray.length];
dataLength= dataArray.length;
decryptData(byte[] resultArray, byte[] dataArray, int dataLength, int enumValue /* in our case should be 01 */, long paramLong /* dunno */)
C 中的反汇编:
//----- (00001354) --------------------------------------------------------
int __fastcall doXor(int result, int a2, int a3, int a4, int a5, int a6, char a7)
{
int v7; // r5@1
int v8; // r6@1
int v9; // r7@1
int v10; // r1@1
char v11; // lr@3
char v12; // t1@3
char v13; // t1@3
v7 = a2 - 1;
v8 = a3 - 1;
v9 = result - 1;
v10 = a2 + a5 - 1;
while ( v7 != v10 )
{
v12 = *(_BYTE *)(v7++ + 1);
v11 = v12;
v13 = *(_BYTE *)(v8++ + 1);
*(_BYTE *)(v9++ + 1) = v11 ^ v13;
} // ====== so far this one just does a xor in the full array
// ===>what does this one do?
*(_BYTE *)(result + a5) = *(_BYTE *)(a3 + a5) ^ a7;
return result;
}
//----- (00001384) --------------------------------------------------------
int getNumber()
{
__int32 v0; // r0@1
v0 = time(0);
srand48(v0);
return (unsigned __int8)lrand48();
}
//----- (00001398) --------------------------------------------------------
int __fastcall getKey(void *a1, unsigned int a2, unsigned __int8 a3, int a4, char a5)
{
void *v5; // r8@1
unsigned int v6; // r7@1
unsigned int v7; // r10@1
void *v8; // r5@1
__int64 v9; // r0@1
signed int v10; // r6@1
__int64 v12; // [sp+8h] [bp-30h]@1
int v13; // [sp+14h] [bp-24h]@1
v5 = a1;
v6 = a2;
v7 = a2 >> 3;
v8 = a1;
v13 = _stack_chk_guard; //a stack guard
LODWORD(v9) = crc64(a3, (int)&a5, _stack_chk_guard, 8);
v10 = 0;
v12 = v9;
do
{
++v10;
if ( 8 * v10 > v6 )
{
if ( v6 >= 8 * v10 - 8 )
LODWORD(v9) = memcpy(v8, &v12, (size_t)((char *)v5 + v6 - (_DWORD)v8));
}
else
{
v9 = v12;
*(_QWORD *)v8 = v12;
}
v8 = (char *)v8 + 8;
}while ( v10 <= (signed int)v7 );
if ( v13 != _stack_chk_guard )
_stack_chk_fail(v9);
return v9;
}
//----- (000014E4) --------------------------------------------------------
signed int __fastcall decryptData(void *a1, unsigned int *a2, int a3, int a4, __int64 a5)
{
int v5; // r4@1
void *v6; // r11@1
unsigned int *v7; // r10@1
unsigned int v8; // r7@3
int v9; // r9@3
int v10; // ST10_4@3
void *v11; // r8@3
const void *v12; // r5@3
int v13; // r6@3
signed int result; // r0@5
v5 = a3;
v6 = a1;
v7 = a2;
if ( check == 1 )
{
if ( a5 )
{
result = 0;
}
else
{
v8 = *(_BYTE *)a2;
v9 = a4 + v8;
v10 = *((_BYTE *)a2 + a3 - 1);
v11 = malloc(a3 - 1);
v12 = malloc(v5 - 1);
getKey(v11, (unsigned __int16)(v5 - 1), v9, (2596069104u * (unsigned __int64)v8 >> 32) + 305419896 * v8, -16 * v8);
v13 = v5 - 2;
doXor((int)v12, (int)((char *)v7 + 1), (int)v11, v10, v13, (unsigned __int64)v13 >> 32, v10);
memcpy(v6, v12, v5 - 2);
if ( *((char *)v12 + v5 - 2) != v9 )
v13 = 0;
if ( v11 )
free(v11);
free((void *)v12);
result = v13;
}
}
else
{
result = -1;
}
return result;
}
我有crc64的实现。我不明白的是它从哪里获取 getKey 的数据数组中的种子。
我不确定,我认为它在最后 2 个字节中存储了用于为 xor 生成更大密钥的密钥。请帮忙,我真的很挣扎,我的 C 技能生锈了。
这是一组数据:
$type = "01";
$length = "37";
$data="ea8bf72287a0af8aa65edf259a43".
"e1d8a67f71bce448273199848e401b33".
"da379966a12ce4442e31991b71bde449".
"39bb907d71bce448cc";
通常,前 8 个字节给出纬度和第二个经度,在这种情况下是:
f8869e63e888bb3f29ae997e0bc6e93f
所以基本上我假设我们可以期望这是编码版本:
ea8bf72287a0af8aa65edf259a43e1d8
xor 的逆是一个 xor 所以在 xor 之后它给出:
120d69416f2814b58ff0465b918508e7
这假设是我们的部分异或键。
现在问题:
- 存储在数据中的种子的长度是多少?
- 异或键是如何计算的?
- 我们确定数据中的纬度/经度位置吗?
如果您想在堆栈外提供帮助并讨论此问题,请与我联系。非常感谢