首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

大伙儿来看看这个代码HOOK了什么

2012-08-14 
大家来看看这个代码HOOK了什么代码如下所示,我想知道,它HOOK了什么函数???[codeC/C++][/code]#include w

大家来看看这个代码HOOK了什么
代码如下所示,我想知道,它HOOK了什么函数???
[code=C/C++][/code]#include "windows.h"
#include "stdio.h"

#define PARAMNO 15
#define PSETFILEPOINTER DWORD (WINAPI *)(HANDLE, LONG, PLONG, DWORD)
#define PWRITEFILE BOOL (WINAPI *)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED) 
#define PWAITFORSINGLEOBJECT DWORD (WINAPI *)(HANDLE, DWORD)
#define PSETEVENT BOOL (WINAPI *)(HANDLE)
#define PCLOSEHANDLE BOOL (WINAPI *)(HANDLE)
#define PVIRTUALPROTECT BOOL (WINAPI *)(LPVOID, DWORD, DWORD, PDWORD)
#define PENABLEWINDOW BOOL (WINAPI *)(HWND, BOOL)

//确保对于STRUCT的编译是按字节编译的。
#pragma pack(1)

typedef struct {
byte PushCode1; //0xff
ULONG OrgAddr;
byte PushCode2; //0xff
ULONG NameAddr; 
byte JmpCode; //0xe9
ULONG JmpParam;
}*PHOOKAPIPROXY, HOOKAPIPROXY;

typedef struct{
ULONG HookModule;
char LogPath[200];
}* PAPIHOOKSHARE, APIHOOKSHARE;

int nFunCount; //需要分配的HOOKAPIPROXY的个数。
PHOOKAPIPROXY pHookApiProxy;//需要分配的内存地址
BOOLEAN Hooked;//是否已HOOK
ULONG WriteFileAddr, SetFilePointerAddr, SetEventAddr, WaitForSingleObjectAddr, VirtualProtectAddr;
HANDLE hLog, hEvent; //记录日志用的文件。  
PAPIHOOKSHARE pApiHookShare; //取得的共享信息。
HANDLE hFileMapping;

void ProxyFun();//API HOOK代理函数。
void SetIATHook(HMODULE hModule); //设置IAT HOOK
void SetIATUnhook(HMODULE hModule); //设置IAT Unhook.

BOOL CALLBACK DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID Param)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
MessageBeep(0);
//一些需要用到的函数原来的地址。
WriteFileAddr = (ULONG)WriteFile;
SetFilePointerAddr = (ULONG)SetFilePointer;
SetEventAddr = (ULONG)SetEvent;
WaitForSingleObjectAddr = (ULONG)WaitForSingleObject;
VirtualProtectAddr = (ULONG)VirtualProtect;

//建立一个映射对象。取出hModule, 文件路径名称等信息。
hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READONLY, 0, sizeof(APIHOOKSHARE), "HookApiShare");
pApiHookShare = (PAPIHOOKSHARE)MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);

//生成日志文件和事件对象。
hLog = CreateFile(pApiHookShare->LogPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
hEvent = CreateEvent(NULL, FALSE, TRUE, "ApiHookDll");

//设置HOOK
SetIATHook((HMODULE)pApiHookShare->HookModule);
return TRUE;

case DLL_PROCESS_DETACH:
//关闭LOG文件和事件对象
SetIATUnhook((HMODULE)pApiHookShare->HookModule);
CloseHandle(hLog);
CloseHandle(hEvent);
UnmapViewOfFile(pApiHookShare);
CloseHandle(hFileMapping);
return TRUE;

case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
return TRUE;
}

return TRUE;
}

