逆向工程是需要非常复杂的算法来支持,(对此我知之甚少),因此难免在IDA反汇编的结果中会出现一
些错误。一般来说,出现错误的部分IDA都会用红色的背景色来突出这个错误,或者在Problem Subview
中列出这个错误。从这点也能看出IDA作者实事求是的精神。
对于函数的错误分析,很多时候都会影响到阅读反汇编结果,一般来说,该函数读起来总会发现有些地
方不对劲。以下列出几个在反汇编的时候可能出现的错误,以及调整的办法。我用的版本是IDA Pro5.0
。
1、反汇编的函数原型不对,一般可能出现的就是少包含了几个参数。
问题:
i) 对于__cdcel调用的函数,调用完成后释放堆栈的大小大于传入参数所占堆栈的大小。
比如:
反汇编的函数原型为 void __cdcel sub_A(int,int)
而释放堆栈的语句为 add esp, 10h
那么反汇编后的原型就应该为 void __cdcel sub_A(int,int,int,int)
ii) 一些间接寻址出现红色报错,比如:
反汇编中的语句为 1124 mov ebp, [esp+1130h] (左边的1124是stack pointer,可以在Options的
General中打开查看选项)
这里[esp+1130h]被用红色突出,很明显这里寻址的应该是传入的形参(因为1130h已经大于1124h),
但是由于反汇编的函数原型少算了几个参数,就会导致出现这样的错误。
解决办法:
在该函数上右键选择"Set function type",把少分析的参数都补上。
2、反汇编的局部参数中没有列出某些在函数中被使用的局部参数,导致分析错误。
问题:
反汇编的语句为 1124 mov ecx, [esp+128h]
这里[esp+128h]肯定是一个局部参数,因为128h小于1124h。但是反汇编的函数原型中并出现该局参
,因为[esp+128h]被用红色突出。
解决办法:
双击反汇编出来的函数的其他局部参数,比如var_1008,就会弹出该函数的Stack frame窗口。由于
1124h - 128h = ffch,所以直接到ffch这个位置进行"Data"处理,把它从以前的db变为dd,这样该函
数就自动增加一个局部参数var_FFC,刚才的语句变为: 1124 mov ecx, [esp+1124h+var_FFC]
3、在某些时候对于用LoadLibrary导入的__stdcall函数,在调用时,不会恢复stack pointer。
问题:
008 push offset aNtqueryobject ; "NtQueryObject"
00C push offset ModuleName ; "ntdll.dll"
010 call esi ; GetModuleHandleA
00C push eax ; hModule
010 call edi ; GetProcAddress
008 test eax, eax
008 mov NtQueryObject, eax
......
1120 mov ecx, [esp+1120h+TargetHandle]
1120 lea edx, [esp+1120h+BytesReturned]
1120 push edx
1124 lea eax, [esp+1124h+var_1000]
1124 push 1000h
1128 push eax
112C push 2 ; ObjectTypeInformation
1130 push ecx
1134 call NtQueryObject
1134 test eax, eax
1134 jz short loc_401BB4
最左边的数字都是stack pointer。可以看到在call NtQueryObject以后, stack pointer仍然没有进
行调整,但按照__stdcall的说明,应该是在被调函数返回前必须对传入参数的堆栈进行恢复。
解决办法:
在call NtQueryObject语句上右键,选择"Change stack pointer",因为NtQueryObject一共是传入5
个参数,因此把修改值设为"0x14"即可。这样后面的stack pointer就都正确了。
1134 call NtQueryObject
1120 test eax, eax
1120 jz short loc_401BB4
关于这个问题,在Ilfak Guilfanov的Blog讲的很清楚,不过具体修改这个错误的版本可能要到5.1才有
吧。http://www.hexblog.com/2006/06/simplex_method_in_ida_pro.html#more