汇编逆向(三)
本帖最后由 gmh5225 于 2014-12-25 17:11 编辑写这个纯属就是自己记录下自己的学习经历,没有其他的意思。
局部变量,参数,全局变量
无脑记法:
局部变量:第一个 第二个,类推
参数:第一个参数,第二个,类推
全局变量:一般都是 mov eax,dword ptr ds:之类的
局部变量需要使用subesp,xx 开辟空间xx个字节空间,有几个局部变量就开几个
举例:
003C1040 >55 push ebp ;保存原来ebp指针
003C1041 8BEC mov ebp, esp ;ebp指向esp,即堆栈
003C1043 83EC 0C sub esp, 0xC ; 开辟12个字节空间供3个变量
003C1046 C745 FC 0300000>mov dword ptr , 0x3 ; int a
003C104D C745 F8 0400000>mov dword ptr , 0x4 ; int b
003C1054 C745 F4 0000000>mov dword ptr , 0x0 ; int c
////////////////////////////////////////////////////////////////////////
003C10A9 83C4 04 add esp, 0x4
003C10AC 33C0 xor eax, eax ;清空eax
003C10AE 8BE5 mov esp, ebp ;esp指向当前ebp,同步跟进
003C10B0 5D pop ebp ;还原原来ebp指针
003C10B1 C3 retn
可以看到我的第一个局部变量是 ,初值是3,第二个是b,第三个是c
而参数因为之前的压栈导致esp的减少,一般如果是int型,就每次减4个字节,进行call的时候还会减4字节,在ret时返回4字节平衡,所以第一个参数就是ebp+8,注意堆栈的存储方式
,第二个就是ebp+c
举例:
003C1000 >55 push ebp
003C1001 8BEC mov ebp, esp
003C1003 8B45 08 mov eax, dword ptr //这里是第一个参数
003C1006 0345 0C add eax, dword ptr // b
003C1009 5D pop ebp
003C100A C3 retn
此外,编译器还会用其他的寄存器来代替开辟局部变量的操作,以此来节省二进制的大小
C源代码:
int add(int a,int b)
{
int c=a+b;
return c;
}
int main()
{
int a=3,b=4,c=0;
c=add(a,b);
printf("%d",c);
system("pause");
return 0;
}OD反汇编:
主要看add这个函数内部:
010E1000 >55 push ebp
010E1001 8BEC mov ebp, esp
010E1003 51 push ecx //这里就是运用了节省空间的方法,达到同样开辟4字节的效果
010E1004 8B45 08 mov eax, dword ptr
010E1007 0345 0C add eax, dword ptr
010E100A 8945 FC mov dword ptr , eax
010E100D 8B45 FC mov eax, dword ptr
010E1010 >8BE5 mov esp, ebp
010E1012 5D pop ebp
010E1013 C3 retn
上面的代码可以看到,push ecx这命令,相当于是subesp,4 不过这样写二进制编码就是51,节省了很大的空间,提高效率
全局变量:一般都是 mov eax,dword ptr ds:之类的,里面的内容是一个4字节的内存地址
C源代码:
int x=0;
int add(int a,int b)
{
return a+b+x;
}
int main()
{
int a=3,b=4,c=0;
x=5;
c=add(a,b);
printf("%d",c);
system("pause");
return 0;
}OD反汇编: 01071020 >55 push ebp
01071021 8BEC mov ebp, esp
01071023 83EC 0C sub esp, 0xC ; 开辟12个字节的空间
01071026 C745 FC 0300000>mov dword ptr , 0x3 ; int a=3
0107102D C745 F8 0400000>mov dword ptr , 0x4 ; int b=4
01071034 C745 F4 0000000>mov dword ptr , 0x0 ; int c=0
0107103B C705 6C330701 0>mov dword ptr , 0x5 ; 全局变量x=5
01071045 8B45 F8 mov eax, dword ptr
01071048 50 push eax ; 压b
01071049 8B4D FC mov ecx, dword ptr
0107104C 51 push ecx ; 压a
0107104D E8 AEFFFFFF call testtest.add ; 调用add函数
01071052 83C4 08 add esp, 0x8 ; 堆栈平衡
01071055 8945 F4 mov dword ptr , eax
01071058 8B55 F4 mov edx, dword ptr
0107105B 52 push edx
0107105C 68 F4200701 push testtest.010720F4 ; ASCII "%d"
01071061 FF15 9C200701 call dword ptr [<&MSVCR100.printf>] ; msvcr100.printf
01071067 83C4 08 add esp, 0x8
0107106A 68 F8200701 push testtest.010720F8 ; ASCII "pause"
0107106F FF15 A4200701 call dword ptr [<&MSVCR100.system>] ; msvcr100.system
01071075 83C4 04 add esp, 0x4 ; 压 a
01071078 33C0 xor eax, eax
0107107A 8BE5 mov esp, ebp
0107107C 5D pop ebp
0107107D C3 retn
看下add函数
01071000 >55 push ebp
01071001 8BEC mov ebp, esp
01071003 8B45 08 mov eax, dword ptr ; 参数1 a
01071006 0345 0C add eax, dword ptr ; 参数2 ba=a+b
01071009 0305 6C330701 add eax, dword ptr ; 全局变量x a=a+x
0107100F 5D pop ebp
01071010 >C3 retn
变量到此结束!
很详细的教程,学习了!
希望这个系列一直做下去!
{:5_117:}谢谢分享。这个要支持一下,对于新手来说,非常的有用呀。。。。
不会c语言怎么破
教程不错学习一下
感谢楼主教程,继续学习中。 学习学习
页:
[1]
2