YLLEN

要去看埃菲尔铁塔的顶

欢迎关注本人微博:t.cn/RGSLVUk

写壳<二>

    自己动手写 程序外壳<二>


  本次来讨论写壳是修改程序入口,从编译时地址转换运行时地址技术。



 

        程序运行时由PE加载器将其加载内存,换算程序入口,根据重定位表进行地址重定位,根据导入表中dll 获取 所需API地址填入IAT中 ,然后调用main函数大致如此。


     程序入口 = 加载地址 + OptionalHeader.AddressOfEntryPoint 。需要修改正常程序的OptionalHeader.AddressOfEntryPoint字段指向 外壳程序入口函数 RVA地址。

    

关于编译时地址转换运行时地址,其原理如下公式:

    差值A = 编译地址  -  运行时地址    

    运行时地址  =  差值A + 编译地址



 

 

这里 用 CALL 指令 来获取运行时地址,然后计算偏移。

        由CALL指令原理可知,其功能是将当前EIP(当前?) 保存在栈中,然后 JMP 到 指定地址

CALL 指令形如在下面场景中

  void A() {}

  void B() { A() ;}

  那么其机器码是  E8 offset   ( offset = 当前EIP - A的地址 ,然后取数值的补码)

总之 这中调用是以相对地址来调用,所以总是可以执行成功的。

 

      那么 根据CALL 指令 将返回地址压入栈中 ,我们利用 [ ESP+ 4] 处即为返回地址,

利用这个值 -  5(CALL指令占5 字节)  -  硬编码函数地址 = 差值A。 



程序如下


// & RetAddress = ESP + 8

long __stdcall RunAddressSubIfAddress(long RetAddress)

{

        long* pRetAddress;

        long ret ;


if(0 == RetAddress)    //触发异常

{

    DB(0xCC);

    DB(0xEB);

    DB(0xCC);

}

    pRetAddress = &RetAddress;

    pRetAddress --;


    ret = (*pRetAddress) - 5 - (long)GetRunAddressSubIfAddress;

    *pRetAddress = RetAddress;

    return ret;

}


__declspec(naked)


long __stdcall GetRunAddressSubIfAddress()

{

    __asm call RunAddressSubIfAddress;    //这里没有给数

}


// 将编译地址转换为运行时地址


PVOID __stdcall GetRunAddress(PVOID pData)

{


    

      

// 编译值 + 偏移(运行时 - 编译时)


    long sub =  GetRunAddressSubIfAddress();

    long ret = (long)((long)pData + sub);

return (PVOID) ret;

}




//计算 运行地址 - 编译地址

//

//

//    跳到 RunAddressSubIfAddress 时

//    push ebp

//    mov ebp ,esp

//     RetAddress 在: [ esp + 8 ] 实参  <其实值是  的 返回到 GetRunAddress 的下一条地址>

//    [ esp+ 4 ] 是返回地址 也就是 GetRunAddress调用 RunAddressSubIfAddress 后的下一条地址

//   pRetAddress = &RetAddress , 也就是  pRetAddress = esp + 8

//   pRetAddress --  就是 esp + 4  也就是指向的是 返回地址 (运行时)

//     那么 (* pRetAddress )  <运行是返回 GetRunAddressSubIfAddress 下一条地址 >-  ( GetRunAddressSubIfAddress + 5  编译后下一条指令地址) 

//     这个差值就是 运行时  与 编译时 的差值,得到这个差值就可以 定位所有 编译时数据了。。。

//








评论

© YLLEN | Powered by LOFTER