首页
社区
课程
招聘
[求助][求助]关于写壳时壳的重定位问题
发表于: 2015-8-9 17:15 5282

[求助][求助]关于写壳时壳的重定位问题

2015-8-9 17:15
5282
思路如下,
    1. 为待加壳程序新添一个区段,
    2. 处理壳的重定位表,
    3. 将壳复制进去,
    4. 设置新的OEP指向( OEP - 壳代码段RVA + 新段RVA)
   
大体如上

    在修复重定位表时,采用 
  
     *((ULONG*)Data) -=  ShellCodeOffset;  //重定位地址 - 壳的代码段偏移
    *((ULONG*)Data) -= ShellImageBase;  //重定位地址 - 壳的 Imagebase

 
    *((ULONG*)Data) += NewSecOffset;  // 加 新段偏移
    *((ULONG*)Data) += ImageBase;      //加 待加壳程序 基址

    其中 Data 是就是 重定位表中需重定位的项的地址,
    壳已将 text 和data 段合并

出现的问题:

     在运行 加壳后的程序后, 用OD 跟,发现

013D6012    68 54604000     push 0x406054
013D6017    68 5C604000     push 0x40605C
013D601C    6A 00           push 0x0
013D601E    FF15 00604000   call dword ptr ds:[0x406000] ; 这是MessageBox IAT 还没修复

其中 0x406054 和 0x40605C 就是 修复后的值,但是程序加载时的地址是
013D0000 新的起始段在  013D6000  ,所以的重定位后正确的字符串应该在
0x13D6054
如下:
013D6054  61 61 61 61 00 00 00 00  aaaa....

问题就是 为什么 壳的重定位表没有生效,没有随待加壳程序的加载地址变化而动态修改?
可能理解有问题,希望哪位好心人能给予一个提示。

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
2
好好去撸   pe 权威指南  的知识把~
2015-8-9 19:34
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
目测ImageBase有点问题,如果重定位正确,ImageBase应该是0x01000000,而不是0x00400000。
2015-8-10 08:40
0
雪    币: 608
活跃值: (643)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
需要重定位的地址的RVA要在重定位表中,并且FileHeader->Characteristics &= ~IMAGE_FILE_RELOCS_STRIPPED;
2015-8-10 08:58
0
雪    币: 1258
活跃值: (1434)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
那意思是 要将壳的重定位表复制到 待加壳的重定位表中吗?
2015-8-10 10:59
0
雪    币: 1272
活跃值: (746)
能力值: ( LV13,RANK:810 )
在线值:
发帖
回帖
粉丝
6
处理重定位的方式有两种
1.自己动态计算重定位偏移
call @F
@@:
pop ebx
sub ebx, offset @B

lea eax, [ebx+offset Sleep]
push 1
call    eax

传统的壳大部分都是采用这种

2.重定位表处理
把壳的loader部分写成stub
加壳前,把stub基址修复成新的壳区段地址,然后再附加上去
比如bambam,npack,ZProtect,eXPressor都是这类结构

根据你不同的需求来决定了
2015-8-27 11:17
0
雪    币: 1258
活跃值: (1434)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=Anskya;1389013]处理重定位的方式有两种
1.自己动态计算重定位偏移

call @F
@@:
pop ebx
sub ebx, offset @B

lea eax, [ebx+offset Sleep]
push 1
call    eax

传统的壳大部分都是采用这种

2.重定位表...[/QUOTE]

非常感谢 楼上大哥给的提示,
后来 我在论坛找到一个code ,
是动态获取的 运行时地址的 ,

// 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;

}

原理就是  
        修正 =     运行时地址 (返回地址 - 5) -  编译地址 ( 函数名 )
        
任何 编译地址 + 修正值就得到了 运行时地址。

非常感谢!
2015-9-5 22:33
0
游客
登录 | 注册 方可回帖
返回
//