手动修改PE文件实现dll注入-记事本

查看 78|回复 6
作者:hhhh214   
手动修改PE文件实现dll注入-记事本
目标:通过手动修改PE文件实现弹出一个窗口。首先是找到输入表的文件偏移位置。使用010 Editor中打开notepad.exe。在struct IMAGE_NT_HEADERS NtHeader下的struct IMAGE_OPTIONAL_HEADER32 OptionalHeader下的struct IMAGE_DATA_DIRECTORY_ARRAY DataDirArray的第二个元素中可以找到输入表的地址。如下图。


image-20230514211558699.png (23.95 KB, 下载次数: 0)
下载附件
2023-5-15 20:42 上传

7604h是输入表的内存虚拟地址,由于notepad.exe的ImageBase为01000000h,所以输入表在内存的地址为01000000h+7604h=01007604h。在OllyDbg打开notepad.exe转到地址01007604h可以发现,是IID表(数组)的位置。如下图。


image-20230514205250438.png (56.72 KB, 下载次数: 0)
下载附件
2023-5-15 20:42 上传

IID表在文件中的位置0x6A04如下图。


image-20230514214757329.png (52.35 KB, 下载次数: 0)
下载附件
2023-5-15 20:42 上传

要添加一个IID数组,就要修改当前数组的一块内存。这块内存一般是以IID相关联的的结构OriginalFisrtThunk和FirstThunk,不能被覆盖,所以只能将整个数组移到一个新的区域里。接下来就是思考将IID数组放在哪一个位置了。由于IID数组的大小为C8h,新加一个数组后,IID的数组大小为0xDC(0xC8+0x14)。新加入IID数组的空隙地址要大于0xDC。此时要考虑节区之间的空隙地址。notepad.exe程序下的节区只有三个.text、.data和.rsrc。如下图。


image-20230514212602939.png (21.88 KB, 下载次数: 0)
下载附件
2023-5-15 20:43 上传

由于本程序中FileAlignment为200h,所以节区的对齐都是以200h为标准的。先看.text节区的。


image-20230514212711941.png (32.75 KB, 下载次数: 0)
下载附件
2023-5-15 20:43 上传

VirtualSize:指出实际被使用的区块的大小,是在进行对齐处理前区块的实际大小。如果VirutalSize的值大于SizeofRawData的值,那么SizeofRawData表示来自可执行文件初始化数据的大小,与VirtualSize相差的节区用0填充。SizeofRawData:该块在磁盘中所占的空间。PointerToRawData:该块在磁盘文件中的偏移。可以看到.text节区剩余的区域为7800h-7748h=0xB8(小于0xDC)、,所以不能作于新的IID数组地址位置。接下来看.data节区的。


image-20230514212956941.png (30.41 KB, 下载次数: 0)
下载附件
2023-5-15 20:43 上传

也没有空余空间。最后看一下.rsrc节区的。


image-20230514213929254.png (30.82 KB, 下载次数: 0)
下载附件
2023-5-15 20:44 上传

VirtualSize也小于SizeofRawData。由于这三个节区都没有满足有足够的空隙空间,所以只能扩展最后一块节区的空间了,最后一个节区的结束地址为PointerToRawData+SizeofRawData=0x10400。将IID数组复制到0x10400地址中。


image-20230514215802699.png (45.5 KB, 下载次数: 0)
下载附件
2023-5-15 20:44 上传

在104B4后的0x14个地址是准备新加入的IID数组,后面还要添加一项全是0的数组元素作为数组结尾。 IMAGE_IMPORT_DESCRIPTOR STRUCT
     union
         Characteristics           DWORD   ?
         OriginalFirstThunk        DWORD   ?   ;指向INT
     ends
     TimeDateStamp                 DWORD   ?
     ForwarderChain                DWORD   ?
     Name                          DWORD   ?
     FirstThunk                    DWORD   ?   ;指向IAT
IMAGE_IMPORT_DESCRIPTOR ENDS
接下来在原来的IID区域构建新的OriginalFirstThunk和FirstThunk,这些只是数据,之后会在新的IID区域写上指针指向这些数据。首先是写上OriginalFirstThunk和FirstThunk,要与0项结尾。


image-20230515103152486.png (140.57 KB, 下载次数: 0)
下载附件
2023-5-15 20:44 上传



image-20230515113425590.png (33 KB, 下载次数: 0)
下载附件
2023-5-15 20:45 上传

