给pediy.dll手动增加引入函数(附图)
原文:https://www.pediy.com/kssd/pediy10/73963.html
高手就不用看了,仅以此献给和我一样第一次接触在引入表中新增函数的各位
起因是改造第一题的pediy.dll。
最初没有引入API,用PEB搜索Kernell32基址->搜GetProcAddress->LoadLibraryA->ShellExecuteA的ShellCode模式,写了个长达115+字节的OpenUrlA
,于是决定寻找其他解法。
按书上所说,LoadPE可以自动增加函数,但会在DLL末尾增加一个节。看了 【原创】看雪论坛.腾讯公司2008软件安全技术竞赛第一题分析过程 一文的相关部分,原来可以通过移动新节的内容来完成引入表的添加,我果然小白了
自己试着做了一下,把整个过程详细记录了下来,有什么问题欢迎指正。
-------------------------------------------------------------------------------------------
拿出原始DLL,用LoadPE载入。点击"Directories"(目录)按钮弹出如下对话框:

找到引入表,点击其后的"..."按钮。在弹出窗口的上方DLL信息框中点反键,选择"add import..."(新增引入):

输入要添加新函数和DLL名称,例如:
SHELL32.DLL
ShellExecuteExA
点击"+",然后"OK"。

确定保存修改的DLL,接着用WinHex打开查看。找到刚才添加的新节内容:
复制这个部分到.rdata节的空白处,例如这里选取的 000006B0 处。修改代码中的RAV地址(红色标出的部分):
其实不清楚引入表的构造也没有关系,只要把指向原来位置的几个偏移改到你移动的位置就行了。一图胜千言,用OD加载DLL,按Alt+M打开内存映射窗口,找到pediy.dll的最后一个节:

蓝色的4个字节暂时不管,先看红色部分。
003F504E 1E 50 00 00 对应文件中的 00000C4E 1E 50 00 00
查 引入表结构 可知,这是用于存放API实际地址的位置(从上图也可以看出,其值再被加载时自动修正了)。它正好在'ShellExecuteExA',0后面,所以对应的,移动后 000006FE 的值也要指向在'ShellExecuteExA',0的后面,即000020CE处。
这里过了就完成了大半,稍微调整引入表的偏移地址:
00000150 26 50 00 00 &P..
->
00000150 D6 20 00 00 ?..
至此已经完成了大半,DLL的功能已经没有问题。(二楼待续)
继续修改DLL,让他变得更完美吧。
保存后拿LoadPE载入,看看引入表是否正常(例如点击引入表后面的"L"按钮):
好了,ShellExecuteExA成功引入,其调用偏移为0x20CE。
现在来去掉新增的节,还原DLL的大小。
打开区段对话框,找到最后一个由LoadPE新增的节(我这里是.Silvana) ,反键选择"wipe section header"(清除区段)。

用WinHex清除文件末尾从00000C00开始的节内容,保存退出。
之后用OD载入,Oh..NO! 怎么提示“应用程序或DLL pediy.dll 为无效的 Windows 映像。请再检测一遍您的安装盘。”!

LoadPE已经能认识新的引入表了啊?仔细回想刚才的步骤,终于发现问题所在:刚才直接删除了新节,没有去调整镜像大小到原始值。LoadPE打开DLL,找到镜像大小:0000504C,改回0000404C保存。

好了,用OD载入DLL,这次顺利载入了。测试一下吧,向上找到
003F100E |. FF15 0C203F00 CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
双击反汇编,提示的内容是:CALL DWORD PTR DS:[3F200C]
由于ShellExecuteExA偏移为0x20CE,改成CALL DWORD PTR DS:[3F20CE]
003F100E FF15 CE203F00 CALL DWORD PTR DS:[<&SHELL32.ShellExecut>; SHELL32.ShellExecuteExA
看来改造成功了!之后想怎么发挥就怎么发挥了,例如7字节完成OpenUrlA
附件中有原始的 pediy.dll 和修改好的DLL(pediy_引入ShellExecuteExA.rar)。
附带我之前说的那个不用引入函数,115字节搜索API方法改造的DLL,包括引出表修改等完整的改造过程(pediy_115+字节的改造过程.zip)。