max函数的逆向
先来看代码
1 // 求两个数中的大者.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 6 int main(int argc, char* argv[]) 7 { 8 int max(int x,int y); //函数的声明 9 int a,b,c; 10 scanf("%d,%d",&a,&b); 11 c=max(a,b); 12 printf("max=%d\n",c); 13 return 0; 14 } 15 16 17 int max(int x,int y) 18 { 19 int z; 20 if (x>y) 21 { 22 z=x; 23 } 24 else 25 z=y; 26 return z; 27 }
然后来看IDA的样子
1 ; int __cdecl main(int argc, const char **argv, const char **envp) 2 _main proc near 3 4 var_8= dword ptr -8 5 var_4= dword ptr -4 6 argc= dword ptr 4 7 argv= dword ptr 8 8 envp= dword ptr 0Ch 9 10 sub esp, 8 11 lea eax, [esp+8+var_8] 12 lea ecx, [esp+8+var_4] 13 push eax 14 push ecx 15 push offset Format ; "%d,%d" 16 call _scanf 17 mov edx, [esp+14h+var_8] 18 mov eax, [esp+14h+var_4] 19 push edx 20 push eax 21 call sub_401040 22 push eax 23 push offset aMaxD ; "max=%d\n" 24 call sub_401050 25 xor eax, eax 26 add esp, 24h 27 retn 28 _main endp
然后看看注释:
1 sub esp, 8 2 lea eax, [esp+8+b] ; 取b的地址放入eax中 3 lea ecx, [esp+8+a] ; 取a的地址放入ecx中 4 push eax 5 push ecx ; 将两个地址压入堆栈,作为scanf的参数 6 push offset Format ; 使用输入的格式"%d,%d" 7 call _scanf 8 mov edx, [esp+14h+b] ; 将b的值放入edx 9 mov eax, [esp+14h+a] ; 将a的值放入eax 10 push edx 11 push eax 12 call sub_401040 ; 调用max 13 push eax ; 将max的结果压入堆栈,作为printf的参数之一 14 push offset aMaxD ; 确定输出的格式"max=%d\n" 15 call sub_401050 ; 调用printf函数 16 xor eax, eax 17 add esp, 24h 18 retn 19 _main endp
这些都只是大概的理解,需要自己调试来验证。
下面来继续看看max的具体实现,这样,我们在编写程序的时候就可以自己对其进行优化。
1 .text:00401040 x = dword ptr 4 2 .text:00401040 y = dword ptr 8 3 .text:00401040 4 .text:00401040 mov eax, [esp+x] 5 .text:00401044 mov ecx, [esp+y] 6 .text:00401048 cmp eax, ecx 7 .text:0040104A jg short locret_40104E 8 .text:0040104C mov eax, ecx 9 .text:0040104E 10 .text:0040104E locret_40104E: ; CODE XREF: fun_max+Aj 11 .text:0040104E retn 12 .text:0040104E fun_max endp
看起来很简单,默认就返回eax为最大值,如果ecx比eax大,就把ecx赋值给eax。