GetProcAddressEx跨进程获取导出函数地址

没什么新技术,就是把目标进程的内存读过来分析而已。

代码在x86下测试通过,由于手头没有x64系统,希望热心的朋友测试一下x64的兼容性,可能不兼容的地方已经在代码中标出。

PVOID GetProcAddressEx(HANDLE hProc, HMODULE hModule, LPCSTR lpProcName)
{
	PVOID pAddress = NULL;
	SIZE_T OptSize;
	IMAGE_DOS_HEADER DosHeader;
	SIZE_T ProcNameLength = lstrlenA(lpProcName) + sizeof(CHAR);//'\0'

	//读DOS头
	if (ReadProcessMemory(hProc, hModule, &DosHeader, sizeof(DosHeader), &OptSize))
	{
		IMAGE_NT_HEADERS NtHeader;

		//读NT头
		if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + DosHeader.e_lfanew), &NtHeader, sizeof(NtHeader), &OptSize))
		{
			IMAGE_EXPORT_DIRECTORY ExpDir;
			SIZE_T ExportVirtualAddress = NtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;

			//读输出表
			if (ExportVirtualAddress && ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExportVirtualAddress), &ExpDir, sizeof(ExpDir), &OptSize))
			{
				if (ExpDir.NumberOfFunctions)
				{
					//x64待定:地址数组存放RVA的数据类型是4字节还是8字节???
					SIZE_T *pProcAddressTable = (SIZE_T *)GlobalAlloc(GPTR, ExpDir.NumberOfFunctions * sizeof(SIZE_T));

					//读函数地址表
					if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfFunctions), pProcAddressTable, ExpDir.NumberOfFunctions * sizeof(PVOID), &OptSize))
					{
						//x64待定:名称数组存放RVA的数据类型是4字节还是8字节???
						SIZE_T *pProcNamesTable = (SIZE_T *)GlobalAlloc(GPTR, ExpDir.NumberOfNames * sizeof(SIZE_T));

						//读函数名称表
						if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNames), pProcNamesTable, ExpDir.NumberOfNames * sizeof(PVOID), &OptSize))
						{
							CHAR *pProcName = (CHAR *)GlobalAlloc(GPTR, ProcNameLength);

							//遍历函数名称
							for (DWORD i = 0; i < ExpDir.NumberOfNames; i++)
							{
								if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + pProcNamesTable[i]), pProcName, ProcNameLength, &OptSize))
								{
									if (RtlEqualMemory(lpProcName, pProcName, ProcNameLength))
									{
										//x64待定:函数在地址数组索引的数据类型是2字节还是???
										WORD NameOrdinal;

										//获取函数在地址表的索引
										if (ReadProcessMemory(hProc, (PVOID)((SIZE_T)hModule + ExpDir.AddressOfNameOrdinals + sizeof(NameOrdinal) * i), &NameOrdinal, sizeof(NameOrdinal), &OptSize))
										{
											pAddress = (PVOID)((SIZE_T)hModule + pProcAddressTable[NameOrdinal]);
										}
										break;//for
									}
								}
							}
							GlobalFree(pProcName);
						}
						GlobalFree(pProcNamesTable);
					}
					GlobalFree(pProcAddressTable);
				}
			}
		}
	}
	return pAddress;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值