重学C第二节:求两个整数之和

求两个整数之和,也是一个很小的程序,但是其中的道理,还是很多的,我们要好好体会。

相加的两个数从哪来,到哪去?

 1 #include <stdio.h>
 2 
 3 void main()
 4 {
 5     int a,b,sum;
 6     a=123;
 7     b=456;
 8     sum=a+b;
 9     printf("sum is %d \n",sum);
10 }

工程下载地址:https://files.cnblogs.com/tk091/rl002.zip

同样的,我们我OD来查看对应的汇编代码:

00401010 >  55              push ebp
00401011    8BEC            mov ebp,esp
00401013    83EC 4C         sub esp,0x4C
00401016    53              push ebx
00401017    56              push esi
00401018    57              push edi
00401019    8D7D B4         lea edi,dword ptr ss:[ebp-0x4C]
0040101C    B9 13000000     mov ecx,0x13
00401021    B8 CCCCCCCC     mov eax,0xCCCCCCCC
00401026    F3:AB           rep stos dword ptr es:[edi]
00401028    C745 FC 7B00000>mov dword ptr ss:[ebp-0x4],0x7B
0040102F    C745 F8 C801000>mov dword ptr ss:[ebp-0x8],0x1C8
00401036    8B45 FC         mov eax,dword ptr ss:[ebp-0x4]
00401039    0345 F8         add eax,dword ptr ss:[ebp-0x8]
0040103C    8945 F4         mov dword ptr ss:[ebp-0xC],eax
0040103F    8B4D F4         mov ecx,dword ptr ss:[ebp-0xC]
00401042    51              push ecx                                 ; <%d>
00401043    68 1C204200     push rl002.0042201C                      ; format = "sum is %d "
00401048    E8 33000000     call rl002.printf                        ; printf
0040104D    83C4 08         add esp,0x8
00401050    5F              pop edi
00401051    5E              pop esi
00401052    5B              pop ebx
00401053    83C4 4C         add esp,0x4C
00401056    3BEC            cmp ebp,esp
00401058    E8 A3000000     call rl002._chkesp
0040105D    8BE5            mov esp,ebp
0040105F    5D              pop ebp
00401060    C3              retn

对应的,我们用IDA来看看对应的代码是什么:

 1 int __cdecl main()
 2 {
 3   char v1; // [sp+Ch] [bp-4Ch]@1
 4   unsigned int v2; // [sp+4Ch] [bp-Ch]@1
 5   int v3; // [sp+50h] [bp-8h]@1
 6   int v4; // [sp+54h] [bp-4h]@1
 7 
 8   memset(&v1, -858993460, 0x4Cu);
 9   v4 = 123;         //int a=123;
10   v3 = 456;         //int b=456;
11   v2 = 579;         
12   printf("sum is %d \n", 579);
13   return _chkesp();
14 }

上面我们看的都是Debug版的程序,我们来瞅瞅Release版的。

--------------------------------------------------------------------------------------------------------------------------------------------------------------

首先是OD查看:

1 00401000  /$  68 43020000   push 0x243
2 00401005  |.  68 30704000   push rl002.00407030                      ;  ASCII "sum is %d 
3 "
4 0040100A  |.  E8 11000000   call rl002.00401020
5 0040100F  |.  83C4 08       add esp,0x8
6 00401012  \.  C3            retn

然后是IDA查看:

1 int __cdecl main(int argc, const char **argv, const char **envp)
2 {
3   return sub_401020("sum is %d \n", 579);
4 }

我们突然发现,原来main函数是有三个参数的,而不是两个。

我把它修改成这个样子:

1 ; int __cdecl main(int argc, const char **argv, const char **envp)
2 _main proc near
3 push    579
4 push    offset Format   ; "sum is %d \n"
5 call    _printf
6 add     esp, 8
7 retn
8 _main endp

很多东西,在编译的过程中已经丢失了。

当你苦苦追寻,在学习中经过多次努力,忽然获得我们所求的东西,那种感受,就是 一种幸福。

通过对sig文件的研究,终于对这个程序的逆向变成了:

主函数:

1 ; int __cdecl main(int argc, const char **argv, const char **envp)
2 _main proc near
3 push    243h
4 push    offset Format   ; "sum = %d \n"
5 call    _printf
6 add     esp, 8
7 retn
8 _main endp

而进入call则是:

1 int __cdecl main(int argc, const char **argv, const char **envp)
2 {
3     return printf("sum = %d \n", 579);
4 }

在这里感谢所有的前辈给出的经验。

原文地址:https://www.cnblogs.com/tk091/p/2481291.html