VC和汇编高手请进

 

wangzhangyong411 发表于: 2007-04-13 11:14:21 楼主
请问下 , VC 中函数调用的时候不是 push edi,esi,ebx,ebp
其他三个还好理解是什么  在数值上也好判断
那个 ebx 到底存放了什么啊 ?
为什么每次运行都不一样 , 有时是 7FFDD000, 都在这个值附近
在线等

 

wangzhangyong411 发表于: 2007-04-13 11:15:141   得分 : 0
难道是真正的内存地址 ?     而不象其他几个所示的是虚拟内存地址 ?

 

wangzhangyong411 发表于: 2007-04-13 11:54:502   得分 : 0
高手都上哪去了 ?
回答问题啦

 

attababy 发表于: 2007-04-13 12:01:593   得分 : 0
你可以在在单步调试中反汇编代码,就清楚了。

 

wangzhangyong411 发表于: 2007-04-13 12:04:395   得分 : 0
我就是反汇编了才看到 ebx 的值
没看懂
已经单步到最细了

 

wangzhangyong411 发表于: 2007-04-13 13:02:406   得分 : 0
谁给我个满意的答案     马上给 50

 

funics 发表于: 2007-04-13 13:31:018   得分 : 10
根据我的试验,在 win2000 以上操作系统对于 ebx,esi,edi 好像是拿来就用,没有进行保护和恢复,如果你的程序中使用了这几个寄存器,请一定先压栈,用完后恢复。否则会使程序在 win98 下正常,在 win2000 下出现莫名其妙的非法操作,一般是提示某个地址不能进行读写操作,而这个地址并不在你的程序的控制下。
基于以上的原因,由编译器生成的函数代码一般都先保存了这几个寄存器的内容
反汇编以后的函数大概都有如下的结构 , 进入函数和退出函数之处都有这几行保存寄存器的代码:
void   shellcode_main(void)
{
0041C750     push                 ebp    
0041C751     mov                   ebp,esp  
0041C753     sub                   esp,40h  
0041C756     push                 ebx    
0041C757     push                 esi    
0041C758     push                 edi    

        make_shellcode(   4444,   shellcode_buf,   shellcode_len   );
0041C759     push                 offset   shellcode_len   (456D00h)  
0041C75E     push                 offset   shellcode_buf   (456900h)  
0041C763     push                 115Ch  
0041C768     call                 make_shellcode   (419BEFh)  
0041C76D     add                   esp,0Ch  
        print_shellcode(   shellcode_buf,   shellcode_len   );
0041C770     mov                   eax,dword   ptr   [shellcode_len   (456D00h)]  
0041C775     push                 eax    
0041C776     push                 offset   shellcode_buf   (456900h)  
0041C77B     call                 print_shellcode   (419E15h)  
0041C780     add                   esp,8  

        __asm
        {
                lea         eax,   shellcode_buf
0041C783     lea                   eax,[shellcode_buf   (456900h)]  
                jmp         eax
0041C789     jmp                   eax    
        }
}
0041C78B     pop                   edi    
0041C78C     pop                   esi    
0041C78D     pop                   ebx    
0041C78E     mov                   esp,ebp  
0041C790     pop                   ebp    
0041C791     ret                

 

funics 发表于: 2007-04-13 13:33:109   得分 : 10
解析 C++ 汇编代码
         
首先,进入函数体,就要执行三条初试化指令:
        @01:   push                 ebp  
        @02:   mov                   ebp,esp  
        @03:   sub                   esp,0C0h
 
ebp
寄存器在 Visual   C++ 中是被默认用来做基址指针的。因此,在刚进入函数执行阶段,都要对 ebp 进行相应的操作。第一步,如 @1 语句 ebp 中的值,然后将它用在本函数中。第二步,获取当前堆栈指针。获得的堆栈指针将作为函数局部变量的基址指针使用。第三条语句 @3 ,因为 C/C++ 中,程序局部变量是在堆栈中分配的。可是,我们并没有在每个函数中发现诸如 AllocMem 等申请内存的函数或指令。实际上,函数中的局部变量空间的分配就是由这条指令完成的。在本例中,程序分配了 0C0H 192 )字节的空间供该子函数使用。
 
     
其次,是辅助寄存器 ebx,edi,esi 的状态保存。作为通用寄存器,它们经常被用在一些常见的操作中。特别是在字符串、数组等的操作中, edi esi 通常作为存储目的、源数据的地址指针来使用。因此这里先保存这三个寄存器的值。虽然在本例中,并没有用到 ebx esi ,但两者还是被保存了。

 

