加固壳分析2-某加固厂商加固流程分析
引言
安卓应用加固壳作为一种保护技术,能够有效防止我们的应用程序被反编译和篡改。在这篇文章中,我们将探讨一个加固流程,以提供对加固壳实现的更深入理解。在本文中,我们将不提供厂商的具体名称,以避免可能的法律问题,但我们将分析其加固流程。
加载加壳的 ELF文件
1.通过安卓系统的机制在linker中(__dl__ZL10call_arrayIPFviPPcS1_EEvPKcPT_mbS5_) 打一个断点,当链接完一个so文件之后,会开始执行init函数
2.进入init函数1
strcpy((char *)v40, "r");
v37 = 0LL;
v38 = 56;
v39 = 0;
v25 = fopen((const char *)&v42, (const char *)v40);
memset(v48, 0, 0x400uLL);
v26 = fun1((__int64)v48, (__int64)v48);
v27 = FUN2(v26, (__int64)v48);
v28 = fun1(v27, v27);
v29 = fun2(v28, v27);
v30 = FUN2(v29, 17LL);
v31 = fun2(v29, 41LL);
v32 = fun1(v30, v31);
v33 = FUN2(v29, 9LL);
if ( (FUN2(v32, v33) & 1) == 0 )
NOP();
while ( fgets((char *)v48, 1023, v25) )
{
v35 = 0;
*(_DWORD *)&v40[3] = 0;
v41 = 0;
if ( sscanf((const char *)v48, (const char *)&v44, &v36, &v37, &v40[3], &v35) == 3
&& (unsigned __int64)v4 >= v36
&& (unsigned __int64)v4 < v37 )
{
if ( LOBYTE(v40[4]) != 120 )
dword_7924822030 = 0;
return *(_QWORD *)off_7924821F00;
}
}
return *(_QWORD *)off_7924821F00;
}
可能是扫描maps和做一些全局变量的初始化工作。
3.进入init函数2
解析 ELF 头部,获取段的数量和段表的位置。
进行prelink操作
壳的字符串表,符号表解密
if ( !a6 )
{
if ( a5 )
{
v6 = 0LL;
v7 = 0x56312342;
do
{
v8 = *(_DWORD *)(stringtable + v6) ^ v7;
v7 += v6;
*(_DWORD *)(stringtable + v6) = v8;
v6 += 4LL;
}
while ( a5 > (unsigned int)v6 );
}
v9 = systable_1 + 0x18LL * CONST_10A;
if ( CONST_10A < CONST_8A2 )
{
v10 = CONST_10A + 0x151;
v11 = CONST_8A2 - 1 - CONST_10A;
v12 = CONST_10A + 0x15B;
v13 = v9 + 0x18 * (v11 + 1);
do
{
v14 = *(_QWORD *)(v9 + 8);
v15 = v14 ^ v10;
if ( v14 )
{
v16 = *(_QWORD *)(v9 + 0x10);
*(_QWORD *)(v9 + 8) = v15;
*(_QWORD *)(v9 + 0x10) = v16 ^ v12;
}
v9 += 0x18LL;
}
while ( v9 != v13 );
}
}
return 1LL;
}
可以把解密之后的字符串表和符号表dump下来 使用010直接覆盖加密数据
import idaapi
start = 0x7BFEBBCA50
length = 0x18c50
data = idaapi.dbg_read_memory(start, length)
if data is not None:
with open("ppp666", "wb") as f:
f.write(data)
print("Memory data written to file 'ppp666'.")
else:
print("Failed to read memory from address: {:016X}".format(start))
4.进入init函数3自定义链接真实的so
初始化soinfo,初始化一些结构体,等待解析so文件的数据来填充。
解密一些代码段,解密之后又加密回去
__int64 __fastcall sub_724B521040(_BYTE *a1, __int64 a2, int a3)
{
void *v4; // x19
int v7[3]; // [xsp+3Ch] [xbp-114h] BYREF
_OWORD v8[16]; // [xsp+48h] [xbp-108h] BYREF
__int64 v9; // [xsp+148h] [xbp-8h]
v4 = off_7924821F00;
v7[0] = a3;
v9 = *(_QWORD *)off_7924821F00;
rc4_init(v8, (__int64)v7, 4uLL); // rc4初始化
//
//
rc4_func((__int64)v8, a1, a2); // rc4解密流
return *(_QWORD *)v4;
}
将解密的program header以及代码数据加载到内存空间中,获取到真实so的字符串表和符号表
prelink之后进行重定位,至此真实的so文件就可以执行了。
通过学习其他加固厂商的加固方法对elf加固流程有了认识,对于入门学习elf的小伙伴非常适合,感兴趣的小伙伴可以参考链接。
需要注意,本文旨在提供有关加固壳分析的信息,仅供参考和学习目的。作者和本加固厂商对于本文中提供的信息的准确性和完整性不作任何明示或暗示的保证。读者在使用本文中的信息时,应自行判断其适用性,并自行承担相关风险。本文中的任何观点、意见或建议不构成任何形式的担保或保证,也不代表作者和本加固厂商的立场。
参考文章:
https://mp.weixin.qq.com/s/9aUBWxPynTFeYuw9J9Guvg
https://bbs.kanxue.com/thread-277443.htm
https://bbs.kanxue.com/thread-274573.htm
原文始发于微信公众号(小瑶在工地):加固壳分析2-某加固厂商加固流程分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论