//函数HOOK API。
_declspec(naked) void ProxyFun()
{
DWORD ByteWrite;
PCHAR pFunctionName;
char Str[200];
ULONG Param[PARAMNO];
char StrParam[200], StrTemp[20];
ULONG nParam, i;
ULONG Result;

_asm{
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
push esi
push edi
push ebx

  //先取出函数名称地址。
mov eax, [ebp+4]
mov pFunctionName, eax

//下面拷贝参数PARAMNO * 4
mov ecx, PARAMNO
mov esi, ebp
add esi, 12 + PARAMNO * 4//4:原函数EIP + 4:原来函数地址 + 4:FUNCTIONNAME PARAMNO参数

nextmove:
mov eax, [esi]
push eax
sub esi, 4
dec ecx
jnz nextmove  

mov nParam, esp
//调用原来的函数。
call dword ptr [ebp + 8]
mov Result, eax //保存可能的返回值

mov ecx, esp
//先复原ESP
mov esp, nParam  
add esp, PARAMNO * 4
//判断到底有几个参数。
sub ecx, nParam
shr ecx, 2
mov nParam, ecx
jcxz noparam //若没有参数

//下面拷贝参数
lea esi, Param
mov edi, ebp
add edi, 16



nextparam:
mov eax, [edi]
mov [esi], eax
add esi, 4
add edi, 4
loop nextparam
noparam: //若没有参数,便直接出来。
}

//往文件中写数据。
StrParam[0] = '\0';
for(i = 0; i < nParam; i ++)
{
sprintf_s(StrTemp, " 0x%08x ", Param[i]);
strcat_s(StrParam, StrTemp);
}

((PWAITFORSINGLEOBJECT)WaitForSingleObjectAddr)(hEvent, INFINITE);
((PSETFILEPOINTER)SetFilePointerAddr)(hLog, 0, NULL, FILE_END);
if ((ULONG)pFunctionName >= 0x80000000)
sprintf_s(Str, "[Ord: 0x%x] 参数个数: %d [%s]返回值: 0x%x \x0d\x0a", (ULONG)pFunctionName - 0x80000000, nParam, StrParam, Result);
else
sprintf_s(Str, "[%s] 参数个数: %d [%s]返回值: 0x%x \x0d\x0a", pFunctionName, nParam, StrParam, Result);
((PWRITEFILE)WriteFileAddr)(hLog, Str, strlen(Str), &ByteWrite, NULL);
((PSETEVENT)SetEventAddr)(hEvent);


//准备返回
_asm{

mov eax, Result
mov ecx, nParam
shl ecx, 2

pop ebx
pop edi
pop esi
mov esp, ebp
pop ebp

add esp, 8 //4:原来函数地址 + 4:FUNCTIONNAME PARAMNO参数
pop edx
add esp, ecx
push edx
ret
}
}

//设置IAT HOOK
void SetIATHook(HMODULE hModule)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNtHeaders;
PIMAGE_OPTIONAL_HEADER pOptionHeader;
PIMAGE_DATA_DIRECTORY pDataDirectory;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc, pImportDesc0;
PULONG pImportAddrTable;
PULONG pFirstThunk, pOrgFirstThunk;
PIMAGE_IMPORT_BY_NAME pImportByName;
DWORD OldProtect;


pDosHeader = (PIMAGE_DOS_HEADER)hModule;
pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)pDosHeader + pDosHeader->e_lfanew);
pOptionHeader = &pNtHeaders->OptionalHeader;
pDataDirectory = pOptionHeader->DataDirectory;
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)hModule + pOptionHeader->DataDirectory[1].VirtualAddress);
pImportAddrTable = (PULONG)((ULONG)hModule + pOptionHeader->DataDirectory[12].VirtualAddress);

//修改内存保护属性
VirtualProtect(pImportAddrTable, pOptionHeader->DataDirectory[12].Size, PAGE_READWRITE, &OldProtect);

//先检测一下IMPORT中引用了多少函数。
pImportDesc0 = pImportDesc;
nFunCount = 0;
while(pImportDesc0->FirstThunk != 0)
{
pFirstThunk = (PULONG)(pImportDesc0->FirstThunk + (ULONG)hModule);
while(*(pFirstThunk++) ) nFunCount ++;
pImportDesc0 ++;
}

