首页
社区
课程
招聘
[原创]放个LoadLibrary和GetProcAddress
发表于: 2012-5-12 12:28 16699

[原创]放个LoadLibrary和GetProcAddress

2012-5-12 12:28
16699
简单实现LoadLibrary然后实现GetProcAddress再然后用LoadLibrary的结果填充输入表,达到隐形调用API的目的.32位测试,正规PE文件测试,优化过的不认.
出处:本文来自看雪学院.
作者:Worker
编译平台:VS2005
#include "stdafx.h"
#include "LoadLibrary.h"
DWORD AlignUp(DWORD n, DWORD A)
{
	return ((n / A) +  ((n % A) ? 1 : 0)) * A;
}
HMODULE LoadStandardDLL(LPCWSTR pszDLLName)
{
	wchar_t pwzFullPath[MAX_PATH*2];
//获得DLL的全部路径
	memset(pwzFullPath,0,MAX_PATH*2);
	GetSystemDirectory(pwzFullPath,MAX_PATH*2);
	wcscat_s(pwzFullPath,pszDLLName);
//映射文件到内存
	HANDLE hFile=CreateFile(pwzFullPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(INVALID_HANDLE_VALUE==hFile)
	{
		return NULL;
	}
	HANDLE hMapFile=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,GetFileSize(hFile,NULL),NULL);
	if(NULL==hMapFile)
	{
		return NULL;
	}   
	PBYTE lpMapAddress=(PBYTE)MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,0);    
	if(NULL==lpMapAddress)
	{
		return NULL;
	}
//解析PE文件格式
	PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)lpMapAddress;
	PIMAGE_NT_HEADERS pNtHeader=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
	IMAGE_OPTIONAL_HEADER32 pOptionalHead=pNtHeader->OptionalHeader;
	PIMAGE_SECTION_HEADER pSecHeader=(PIMAGE_SECTION_HEADER)((DWORD)pNtHeader+sizeof(IMAGE_OPTIONAL_HEADER)+sizeof(IMAGE_FILE_HEADER)+sizeof(DWORD));
	DWORD dwSecAlign=pOptionalHead.SectionAlignment;
//分配新内存PE的空间
	PBYTE pMemPE=(PBYTE)VirtualAlloc(NULL,pOptionalHead.SizeOfImage,MEM_COMMIT,PAGE_READWRITE);
	if(NULL==pMemPE)
	{
		return NULL;
	}
//保留.用于返回值
	PBYTE pbBase=(PBYTE)pMemPE;
//复制PE头到虚拟内存
	memcpy(pMemPE,lpMapAddress,pOptionalHead.SizeOfHeaders);
	pMemPE+=4096;
//复制区段信息.根据内存中的物理地址,复制到区段中的虚拟地址.虚拟地址的大小增长以虚拟大小计算.
	for(int Index=0;Index<pNtHeader->FileHeader.NumberOfSections;Index++) //注意PE虚拟内存大小对齐.
	{
		DWORD RawSize=pSecHeader[Index].SizeOfRawData;
		DWORD VirtualSize=pSecHeader[Index].Misc.VirtualSize;
		DWORD Align=AlignUp(VirtualSize,dwSecAlign);
		PBYTE pbPhysicalPE=(PBYTE)(pSecHeader[Index].PointerToRawData+lpMapAddress);
		memcpy(pMemPE,pbPhysicalPE,RawSize);
		pMemPE+=Align;
	}
//填充输出表
	PIMAGE_EXPORT_DIRECTORY pExportTable=(PIMAGE_EXPORT_DIRECTORY)
		(pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+pbBase);
	DWORD dwExportSize=pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
	if(false!=dwExportSize&&NULL!=pExportTable)
	{
		PBYTE *pbAddressArray=(PBYTE*)(pExportTable->AddressOfFunctions+pbBase);
		PBYTE *pbSerialIndex=(PBYTE*)(pExportTable->AddressOfNameOrdinals+pbBase);
		for(WORD Index=reinterpret_cast<WORD>(pbSerialIndex[0*2]);Index<pExportTable->NumberOfFunctions;Index++)
		{
			pbAddressArray[Index*1]=(pbAddressArray[Index*1]+(DWORD)pbBase);
		}
	}
