void MemDump(DEBUG_EVENT *pDe, DWORD dwEntryPoint, char *DumpFileName) { DWORD dwPid = pDe->dwProcessId; MODULEENTRY32 me32;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid);
me32.dwSize = sizeof(MODULEENTRY32); BOOL bRet = Module32First(hSnap, &me32); printf("[+] 当前转储原程序路径: %s \n", me32.szExePath);
HANDLE hFile = CreateFile(me32.szExePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) exit(0);
IMAGE_DOS_HEADER imgDos = { 0 }; IMAGE_NT_HEADERS imgNt = { 0 };
DWORD dwReadNum = 0;
ReadFile(hFile, &imgDos, sizeof(IMAGE_DOS_HEADER), &dwReadNum, NULL); if (imgDos.e_magic != IMAGE_DOS_SIGNATURE) return; SetFilePointer(hFile, imgDos.e_lfanew, 0, FILE_BEGIN); ReadFile(hFile, &imgNt, sizeof(IMAGE_NT_HEADERS), &dwReadNum, NULL); if (imgNt.Signature != IMAGE_NT_SIGNATURE) return;
DWORD BaseSize = me32.modBaseSize; printf("[+] 当前内存文件大小: %d --> NT结构原始大小: %d 一致性检测: True \n", BaseSize, imgNt.OptionalHeader.SizeOfImage);
if (imgNt.OptionalHeader.SizeOfImage > BaseSize) { BaseSize = imgNt.OptionalHeader.SizeOfImage; }
LPVOID pBase = VirtualAlloc(NULL, BaseSize, MEM_COMMIT, PAGE_READWRITE); printf("[+] 正在分配转储空间 句柄: %d \n", pBase);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
bRet = ReadProcessMemory(hProcess, me32.modBaseAddr, pBase, me32.modBaseSize, NULL);
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBase; if (pDos->e_magic != IMAGE_DOS_SIGNATURE) return;
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (PBYTE)pBase); if (pNt->Signature != IMAGE_NT_SIGNATURE) return;
pNt->OptionalHeader.AddressOfEntryPoint = dwEntryPoint - pNt->OptionalHeader.ImageBase; printf("[*] 正在设置Dump文件相对RVA入口地址: 0x%08X \n", pNt->OptionalHeader.AddressOfEntryPoint);
pNt->OptionalHeader.FileAlignment = 0x1000; printf("[*] 正在设置Dump文件的对齐值: %d \n", pNt->OptionalHeader.FileAlignment);
PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((PBYTE)&pNt->OptionalHeader + pNt->FileHeader.SizeOfOptionalHeader); for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++) { pSec->PointerToRawData = pSec->VirtualAddress; printf("[+] 正在将虚拟地址: 0x%08X --> 设置到文件地址: 0x%08X \n", pSec->VirtualAddress, pSec->PointerToRawData); pSec->SizeOfRawData = pSec->Misc.VirtualSize; printf("[+] 正在将虚拟大小: %d --> 设置到文件大小: %d \n", pSec->Misc.VirtualSize, pSec->SizeOfRawData); pSec++; } CloseHandle(hFile);
hFile = CreateFile(DumpFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) exit(0); printf("[*] 转储 %s 文件到本地 \n", DumpFileName);
DWORD dwWriteNum = 0;
bRet = WriteFile(hFile, pBase, me32.modBaseSize, &dwWriteNum, NULL); if (dwWriteNum != me32.modBaseSize || FALSE == bRet) printf("写入错误 !"); CloseHandle(hFile); VirtualFree(pBase, me32.modBaseSize, MEM_RELEASE); CloseHandle(hProcess); CloseHandle(hSnap); }
|