其他
一款最简单的关于动态注册的APP分析
本来想着动态调试吧,可是还得先过360加固的反调试,算了还是静态分析吧。
先看.init.array段:
unsigned int str_decode()
{
unsigned int v0; // r0
unsigned int v1; // r0
unsigned int v2; // r0
unsigned int v3; // r0
unsigned int v4; // r0
unsigned int v5; // r0
unsigned int v6; // r0
unsigned int v7; // r0
unsigned int v8; // r0
unsigned int v9; // r0
unsigned int v10; // r0
unsigned int v11; // r0
unsigned int v12; // r0
unsigned int result; // r0
unsigned int v14; // [sp+0h] [bp-38h]
unsigned int v15; // [sp+4h] [bp-34h]
unsigned int v16; // [sp+8h] [bp-30h]
unsigned int v17; // [sp+Ch] [bp-2Ch]
unsigned int v18; // [sp+10h] [bp-28h]
unsigned int v19; // [sp+14h] [bp-24h]
unsigned int v20; // [sp+18h] [bp-20h]
unsigned int v21; // [sp+1Ch] [bp-1Ch]
unsigned int v22; // [sp+20h] [bp-18h]
unsigned int v23; // [sp+24h] [bp-14h]
unsigned int v24; // [sp+28h] [bp-10h]
unsigned int v25; // [sp+2Ch] [bp-Ch]
unsigned int v26; // [sp+30h] [bp-8h]
unsigned int i; // [sp+34h] [bp-4h]
i = 0;
do
{
v0 = i;
ELF[i++] ^= 0x61u; // ELF
}
while ( v0 < 4 );
v26 = 0;
do
{
v1 = v26;
read_maps[v26++] ^= 0xBAu; // read /proc/self/maps
}
while ( v1 < 0x14 );
v25 = 0;
do
{
v2 = v25;
self_maps[v25++] ^= 0xE6u; // /proc/self/maps
//
}
while ( v2 < 0xF );
v24 = 0;
do
{
v3 = v24;
frida[v24] ^= 0x51u; // frida
//
++v24;
}
while ( v3 < 5 );
v23 = 0;
do
{
v4 = v23;
frida_so_found[v23++] ^= 0x98u; // found frida.so in memory
}
while ( v4 < 0x18 );
v22 = 0;
do
{
v5 = v22;
fmt[v22++] ^= 0x5Cu; // %x-%lx %4s %lx %*s %*s %s
}
while ( v5 < 0x19 );
v21 = 0;
do
{
v6 = v21;
end_oat[v21++] ^= 0xA6u; // .oat
}
while ( v6 < 4 );
v20 = 0;
do
{
v7 = v20;
found_frida[v20++] ^= 0x31u; // found frida in memory
}
while ( v7 < 0x15 );
v19 = 0;
do
{
v8 = v19;
course[v19++] ^= 0x86u; // course
}
while ( v8 < 6 );
v18 = 0;
do
{
v9 = v18;
check[v18] ^= 0x24u; // check
++v18;
}
while ( v9 < 5 );
v17 = 0;
do
{
v10 = v17;
sig[v17] ^= 0xFDu; // (Ljava/lang/Object;)Z
++v17;
}
while ( v10 < 0x15 );
v16 = 0;
do
{
v11 = v16;
MainActivity[v16] ^= 0xD1u; // com/kanxue/reflectiontest/MainActivity
++v16;
}
while ( v11 < 0x26 );
v15 = 0;
do
{
v12 = v15;
training[v15++] ^= 0x32u; // training
}
while ( v12 < 8 );
v14 = 0;
do
{
result = v14;
kanxue[v14++] ^= 0x18u; // kanxue
}
while ( result < 6 );
return result;
}
直接IDA脚本,一一解密,从解密后的字符串可以看到,这个so存在检测frida的反调试,以及其他不知名的字符串。
再之后看.init函数:
如果检测不通过,则kill掉进程。
接下来,看JNI_Onload函数:
1. 检测输入string长度是否为20
2. 再次动态注册check函数到,新的native函数偏移为0x1234
3. 检测输入的string是否以kanxue开头
4. 调用新的check函数,即sub_1234函数,并传递输入字符串的第六位之后的字符串为参数
1. 检测输入string长度是否为14
2. 再次动态注册check函数到,新的native函数偏移为0x1148
3. 检测输入的string是否以training开头
4. 调用新的check函数,即sub_1148函数,并传递输入字符串的第8位之后的字符串为参数
验证。
看雪ID:小白abc
https://bbs.pediy.com/user-715334.htm
推荐文章++++
好书推荐