逆向工程核心原理:PE映像切換 原始碼
阿新 • • 發佈:2021-09-05
示例程式碼下載地址:https://pan.baidu.com/s/1cb1qg9YVgzwQ2X9umSU7qw 密碼:pnmq
Debugme3.cpp
#include <Windows.h> #include <stdio.h> #include <tchar.h> #define ModuleName "ntdll.dll" #define ProcName "ZwUnmapViewOfSection" VOID *loadFile(TCHAR* real); DWORD UnmapFakeProcImage(PROCESS_INFORMATION* pProcessInformation, VOID *); DWORD MapRealProcImage(PROCESS_INFORMATION* pProcessInformation, VOID* Buffer); NTSTATUS(WINAPI * ZwUnmapViewOfSection)( HANDLE ProcessHandle, PVOID BaseAddress ); int _tmain(int argc, TCHAR ** argv) { PROCESS_INFORMATION ProcessInformation = { 0, }; STARTUPINFO StartupInfo = { 0x44, }; VOID* Buffer; //若引數不等於3,則輸出錯誤資訊並返回 if (argc != 3) { _tprintf(_T("USAGE : %s <fake file path> <real file path>"), argv[0]); return 0; } Buffer = loadFile(argv[2]); if (Buffer != 0) { if (!CreateProcess(NULL, argv[1], 0, 0, 0, 4, 0, 0, &StartupInfo, &ProcessInformation)) { _tprintf(_T("CreateProcess() failed! [%d]\n"), GetLastError()); } else { do { if (!UnmapFakeProcImage(&ProcessInformation, Buffer)) { _tprintf(_T("UnmapFakeProcImage() failed!!!\n")); break; } if (!MapRealProcImage(&ProcessInformation, Buffer)) { _tprintf(_T("MapRealProcImage() failed!!!\n")); break; } if (ResumeThread(ProcessInformation.hThread) == -1) { _tprintf(_T("ResumeThread() failed! [%d]\n"), GetLastError()); break; } WaitForSingleObject(ProcessInformation.hProcess, 0xFFFFFFFF); } while (FALSE); } delete Buffer; if (ProcessInformation.hThread) { CloseHandle(ProcessInformation.hThread); } if (ProcessInformation.hProcess) { CloseHandle(ProcessInformation.hProcess); } } return 0; } DWORD MapRealProcImage(PROCESS_INFORMATION* pProcessInformation, VOID* realBuffer) { LPVOID buffer = NULL; DWORD i = 0; CONTEXT Context = { 0x10007, 0, }; DWORD pNT = *(DWORD*)((DWORD)realBuffer + 0x3c) + (DWORD)realBuffer; DWORD sizeOfImage = *(DWORD*)(pNT + 0x50); DWORD pImageBase = *(DWORD*)(pNT + 0x34); buffer = VirtualAllocEx(pProcessInformation->hProcess, (LPVOID)pImageBase, sizeOfImage, 0x3000, 0x40); if (buffer == 0) { _tprintf(_T("VirtualAllocEx() failed!!! [%d]\n"), GetLastError()); } WriteProcessMemory(pProcessInformation->hProcess, buffer, realBuffer, *(DWORD*)(*(DWORD*)((DWORD)realBuffer + 0x3c) + (DWORD)realBuffer + 0x54), 0); i = 0; //.text節區的地址 DWORD SectionOfStart = pNT + 0xf8; if (0 <= *(DWORD*)(pNT + 0x54)) { do { if (*(DWORD*)(SectionOfStart + 0x10) != 0) { if (WriteProcessMemory(pProcessInformation->hProcess, (LPVOID)(*(DWORD*)(SectionOfStart + 0x0c) + (DWORD)buffer), (LPCVOID) ((*(DWORD*)(SectionOfStart + 0x14) + (DWORD)realBuffer)), *(DWORD*)(SectionOfStart + 0x10), 0) == 0) { _tprintf(_T("WriteProcessMemory(%.8X) failed!!! [%d]"), *(DWORD *)(SectionOfStart + 0xc), GetLastError()); } } SectionOfStart += 0x28; i++; } while (i < *(WORD*)(pNT + 6)); } if (GetThreadContext(pProcessInformation->hThread, &Context)==0) { _tprintf(_T("GetThreadContext() failed! [%d]\n"), GetLastError()); return 0; } int newEntryPoint = *(DWORD*)(pNT + 0x28); newEntryPoint += *(DWORD*)(pNT + 0x34); Context.Eax = newEntryPoint; if (SetThreadContext(pProcessInformation->hThread, &Context)==0) { _tprintf(_T("SetThreadContext() failed! [%d]\n"), GetLastError()); return 0; } return 1; } DWORD UnmapFakeProcImage(PROCESS_INFORMATION* pProcessInformation, VOID * realBuffer) { CONTEXT Context = {0x10007,}; DWORD buffer = NULL; /*memset(&Context.Dr0, 0, 0x2c8); Context.ContextFlags = 0x10007;*/ if (!GetThreadContext(pProcessInformation->hThread, &Context)) { _tprintf(_T("GetThreadContext() failed! [%d]\n"), GetLastError()); return 0; } if (!ReadProcessMemory(pProcessInformation->hProcess, (LPCVOID)(Context.Ebx + 8), &buffer, 4, 0)) { _tprintf(_T("ReadProcessMemory() failed! [%d]\n"), GetLastError()); } DWORD* pImageBase = (DWORD*)((BYTE*)realBuffer + *((BYTE*)realBuffer + 0x3c) + 0x34); if (*pImageBase == buffer) { ZwUnmapViewOfSection = (NTSTATUS(WINAPI *)(HANDLE, PVOID))GetProcAddress(GetModuleHandle(ModuleName), ProcName); if (ZwUnmapViewOfSection(pProcessInformation->hProcess, (VOID*)buffer)) { _tprintf(_T("ZwUnmapViewOfSection() failed!!! [%d]\n"), GetLastError()); return 0; } } else { WriteProcessMemory(pProcessInformation->hProcess, (LPVOID)(Context.Ebx + 8), pImageBase, 4, 0); } return 1; } VOID * loadFile(TCHAR* real) { int NumberOfBytesRead = 0; HANDLE hFile = NULL; VOID* lpBuffer = NULL; int Size = 0; hFile = CreateFile(real, 0x80000000, 1, 0, 3, 0x80, 0); if (hFile==(HANDLE)-1) { return 0; } Size = GetFileSize(hFile, 0); lpBuffer = operator new(Size); if (lpBuffer == 0) { return 0; } ReadFile(hFile, lpBuffer, Size, (LPDWORD)&Size, 0); CloseHandle(hFile); return lpBuffer; }