小鱼塘--自说自话的地方

  • 小玩意
  • 小想法
记录自己技术和想法地方
  1. 首页
  2. windows
  3. 正文

手工构建PE-导入表构建(二)

5 6 月, 2024 1061点热度 0人点赞 0条评论
内容目录

背景

这里进行导入表,方便自己使用代码,导入一个代码进行测试,这个比较方便。

逻辑

  1. 分析导入表的逻辑
  2. 添加导入表

知识点

  1. 导入表的地址是虚拟地址(内存地址,不是相对地址)
  2. 需要一个节点起始地址(否则无效),所以如果需要单独节点地址
  3. 其他的参数需要分析
typedef struct _IMAGE_IMPORT_DESCRIPTOR
{
    union {
        DWORD   Characteristics;
        DWORD   OriginalFirstThunk;     // 包含指向IMAGE_THUNK_DATA(输入名称表)结构的数组
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;              // 当可执行文件不与被输入的DLL进行绑定时,此字段为0 
    DWORD   ForwarderChain;             // 第一个被转向的API的索引
    DWORD   Name;                       // 指向被输入的DLL的ASCII字符串的RVA
    DWORD   FirstThunk;                 // 指向输入地址表(IAT)的RVA
} IMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_THUNK_DATA32
{
    union {
        DWORD ForwarderString;      // 转发字符串的RAV
        DWORD Function;             // 被导入函数的地址
        DWORD Ordinal;              // 被导入函数的序号
        DWORD AddressOfData;        // 指向输入名称表 PIMAGE_IMPORT_BY_NAME
    } u1;
} IMAGE_THUNK_DATA32;
typedef struct _IMAGE_IMPORT_BY_NAME
{
    WORD    Hint;          // 函数序号
    CHAR   Name[1];        // 导入函数的名称
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

2.5 PE结构:导入表详细解析-腾讯云开发者社区-腾讯云 (tencent.com)

过程

  1. 找到导入表的描述,填充十六进制 0x2000
  2. 在文件偏移0x600 按照 IMAGE_IMPORT_DESCRIPTOR 填写
  3. 在文件偏移0x700 按照 IMAGE_THUNK_DATA32 填写
  4. 在文件偏移0x400 修改代码改成 call 导入表的地址调用函数的数组地址

导入表目录,这个地址必须指向节起始虚地址:0x2000指向第二个节点起始地址,对应的文件地址0x600(pe头用0x400 ,再加上一个节0x200,那么就是0x600)

0x600填写一个字段

OriginalFirstThunk:00 21 00 00 :0x2100 (虚拟地址)
TimeDateStamp:00 00 00 00 :0x0(用不到,无所谓)
ForwarderChain: 00 00 00 00 :0x0(用不到)
Name:80 21 00 00:0x2180 (虚拟地址):文件地址0x780,这里在0x780位置直接编辑字符串
FirstThunk:这里偷懒跟OriginalFirstThunk 一样地址

0x700编辑

Ordinal:1C 04 00 80:0x800041C 这里80 代表最高位是1,代表这个序号导入的,所以序号是0x41C 这个函数是:OutputDebugstringA
0x2100 + 0x400000 = 0x402100

修改0x400代码

我直接用x64 dbg 调试编辑代码,然后打补丁,因为我不记得机器码,懒的自己转换。

call dword ptr ds:[0x00402100]

运行代码

这里运行代码会报错,这里地址写死,但基地址会变化,所以我们要在pe头修改属性,不要动态调整基本地址,否则会有问题。

修改后你会发现不异常,因为我们没有压入字符串,我们直接用pe导入表那个地址,减少不必要麻烦。

现在重写代码
0x2180 + 0x400000 = 0x402180(之前的虚拟地址)

push  0x402180
call dword ptr ds:[0x00402100]

直接x64 dbg直接改,进行就可以了,或者通过C语言编译得到机器码,然后对应修改,直接填写(但这种容易写错,直接反汇编工具直接修改即可。)


保存补丁就可以了, 再次跑一下,

效果图

一个简单程序打印就完成了,你可以用改成puts 函数进行打印,逻辑还是一样。这里我全部变量,同时基地址不变化,不然就需要重定位表了,后面增加重定位表了。

文件

上版本原始文件,没有重定位表的
链接:https://pan.quark.cn/s/e1303184a80e
建立重定位表用序号导入函数的exe
链接:https://pan.quark.cn/s/116f05487951

标签: 手动构建pe
最后更新:5 6 月, 2024

小鱼儿

爱研究技术,爱玩LOL

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2022 小鱼塘. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

湘ICP备18005349号