神秘的call $+5 pop eax win7 动态基址每次都不同

call $5
pop eax
and eax,0xffff0000
and eax,base
jmp eax

 delphi可以这样

    mov ecx,$12345678   //这里写入原来OEP入口

    //动态基址获取
    //call $+5
    CALL @@1
  @@1:
    pop eax
    and eax,$ffff0000
    and ecx,$0000ffff
    or eax,ecx
    //jmp eax
    push eax

上面再实际情况中并不起作用,而应该用以下方式

    mov ecx,$12345678   //这里写入原来OEP入口
    mov edx,$12345678   //这里写入原ImageNtHeaders.OptionalHeader.ImageBase基址
    mov edi,$12345678   //这里写入新ep入口
    //动态基址获取
    //call $+5
    CALL @@1
  @@1:
    pop eax
    sub eax,35 //得到现在的ep+基址
    sub eax,edi  //减去ep 获得新的基址
    add ecx,eax  //得到动态的原oep
    //or eax,ecx
    //jmp eax
    //push eax
    push ecx
 

在进行病毒分析时,或者调试漏洞的shellcode时,经常看到标题中的指令流(E800000000 58,第二条肯定是pop指令,但是目的寄存器不一定是eax),这是干什么的呢?

       看起来貌似很神秘,其实结合前后代码的意图可以知道(进行实时调试),最终eax中存放的数据是0x00413935(就上面的代码),而这个0x00413935,恰好就是pop eax指令的地址,因此实际上这条指令流的作用就是获取执行call $+5时,eip的值,也可以简单认为是获取当前指令地址,获取当前指令地址有什么用呢?我所见过最多是使用场景是通过得到当前指令地址来获取硬编码到shellcode中的字符串的地址,通过简单计算当前指令地址+偏移(这个已知,因为shellcode就是自己写的),就可以获取到字符串的地址。

       这条指令流的原理也很简单,E8是call指令中的相对跳转指令(可以参考:http://www.mouseos.com/assembly/example/calling.html),它可以带一个dword参数,指明相对跳转的距离(E8 dword offset),计算方式很简单:下一条指令地址+ offset 即是call指令的目的地。下一条指令地址就是pop eax的地址啦。因此这个地方场景是这样滴:

       1、CPU执行到E800000000时,eip中此时存放的是下一条指令的地址,也就是0x00413935(计算机组成原理);

       2、CPU执行call指令,将call指令的下一条指令地址push到栈中(也就是0x00413935被push到栈中,这是用于函数调用后返回的);

       3、对E8指令进行解析,offset == 0,计算call指令目的跳转地址:下一条指令地址+ offset ,eip被存入0x00413935;

       4、跳转到0x00413935执行(实际就是call的下一条指令),执行pop eax,从上面的分析可知,此时栈顶的值是0x00413935,因此eax就被赋值0x00413935。

 

       有人可能想,获取当前指令地址,直接mov eax, eip不就行了么?还真不行,因为木有直接操作eip的指令的。

 

转载于:https://my.oschina.net/u/1777508/blog/608039

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值