返回列表 发帖

[转帖]装载一个exe,并且执行

hiahia,被这个题目吓住了吧,一个CreateProcess不就可以吗,嘿嘿,可是你会看到两个进程存在,这里要干的是让进程管理器只能看到一个进程。好了,如果你有了Win32进程的基础理论,了解PE格式,再加上熟悉管理进程(当然你要是不知道这些,代码运行以后的效果你都不会看到。。。那我不是白忙了:P)开始: 先来看看代码: // ExeLoader.cpp : Defines the entry point for the console application. // // Coder Jozu #include #include #include #include #define MakePtr( cast, ptr, addValue ) (cast)( (DWORD)(ptr) + (DWORD)(addValue)) ////////////////////////////////////////////////////////////////////////// void CopyRight() { _tprintf("ExeLoader --- Load a exe FILE and execute it IN CURRENT CONTEXT.\n"); _tprintf(" Coder Jozu.\n"); _tprintf("----------------------------------------------------------------\n"); } ////////////////////////////////////////////////////////////////////////// void Usage() { _tprintf("Exeloader program\n"); _tprintf("ExeLoader program\n"); _tprintf(" Program is what you want to executed.\n"); } ////////////////////////////////////////////////////////////////////////// HINSTANCE hInst; typedef HMODULE (WINAPI* LPFNGETMODULEHANDLEA)(LPCSTR lpModuleFilename); typedef HMODULE (WINAPI* LPFNGETMODULEHANDLEW)(LPCWSTR lpModuleFilename); LPFNGETMODULEHANDLEA lpfnGetModulehandleA = NULL; LPFNGETMODULEHANDLEW lpfnGetModulehandleW = NULL; static HMODULE WINAPI HandlerGetModuleHandleA(LPCSTR lpModuleFileName) { if(!lpModuleFileName) return hInst; return lpfnGetModulehandleA(lpModuleFileName); } static HMODULE WINAPI HandlerGetModuleHandleW(LPCWSTR lpModuleFileName) { if(!lpModuleFileName) return hInst; return lpfnGetModulehandleW(lpModuleFileName); } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// DWORD WINAPI GetFunctionAddrWithIndex(HMODULE hInst, PIMAGE_IMPORT_BY_NAME piibn) { // // I am tired of do this bitch, so just do it directly // Don';t say it is a bug. en.... // if( !stricmp((LPCSTR)piibn->Name, "GetModuleHandleA") ) return (DWORD)HandlerGetModuleHandleA; if( !stricmp((LPCSTR)piibn->Name, "GetModuleHandleW") ) return (DWORD)HandlerGetModuleHandleW; return (DWORD)GetProcAddress(hInst, (LPCSTR)piibn->Hint); } ////////////////////////////////////////////////////////////////////////// DWORD WINAPI GetFunctionAddrWithName(HMODULE hInst, PIMAGE_IMPORT_BY_NAME piibn) { if( !stricmp((LPCSTR)piibn->Name, "GetModuleHandleA") ) return (DWORD)HandlerGetModuleHandleA; if( !stricmp((LPCSTR)piibn->Name, "GetModuleHandleW") ) return (DWORD)HandlerGetModuleHandleW; return (DWORD)GetProcAddress(hInst, (LPCSTR)piibn->Name); } ////////////////////////////////////////////////////////////////////////// BOOL WINAPI WalkWithImportTable(PVOID hInst) { #define THUNK_INDEXMASK 0x80000000 PIMAGE_DOS_HEADER pidh; PIMAGE_NT_HEADERS pinhs; PIMAGE_SECTION_HEADER pish; PIMAGE_IMPORT_DESCRIPTOR piid; BOOL bDone = FALSE; HMODULE hModule; LPCSTR lpDllName; PIMAGE_THUNK_DATA pitd; PIMAGE_THUNK_DATA pFirstThunk; PIMAGE_IMPORT_BY_NAME piibn; DWORD dwFuncAddr; SYSTEM_INFO si; MEMORY_BASIC_INFORMATION mbi; pidh = (PIMAGE_DOS_HEADER)hInst; pinhs = MakePtr(PIMAGE_NT_HEADERS, pidh, pidh->e_lfanew); pish = MakePtr(PIMAGE_SECTION_HEADER, pinhs, sizeof(*pinhs)); piid = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pidh, pinhs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); if(piid->TimeDateStamp == 0) { _tprintf("sorry about it.... You try to execute a exe with no bind import table. I will process later\n"); return FALSE; } if((DWORD)piid == (DWORD)pidh) { _tprintf("ft.... You try to execute a exe with no import table?"); return FALSE; } while(piid->Name != (DWORD)0) { lpDllName = MakePtr(LPCSTR, pidh, piid->Name); _tprintf("Processes dll: %s.\n", lpDllName); // // Check this dll is loaded, if not, just load it! // if((hModule = GetModuleHandle(lpDllName)) == NULL) hModule = LoadLibrary(lpDllName); // // Walk with the functions, if the functions not been bind, // we can use FirstThunk or OriginalFirstThunk, else // we use OriginalFirstThunk // pitd = MakePtr(PIMAGE_THUNK_DATA, pidh, piid->OriginalFirstThunk); pFirstThunk = MakePtr(PIMAGE_THUNK_DATA, pidh, piid->FirstThunk); // // Make virtual memory could be write // GetSystemInfo(&si); VirtualQuery(pFirstThunk, &mbi, sizeof(mbi)); if( (mbi.Protect & PAGE_READWRITE) != PAGE_READWRITE) { if(!VirtualProtect(mbi.BaseAddress, si.dwPageSize, PAGE_READWRITE, &mbi.Protect)) return FALSE; } while(*(DWORD*)pitd) { if((*(DWORD*)pitd & THUNK_INDEXMASK) == THUNK_INDEXMASK) { piibn = MakePtr(PIMAGE_IMPORT_BY_NAME, pidh, (*(DWORD*)pitd & ~THUNK_INDEXMASK)); dwFuncAddr = GetFunctionAddrWithIndex(hModule, piibn); } else { piibn = MakePtr(PIMAGE_IMPORT_BY_NAME, pidh, *(DWORD*)pitd); dwFuncAddr = GetFunctionAddrWithName(hModule, piibn); } if(!dwFuncAddr) { _tprintf("Function address return NULL. abort...\n"); return FALSE; } // // Patch to import table. // pFirstThunk->u1.AddressOfData = dwFuncAddr; pFirstThunk++; pitd++; } if(!VirtualProtect(mbi.BaseAddress, si.dwPageSize, mbi.Protect, &mbi.Protect)) return FALSE; piid++; } return TRUE; } ////////////////////////////////////////////////////////////////////////// int _tmain(int argc, LPCTSTR argv[]) { BOOL bDone = FALSE; DWORD dwOffset; PIMAGE_DOS_HEADER pidh; PIMAGE_NT_HEADERS pinhs; LPSTR lpCmdLine; LPWSTR lpwCmdLine; WCHAR lpwArgv1[MAX_PATH]; CopyRight(); if(argc != 2) { Usage(); return 1; } /* #ifdef _DEBUG LoadLibrary("User32.dll"); WalkWithImportTable(GetModuleHandle("user32.dll")); #endif */ // // We should handle GetModuelhandle() function // lpfnGetModulehandleA = (LPFNGETMODULEHANDLEA) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetModuleHandleA"); lpfnGetModulehandleW = (LPFNGETMODULEHANDLEW) GetProcAddress(GetModuleHandle("kernel32.dll"), "GetModuleHandleW"); __try { // // Validate this file is a executable PE file // GetFileAttributes(argv[1]); if(GetLastError() != ERROR_SUCCESS) { _tprintf("%s File not found!\n", argv[1]); __leave; } // // Load file with DONT_RESOLVE_DLL_REFERENCES will not redirect import table, // so we will do it manual // hInst = LoadLibraryEx(argv[1], NULL, DONT_RESOLVE_DLL_REFERENCES); pidh = MakePtr(PIMAGE_DOS_HEADER, hInst, 0); if(pidh->e_magic != IMAGE_DOS_SIGNATURE) { _tprintf("Invalidate file format.\n"); __leave; } pinhs = MakePtr(PIMAGE_NT_HEADERS, hInst, pidh->e_lfanew); if(pinhs->Signature != IMAGE_NT_SIGNATURE) { _tprintf("Invalidate file format.\n"); __leave; } dwOffset = pinhs->OptionalHeader.AddressOfEntryPoint + (DWORD)hInst; // // Redirect import table of PE file. // if(!WalkWithImportTable(hInst)) { _tprintf("Redirect file import table failed. abort...\n"); __leave; } // // We will patch the command line, There is no error handler, // if it is failed, I could say nothing.... // lpCmdLine = GetCommandLine(); strcpy(lpCmdLine, argv[1]); lpwCmdLine = GetCommandLineW(); MultiByteToWideChar(CP_ACP, 0, argv[1], -1, lpwArgv1, MAX_PATH); wcscpy(lpwCmdLine, lpwArgv1); __try { // // Goto call entrypoint. // ((FARPROC)(dwOffset))(); // // If the exe call exitprocess() directly, We will never goto next. // so if you want to do some post-processes, please hook this functions. // } __finally {} bDone = TRUE; } __finally {} getchar(); return 0; } 基本思路是这样的: 首先装载exe文件,然后自己为它进行导出函数的重定向,把控制转移到exe文件的入口点,代码中有一些会有问题,我都作了注释,希望你看得时候注意。 其中未邦定的API定位部分我没有时间实现了,不过如果你有兴趣可以自己加。have fun。

[转帖]装载一个exe,并且执行


看不懂

TOP

返回列表 回复 发帖