参考课件 chap06.pdf 中“通过修改PE装载DLL”一节的内容,以及课本第 5.5节的 内容,实现对notepad.exe(修復並下載Notepad.exe )的修改,使得修改后的 notepad.exe 在双击运行时,能够自动隐式装载 MyDll3.dll,并进而 将一个网页下载到本地index.html 文件。
本上机作业的目的是让大家深入理解 PE 文件中的导入表、导入地址表等关键结构及相关的功能。
本实验所使用的notepad.exe 是 Windows 7系统(最好32位版)中的可执行程序,MyDll3.dll 也仅保证在 Windows 7下能正常工作,因此,建议在 Windows 7环境(可预先安装虚拟机)下进行修改。请在虚拟机中禁用所有杀毒软件,确保修改过程不会受到杀毒软件的干扰。保证虚拟机能联网,以便DLL装载后的网页下载动作能正常完成。
下载notepad.exe可能与课本中所描述的notepad.exe版本不一致,应主要参考课件中的修改流程。
使用PEview分析PE文件,使用HxD编辑器修改PE文件。
直接使用本书所附代码编译生成 MyDll3.dll。
PE文件静态注入
这里因为notepad一直注入不成功,换了个win7版本也不行,好像是安全策略的原因,就只好找另外一个textview.exe 进行注入
代码是李承远老师的逆向工程核心原理当中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 #include "pch.h" #include "stdio.h" #include "windows.h" #include "shlobj.h" #include "Wininet.h" #include "tchar.h" #pragma comment(lib, "Wininet.lib" ) #define DEF_BUF_SIZE (4096) #define DEF_URL L"http://www.baidu.com/index.html" #define DEF_INDEX_FILE L"index.html" HWND g_hWnd = NULL ; #ifdef __cplusplus extern "C" {#endif __declspec(dllexport) void dummy () { return ; } #ifdef __cplusplus } #endif BOOL DownloadURL (LPCTSTR szURL, LPCTSTR szFile) { BOOL bRet = FALSE; HINTERNET hInternet = NULL , hURL = NULL ; BYTE pBuf[DEF_BUF_SIZE] = { 0 , }; DWORD dwBytesRead = 0 ; FILE* pFile = NULL ; errno_t err = 0 ; hInternet = InternetOpen(L"ReverseCore" , INTERNET_OPEN_TYPE_PRECONFIG, NULL , NULL , 0 ); if (NULL == hInternet) { OutputDebugString(L"InternetOpen() failed!" ); return FALSE; } hURL = InternetOpenUrl(hInternet, szURL, NULL , 0 , INTERNET_FLAG_RELOAD, 0 ); if (NULL == hURL) { OutputDebugString(L"InternetOpenUrl() failed!" ); goto _DownloadURL_EXIT; } if (err = _tfopen_s(&pFile, szFile, L"wt" )) { OutputDebugString(L"fopen() failed!" ); goto _DownloadURL_EXIT; } while (InternetReadFile(hURL, pBuf, DEF_BUF_SIZE, &dwBytesRead)) { if (!dwBytesRead) break ; fwrite(pBuf, dwBytesRead, 1 , pFile); } bRet = TRUE; _DownloadURL_EXIT: if (pFile) fclose(pFile); if (hURL) InternetCloseHandle(hURL); if (hInternet) InternetCloseHandle(hInternet); return bRet; } BOOL CALLBACK EnumWindowsProc (HWND hWnd, LPARAM lParam) { DWORD dwPID = 0 ; GetWindowThreadProcessId(hWnd, &dwPID); if (dwPID == (DWORD)lParam) { g_hWnd = hWnd; return FALSE; } return TRUE; } HWND GetWindowHandleFromPID (DWORD dwPID) { EnumWindows(EnumWindowsProc, dwPID); return g_hWnd; } BOOL DropFile (LPCTSTR wcsFile) { HWND hWnd = NULL ; DWORD dwBufSize = 0 ; BYTE* pBuf = NULL ; DROPFILES* pDrop = NULL ; char szFile[MAX_PATH] = { 0 , }; HANDLE hMem = 0 ; WideCharToMultiByte(CP_ACP, 0 , wcsFile, -1 , szFile, MAX_PATH, NULL , NULL ); dwBufSize = sizeof (DROPFILES) + strlen (szFile) + 1 ; if (!(hMem = GlobalAlloc(GMEM_ZEROINIT, dwBufSize))) { OutputDebugString(L"GlobalAlloc() failed!!!" ); return FALSE; } pBuf = (LPBYTE)GlobalLock(hMem); pDrop = (DROPFILES*)pBuf; pDrop->pFiles = sizeof (DROPFILES); strcpy_s((char *)(pBuf + sizeof (DROPFILES)), strlen (szFile) + 1 , szFile); GlobalUnlock(hMem); if (!(hWnd = GetWindowHandleFromPID(GetCurrentProcessId()))) { OutputDebugString(L"GetWndHandleFromPID() failed!!!" ); return FALSE; } PostMessage(hWnd, WM_DROPFILES, (WPARAM)pBuf, NULL ); return TRUE; } DWORD WINAPI ThreadProc (LPVOID lParam) { TCHAR szPath[MAX_PATH] = { 0 , }; TCHAR* p = NULL ; OutputDebugString(L"ThreadProc() start..." ); GetModuleFileName(NULL , szPath, sizeof (szPath)); if (p = _tcsrchr(szPath, L'\\' )) { _tcscpy_s(p + 1 , wcslen(DEF_INDEX_FILE) + 1 , DEF_INDEX_FILE); OutputDebugString(L"DownloadURL()" ); if (DownloadURL(DEF_URL, szPath)) { OutputDebugString(L"DropFlie()" ); DropFile(szPath); } } OutputDebugString(L"ThreadProc() end..." ); return 0 ; } BOOL APIENTRY DllMain ( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: CloseHandle(CreateThread(NULL , 0 , ThreadProc, NULL , 0 , NULL )); break ; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break ; } return TRUE; }
dummmy()
函数实际是dll文件向外部提供服务的导出函数,但正如所见,它没有任何功能。既然如此,为何还要将其导出呢?这是为了保持形式上的完整性,mydll3.dll能够顺利添加到notepad_patch.exe文件的导入表。
生成的myhack3.dll
查看IDT是否有足够空间
我们从Image_Optional_Header的IMPORT Table得到结构体数组的RVA和Size
通过查看image_section_header,发现RVA84CC处于rdata区域
计算偏移
0x6000-0x5200 = 0xE00
文件偏移=即0x84CC -0xE00 = 0x76CC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; DWORD OriginalFirstThunk; }; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; } IMAGE_IMPORT_DESCRIPTOR; typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
也可以将PEview调成文件偏移视图查看,可以看到文件偏移确实是0x76CC
然后我们使用010 editor打开可以发现64Bytes的空间,有五个IDT结构体,最后一个为NULL,在我们的IDT之后紧贴着其它数据,我们没有足够的空间来添加一个0x14字节的结构体进去
移动IDT
从节区头信息可以得到,其内存virtual Size与文件的大小Size of Raw Data是不一样的
.rdata
节区在磁盘文件中的大小为 2E00
,而文件执行后被加载到内存时,程序实际使用的数据大小(映射大小)仅为 2C56 ,剩余未被使用的区域大小为 1AA (2E00 - 2C56)足够放下(0x14 * 6 = 0x78)字节的数据
可以先从0x8C80开始存放我们的IDT(转化为文件偏移为0x7E80)(新IDT: 0x7E80到(0x7E80+0x78))
TextView.exe 文件中,导入表的 RVA 值为 84CC 。接下来,将导入表的 RVA 值更改为新 IDT 的 RVA 值 8C80,在 Size 原值64字节的基础上再加 14字节(IID 结构体的大小),修改为78字节
修改后导入表位于 RVA: 8C80(RAW : 7E80)地址处
先使用010 Editor完全复制原IDT(RAW:76CC~772F),然后覆盖到IDT的新位置(RAW:7E80)
在7ED0处写入IID
然后在新IDT尾部(RAW:7ED0)添加与mydll3对应的IID
转到 7F00 地址处,输入相应值
3.修改 IAT 节区的属性值
向原属性(ChAracteristics)40000040 添加 IMAGE_SCN_MEM_WRITE(80000000)属性值
也就是C0000040
使用 PEView 工具打开修改后的 TextView.exe 文件,查看其 IDT,发现已经装载上了myhack3.dll
点开,我们发现它成功下载了百度某个cdn下的index.html,并展示在文字框中
参考文献
[[原创]通过修改PE加载DLL]https://bbs.pediy.com/thread-267045-1.htm
[通过修改PE文件的方式导入DLL]https://blog.csdn.net/fanxiaoyao1/article/details/125379489
李承远 逆向工程核心原理