有时候用IDA F5的时候遇到带sp-analysis failed 的函数会失败.
这只是一个极其简单的一个例子.希望大家能依此类推.也更希望大家把类似的代码放出来一起解决。原本是一朋友问我的,我只是顺便发出来.以后遇到类似情况百度就可以找到了。
方法一
.text:004015ED sub_4015ED proc near ; CODE XREF: sub_40116A+1A6p .text:004015ED ; sub_40116A+1C7p .text:004015ED .text:004015ED var_C = byte ptr -0Ch .text:004015ED var_8 = dword ptr -8 .text:004015ED var_4 = dword ptr -4 .text:004015ED arg_0 = dword ptr 10h .text:004015ED .text:004015ED push ecx .text:004015EE push esi .text:004015EF push ebp .text:004015F0 mov ebp, esp .text:004015F2 add esp, 0FFFFFFF8h .text:004015F5 mov ebx, offset String .text:004015FA cmp dword ptr [ebx], 0FFFFFFFFh .text:004015FD jz short loc_401606 .text:004015FF mov eax, offset loc_401607 .text:00401604 jmp eax .text:00401606 ; --------------------------------------------------------------------------- .text:00401606 .text:00401606 loc_401606: ; CODE XREF: sub_4015ED+10j .text:00401606 nop .text:00401607 .text:00401607 loc_401607: ; DATA XREF: sub_4015ED+12o .text:00401607 xor eax, eax .text:00401609 mov esi, [ebp+arg_0] .text:0040160C mov al, [esi+ebx] .text:0040160F xor ebx, ebx .text:00401611 push eax .text:00401612 call sub_4014BF .text:00401617 mov [ebp+var_4], ebx .text:0040161A call sub_4014D5 .text:0040161F mov [ebp+var_8], ebx .text:00401622 push 0 .text:00401624 push offset dword_403425 .text:00401629 push [ebp+var_4] .text:0040162C push [ebp+var_8] .text:0040162F call sub_401561 .text:00401634 mov eax, dword_403425 .text:00401639 ror eax, 8 .text:0040163C cmp eax, 5 .text:0040163F jz short loc_401649 .text:00401641 push eax .text:00401642 mov eax, offset loc_40164A .text:00401647 jmp eax .text:00401649 ; --------------------------------------------------------------------------- .text:00401649 .text:00401649 loc_401649: ; CODE XREF: sub_4015ED+52j .text:00401649 nop .text:0040164A .text:0040164A loc_40164A: ; DATA XREF: sub_4015ED+55o .text:0040164A pop eax .text:0040164B xor ah, [ebp+var_C] .text:0040164E xor al, [ebp+var_C] .text:00401651 xor edx, edx .text:00401653 mov bx, ax .text:00401656 mov ecx, 4 .text:0040165B .text:0040165B loc_40165B: ; CODE XREF: sub_4015ED+83j .text:0040165B and al, 0Fh .text:0040165D cmp al, 9 .text:0040165F jle short loc_401663 .text:00401661 add al, 7 .text:00401663 .text:00401663 loc_401663: ; CODE XREF: sub_4015ED+72j .text:00401663 add al, 30h .text:00401665 mov dl, al .text:00401667 ror edx, 8 .text:0040166A shr bx, 4 .text:0040166E mov al, bl .text:00401670 loop loc_40165B .text:00401672 add esp, 1Ch .text:00401675 pop ebp .text:00401676 pop esi .text:00401677 pop ecx .text:00401678 retn .text:00401678 [COLOR="Red"]sub_4015ED endp ; sp-analysis failed[/COLOR]
废话我就不多说了,造成不能F5的原因在于:
.text:00401642 mov eax, offset loc_40164A .text:00401647 jmp eax
用OD打开之后改掉代码在保存,然后重新用IDA打开F5就可以了,sp-analysis failed也就消失了.
在OD里直接改成JMP 40164A
分析之后不难发现不能F5的原因,就在于跳转.
一个函数里面的一个跳转在未知的情况下会出现不能F5.
结果:
char __cdecl sub_4015ED(int a1) { unsigned __int16 v1; // ax@1 int v2; // edx@1 signed int v3; // ecx@1 unsigned __int16 v4; // bx@1 char v5; // ST10_1@1 int v6; // eax@1 char v7; // ST10_1@1 char v8; // al@2 sub_4014BF(String[a1]); sub_4014D5(v5); sub_401561(0, 0, &dword_403425, 0); v6 = __ROR__(dword_403425, 8); HIBYTE(v1) = v7 ^ BYTE1(v6); LOBYTE(v1) = v7 ^ v1; v2 = 0; v4 = v1; v3 = 4; do { v8 = v1 & 0xF; if ( v8 > 9 ) v8 += 7; LOBYTE(v2) = v1 + 48; v2 = __ROR__(v2, 8); v4 >>= 4; LOBYTE(v1) = v4; --v3; } while ( v3 ); return v1; }
方法二
代码是红色的,就是说IDA没有分析出来,为了方便分析,我们会用快捷键P(Create Function) 来创建函数.只是我们在函数头部按P的时候总会提示
-
The function has undefined instruction/data at the specified address.
Your request has been put in the autoanalysis queue.
大家注意retn
后面两行多余的代码,这是罪魁祸首.如果我们不能创建函数,就不能使用F5来分析代码了,想让这些代码变绿色的方法(创建函数)很简单.
用鼠标从函数头部开始到retn
结尾 拖一下,变成灰色.
然后用快捷键P
或者右键菜单,CreateFunction
来创建函数就可以了。
用拖的方法,去创建一个函数的好处是,我们可以选择任意的一部分IDA分析不出来的代码(就是红色代码),成为一个绿色的代码(IDA可识别的代码).
当然了,到这里也不算完.下图是代码变绿色的,我用上面的方法创建函数了,可还是不能F5.
我们通过Stack Pointer
发现这个函数的堆栈是不平衡的.此时我们需要找接近retn
的 最后一个Call
然后去修正堆栈.
我们看到retn
左边绿色的数字是28,我们通过ALT + k
修正堆栈,把28 retn
改成0
就可以了。
修正堆栈的时候一定要选择Call
然后修正堆栈,下图是修正后的代码
很简单的一个东西,篇幅有点大了,可能存在一些问题,不过目的是可以F5就好了.