ManualMap 从 C++ 资源中注入一个 DLL
ManualMap inject a DLL from Resources in C++
我正在学习 C++,我需要帮助弄清楚如何使用 C++ 项目资源中的 ManualMap 注入来注入 DLL。
我在 C# 中有一个源代码,但我不确定如何转换它,我不想尝试转换大约 5000 行代码。
这是一个使用 ManualMapping 的未检测到的 DLL 注入,许多 GameGuard 未检测到它用于将 DLL 注入游戏。
#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h> /* PROCESSENTRY32 */
#include <conio.h> /* _getch() */
#include <shlwapi.h> /* StrStrI */
#pragma comment(lib, "shlwapi.lib") /* unresolved external symbol __imp__StrStrIW@8 */
typedef HMODULE (WINAPI *pLoadLibraryA)(LPCSTR);
typedef FARPROC (WINAPI *pGetProcAddress)(HMODULE,LPCSTR);
typedef BOOL (WINAPI *PDLL_MAIN)(HMODULE,DWORD,PVOID);
typedef struct _MANUAL_INJECT
{
PVOID ImageBase;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_BASE_RELOCATION BaseRelocation;
PIMAGE_IMPORT_DESCRIPTOR ImportDirectory;
pLoadLibraryA fnLoadLibraryA;
pGetProcAddress fnGetProcAddress;
}MANUAL_INJECT,*PMANUAL_INJECT;
DWORD WINAPI LoadDll(PVOID p)
{
PMANUAL_INJECT ManualInject;
HMODULE hModule;
DWORD i,Function,count,delta;
PDWORD ptr;
PWORD list;
PIMAGE_BASE_RELOCATION pIBR;
PIMAGE_IMPORT_DESCRIPTOR pIID;
PIMAGE_IMPORT_BY_NAME pIBN;
PIMAGE_THUNK_DATA FirstThunk,OrigFirstThunk;
PDLL_MAIN EntryPoint;
ManualInject=(PMANUAL_INJECT)p;
pIBR=ManualInject->BaseRelocation;
delta=(DWORD)((LPBYTE)ManualInject->ImageBase-ManualInject->NtHeaders->OptionalHeader.ImageBase); // Calculate the delta
// Relocate the image
while(pIBR->VirtualAddress)
{
if(pIBR->SizeOfBlock>=sizeof(IMAGE_BASE_RELOCATION))
{
count=(pIBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/sizeof(WORD);
list=(PWORD)(pIBR+1);
for(i=0;i<count;i++)
{
if(list[i])
{
ptr=(PDWORD)((LPBYTE)ManualInject->ImageBase+(pIBR->VirtualAddress+(list[i] & 0xFFF)));
*ptr+=delta;
}
}
}
pIBR=(PIMAGE_BASE_RELOCATION)((LPBYTE)pIBR+pIBR->SizeOfBlock);
}
pIID=ManualInject->ImportDirectory;
// Resolve DLL imports
while(pIID->Characteristics)
{
OrigFirstThunk=(PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase+pIID->OriginalFirstThunk);
FirstThunk=(PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase+pIID->FirstThunk);
hModule=ManualInject->fnLoadLibraryA((LPCSTR)ManualInject->ImageBase+pIID->Name);
if(!hModule)
{
return FALSE;
}
while(OrigFirstThunk->u1.AddressOfData)
{
if(OrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
{
// Import by ordinal
Function=(DWORD)ManualInject->fnGetProcAddress(hModule,(LPCSTR)(OrigFirstThunk->u1.Ordinal & 0xFFFF));
if(!Function)
{
return FALSE;
}
FirstThunk->u1.Function=Function;
}
else
{
// Import by name
pIBN=(PIMAGE_IMPORT_BY_NAME)((LPBYTE)ManualInject->ImageBase+OrigFirstThunk->u1.AddressOfData);
Function=(DWORD)ManualInject->fnGetProcAddress(hModule,(LPCSTR)pIBN->Name);
if(!Function)
{
return FALSE;
}
FirstThunk->u1.Function=Function;
}
OrigFirstThunk++;
FirstThunk++;
}
pIID++;
}
if(ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint)
{
EntryPoint=(PDLL_MAIN)((LPBYTE)ManualInject->ImageBase+ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint);
return EntryPoint((HMODULE)ManualInject->ImageBase,DLL_PROCESS_ATTACH,NULL); // Call the entry point
}
return TRUE;
}
DWORD WINAPI LoadDllEnd()
{
return 0;
}
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
{
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval, ProcFound = false;
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (thSnapShot == INVALID_HANDLE_VALUE)
{
//MessageBox(NULL, "Error: Unable to create toolhelp snapshot!", "2MLoader", MB_OK);
printf("Error: Unable to create toolhelp snapshot!");
return false;
}
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapShot, &pe);
while (retval)
{
if (StrStrI(pe.szExeFile, ProcName))
{
return pe.th32ProcessID;
}
retval = Process32Next(thSnapShot, &pe);
}
return 0;
}
void GetGamePath(char* buff) {
HKEY hKey = 0;
char path[255] = { 0 };
char filename[255] = { 0 };
DWORD dwType = 0;
DWORD dwBufSize = 255;
GetFullPathName("Game.exe", MAX_PATH, buff, NULL);
//If file exists, then just exit.
if (FILE *file = fopen(buff, "r")) {
fclose(file);
return;
}
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\SomeGame\Game", 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
{
bool failed = false;
dwType = REG_SZ;
if (RegQueryValueEx(hKey, "PATH", 0, &dwType, (BYTE*)&path, &dwBufSize) != ERROR_SUCCESS)
failed = true;
if (RegQueryValueEx(hKey, "FILENAME", 0, &dwType, (BYTE*)&filename, &dwBufSize) != ERROR_SUCCESS)
failed = true;
RegCloseKey(hKey);
sprintf(buff, "%s%s", path, filename);
if (failed) {
GetFullPathName("Game.exe", MAX_PATH, buff, NULL);
}
}
}
int wmain(int argc,wchar_t* argv[])
{
PIMAGE_DOS_HEADER pIDH;
PIMAGE_NT_HEADERS pINH;
PIMAGE_SECTION_HEADER pISH;
HANDLE hProcess,hThread,hFile,hToken;
PVOID /*buffer,*/image,mem;
DWORD i,FileSize,ProcessId,ExitCode,read;
TOKEN_PRIVILEGES tp;
MANUAL_INJECT ManualInject;
if(OpenProcessToken((HANDLE)-1,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid.LowPart=20;
tp.Privileges[0].Luid.HighPart=0;
AdjustTokenPrivileges(hToken,FALSE,&tp,0,NULL,NULL);
CloseHandle(hToken);
}
printf("\nOpening the DLL.\n");
/*
hFile=CreateFile("AO.dll",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); // Open the DLL
if(hFile==INVALID_HANDLE_VALUE)
{
printf("\nError: Unable to open the DLL (%d)\n",GetLastError());
return -1;
}
FileSize=GetFileSize(hFile,NULL);
buffer=VirtualAlloc(NULL,FileSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
if(!buffer)
{
printf("\nError: Unable to allocate memory for DLL data (%d)\n",GetLastError());
CloseHandle(hFile);
return -1;
}
// Read the DLL
if(!ReadFile(hFile,buffer,FileSize,&read,NULL))
{
printf("\nError: Unable to read the DLL (%d)\n",GetLastError());
VirtualFree(buffer,0,MEM_RELEASE);
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
*/
MODULE hModule = GetModuleHandle(NULL); // get the handle to the current module (the executable file)
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(RESOURCE_ID), RESOURCE_TYPE); // substitute RESOURCE_ID and RESOURCE_TYPE.
HGLOBAL hMemory = LoadResource(hModule, hResource);
DWORD dwSize = SizeofResource(hModule, hResource);
LPVOID lpAddress = LockResource(hMemory);
unsigned char *buffer = new char[dwSize];
memcpy(buffer, lpAddress, dwSize);
pIDH=(PIMAGE_DOS_HEADER)buffer;
if(pIDH->e_magic!=IMAGE_DOS_SIGNATURE)
{
printf("\nError: Invalid executable image.\n");
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
pINH=(PIMAGE_NT_HEADERS)((LPBYTE)buffer+pIDH->e_lfanew);
if(pINH->Signature!=IMAGE_NT_SIGNATURE)
{
printf("\nError: Invalid PE header.\n");
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
if(!(pINH->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
printf("\nError: The image is not DLL.\n");
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
// Retrieve process ID
ProcessId = 0;
char buf[MAX_PATH] = { 0 };
//Game.exe not started, attempt to start Game.exe (same path as this tool).
if (ProcessId == 0) {
// Gets the exe's full path name.
GetGamePath(buf);
printf("GamePath: ");
printf(buf);
printf("\n");
LPCTSTR lpApplicationName = buf; /* The program to be executed */
STARTUPINFO lpStartupInfo;
PROCESS_INFORMATION lpProcessInfo;
memset(&lpStartupInfo, 0, sizeof(lpStartupInfo));
memset(&lpProcessInfo, 0, sizeof(lpProcessInfo));
/* Create the process */
if (!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &lpStartupInfo, &lpProcessInfo)) {
printf("Uh-Oh! CreateProcess() failed to start program %s\n", lpApplicationName);
_getch();
return 0;
} else {
WaitForSingleObject(lpProcessInfo.hProcess, 2000);
CloseHandle(lpProcessInfo.hThread);
CloseHandle(lpProcessInfo.hProcess);
ProcessId = lpProcessInfo.dwProcessId;
}
}
printf("Game.exe ProcessId = %d\n", ProcessId);
printf("\nOpening target process.\n");
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessId);
if(!hProcess)
{
printf("\nError: Unable to open target process (%d)\n",GetLastError());
VirtualFree(buffer,0,MEM_RELEASE);
CloseHandle(hProcess);
return -1;
}
printf("\nAllocating memory for the DLL.\n");
image=VirtualAllocEx(hProcess,NULL,pINH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); // Allocate memory for the DLL
if(!image)
{
printf("\nError: Unable to allocate memory for the DLL (%d)\n",GetLastError());
VirtualFree(buffer,0,MEM_RELEASE);
CloseHandle(hProcess);
return -1;
}
// Copy the header to target process
printf("\nCopying headers into target process.\n");
if(!WriteProcessMemory(hProcess,image,buffer,pINH->OptionalHeader.SizeOfHeaders,NULL))
{
printf("\nError: Unable to copy headers to target process (%d)\n",GetLastError());
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
pISH=(PIMAGE_SECTION_HEADER)(pINH+1);
// Copy the DLL to target process
printf("\nCopying sections to target process.\n");
for(i=0;i<pINH->FileHeader.NumberOfSections;i++)
{
WriteProcessMemory(hProcess,(PVOID)((LPBYTE)image+pISH[i].VirtualAddress),(PVOID)((LPBYTE)buffer+pISH[i].PointerToRawData),pISH[i].SizeOfRawData,NULL);
}
printf("\nAllocating memory for the loader code.\n");
mem=VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); // Allocate memory for the loader code
if(!mem)
{
printf("\nError: Unable to allocate memory for the loader code (%d)\n",GetLastError());
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
printf("\nLoader code allocated at %#x\n",mem);
memset(&ManualInject,0,sizeof(MANUAL_INJECT));
ManualInject.ImageBase=image;
ManualInject.NtHeaders=(PIMAGE_NT_HEADERS)((LPBYTE)image+pIDH->e_lfanew);
ManualInject.BaseRelocation=(PIMAGE_BASE_RELOCATION)((LPBYTE)image+pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
ManualInject.ImportDirectory=(PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)image+pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
ManualInject.fnLoadLibraryA=LoadLibraryA;
ManualInject.fnGetProcAddress=GetProcAddress;
printf("\nWriting loader code to target process.\n");
WriteProcessMemory(hProcess,mem,&ManualInject,sizeof(MANUAL_INJECT),NULL); // Write the loader information to target process
WriteProcessMemory(hProcess,(PVOID)((PMANUAL_INJECT)mem+1),LoadDll,(DWORD)LoadDllEnd-(DWORD)LoadDll,NULL); // Write the loader code to target process
printf("\nExecuting loader code.\n");
hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)((PMANUAL_INJECT)mem+1),mem,0,NULL); // Create a remote thread to execute the loader code
if(!hThread)
{
printf("\nError: Unable to execute loader code (%d)\n",GetLastError());
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
WaitForSingleObject(hThread,INFINITE);
GetExitCodeThread(hThread,&ExitCode);
if(!ExitCode)
{
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
CloseHandle(hThread);
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
CloseHandle(hProcess);
printf("\nDLL injected at %#x\n",image);
if(pINH->OptionalHeader.AddressOfEntryPoint)
{
printf("\nDLL entry point: %#x\n",(PVOID)((LPBYTE)image+pINH->OptionalHeader.AddressOfEntryPoint));
}
VirtualFree(buffer,0,MEM_RELEASE);
return 0;
}
我正在学习 C++,我需要帮助弄清楚如何使用 C++ 项目资源中的 ManualMap 注入来注入 DLL。
我在 C# 中有一个源代码,但我不确定如何转换它,我不想尝试转换大约 5000 行代码。
这是一个使用 ManualMapping 的未检测到的 DLL 注入,许多 GameGuard 未检测到它用于将 DLL 注入游戏。
#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h> /* PROCESSENTRY32 */
#include <conio.h> /* _getch() */
#include <shlwapi.h> /* StrStrI */
#pragma comment(lib, "shlwapi.lib") /* unresolved external symbol __imp__StrStrIW@8 */
typedef HMODULE (WINAPI *pLoadLibraryA)(LPCSTR);
typedef FARPROC (WINAPI *pGetProcAddress)(HMODULE,LPCSTR);
typedef BOOL (WINAPI *PDLL_MAIN)(HMODULE,DWORD,PVOID);
typedef struct _MANUAL_INJECT
{
PVOID ImageBase;
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_BASE_RELOCATION BaseRelocation;
PIMAGE_IMPORT_DESCRIPTOR ImportDirectory;
pLoadLibraryA fnLoadLibraryA;
pGetProcAddress fnGetProcAddress;
}MANUAL_INJECT,*PMANUAL_INJECT;
DWORD WINAPI LoadDll(PVOID p)
{
PMANUAL_INJECT ManualInject;
HMODULE hModule;
DWORD i,Function,count,delta;
PDWORD ptr;
PWORD list;
PIMAGE_BASE_RELOCATION pIBR;
PIMAGE_IMPORT_DESCRIPTOR pIID;
PIMAGE_IMPORT_BY_NAME pIBN;
PIMAGE_THUNK_DATA FirstThunk,OrigFirstThunk;
PDLL_MAIN EntryPoint;
ManualInject=(PMANUAL_INJECT)p;
pIBR=ManualInject->BaseRelocation;
delta=(DWORD)((LPBYTE)ManualInject->ImageBase-ManualInject->NtHeaders->OptionalHeader.ImageBase); // Calculate the delta
// Relocate the image
while(pIBR->VirtualAddress)
{
if(pIBR->SizeOfBlock>=sizeof(IMAGE_BASE_RELOCATION))
{
count=(pIBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/sizeof(WORD);
list=(PWORD)(pIBR+1);
for(i=0;i<count;i++)
{
if(list[i])
{
ptr=(PDWORD)((LPBYTE)ManualInject->ImageBase+(pIBR->VirtualAddress+(list[i] & 0xFFF)));
*ptr+=delta;
}
}
}
pIBR=(PIMAGE_BASE_RELOCATION)((LPBYTE)pIBR+pIBR->SizeOfBlock);
}
pIID=ManualInject->ImportDirectory;
// Resolve DLL imports
while(pIID->Characteristics)
{
OrigFirstThunk=(PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase+pIID->OriginalFirstThunk);
FirstThunk=(PIMAGE_THUNK_DATA)((LPBYTE)ManualInject->ImageBase+pIID->FirstThunk);
hModule=ManualInject->fnLoadLibraryA((LPCSTR)ManualInject->ImageBase+pIID->Name);
if(!hModule)
{
return FALSE;
}
while(OrigFirstThunk->u1.AddressOfData)
{
if(OrigFirstThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
{
// Import by ordinal
Function=(DWORD)ManualInject->fnGetProcAddress(hModule,(LPCSTR)(OrigFirstThunk->u1.Ordinal & 0xFFFF));
if(!Function)
{
return FALSE;
}
FirstThunk->u1.Function=Function;
}
else
{
// Import by name
pIBN=(PIMAGE_IMPORT_BY_NAME)((LPBYTE)ManualInject->ImageBase+OrigFirstThunk->u1.AddressOfData);
Function=(DWORD)ManualInject->fnGetProcAddress(hModule,(LPCSTR)pIBN->Name);
if(!Function)
{
return FALSE;
}
FirstThunk->u1.Function=Function;
}
OrigFirstThunk++;
FirstThunk++;
}
pIID++;
}
if(ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint)
{
EntryPoint=(PDLL_MAIN)((LPBYTE)ManualInject->ImageBase+ManualInject->NtHeaders->OptionalHeader.AddressOfEntryPoint);
return EntryPoint((HMODULE)ManualInject->ImageBase,DLL_PROCESS_ATTACH,NULL); // Call the entry point
}
return TRUE;
}
DWORD WINAPI LoadDllEnd()
{
return 0;
}
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
{
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval, ProcFound = false;
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (thSnapShot == INVALID_HANDLE_VALUE)
{
//MessageBox(NULL, "Error: Unable to create toolhelp snapshot!", "2MLoader", MB_OK);
printf("Error: Unable to create toolhelp snapshot!");
return false;
}
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapShot, &pe);
while (retval)
{
if (StrStrI(pe.szExeFile, ProcName))
{
return pe.th32ProcessID;
}
retval = Process32Next(thSnapShot, &pe);
}
return 0;
}
void GetGamePath(char* buff) {
HKEY hKey = 0;
char path[255] = { 0 };
char filename[255] = { 0 };
DWORD dwType = 0;
DWORD dwBufSize = 255;
GetFullPathName("Game.exe", MAX_PATH, buff, NULL);
//If file exists, then just exit.
if (FILE *file = fopen(buff, "r")) {
fclose(file);
return;
}
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\SomeGame\Game", 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
{
bool failed = false;
dwType = REG_SZ;
if (RegQueryValueEx(hKey, "PATH", 0, &dwType, (BYTE*)&path, &dwBufSize) != ERROR_SUCCESS)
failed = true;
if (RegQueryValueEx(hKey, "FILENAME", 0, &dwType, (BYTE*)&filename, &dwBufSize) != ERROR_SUCCESS)
failed = true;
RegCloseKey(hKey);
sprintf(buff, "%s%s", path, filename);
if (failed) {
GetFullPathName("Game.exe", MAX_PATH, buff, NULL);
}
}
}
int wmain(int argc,wchar_t* argv[])
{
PIMAGE_DOS_HEADER pIDH;
PIMAGE_NT_HEADERS pINH;
PIMAGE_SECTION_HEADER pISH;
HANDLE hProcess,hThread,hFile,hToken;
PVOID /*buffer,*/image,mem;
DWORD i,FileSize,ProcessId,ExitCode,read;
TOKEN_PRIVILEGES tp;
MANUAL_INJECT ManualInject;
if(OpenProcessToken((HANDLE)-1,TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
tp.PrivilegeCount=1;
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid.LowPart=20;
tp.Privileges[0].Luid.HighPart=0;
AdjustTokenPrivileges(hToken,FALSE,&tp,0,NULL,NULL);
CloseHandle(hToken);
}
printf("\nOpening the DLL.\n");
/*
hFile=CreateFile("AO.dll",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); // Open the DLL
if(hFile==INVALID_HANDLE_VALUE)
{
printf("\nError: Unable to open the DLL (%d)\n",GetLastError());
return -1;
}
FileSize=GetFileSize(hFile,NULL);
buffer=VirtualAlloc(NULL,FileSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
if(!buffer)
{
printf("\nError: Unable to allocate memory for DLL data (%d)\n",GetLastError());
CloseHandle(hFile);
return -1;
}
// Read the DLL
if(!ReadFile(hFile,buffer,FileSize,&read,NULL))
{
printf("\nError: Unable to read the DLL (%d)\n",GetLastError());
VirtualFree(buffer,0,MEM_RELEASE);
CloseHandle(hFile);
return -1;
}
CloseHandle(hFile);
*/
MODULE hModule = GetModuleHandle(NULL); // get the handle to the current module (the executable file)
HRSRC hResource = FindResource(hModule, MAKEINTRESOURCE(RESOURCE_ID), RESOURCE_TYPE); // substitute RESOURCE_ID and RESOURCE_TYPE.
HGLOBAL hMemory = LoadResource(hModule, hResource);
DWORD dwSize = SizeofResource(hModule, hResource);
LPVOID lpAddress = LockResource(hMemory);
unsigned char *buffer = new char[dwSize];
memcpy(buffer, lpAddress, dwSize);
pIDH=(PIMAGE_DOS_HEADER)buffer;
if(pIDH->e_magic!=IMAGE_DOS_SIGNATURE)
{
printf("\nError: Invalid executable image.\n");
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
pINH=(PIMAGE_NT_HEADERS)((LPBYTE)buffer+pIDH->e_lfanew);
if(pINH->Signature!=IMAGE_NT_SIGNATURE)
{
printf("\nError: Invalid PE header.\n");
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
if(!(pINH->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
printf("\nError: The image is not DLL.\n");
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
// Retrieve process ID
ProcessId = 0;
char buf[MAX_PATH] = { 0 };
//Game.exe not started, attempt to start Game.exe (same path as this tool).
if (ProcessId == 0) {
// Gets the exe's full path name.
GetGamePath(buf);
printf("GamePath: ");
printf(buf);
printf("\n");
LPCTSTR lpApplicationName = buf; /* The program to be executed */
STARTUPINFO lpStartupInfo;
PROCESS_INFORMATION lpProcessInfo;
memset(&lpStartupInfo, 0, sizeof(lpStartupInfo));
memset(&lpProcessInfo, 0, sizeof(lpProcessInfo));
/* Create the process */
if (!CreateProcess(lpApplicationName, NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &lpStartupInfo, &lpProcessInfo)) {
printf("Uh-Oh! CreateProcess() failed to start program %s\n", lpApplicationName);
_getch();
return 0;
} else {
WaitForSingleObject(lpProcessInfo.hProcess, 2000);
CloseHandle(lpProcessInfo.hThread);
CloseHandle(lpProcessInfo.hProcess);
ProcessId = lpProcessInfo.dwProcessId;
}
}
printf("Game.exe ProcessId = %d\n", ProcessId);
printf("\nOpening target process.\n");
hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,ProcessId);
if(!hProcess)
{
printf("\nError: Unable to open target process (%d)\n",GetLastError());
VirtualFree(buffer,0,MEM_RELEASE);
CloseHandle(hProcess);
return -1;
}
printf("\nAllocating memory for the DLL.\n");
image=VirtualAllocEx(hProcess,NULL,pINH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); // Allocate memory for the DLL
if(!image)
{
printf("\nError: Unable to allocate memory for the DLL (%d)\n",GetLastError());
VirtualFree(buffer,0,MEM_RELEASE);
CloseHandle(hProcess);
return -1;
}
// Copy the header to target process
printf("\nCopying headers into target process.\n");
if(!WriteProcessMemory(hProcess,image,buffer,pINH->OptionalHeader.SizeOfHeaders,NULL))
{
printf("\nError: Unable to copy headers to target process (%d)\n",GetLastError());
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
pISH=(PIMAGE_SECTION_HEADER)(pINH+1);
// Copy the DLL to target process
printf("\nCopying sections to target process.\n");
for(i=0;i<pINH->FileHeader.NumberOfSections;i++)
{
WriteProcessMemory(hProcess,(PVOID)((LPBYTE)image+pISH[i].VirtualAddress),(PVOID)((LPBYTE)buffer+pISH[i].PointerToRawData),pISH[i].SizeOfRawData,NULL);
}
printf("\nAllocating memory for the loader code.\n");
mem=VirtualAllocEx(hProcess,NULL,4096,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); // Allocate memory for the loader code
if(!mem)
{
printf("\nError: Unable to allocate memory for the loader code (%d)\n",GetLastError());
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
printf("\nLoader code allocated at %#x\n",mem);
memset(&ManualInject,0,sizeof(MANUAL_INJECT));
ManualInject.ImageBase=image;
ManualInject.NtHeaders=(PIMAGE_NT_HEADERS)((LPBYTE)image+pIDH->e_lfanew);
ManualInject.BaseRelocation=(PIMAGE_BASE_RELOCATION)((LPBYTE)image+pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
ManualInject.ImportDirectory=(PIMAGE_IMPORT_DESCRIPTOR)((LPBYTE)image+pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
ManualInject.fnLoadLibraryA=LoadLibraryA;
ManualInject.fnGetProcAddress=GetProcAddress;
printf("\nWriting loader code to target process.\n");
WriteProcessMemory(hProcess,mem,&ManualInject,sizeof(MANUAL_INJECT),NULL); // Write the loader information to target process
WriteProcessMemory(hProcess,(PVOID)((PMANUAL_INJECT)mem+1),LoadDll,(DWORD)LoadDllEnd-(DWORD)LoadDll,NULL); // Write the loader code to target process
printf("\nExecuting loader code.\n");
hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)((PMANUAL_INJECT)mem+1),mem,0,NULL); // Create a remote thread to execute the loader code
if(!hThread)
{
printf("\nError: Unable to execute loader code (%d)\n",GetLastError());
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
WaitForSingleObject(hThread,INFINITE);
GetExitCodeThread(hThread,&ExitCode);
if(!ExitCode)
{
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
VirtualFreeEx(hProcess,image,0,MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
VirtualFree(buffer,0,MEM_RELEASE);
return -1;
}
CloseHandle(hThread);
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
CloseHandle(hProcess);
printf("\nDLL injected at %#x\n",image);
if(pINH->OptionalHeader.AddressOfEntryPoint)
{
printf("\nDLL entry point: %#x\n",(PVOID)((LPBYTE)image+pINH->OptionalHeader.AddressOfEntryPoint));
}
VirtualFree(buffer,0,MEM_RELEASE);
return 0;
}