逆向工程核心原理:PE映像切换 源代码
示例代码下载地址: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;
}