http://ift.tt/2AocAD0
// 课上练习.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
//要实现的功能:
/*
自己实现GerProcAddress
LoadLibraryA
*/
//思路:
/*
GerProcAddress和LoadLibraryA都是在Kernel32.dll中的
首要的任务就是找到Kernel32.dll,然后遍历IAT就能找到这两个函数
现在首要的难点就是如何找到kernel32.dll()
通过dll的加载顺序可以找到,而且虽然需要使用未文档化的API,但是好在windgb可以直接看,而且用到的也并不是很多
懒得去晚上搜了,直接自己实现一个得了,作为演示,能用就行(最好还是搜一个正规的结构体)
*/
/*
0: kd> dt _TEB /a
nt!_TEB
+0x000 NtTib : _NT_TIB
+0x01c EnvironmentPointer : Ptr32 Void
+0x020 ClientId : _CLIENT_ID
+0x028 ActiveRpcHandle : Ptr32 Void
+0x02c ThreadLocalStoragePointer : Ptr32 Void
+0x030 ProcessEnvironmentBlock : Ptr32 _PEB
//首先实现部分TEB结构体,因为只需要用的PEB的部分,所以实现到这就ok了
*/
//构建 TEB
typedef struct _TEB
{
//保证0x30是peb的结构体就ok了
struct _tem
{
DWORD a1;
DWORD a2;
DWORD a3;
DWORD a4;
DWORD a5;
DWORD a6;
DWORD a7;
DWORD a8;
DWORD a9;
DWORD a10;
DWORD a11;
DWORD a12;
}tem;
DWORD _Peb;
}TEB,*PTEB;
//构建 局部 _PEB
/*
0: kd> dt _PEB /b
nt!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
+0x002 BeingDebugged : UChar
+0x003 BitField : UChar
+0x003 ImageUsesLargePages : Pos 0, 1 Bit
+0x003 IsProtectedProcess : Pos 1, 1 Bit
+0x003 IsLegacyProcess : Pos 2, 1 Bit
+0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
+0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
+0x003 SpareBits : Pos 5, 3 Bits
+0x004 Mutant : Ptr32
+0x008 ImageBaseAddress : Ptr32
+0x00c Ldr : Ptr32
*/
typedef struct _PEB_LDR_DATA
{
int Length;
int Initialized;
DWORD SsHandle;
PLIST_ENTRY InLoadOrderModuleList; //只用到这里,所以到这就暂时ok吧
}PEB_LDR_DATA,*PPEB_LDR_DATA;
typedef struct _PEB
{
DWORD tem1;
DWORD tem2;
DWORD tem3;
PPEB_LDR_DATA Ldr; //需要先实现一个此结构体
}PEB,*PPEB;
typedef struct _LDR_DATA_TABLE_ENTRY
{
struct InLoadOrderLinks
{
PLIST_ENTRY Flink;
PLIST_ENTRY Blink;
}InLoadOrderLinks;
struct InMemoryOrderLinks
{
PLIST_ENTRY Flink;
PLIST_ENTRY Blink;
}InMemoryOrderLinks;
struct InInitializationOrderLinks
{
PLIST_ENTRY Flink;
PLIST_ENTRY Blink;
}InInitializationOrderLinks;
DWORD DllBase;//加载基址
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
//遍历导出表,然后根据函数名称,获取制定的函数地址
PVOID MyGetFnAddress(HMODULE hMoudle, const char * pProcName)
{
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMoudle;
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(pDosHdr->e_lfanew + (ULONG_PTR)pDosHdr);
PIMAGE_OPTIONAL_HEADER pOpHdr = (PIMAGE_OPTIONAL_HEADER)&pNtHdr->OptionalHeader;
//获取到op头之后,就是获取导出表
PIMAGE_EXPORT_DIRECTORY pExportDir = (PIMAGE_EXPORT_DIRECTORY)(pOpHdr->DataDirectory[0].VirtualAddress+(ULONG)pDosHdr);
DWORD *pEnt = (DWORD *)(pExportDir->AddressOfNames + (ULONG_PTR)pDosHdr);
//然后就开始便利了,首先遍历的是导入名称表
for (DWORD i =0;i<pExportDir->NumberOfNames;i++)
{
char * pEntName = (char*)(pEnt[i] + (ULONG_PTR)pDosHdr);
if (strcmp(pProcName, pEntName)==0)
{
//说明找到了输入的函数名
//然后去找这个函数名的在导出函数地址表中的地址
WORD* pEot = (WORD* )(pExportDir->AddressOfNameOrdinals+(ULONG_PTR)pDosHdr);
DWORD index = pEot[i];
DWORD * pEat = (DWORD*)(pExportDir->AddressOfFunctions + (ULONG_PTR)pDosHdr);
DWORD pFnAddress = pEat[index];
return (PVOID)pFnAddress;
}
}
//没有找到
return NULL;
}
int main()
{
//获取teb
PTEB pTeb = NtCurrentTeb();
//获取peb
PPEB pPeb= (PPEB)pTeb->_Peb;
//然后是找到ldr
PPEB_LDR_DATA pLdr = pPeb->Ldr;
//首先是获取InLoadOrderModuleList
PLIST_ENTRY pListEntry = pLdr->InLoadOrderModuleList->Flink;
PLDR_DATA_TABLE_ENTRY pKernel32 = (PLDR_DATA_TABLE_ENTRY)pListEntry->Flink;
HMODULE hMoudle = (HMODULE)pKernel32->DllBase;
//定义两个函数指针
/*
原型
WINAPI
GetProcAddress(
_In_ HMODULE hModule,
_In_ LPCSTR lpProcName
);
HMODULE
WINAPI
LoadLibraryA(
_In_ LPCSTR lpLibFileName
);
*/
typedef LPVOID(WINAPI* MYGETPROCADDRESS)(HMODULE hMoudle, LPCSTR lpProcName);
typedef HMODULE(WINAPI*MYLOADLIBRARYA)(LPCSTR lpLibFileName);
MYGETPROCADDRESS MyGetProcAddress = (MYGETPROCADDRESS)MyGetFnAddress(hMoudle, "GetProcAddress");
MYLOADLIBRARYA MyLoadLibraryA = (MYLOADLIBRARYA)MyGetFnAddress(hMoudle, "LoadLibraryA");
//这就找到了这个2个api的地址,如果对方进行了自定义hook,这个时候大可以自定去读取OpCode进行判断
// c++ 写的比较麻烦,稍后用汇编写一个,比较简洁易懂
return 0;
}
The post 反Hook 之自己实现GetProcAddress和LoadLibraryA(c++ version) appeared first on cole.
http://ift.tt/eA8V8J reverse engineering, reverse December 04, 2017 at 07:33PM
评论
发表评论