wangzhangyong411 发表于: 2007-04-13 13:37:5910   得分 : 0
感觉上这几个寄存器应该是用来恢复现场的

edi,esi,ebp 都可以看出来 ,PUSH 在被调函数的栈里     应该是调用完后回去的用的

但是 ebx 是什么用的 ?     main 调用一个函数的时候     一般的 edi   =   0   esi   =   0012ff80   ebp   =  

0012ff80      
但是 EBX 怎么就是一个不确定的数值呢

就想知道 ebx 到底在这个时候存放的是什么

 

wangzhangyong411 发表于: 2007-04-13 13:43:1811   得分 : 0
#include   <stdio.h>

void   mytrangle()
{
int   p[10]   =   {1};

//p[10]   =   p[10]   -   1;
p[10]   =   0x0012FF2C;
p[10   -   32]   =   0x0012FF2C;
}

int   main()
{
mytrangle();
//test();

return   0;
}

现在帖的这个函数     我本想用这个来直接换掉 ebp     edi 的值     也确实换掉了
而且换成本身自己这个函数的基址 , 但是按原来的想法他应该返回到自己这个函数     成为不断
自我调用才对  为什么没有效果呢     只是程序最后结束才出错

 

al0n9 发表于: 2007-04-13 13:52:5312   得分 : 10
一般按照函数间调用的约定 , 函数中可以自由使用 eax,ecx,edx;
其它寄存器如果需要使用则需要保存 , 用完时恢复;

进入函数后 EBX 就入栈,这样后面就可以自由使用 EBX 了。虽然一般的 C 函数反汇编后看,都没有使用 EBX ,但是在很多需要内嵌汇编指令的地方,由于 80x86 系列的 CPU 通用寄存器非常少,所以非常有可能要用到 EBX ,而且编译程序不可能先扫描一遍源程序,看看有没有在内嵌汇编指令中用到 EBX 然后再入栈,通用的做法就是直接将 EBX 入栈。
如果函数中没有用到 EBX 寄存器,通过优化指令,就可以去掉 EBX 入栈出栈的语句。你可以通过一些专门的反汇编工具看看那些优化过的程序反汇编码,你就会发现,里面没有 EBX 入栈和出栈的指令。

 

wangzhangyong411 发表于: 2007-04-13 14:08:2613   得分 : 0
那如果想在自己的代码里实现用代码覆盖返回地址以达到返回到自己指定的地址去  

那应该怎么做呢


恭候高手回答 ~~~

 

funics 发表于: 2007-04-13 14:15:2114   得分 : 10
void   overflow_func(const   char   *str)
{
        //   +   9   /
        //   +   8   |
        //   +   7   |
        //   +   6   str   :   char   *           <--  
函数参数
        //   +   5   /
        //   +   4   |
        //   +   3   |
        //   +   2   ret   :   int                 <--  
返回地址
        //   +   1   /
        //   +   0   |
        //   +   9   |
        //   +   8   ebp   :   int                 <--   esp                   push                 ebp
        //   +   7   buf[7]   :   char                                         mov                   ebp,esp  
        //   +   6                                                                     sub                   esp,48h   ;72   Byte?
        //   +   5                                                                     push                 ebx
        //   +   4                                                                     push                 esi
        //   +   3                                                                     push                 edi
        //   +   2
        //   +   1
        //   +   0   buf[0]
        char   buf[8];

wangzhangyong411(B41)   :
void   mytrangle()
{
int   p[10]   =   {1};

//p[10]   =   p[10]   -   1;
p[10]   =   0x0012FF2C;
p[10   -   32]   =   0x0012FF2C;
}
p 缓冲区之前还有一个 push   ebp ,所以 p[10+4] 的位置才是函数的 ret 地址,
p[10+4]   =   0x0012FF2C
才能覆盖掉返回地址,让他不断自我调用。

 

yuanchengjun 发表于: 2007-04-13 14:40:4615   得分 : 10
不用关心 ebx 什么意思。

程序运行到需要调用函数的时候,保存一下 ebx ,函数中就可以随便使用 ebx

函数退出就回复 ebx ,继续做该做的事情。

汇编能用的寄存器就那么几个,不够用的,所以只能这样了。

 

wangzhangyong411 发表于: 2007-04-13 14:44:5616   得分 : 0
成功了 , 终于按照我说的直接在代码里实现跳转了

不容易 .....

小时候没好好学汇编

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值