行业解决方案
查看所有行业解决方案
IDA 用于解决软件行业的关键问题。
发布时间:2026-08-24 06: 57: 00
Android或Linux平台的SO文件被动态链接器装载时,可能先执行.init和.init_array中的初始化函数,再进入后续导出接口。处理“IDA Pro逆向SO怎么分析构造函数IDA Pro全局构造函数执行顺序如何判断”时,应先找到初始化数组,再区分全局初始化包装函数与具体C++类构造函数,不能把JNI_OnLoad或普通导出函数直接当成全局构造入口。
一、IDA Pro逆向SO怎么分析构造函数
SO保留符号时,可以从函数名和反编译结果入手;符号被剥离后,则要沿.init_array、全局对象地址和构造调用逐层恢复。
1、找到SO中的初始化入口
先检查ELF段,确认文件中是否存在.init、.init_array或旧式.ctors区域。
①进入【视图】→【打开子视图】→【段】。
②在段列表中查找.init、.init_array和.ctors。
③双击.init_array跳转到数组起始位置。
④32位SO按4字节检查条目,64位SO按8字节检查条目。
⑤对尚未识别的条目按O转换为偏移。
⑥跳转到目标地址,按P创建函数。
IDA的段窗口会显示各段的起止地址和读写执行属性,交叉引用视图可以继续检查数据条目指向的代码关系。
2、区分包装函数和类构造函数
.init_array中的条目经常先进入包装函数,由包装函数取得全局对象地址,再调用真正的类构造函数。
①对数组中的每个函数按F5打开伪代码。
②检查函数是否连续调用多个初始化函数。
③查看调用前是否向第一个参数传入固定全局地址。
④跳转到被调用函数,检查是否写入成员、虚表或默认值。
⑤出现__cxa_atexit时,记录析构函数和对象地址。
⑥按对象地址查看交叉引用,确认后续使用位置。
常见C++ABI会为完整对象和基类子对象生成不同构造入口,符号中可能出现C1、C2等变体。分析时仍应以this地址、成员写入和实际调用链为准。
3、恢复构造函数参数和类结构
构造函数原型错误时,F5会把对象地址显示成普通整数,成员访问也容易变成大量指针偏移。
①在构造函数首行按Y修改函数类型。
②将第一个参数设置为目标类指针。
③在【本地类型】中新建对应结构体。
④根据写入偏移添加成员和虚表指针。
⑤为伪代码中的对象变量设置结构体指针类型。
⑥按N重命名构造函数、全局对象和包装函数。
二、IDA Pro全局构造函数执行顺序如何判断
同一个SO内部可以按动态标签和数组位置判断;多个SO之间还要考虑依赖关系,不能只比较文件名或函数地址大小。
1、判断同一个SO内部的顺序
ELF对象同时包含DT_INIT和DT_INIT_ARRAY时,DT_INIT对应函数先执行;.init_array中的函数按数组条目从前到后调用。
①记录.init函数地址。
②按存放顺序列出.init_array全部条目。
③为每个条目标注序号和目标函数。
④打开包装函数,记录其内部调用顺序。
⑤检查不同条目是否调用了同一个构造函数。
⑥整理“数组序号—包装函数—对象—构造函数”关系。
GCC允许通过优先级控制部分初始化顺序,数值较小的构造优先级通常更早执行。没有显式优先级时,不能仅凭源文件名推断不同编译单元的先后关系。
2、判断多个SO之间的顺序
Android动态链接器会先处理当前SO依赖库的构造函数,再执行当前SO的DT_INIT和DT_INIT_ARRAY。同一个初始化数组仍按正向顺序调用。
①打开动态段,记录全部DT_NEEDED依赖。
②分别加载需要分析的依赖SO。
③找出各SO的.init和.init_array。
④先整理依赖库,再整理当前SO。
⑤遇到dlopen时,记录实际触发加载的位置。
⑥存在循环依赖时,改用动态调试确认。
依赖库的加载关系和初始化关系可能跨越多个层级。只分析当前SO的.init_array,无法解释构造函数依赖的全局对象为什么已经提前生成。
3、动态记录真实执行顺序
ASLR、动态加载和复杂依赖会增加静态判断难度,可以通过入口断点记录实际命中顺序。
①在各构造函数入口设置模块加偏移断点。
②启动Android或Linux远程调试。
③在【调试器选项】中启用库加载事件提示。
④等待目标SO装载并命中首个构造函数。
⑤依次记录命中地址、线程和调用栈。
⑥根据模块基址核对实际相对偏移。
⑦启用函数跟踪保存调用记录。
IDA调试器可以报告库加载事件,并通过函数跟踪记录调用与返回。模块运行地址尚未固定时,模块加偏移断点也更容易适配ASLR。
三、构造函数顺序判断错误如何修正
静态顺序与运行结果不一致时,应检查重定位、函数边界和对象初始化类型,不能直接调整函数名称来迁就已有结论。
1、重新检查初始化数组
①确认.init_array条目已经应用重定位。
②检查条目指向函数本体还是跳板代码。
③删除误创建的数据和错误函数。
④重新转换偏移并创建函数。
⑤查看每个条目的数据交叉引用。
⑥核对SO基址和段加载地址。
若数组条目看起来落在无效地址,常见问题是重定位没有正确处理、文件加载基址错误,或者目标地址仍被识别为普通数据。
2、排除局部静态对象干扰
函数内部的局部静态对象通常在程序首次执行到对应位置时初始化,不属于SO装载阶段的全局初始化数组。
①搜索__cxa_guard_acquire和__cxa_guard_release。
②查看调用这些函数的业务函数。
③记录守卫变量和静态对象地址。
④将对应构造函数移出全局顺序表。
⑤在首次业务调用位置单独设置断点。
⑥对照守卫变量变化确认只初始化一次。
C++ABI使用守卫变量控制局部静态对象的一次性构造,这类函数即使调用了类构造函数,也不代表它会在SO装载阶段运行。
总结
“IDA Pro逆向SO怎么分析构造函数IDA Pro全局构造函数执行顺序如何判断”需要从.init、.init_array和初始化包装函数入手,再恢复具体类构造函数、对象地址与依赖关系。同一SO按动态初始化规则和数组位置判断,跨SO顺序则结合依赖链与动态断点复核。希望本文对大家分析SO构造函数和还原全局初始化流程有所帮助。
展开阅读全文
︾