注入(二):修改导入表(c++)
2015-04-14 12:48
232 查看
导入表注入:修改游戏EXE依赖dll树上找个结点,程序运行前加载,加载修改回导入表。
优:游戏依赖库多,不易用完整性来查验,同时客户端版本不同,更易躲过检测
缺点:文件操作明显,易被ProcessMonitor检测到
注入没问题,运行有问题,还有待调试。
优:游戏依赖库多,不易用完整性来查验,同时客户端版本不同,更易躲过检测
缺点:文件操作明显,易被ProcessMonitor检测到
//BeModeImportTableExe.exe void main(void) { int i = 0; while(true) { __asm{ mov eax,i inc eax } } }
//修改导入表的exe #include <Windows.h> DWORD PEAlign(DWORD dwTarNum,DWORD dwAlignTo) { return(((dwTarNum+dwAlignTo-1)/dwAlignTo)*dwAlignTo); } // //增加导入表项 // BOOL AddNewSection(LPCTSTR lpStrModulePath, DWORD dwNewSectionSize) { bool bSuccess = false; LPVOID lpMemModule = NULL; LPBYTE lpData = NULL; HANDLE hFile = INVALID_HANDLE_VALUE, hFileMapping = INVALID_HANDLE_VALUE; PIMAGE_NT_HEADERS pNtHeader = NULL; PIMAGE_SECTION_HEADER pNewSection = NULL, pLastSection = NULL; OutputDebugString("[!] AddNewSection Enter!\n"); //TODO:可能还涉及关闭windows文件保护 __try { //pe文件映射到内存 hFile = CreateFile( lpStrModulePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( INVALID_HANDLE_VALUE == hFile ) { OutputDebugString("[-] AddNewSection CreateFile fail!\n"); goto _EXIT_; } DWORD dwFileSize = GetFileSize(hFile, NULL); hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE/* | SEC_IMAGE*/, 0, dwFileSize, "WINSUN_MAPPING_FILE"); if ( NULL == hFileMapping ) { OutputDebugString("[-] AddNewSection CreateFileMapping fail!\n"); goto _EXIT_; } lpMemModule = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, dwFileSize); if ( NULL == lpMemModule ) { OutputDebugString("[-] AddNewSection MapViewOfFile fail!\n"); goto _EXIT_; } lpData = (LPBYTE)lpMemModule; //判断是否是PE文件 if (((PIMAGE_DOS_HEADER)lpData)->e_magic != IMAGE_DOS_SIGNATURE ) { OutputDebugString("[-] AddNewSection PE Header MZ error!\n"); goto _EXIT_; } pNtHeader = (PIMAGE_NT_HEADERS)(lpData + ((PIMAGE_DOS_HEADER)(lpData))->e_lfanew); if ( pNtHeader->Signature != IMAGE_NT_SIGNATURE ) { OutputDebugString("[-] AddNewSection PE Header PE error!\n"); goto _EXIT_; } //判断是否可以增加一个新节 if ( ((pNtHeader->FileHeader.NumberOfSections + 1) * sizeof(IMAGE_SECTION_HEADER)) > (pNtHeader->OptionalHeader.SizeOfHeaders) ) { OutputDebugString("[-] AddNewSection cannot add a new section!\n"); goto _EXIT_; } pNewSection = (PIMAGE_SECTION_HEADER)(pNtHeader+1) + pNtHeader->FileHeader.NumberOfSections; pLastSection = pNewSection - 1; DWORD rsize,vsize,roffset,voffset; //对齐偏移和RVA rsize=PEAlign(dwNewSectionSize, pNtHeader->OptionalHeader.FileAlignment); roffset=PEAlign(pLastSection->PointerToRawData+pLastSection->SizeOfRawData, pNtHeader->OptionalHeader.FileAlignment); vsize=PEAlign(dwNewSectionSize, pNtHeader->OptionalHeader.SectionAlignment); voffset=PEAlign(pLastSection->VirtualAddress+pLastSection->Misc.VirtualSize, pNtHeader->OptionalHeader.SectionAlignment); //填充新节表 memcpy(pNewSection->Name, "WINSUN", strlen("WINSUN")); pNewSection->VirtualAddress = voffset; pNewSection->PointerToRawData = roffset; pNewSection->Misc.VirtualSize = vsize; pNewSection->SizeOfRawData = rsize; pNewSection->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; //修改IMAGE_NT_HEADERS,增加新节表 pNtHeader->FileHeader.NumberOfSections++; pNtHeader->OptionalHeader.SizeOfImage += vsize; pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; //增加新节到文件尾部 DWORD dwWriteBytes; SetFilePointer(hFile,0,0,FILE_END); PBYTE pbNewSectionContent = new BYTE[rsize]; ZeroMemory(pbNewSectionContent, rsize); bSuccess = WriteFile(hFile, pbNewSectionContent, rsize, &dwWriteBytes, NULL); if (!bSuccess) { MessageBox(NULL,"新增节失败","error",MB_OK); goto _EXIT_; } } __except(EXCEPTION_EXECUTE_HANDLER) { OutputDebugString("[-] AddImportTableItem Exception!\n"); return false; } OutputDebugString("[!] AddNewSection Exit!\n"); bSuccess = true; _EXIT_: if ( hFile ) { CloseHandle(hFile); } if ( lpMemModule) { UnmapViewOfFile(lpMemModule); } if ( hFileMapping ) { CloseHandle(hFileMapping); } return true; } // PIMAGE_SECTION_HEADER ImageRVA2Section(PIMAGE_NT_HEADERS pImgNTHeader, DWORD dwRVA) { int i; PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pImgNTHeader+1); for(i=0;i<pImgNTHeader->FileHeader.NumberOfSections;i++) { if((dwRVA>=(pSectionHeader+i)->VirtualAddress) && (dwRVA<=((pSectionHeader+i)->VirtualAddress+(pSectionHeader+i)->SizeOfRawData))) { return ((PIMAGE_SECTION_HEADER)(pSectionHeader+i)); } } return(NULL); } // // calulates the Offset from a RVA // Base - base of the MMF // dwRVA - the RVA to calculate // returns 0 if an error occurred else the calculated Offset will be returned DWORD RVA2Offset(PIMAGE_NT_HEADERS pImgNTHeader, DWORD dwRVA) { DWORD _offset; PIMAGE_SECTION_HEADER section; section=ImageRVA2Section(pImgNTHeader,dwRVA);//ImageRvaToSection(pimage_nt_headers,Base,dwRVA); if(section==NULL) { return(0); } _offset=dwRVA+section->PointerToRawData-section->VirtualAddress; return(_offset); } BOOL AddNewImportDescriptor(const char * szPEFilePath,char * szInjectDllName, char *szImportFuncName) { BOOL bSuccess = FALSE; LPVOID lpMemModule = NULL; LPBYTE lpData = NULL; HANDLE hFile = INVALID_HANDLE_VALUE, hFileMapping = INVALID_HANDLE_VALUE; PIMAGE_NT_HEADERS pNtHeader = NULL; PIMAGE_IMPORT_DESCRIPTOR pstImportTable = NULL; PIMAGE_SECTION_HEADER pstSectionHeader = NULL; __try { //pe文件映射到内存 hFile = CreateFile( szPEFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( INVALID_HANDLE_VALUE == hFile ) { OutputDebugString("[-] AddNewImportDescriptor CreateFile fail!\n"); goto _EXIT_; } DWORD dwFileSize = GetFileSize(hFile, NULL); hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE/* | SEC_IMAGE*/, 0, dwFileSize, "WINSUN_MAPPING_FILE"); if ( NULL == hFileMapping ) { OutputDebugString("[-] AddNewImportDescriptor CreateFileMapping fail!\n"); goto _EXIT_; } lpMemModule = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, dwFileSize); if ( NULL == lpMemModule ) { OutputDebugString("[-] AddNewImportDescriptor MapViewOfFile fail!\n"); goto _EXIT_; } lpData = (LPBYTE)lpMemModule; //判断是否是PE if (((PIMAGE_DOS_HEADER)lpData)->e_magic != IMAGE_DOS_SIGNATURE ) { OutputDebugString("[-] AddNewImportDescriptor PE Header MZ error!\n"); goto _EXIT_; } pNtHeader = (PIMAGE_NT_HEADERS)(lpData + ((PIMAGE_DOS_HEADER)(lpData))->e_lfanew); if ( pNtHeader->Signature != IMAGE_NT_SIGNATURE ) { OutputDebugString("[-] AddNewImportDescriptor PE Header PE error!\n"); goto _EXIT_; } pstImportTable = (PIMAGE_IMPORT_DESCRIPTOR)(lpData + RVA2Offset(pNtHeader,pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)); BOOL bBoundImport = FALSE; if (pstImportTable->Characteristics == 0 && pstImportTable->FirstThunk != 0) { bBoundImport = TRUE; pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0; pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0; } pstSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHeader+1)+pNtHeader->FileHeader.NumberOfSections-1; PBYTE pbNewSection = pstSectionHeader->PointerToRawData + lpData; int i = 0; while(pstImportTable->FirstThunk != 0) { memcpy(pbNewSection, pstImportTable, sizeof(IMAGE_IMPORT_DESCRIPTOR)); pstImportTable++; pbNewSection += sizeof(IMAGE_IMPORT_DESCRIPTOR); i++; } memcpy(pbNewSection, (pbNewSection-sizeof(IMAGE_IMPORT_DESCRIPTOR)), sizeof(IMAGE_IMPORT_DESCRIPTOR)); DWORD dwDelt = pstSectionHeader->VirtualAddress - pstSectionHeader->PointerToRawData; //avoid import not need table PIMAGE_THUNK_DATA pImgThunkData = (PIMAGE_THUNK_DATA)(pbNewSection + sizeof(IMAGE_IMPORT_DESCRIPTOR)*2); //import dll name PBYTE pszDllNamePosition = (PBYTE)(pImgThunkData + 2); memcpy(pszDllNamePosition, szInjectDllName, strlen(szInjectDllName)); pszDllNamePosition[strlen(szInjectDllName)] = 0; //确定IMAGE_IMPORT_BY_NAM的位置 PIMAGE_IMPORT_BY_NAME pImgImportByName = (PIMAGE_IMPORT_BY_NAME)(pszDllNamePosition + strlen(szInjectDllName) + 1); //init IMAGE_THUNK_DATA pImgThunkData->u1.Ordinal = dwDelt + (DWORD)pImgImportByName - (DWORD)lpData ; //init IMAGE_IMPORT_BY_NAME pImgImportByName->Hint = 1; memcpy(pImgImportByName->Name, szImportFuncName, strlen(szImportFuncName)); //== dwDelt + (DWORD)pszFuncNamePosition - (DWORD)lpData ; pImgImportByName->Name[strlen(szImportFuncName)] = 0; //init OriginalFirstThunk if (bBoundImport) { ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->OriginalFirstThunk = 0; } else ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->OriginalFirstThunk = dwDelt + (DWORD)pImgThunkData - (DWORD)lpData; //init FirstThunk ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->FirstThunk = dwDelt + (DWORD)pImgThunkData - (DWORD)lpData; //init Name ((PIMAGE_IMPORT_DESCRIPTOR)pbNewSection)->Name = dwDelt + (DWORD)pszDllNamePosition-(DWORD)lpData; //改变导入表 pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = pstSectionHeader->VirtualAddress; pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (i+1)*sizeof(IMAGE_IMPORT_DESCRIPTOR); } __except(EXCEPTION_EXECUTE_HANDLER) { OutputDebugString("[-] AddNewImportDescriptor Exception!\n"); return false; } _EXIT_: if ( hFile ) { CloseHandle(hFile); } if ( lpMemModule) { UnmapViewOfFile(lpMemModule); } if ( hFileMapping ) { CloseHandle(hFileMapping); } return true; } BOOL AddImportTable(const char * szPEFilePath, char * szInjectDllName,char *szFuncName) { BOOL bSuccess = FALSE; try { //增加一个叫"WINSUN"的节 bSuccess = AddNewSection(szPEFilePath, 256); if (!bSuccess) { MessageBox(NULL,"add new section fail", "error", MB_OK); return bSuccess; } //增加一个导入表 AddNewImportDescriptor(szPEFilePath, szInjectDllName,szFuncName); } catch ( ... )//CException* e) { return bSuccess; } return bSuccess; } void BackupPE(char * pszPeFilePath) { CHAR szPath[MAX_PATH] = {0}; PCHAR pszPath = pszPeFilePath; pszPath = strrchr(pszPath, '\\'); *pszPath = '\0'; strcpy_s(szPath, strlen(pszPeFilePath)+1,pszPeFilePath); strcat_s(szPath, strlen("\\backup_")+1,"\\backup_"); strcat_s(szPath, strlen(pszPath+1)+1,pszPath+1); *pszPath = '\\'; CopyFile(pszPeFilePath, szPath, FALSE); strncpy(pszPeFilePath, szPath, MAX_PATH); return; } void main(int argc, char **argv) { AddImportTable("BeModeImportTableExe.exe","WaiGua.dll","InjectFunc"); }
//WaiGua.dll // dllmain.cpp : Defines the entry point for the DLL application. #include <Windows.h> #ifdef __cplusplus extern "C" { #endif __declspec (dllexport) void InjectFunc(void); #ifdef __cplusplus } #endif void InjectFunc(void) { MessageBoxA(NULL, "Dll export Inject Success", "Dll Inject", MB_OKCANCEL); } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBoxA(NULL, "the simple inject success", "Dll Inject", MB_OKCANCEL); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
注入没问题,运行有问题,还有待调试。
相关文章推荐
- 一台电脑的Android NDK 工程包,导入另一台电脑后,任意修改一处C++代码就会产生大面积报错的解决方案
- 【神器】yololib 飘云修改版 -- 给iOS APP 添加导入表注入--你懂的
- 驱动开发实现修改导入表注入dll
- 一道C++面试题,只能修改或者增加一个字符,给出至少三种修改方案
- C++ 虚函数 修改虚表
- VS2010 C++环境下DLL和LIB文件目录及名称修改
- C++ 11标准新增加了Lambda表达式、for_each语法,修改了auto
- Eclipse CDT 导入 Makefile 构建的 C/C++ 工程
- Java中的Package.Import.Class以及和C++的比较(一)--包.导入.类权限
- C++设置文件修改时间
- [导入]EditPlus编译器集成例子(Java、Borland C++、Visual C++、Inno Setup、nsis)
- phpadmin导入数据提示文件最大限制的修改方法
- 修改导入的博客图片地址链接
- oracle创建表空间、用户、授权、修改字段长度、导出、导入等
- C++环境下DLL和LIB文件目录及名称修改
- 如何在C中调用C++函数 与 如何在C++中调用C的函数(待修改)
- [导入]修改Ext.form.DateField只选择年月
- C++ 再谈string类型(2) 修改string对象的方法
- 线程注入模块--C++