//填充输入表
	PIMAGE_IMPORT_DESCRIPTOR pImportTable=(PIMAGE_IMPORT_DESCRIPTOR)
		(pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress+pbBase);
	DWORD dwImportSize=pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
	if(false!=dwImportSize&&NULL!=pImportTable)
	{
		for(DWORD DllIndex=0;DllIndex<dwImportSize/sizeof(IMAGE_IMPORT_DESCRIPTOR);DllIndex++)
		{
			PBYTE *pbAddressArray=(PBYTE*)pImportTable->FirstThunk;
			if(NULL==pbAddressArray)
			{
				break;
			}
			pbAddressArray=(PBYTE*)(reinterpret_cast<DWORD>(pbAddressArray)+pbBase);
			LPCSTR pbNameArray=(LPCSTR)pImportTable->Name;
			if(NULL==pbNameArray)
			{
				break;
			}
			pbNameArray=(LPCSTR)((DWORD)pbNameArray+pbBase);
			PIMAGE_THUNK_DATA32 pThunkData=(PIMAGE_THUNK_DATA32)pImportTable->OriginalFirstThunk;
			if(NULL==pThunkData)
			{
				break;
			}
			pThunkData=(PIMAGE_THUNK_DATA32)((DWORD)pThunkData+pbBase);
			HMODULE hModule=LoadLibraryA(pbNameArray);
			PWORD pdwOrdinal=(PWORD)pThunkData->u1.Ordinal;
			for(DWORD NameIndex=0;false!=pdwOrdinal;NameIndex++)
			{
				PSZ pszProcName=(PSZ)(pThunkData->u1.Function+pbBase+2);
				pbAddressArray[NameIndex*1]=(PBYTE)GetProcAddress(hModule,pszProcName);
				pThunkData++;
				pdwOrdinal=(PWORD)pThunkData->u1.Ordinal;
			}
			pImportTable++;
		}
	}
//结束处理
	if(lpMapAddress)
	{
		UnmapViewOfFile(lpMapAddress);
	}
	if(hMapFile)
	{
		CloseHandle(hMapFile);
	}
	if(hFile)
	{
		CloseHandle(hFile);
	}
	return (HMODULE)pbBase;
}
FARPROC GetStandardProc(HMODULE hModule,PSZ pszProcName)
{
	PBYTE pbBase=(PBYTE)hModule;
	PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)pbBase;
	PIMAGE_NT_HEADERS pNtHeader=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
	IMAGE_OPTIONAL_HEADER32 pOptionalHead=pNtHeader->OptionalHeader;
	PIMAGE_EXPORT_DIRECTORY pExportTable=(PIMAGE_EXPORT_DIRECTORY)
		(pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+pbBase);
	if(NULL==pExportTable)
	{
		return NULL;
	}
//获得搜索需要的辅助信息
	PBYTE *pbNameArray=(PBYTE*)(pExportTable->AddressOfNames+pbBase);
	PBYTE *pbAddressArray=(PBYTE*)(pExportTable->AddressOfFunctions+pbBase);
	PBYTE *pbSerialIndex=(PBYTE*)(pExportTable->AddressOfNameOrdinals+pbBase);
