参照书籍:《Windows PE权威指南》;
文件:附件中(文件密码:apebro
);
使用工具:WinHex、CFF、StudyPE+、OD、IDA、MSDN;
1、有时候会需要干净的小exe文件进行魔改;
2、无关紧要的地方就用CC(int3)
或者90(nop)
的地方覆盖了;
3、关键位置我都用红框给框起来了;
使用WinHex
手动构建一个PE;
因为是手动构造,所以就舍弃了DOS头下面的一堆垃圾数据了;
最重要的四个参数标注出来,这四个数都是有来头的,并不是瞎设的;
这分别是:
这时候就可以明白代码页节表的文件起始地址就是从0x00000200
开始的;
这个时候我们需要构建我们的导入表了,因为.text
节区空间很大,所以也放里面了;
首先在导入表节表目录处设置一下。
‘
这里解释一下:
导入符号表为零,系统就会直接引用IAT表,这是系统特性;
然后看导入链接库名(RVA:0x00001030
,FOA:0x00000230
),这是一个C语言类型的字符串,\0
结尾,得到导入的动态库名为user32.dll
;
再看IAT表间接地址(RVA:0x00001050
,FOA:0x00000250
),得到IAT表地址(RVA:0x00001040
,FOA:0x00000240
);
这里就是一个重点了,函数名字符串并不是从0x00000240
开始的,而是从0x00000243
开始的。因为这里的结构类型如下:
所以得到函数名MessageBoxA
;
用OD随便打开一个非我们正在构建的可执行文件,因为我们手动构建的PE文件有些字段被设置,所以OD并不能正常打开,除非有插件;
然后准备进行以下结构的汇编代码插入;
这里的Caption
和Text
两个字符串我们需要先找个地方存放;
然后根据约定,补齐0x200
的倍数;
这里我们补齐到0x3FF
;
然后选定代码存放位置;
这里的0x00000280
是FOA
,我们需要换算成RVA
,也就是0x00001080
;
在Optional Header
中找到OEP
,这里的OEP
是字段,并不是脱壳时说的原始入口点;
保存后,执行文件;
但是问题不大,我们要的就是如此,别退掉这个窗口;
首先是文件地址;
然后是内存地址,这个我们要看我们导入表的节表内容,查看加载地址;
既然导入表没问题了,我们剩下的就是要完善我们的程序了。
进入后很明显不是正常的入口地址;
问题不大,莫慌;
然后开始,我们要写入我们的代码了;
结果就是如此;
保存后退出所有界面,找到这个test1.exe文件,双击运行;
一觉醒来,坛主大佬亲临,并且指出了并不能跨平台的问题;
是可以运行的;
一闪而过,可见的是hello world!
字符串并没有传进去;
经过多方查找问题,终于找到问题所在;
需要将图中框起来的位置(Win32VersionValue
字段)用0
填充;
就运行起来了;
也是能运行起来的;
这里我就懵逼了,坛主大佬指的到底是哪里问题呢,还是先自己找一下,那就先复习一下导入表吧;
这里数据目录找导入表上面有,我就不赘述了;
我再复习了一下导入表的导入流程(以test1为例);
这里的结构是:
说太多容易乱,我直接就开始白话了;
这里要说一下的是桥1指向的地址列表被称为INT
表,桥2指向的地址列表被称为IAT
表;
操作系统如何读取PE的导入表
这里提一句,如果目标为0x00000000
,那么就是continue
操作,搜索下一个导入表,这里涉及一个无效导入表的奇技淫巧;
这里提一句,加载字符串时候,不能超过260个字节,如果超过了,即使是有效导入表,也会被操作系统拒绝加载,这里涉及一个反调试手段的奇技淫巧;
而FOA0x00000250
这个位置在加载后会被重定位API地址;
如果IAT
为00000000
,系统判断是非法PE,直接停止后续运行;
找到的字符串,前一个word
的函数序号,操作系统不参考,所以我填了nop(90)
;
找到了函数名(MessageBoxA),执行GetProcessAddress
,如果错误了,就中断执行;
如果执行成功了,就访问IAT
表(RVA0x00001050
->FOA0x00000250
)地址,并修正地址;
修正后:
整个流程理下来,还是没搞清楚大佬说的写死IAT是什么意思;
现在只能去反汇编一个C语言写的MessageBox
程序,一探究竟;
打开IDA看一下,这里是RA地址;
所以,编译器制作的PE文件也只是通过IAT跳转,系统加载的时候通过修正,得到当前系统的函数地址。
故并不存在跨平台问题
手动制作PE文件是个非常有意思的事情;
原本只是为了写另外一篇帖子,发现需要用到这个,如果写在一起又太臃肿,所以单独水一贴吧;
关于大佬说的写死IAT
的跨平台问题,我并没有找到问题,如果有大佬能指正,感激不尽;
1.
`镜像基址`:`
0x00400000
`;
2.
`镜像对齐`:`
0x00001000
`;
3.
`文件对齐`:`
0x00000200
`;
1.
`镜像基址`:`
0x00400000
`;
2.
`镜像对齐`:`
0x00001000
`;
3.
`文件对齐`:`
0x00000200
`;
IMAGE_IMPORT_BY_NAME struct{
word Hint;
/
/
函数编号;
dword Name;
/
/
函数名字符串;
}
IMAGE_IMPORT_BY_NAME struct{
word Hint;
/
/
函数编号;
dword Name;
/
/
函数名字符串;
}
push
0
push offset Caption
push offset Text
push
0
call MessageBoxA
retn
push
0
push offset Caption
push offset Text
push
0
call MessageBoxA
retn
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2021-4-8 15:35
被平头猿小哥编辑
,原因: 上传附件