www.pudn.com > HookAPI > INJLIB_old.CPP
/* 此文件必须使用release方式编译才能正确运行 */ #include#include #include "injlib.h" #include "util.h" typedef HINSTANCE (WINAPI *PROCLOADLIBRARY)(LPSTR); typedef BOOL (WINAPI *PROCFREELIBRARY)(HINSTANCE); typedef HMODULE (WINAPI *PROCGETMODULEHANDLE)(LPSTR); void WriteLog(char *fmt,...); #define LOAD_DLL 1 #define FREE_DLL 0 typedef struct { PROCLOADLIBRARY fnLoadLibrary; PROCFREELIBRARY fnFreeLibrary; PROCGETMODULEHANDLE fnGetModuleHandle; BOOL ActionFlag; CHAR pbLibFile[MAX_PATH]; } INJLIBINFO, *PINJLIBINFO; // Calls to the stack checking routine must be disabled. #pragma check_stack (off) static DWORD WINAPI ThreadFunc (PINJLIBINFO pInjLibInfo) { // There must be less than a page worth of local // variables used in this function. HINSTANCE hinstDll =NULL; if(pInjLibInfo ==NULL || pInjLibInfo->fnGetModuleHandle ==NULL || pInjLibInfo->fnLoadLibrary ==NULL) return (DWORD)NULL; hinstDll = pInjLibInfo->fnGetModuleHandle(pInjLibInfo->pbLibFile); if (pInjLibInfo->ActionFlag == LOAD_DLL) { if (hinstDll == NULL) hinstDll = pInjLibInfo->fnLoadLibrary(pInjLibInfo->pbLibFile); } else if (pInjLibInfo->ActionFlag == FREE_DLL) pInjLibInfo->fnFreeLibrary(hinstDll); // The thread's exit code is the handle of the DLL. return((DWORD) hinstDll); } ////////////////////////////////////////////////////////////// // This function marks the memory address after ThreadFunc. // ThreadFuncCodeSizeInBytes = // (PBYTE) AfterThreadFunc - (PBYTE) ThreadFunc. static void AfterThreadFunc (void) { } #pragma check_stack ////////////////////////////////////////////////////////////// int WINAPI InjectLib (DWORD process_id, char *pbLibFile) { // Kernel32.DLL's HINSTANCE is used to get the // address of LoadLibraryA or LoadLibraryW and // FreeLibrary. HINSTANCE hinstKrnl = GetModuleHandle("Kernel32"); INJLIBINFO InjLibInfo; // The address to which code will be copied in the // remote process PDWORD pdwCodeRemote = NULL; // Calculate the number of bytes in the ThreadFunc // function. #ifndef _PPC_ const int cbCodeSize = ((LPBYTE) (DWORD) AfterThreadFunc - (LPBYTE) (DWORD) ThreadFunc); #else // Note: The PowerPC does not support 32-bit immediate // values. So, the VC++ PowerPC compiler implements 32-bit // immediates using an offset into a table and grabbing // the 32-bit value from the table. The references to // the functions below, are actually offsets into this // table. So, we have to subtract the contents of these // offsets to get the actual code size. const int cbCodeSize = ((LPBYTE) *(PDWORD) AfterThreadFunc - (LPBYTE) *(PDWORD) ThreadFunc); #endif // The address to which INJLIBINFO will be copied in // the remote process PINJLIBINFO pInjLibInfoRemote = NULL; // The number of bytes written to the remote process DWORD dwNumBytesXferred = 0; // The handle and ID of the thread executing the // remote copy of ThreadFunc DWORD dwThreadId = 0; HANDLE hThread = NULL; HINSTANCE hinstDllRemote = NULL; BOOL fOk = FALSE; // Initialize the INJLIBINFO structure here, and // then copy it to memory in the remote process. InjLibInfo.fnLoadLibrary = (PROCLOADLIBRARY)GetProcAddress(hinstKrnl, "LoadLibraryA"); InjLibInfo.fnFreeLibrary = (PROCFREELIBRARY)GetProcAddress(hinstKrnl, "FreeLibrary"); InjLibInfo.fnGetModuleHandle = (PROCGETMODULEHANDLE)GetProcAddress(hinstKrnl, "GetModuleHandleA"); InjLibInfo.ActionFlag = LOAD_DLL; InjLibInfo.pbLibFile[0] = 0; // Initialized later strcpy(InjLibInfo.pbLibFile, pbLibFile); HANDLE hProcess =OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id); if(hProcess ==NULL) { WriteLog("InjectLib:OpenProcess %d failed!", process_id); return -1; } if((pdwCodeRemote = (PDWORD)VirtualAllocEx(hProcess, NULL, cbCodeSize+20, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) ==NULL) { CloseHandle(hProcess); return FALSE; } // Change the page protection of the allocated memory // to executable, read, and write. int ret; ret =WriteProcessMemory(hProcess, pdwCodeRemote, (LPVOID)(DWORD) ThreadFunc, cbCodeSize, &dwNumBytesXferred); //WriteLog("WriteProcessMemory pdwCodeRemote size:%d, ret=%d, %d", cbCodeSize, ret, STATUS_ACCESS_VIOLATION); if(ret ==STATUS_ACCESS_VIOLATION || ret ==false) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return false; } // Put InjLibInfo in the remote thread's memory block. if((pInjLibInfoRemote = (INJLIBINFO *)VirtualAllocEx(hProcess, NULL, sizeof(InjLibInfo)+20, MEM_COMMIT, PAGE_READWRITE)) ==NULL) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return FALSE; } ret =WriteProcessMemory(hProcess, pInjLibInfoRemote, &InjLibInfo, sizeof(InjLibInfo), &dwNumBytesXferred); //WriteLog("WriteProcessMemory InjLibInfo ret=%d", ret); if(ret ==STATUS_ACCESS_VIOLATION || ret ==false) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return false; } //WriteLog("CreateRemoteProcess..."); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(DWORD) pdwCodeRemote, pInjLibInfoRemote, 0, &dwThreadId); if (hThread == NULL) { //WriteLog("CreateRemoteProcess failed"); VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return false; } //WriteLog("CreateRemoteThread success, WaitForSingleObject..."); WaitForSingleObject(hThread, INFINITE); if (hThread != NULL) { GetExitCodeThread(hThread, (PDWORD) &hinstDllRemote); CloseHandle(hThread); } // Let the remote thread start executing the remote // ThreadFunc function using our modified stack, which // now contains an initialized INJLIBINFO structure. if(pdwCodeRemote) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); } if(pInjLibInfoRemote) { VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE); } //WriteLog("OK++++"); CloseHandle(hProcess); return(hinstDllRemote != NULL); } int WINAPI EjectLib (DWORD process_id, char *pbLibFile) { // Kernel32.DLL's HINSTANCE is used to get the // address of LoadLibraryA or LoadLibraryW and // FreeLibrary. HINSTANCE hinstKrnl = GetModuleHandle("Kernel32"); INJLIBINFO InjLibInfo; // The address to which code will be copied in the // remote process PDWORD pdwCodeRemote = NULL; // Calculate the number of bytes in the ThreadFunc // function. #ifndef _PPC_ const int cbCodeSize = ((LPBYTE) (DWORD) AfterThreadFunc - (LPBYTE) (DWORD) ThreadFunc); #else // Note: The PowerPC does not support 32-bit immediate // values. So, the VC++ PowerPC compiler implements 32-bit // immediates using an offset into a table and grabbing // the 32-bit value from the table. The references to // the functions below, are actually offsets into this // table. So, we have to subtract the contents of these // offsets to get the actual code size. const int cbCodeSize = ((LPBYTE) *(PDWORD) AfterThreadFunc - (LPBYTE) *(PDWORD) ThreadFunc); #endif // The address to which INJLIBINFO will be copied in // the remote process PINJLIBINFO pInjLibInfoRemote = NULL; // The number of bytes written to the remote process DWORD dwNumBytesXferred = 0; // The handle and ID of the thread executing the // remote copy of ThreadFunc DWORD dwThreadId = 0; HANDLE hThread = NULL; HINSTANCE hinstDllRemote = NULL; BOOL fOk = FALSE; // Initialize the INJLIBINFO structure here, and // then copy it to memory in the remote process. InjLibInfo.fnLoadLibrary = (PROCLOADLIBRARY)GetProcAddress(hinstKrnl, "LoadLibraryA"); InjLibInfo.fnFreeLibrary = (PROCFREELIBRARY)GetProcAddress(hinstKrnl, "FreeLibrary"); InjLibInfo.fnGetModuleHandle = (PROCGETMODULEHANDLE)GetProcAddress(hinstKrnl, "GetModuleHandleA"); InjLibInfo.ActionFlag = FREE_DLL; InjLibInfo.pbLibFile[0] = 0; // Initialized later strcpy(InjLibInfo.pbLibFile, pbLibFile); HANDLE hProcess =OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id); if(hProcess ==NULL) { WriteLog("InjectLib:OpenProcess %d failed!", process_id); return -1; } if((pdwCodeRemote = (PDWORD)VirtualAllocEx(hProcess, NULL, cbCodeSize+20, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) ==NULL) { CloseHandle(hProcess); return FALSE; } // Change the page protection of the allocated memory // to executable, read, and write. int ret; ret =WriteProcessMemory(hProcess, pdwCodeRemote, (LPVOID)(DWORD) ThreadFunc, cbCodeSize, &dwNumBytesXferred); //WriteLog("WriteProcessMemory pdwCodeRemote size:%d, ret=%d, %d", cbCodeSize, ret, STATUS_ACCESS_VIOLATION); if(ret ==STATUS_ACCESS_VIOLATION || ret ==false) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return false; } // Put InjLibInfo in the remote thread's memory block. if((pInjLibInfoRemote = (INJLIBINFO *)VirtualAllocEx(hProcess, NULL, sizeof(InjLibInfo)+20, MEM_COMMIT, PAGE_READWRITE)) ==NULL) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return FALSE; } ret =WriteProcessMemory(hProcess, pInjLibInfoRemote, &InjLibInfo, sizeof(InjLibInfo), &dwNumBytesXferred); //WriteLog("WriteProcessMemory InjLibInfo ret=%d", ret); if(ret ==STATUS_ACCESS_VIOLATION || ret ==false) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return false; } //WriteLog("CreateRemoteProcess..."); hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)(DWORD) pdwCodeRemote, pInjLibInfoRemote, 0, &dwThreadId); if (hThread == NULL) { //WriteLog("CreateRemoteProcess failed"); VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE); CloseHandle(hProcess); return false; } //WriteLog("CreateRemoteThread success, WaitForSingleObject..."); WaitForSingleObject(hThread, INFINITE); if (hThread != NULL) { GetExitCodeThread(hThread, (PDWORD) &hinstDllRemote); CloseHandle(hThread); } // Let the remote thread start executing the remote // ThreadFunc function using our modified stack, which // now contains an initialized INJLIBINFO structure. if(pdwCodeRemote) { VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE); } if(pInjLibInfoRemote) { VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE); } //WriteLog("OK++++"); CloseHandle(hProcess); return(hinstDllRemote != NULL); }