//搜索到处表中的API地址.
	for(WORD Index=reinterpret_cast<WORD>(pbSerialIndex[0*2]);Index<pExportTable->NumberOfFunctions;Index++)
	{
		PSZ pszNameBase=(PSZ)pbNameArray[Index*1];
		pszNameBase=(reinterpret_cast<DWORD>(pbBase)+pszNameBase);
		if(false==stricmp(pszNameBase,pszProcName))
		{
			return (FARPROC)pbAddressArray[Index*1];
		}
	}
	return NULL;
}
ULONG FullImportTable()
{
	DWORD OldProtect;
	DWORD NewProtect;
	wchar_t pwzRelativeName[MAX_PATH];
	memset(pwzRelativeName,0,MAX_PATH);
	PBYTE pbBase=(PBYTE)GetModuleHandle(NULL);
	PIMAGE_DOS_HEADER pDosHeader=(PIMAGE_DOS_HEADER)pbBase;
	PIMAGE_NT_HEADERS pNtHeader=(PIMAGE_NT_HEADERS)((DWORD)pDosHeader+pDosHeader->e_lfanew);
	IMAGE_OPTIONAL_HEADER32 pOptionalHead=pNtHeader->OptionalHeader;
	PIMAGE_IMPORT_DESCRIPTOR pImportTable=(PIMAGE_IMPORT_DESCRIPTOR)
		(pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress+pbBase);
	DWORD dwImportSize=pOptionalHead.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
	DWORD SizeImage=pOptionalHead.SizeOfImage;
	VirtualProtect(pbBase,SizeImage,PAGE_EXECUTE_READWRITE,&OldProtect);
	if(NULL==pImportTable)
	{
		return GetLastError();
	}
//获得导入表的每个DLL导入的函数.并且填充为内存中的地址.
	for(DWORD DllIndex=0;DllIndex<dwImportSize/sizeof(IMAGE_IMPORT_DESCRIPTOR);DllIndex++)
	{
		PBYTE *pbAddressArray=(PBYTE*)pImportTable->FirstThunk;
		if(NULL==pbAddressArray)
		{
			break;
		}
		pbAddressArray=(PBYTE*)(reinterpret_cast<DWORD>(pbAddressArray)+pbBase);
		LPCSTR pbNameArray=(LPCSTR)pImportTable->Name;
		if(NULL==pbNameArray)
		{
			break;
		}
		pbNameArray=(LPCSTR)((DWORD)pbNameArray+pbBase);
		PIMAGE_THUNK_DATA32 pThunkData=(PIMAGE_THUNK_DATA32)pImportTable->OriginalFirstThunk;
		if(NULL==pThunkData)
		{
			break;
		}
		pThunkData=(PIMAGE_THUNK_DATA32)((DWORD)pThunkData+pbBase);
		pwzRelativeName[0]=L'\\';
		for(BYTE LengthIndex=0,Index=1;LengthIndex<strlen(pbNameArray);LengthIndex++,Index++)
		{
			pwzRelativeName[Index*1]=pbNameArray[LengthIndex*1];
		}
		HMODULE hModule=LoadStandardDLL(pwzRelativeName);
		if(NULL!=hModule)
		{
			PWORD pdwOrdinal=(PWORD)pThunkData->u1.Ordinal;
			for(DWORD NameIndex=0;false!=pdwOrdinal;NameIndex++)
			{
				PSZ pszProcName=(PSZ)(pThunkData->u1.Function+pbBase+2);
				pbAddressArray[NameIndex*1]=(PBYTE)GetStandardProc(hModule,pszProcName);
				pThunkData++;
				pdwOrdinal=(PWORD)pThunkData->u1.Ordinal;
			}
		}
		memset(pwzRelativeName,0,MAX_PATH);
		pImportTable++;
	}
	VirtualProtect(pbBase,SizeImage,OldProtect,&NewProtect);
	return false;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{	
	void (WINAPI *MyExitProcess)(DWORD ExitCode);
	FullImportTable();
	HMODULE hMod=LoadStandardDLL(L"\\Kernel32.dll");
	*(DWORD*)&MyExitProcess=(DWORD)GetStandardProc(hMod,"ExitProcess");
	MessageBox(NULL,L"请尝试Dump",L"提示",MB_OK);
	MyExitProcess(0);
	return false;
}

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 6
支持
分享
最新回复 (15)
雪    币: 106
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
HANDLE hFile=CreateFile(pwzFullPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(INVALID_HANDLE_VALUE==hFile)
{
return NULL;
}
HANDLE hMapFile=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,GetFileSize(hFile,NULL),NULL);
if(NULL==hMapFile)
{
return NULL;
}


诸如此类,CreateFileMapping返回失败,hFile句柄也应该要关掉.
2012-5-12 13:08
0
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
3Q,大意.
2012-5-12 14:38
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
印象中看雪中最多的帖子有2种,一是破解了什么什么,另一个就是这内存加载了。

1.
  memcpy(pMemPE,lpMapAddress,pOptionalHead.SizeOfHeaders);
  pMemPE+=4096;
SizeOfHeader一定是4096嘛?
记得SectionHeader中有个VirtualAddress属性。

2.
pbSerialIndex[0*2]
pbAddressArray[Index*1]=(pbAddressArray[Index*1]+(DWORD)pbBase)

这的0*2和Index*1有什么特别的意思没?

3. 重定位信息的处理

4. 输入节的处理
DLL的加载是件很复杂的事,这个代码里没有看到如何处理 “绑定输入”?还有“ForwarderChain ”?的情况。

5. 输出的情况和上面类似,也有forwarder的情况。
2012-5-12 15:22
0
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
5
认真看清楚我想干什么再来吧
2012-5-12 15:34
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
#include "LoadLibrary.h"也发出来啊,,,是用VC什么版本编译的?
2012-5-13 02:54
0
雪    币: 316
活跃值: (128)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
7
LoadLibrary.H里面啥都没.只有windows.h.VS2005
2012-5-13 05:56
0
雪    币: 184
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看看再说吧!
2012-5-15 22:31
0
雪    币: 1233
活跃值: (907)
能力值: ( LV12,RANK:750 )
在线值:
发帖
回帖
粉丝
9
我是来模版楼主头像的
2012-5-16 19:13
0
雪    币: 122
活跃值: (72)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
10
vs2005.....
2012-9-7 03:31
0
雪    币: 56
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
话说也正想写一个LoadLibrary呢,先马克,完成发出来
2012-9-8 16:12
0
雪    币: 196
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
怎么回事?这段代码win7运行不了,没有错误,但是运行不了。
2012-10-23 10:30
0
雪    币: 123
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
占位学习楼主大作
2012-10-23 15:14
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
以前自己也写过这样的一个函数 当时是为了做免杀
2012-12-8 16:28
0
雪    币: 3020
活跃值: (3065)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
15
LoadLibrary 在遇到 导入表有msvcr80.dll 的时候一直失败
2012-12-10 09:25
0
雪    币: 225
活跃值: (294)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
不是吧,加载不成功
2012-12-31 18:06
0
游客
登录 | 注册 方可回帖
返回
//