注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

风雨夜归人

专业收集资料,个人爱好!

 
 
 

日志

 
 

逆向_第四课  

2010-03-12 22:32:16|  分类: 逆向 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 在各个语言中有数据结构这个东东,它是计算机存储 组织数据的方式.逆向分析时,确定了数据结构后,算法就容易得到了.有时候事情当然也会反着来,根据特定的算法来判断数据结构.
       先看局部变量的
      局部变量十亿个函数内部定义的变量,只有在函数内才能使用,如计数器,临时变量等.使用局部变量带来的好处,使程序模块化封装变的可能.从汇编语言角度看,局部变量就是在堆栈中进行分配,函数执行完毕后释放这些堆栈,或者直接把局部变量放在寄存器中,我在视频中也告诉各位把寄存器可以理解为变量.
       第一种方法是用堆栈存放局部变量
       局部变量在程序中用"sub esp,8"语句为局部变量分配空间,用[ebp-xxxx]寻址调用这些变量,而参数调用相对于ebp偏移量是正的,即[ebp+xxxx],因此在逆向时比较容易区分开.编译器在优化模式时,则通过esp寄存器直接对局部变量与参数寻址了.当函数退出时,用'add esp,8'平衡堆栈,以释放局部变量所占据的内存.有些编译器,如Delphi通过给esp加一个负值来进行内存分配.另外,编译器可能会用"push reg"指令来取代"sub esp,4"指令,以节省几个字节.局部变量分配堆栈一般有三种形式:
1.
sub esp,n
.....
add esp,n
2.
add esp,-n
....
sub esp,-n
3.
push reg
.....
pop reg
看看第三种形式的实例"push reg"指令来取代"sub  esp,4"指令的.
先看C的代码:
int add(int x,int y)
int main(void)
{
int a=5,b=6; //声明局部变量
add (a,b);
return 0;
}
int add(int x,int y)
{
int z; //声明局部变量
z=x+y;
return (z);
}
将他编译后反汇编.
00401000  /$  55            push    ebp
00401001  |.  8BEC          mov     ebp, esp
00401003  |.  83EC 08       sub     esp, 8                           ;  为局部变量分配内存
00401006  |.  C745 FC 05000>mov     dword ptr ss:[ebp-4], 5          ;  参数1放到局部变量[ebp-4]中
0040100D  |.  C745 F8 06000>mov     dword ptr ss:[ebp-8], 6          ;  参数2放到局部变量[ebp-8]中
00401014  |.  8B45 F8       mov     eax, dword ptr ss:[ebp-8]
00401017  |.  50            push    eax
00401018  |.  8B4D FC       mov     ecx, dword ptr ss:[ebp-4]
0040101B  |.  51            push    ecx
0040101C  |.  E8 09000000   call    local.0040102A
00401021  |.  83C4 08       add     esp, 8
00401024  |.  33C0          xor     eax, eax
00401026  |.  8BE5          mov     esp, ebp
00401028  |.  5D            pop     ebp
00401029  \.  C3            retn
;函数add (int x,int y)反汇编代码如下:
0040102A  /$  55            push    ebp
0040102B  |.  8BEC          mov     ebp, esp
0040102D  |.  51            push    ecx                              ;  为局部变量分配内存
0040102E  |.  8B45 08       mov     eax, dword ptr ss:[ebp+8]        ;  取参数1
00401031  |.  0345 0C       add     eax, dword ptr ss:[ebp+C]        ;  参数1+参数2
00401034  |.  8945 FC       mov     dword ptr ss:[ebp-4], eax        ;  将相加的结果放到局部变量[ebp-04]中
00401037  |.  8B45 FC       mov     eax, dword ptr ss:[ebp-4]        ;  将返回结果放到eax中
0040103A  |.  8BE5          mov     esp, ebp
0040103C  |.  5D            pop     ebp
0040103D  \.  C3            retn
    在函数add()里不存在"sub esp,n"这样的指令,程序是通过一句"push ecx"指令来开辟一块堆栈空间的,然后用[ebp-04]来访问这块空间
    局部变量的起始值是随即的,是其他函数执行完后留在堆栈中的垃圾数据,因此需要对其初始化.初始化局部变量有两种方法:一种是通过mov 指令为变量赋值,如"mov [ebp-04],5";另一种是使用Push 指令直接将值压入堆栈,如push 15.
       第二种是利用寄存器
       除了堆栈占用了2个寄存器外,编译器会利用剩下的6个通用寄存器尽可能有效地存放局部变量,这样可以产生最小的代码,提高效率.如果寄存器不够用,编译器将会将变量放到堆栈中.逆向分析时要注意局部变量的生存周期比较短,必须及时确定当前寄存器的变量是那个变量.
  评论这张
 
阅读(359)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017