直接使用LoadLibrary作为线程入口函数不方便判断DLL是否注入成功。下面介绍使用shellcode作为线程入口函数的方法,该方法对于x86 32位, x64 64位 系统都适用。
先用C语言编写代码编译成二进制shellcode,再用IDA提取shellcode。
shellcode函数 注意事项 :
- shellcode函数原型定义要与线程入口函数一致,如 DWORD WINAPI ThreadProc(LPVOID lpParameter);
- shellcode要执行的代码写在这一个函数体内
- shellcode函数内不能使用全局变量
- shellcode函数不能调用其他函数
- shellcode使用的数据通过函数参数传递
项目属性设置注意事项(以下说明以vs2017为例):
- 使用生成DLL的项目,使用默认的Release模式生成代码
- shellcode函数作为DLL导出函数, 方便后面使用 IDA 定位
- 禁用安全检查。打开项目属性页,依次选择 "配置属性"->"C\C++"->"代码生成"->"安全检查"->"禁用安全检查(/GS-)" 并点击“应用”。启用该选项编译器会在shellcode函数中插入调用安全检查函数的代码,将导致shellcode不能正确运行。
- 忽略SDL检查。打开项目属性页,依次选择 "配置属性"->"C\C++"->"常规"->"SDL检查", 将选项的值删除设置位空,并点击“应用”。不这样设置编译器会产生一个警告。
- 忽略所有默认库。打开项目属性页,依次选择 "配置属性"->"链接器"->"输入"->"忽略所有默认库"->"是 (/NODEFAULTLIB)", 并点击“应用”。这样设置会使生成的DLL体积较小,除了shellcode函数和DllMain函数的代码外,不包含其他运行库代码。
- 设置自定义DLL入口:#pragma comment(linker, "/ENTRY:DllMain")。由于忽略所有默认库,链接器无法找到运行库的DLL默认入口函数,会报错。
使用IDA提取shellcode:
- 使用IDA打开生成dll文件
- 在导出窗口中双击DLL导出的shellcode函数,定位到shellcode函数汇编代码
- 在shellcode函数汇编代码窗口中,按下鼠标左键拖动,选中shellcode函数所有汇编代码
- 选择菜单 “Edit"->"Export data", 在弹出对话框中选择”C unsigned char array (hex)“格式,再复制下面编辑框中的代码即可完成shellcode的提取