注入(二):修改导入表(c++)

导入表注入:修改游戏EXE依赖dll树上找个结点,程序运行前加载,加载修改回导入表。
 优:游戏依赖库多,不易用完整性来查验,同时客户端版本不同,更易躲过检测
 缺点:文件操作明显,易被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;
}

注入没问题,运行有问题,还有待调试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值