//为HOOK API PROXY分配内存
pHookApiProxy = (PHOOKAPIPROXY)VirtualAlloc(NULL, sizeof(HOOKAPIPROXY) * nFunCount, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (pHookApiProxy == NULL) return;

//设置HOOK API PROXY
pImportDesc0 = pImportDesc;
while(pImportDesc0->FirstThunk != 0)
{
pFirstThunk = (PULONG)(pImportDesc0->FirstThunk + (ULONG)hModule);
pOrgFirstThunk = (PULONG)(pImportDesc0->OriginalFirstThunk + (ULONG)hModule);

while(*pFirstThunk)
{
pHookApiProxy->PushCode1 = 0x68;
pHookApiProxy->OrgAddr = *pFirstThunk;
pHookApiProxy->PushCode2 = 0x68;

if ((ULONG)pOrgFirstThunk >= 0x80000000)
pHookApiProxy->NameAddr = *pOrgFirstThunk;
else
{
pImportByName = (PIMAGE_IMPORT_BY_NAME)((ULONG)*pOrgFirstThunk + (ULONG)hModule);
pHookApiProxy->NameAddr = (ULONG)&pImportByName->Name[0];
}
pHookApiProxy->JmpCode = 0xE9;
pHookApiProxy->JmpParam = (ULONG)ProxyFun - (ULONG)&pHookApiProxy->JmpCode - 5;

*pFirstThunk++ = (ULONG)pHookApiProxy++;
pOrgFirstThunk ++;
}
pImportDesc0 ++;
}

//再次修改内存保护属性。
((PVIRTUALPROTECT)VirtualProtectAddr)(pImportAddrTable, pOptionHeader->DataDirectory[12].Size, OldProtect, &OldProtect);

}

//设置IAT Unhook.
void SetIATUnhook(HMODULE hModule)


{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNtHeaders;
PIMAGE_OPTIONAL_HEADER pOptionHeader;
PIMAGE_DATA_DIRECTORY pDataDirectory;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PULONG pImportAddrTable;
PULONG pFirstThunk;
DWORD OldProtect;

pDosHeader = (PIMAGE_DOS_HEADER)hModule;
pNtHeaders = (PIMAGE_NT_HEADERS)((ULONG)pDosHeader + pDosHeader->e_lfanew);
pOptionHeader = &pNtHeaders->OptionalHeader;
pDataDirectory = pOptionHeader->DataDirectory;
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((ULONG)hModule + pOptionHeader->DataDirectory[1].VirtualAddress);
pImportAddrTable = (PULONG)((ULONG)hModule + pOptionHeader->DataDirectory[12].VirtualAddress);

//修改内存保护属性。
((PVIRTUALPROTECT)VirtualProtectAddr)(pImportAddrTable, pOptionHeader->DataDirectory[12].Size, PAGE_READWRITE, &OldProtect);

//恢复原来的设置。
while(pImportDesc->FirstThunk != 0)
{
pFirstThunk = (PULONG)(pImportDesc->FirstThunk + (ULONG)hModule);

while(*pFirstThunk)
{
pHookApiProxy = (PHOOKAPIPROXY)*pFirstThunk;
*pFirstThunk++ = pHookApiProxy->OrgAddr;
}
pImportDesc ++;
}
//再次修改内存保护属性。
((PVIRTUALPROTECT)VirtualProtectAddr)(pImportAddrTable, pOptionHeader->DataDirectory[12].Size, OldProtect, &OldProtect);

//释放内存
VirtualFree(pHookApiProxy, sizeof(HOOKAPIPROXY) * nFunCount, MEM_RELEASE);
}



[解决办法]
同志IAT HOOK,又有一个人掉入万丈深渊!建议你去 看雪 问,那里才是“黑”高手的集聚地!

热点排行