在原来的IID地址中写上数据(也可以不在原来的位置写,只是原来的位置已经没用了),在在绿色的地方写上Dll名字。MsgDll.dll(以00结尾,4D 73 67 44 6C 6C 2E 64 6C 6C),在6A20h处写上函数名字,IMAGE_IMPORT_BY_NAME,第一个字节是IMAGE_IMPORT_BY_NAME结构中的hint(WORD),不是必需的,一般为00 00 。之后的Name写为Msg(4D 73 67 00 ,以NULL结尾,可能要对齐一个WORD。)Msg的文件偏移地址为6A20h,所以RVA为0x6A20-0x400+0x1000=0x7620 。所以OriginalFirstThunk和FirstThunk都要指向0x7620。注意小端模式。更改后的原来IID地址。


image-20230515120156784.png (22.56 KB, 下载次数: 0)
下载附件
2023-5-15 20:45 上传

还有修改新IID数组的信息,OriginalFirstThunk的偏移量是0x7604(将上图的文件偏移量转化即可),Name 的偏移量是0x7614,FiistThunk的偏移量是0x760C.修改后如下图。


image-20230515124835610.png (47.83 KB, 下载次数: 0)
下载附件
2023-5-15 20:45 上传

接下来就是修改PE文件头了,因为IID数组的位置已经改变了,即输入表的位置和大小都改变了。所以要修改PE文件头。还有一个小细节,将最后节区的偏移量增加到0x200的倍数。修改import表的DWORD VirtualAddress和DWORD Size 。


image-20230515123804810.png (5.97 KB, 下载次数: 0)
下载附件
2023-5-15 20:45 上传

修改最后一个节区的大小(SizeOfRawDat)。改成8400h,由于加了200h,VirtualSize还有很多空间,所以不用改VirtualSize。


image-20230515203128385.png (34.48 KB, 下载次数: 0)
下载附件
2023-5-15 20:46 上传

改后。


image-20230515203339245.png (42.87 KB, 下载次数: 0)
下载附件
2023-5-15 20:46 上传

最后还有修改以下节区的块属性(IMAGE_SECTION_HEADER的最后一个成员Charateristics)。块属性的值是叠加了。例子如下。E0000020h=20000000h | 40000000h | 8000 0000h | 0000 0020h,代表该块包含执行代码,可读、可写、可执行。由于原来IID数组的位置用来存放FirstThunk了,这个值载入内存时会被改的。它原来的文件偏移量时0x6A0C。


image-20230515184041676.png (32.58 KB, 下载次数: 0)
下载附件
2023-5-15 20:46 上传

可见,400h到400h+7800h地址内的区域都是.text节区。


image-20230515184255455.png (56.6 KB, 下载次数: 0)
下载附件
2023-5-15 20:46 上传

该值初始为0x60000020,将该值改成0x60000020|0x80000000=E0000020h后,可表示改.text就可以进行写了。


image-20230515184526941.png (27.1 KB, 下载次数: 0)
下载附件
2023-5-15 20:46 上传

改后如上图。但更改后预想中的弹窗还是没有出现,因为其他输入表数组的TimeDateStamp都是0xFFFFFFFF,也就是-1,从IMAGE_IMPORT_DESCRIPTOR的定义可知,如果这个值为-1,表示该输入项是预先bound(绑定)。如果系统发现绑定是有效的,就不会去处理输入表的加载了。所以要把PE文件头数据目录中的Bound Import Table清零,强制重新处理输入表。


image-20230515202021808.png (34.23 KB, 下载次数: 0)
下载附件
2023-5-15 20:47 上传

清完如上图所示。至此打开文件,可以发现先弹出了弹窗。


image-20230515203930679.png (41.36 KB, 下载次数: 0)
下载附件
2023-5-15 20:47 上传

下载次数, 数组

冥界3大法王   

@hhhh214   不喜欢注入记事本,能不能专门表演下注入x64dbg实现新的功能?
但是过程还是值得借鉴的。
而且 看到你的那个记事本 图标想起我的那个记事本,那是早期的(Win9x/Win7/XP),上来默认ANSI编码保存的。
看雪上修改增加各种功能的,基本上都拜读过。。。弄个dll,修改导入导出表。比如增加个窗口置顶啥的。
小宇殿下   

不如依赖注入来的方便呢
Spacecraft   

过程还是值得学习借鉴
r1ck   

学到了谢谢!
01z8z0   

学习学习,谢谢分享。
灵剑丹心   

是永久注入吗
您需要登录后才可以回帖 登录 | 立即注册

返回顶部