输入表与HOOK
来源:互联网 发布:大华端口号 编辑:程序博客网 时间:2024/04/29 14:40
哎,刚开始确实难得看懂,不过耐心看下去就好了
首先很有必要知道几个结构
IMAGE_DOS_HEADER *pidh; //DOS头
MAGE_NT_HEADERS *pinh; //NT头
IMAGE_DATA_DIRECTORY *pSymbolTable; //数据目录
MAGE_IMPORT_DESCRIPTOR *piid; //输入表
IMAGE_THUNK_DATA //函数结构
IMAGE_DOS_HEADER 通过程序的模块句柄换转获得 (IMAGE_DOS_HEADER *)模块句柄;
MAGE_NT_HEADERS 通过 基址 + DOS头结构中的 e_ifanew 标志 给出 . 机制就是将模块句柄强制转换 DWORD类型
IMAGE_DATA_DIRECTORY 通过 NT头的可选头 DataDirectory[1] 成员就是输入表数据目录
MAGE_IMPORT_DESCRIPTOR 通过 基址 + 输入表.VirtualAddress 给出输入表模块的第一个DLL
IMAGE_THUNK_DATA 基址 + 输入表.OriginalFirstThunk 等于 函数名 的 RVA
IMAGE_THUNK_DATA 基址 + 输入表.FirstThunk等于 IAT ,也就是函数呼叫地址
下面给出例子源码,c++程序
#include <windows.h>#include <iostream>typedef int (WINAPI *MsgBoxType)(HWND,LPCWSTR,LPCWSTR,UINT); MsgBoxType oldMsg; /*API原入口地址*/int WINAPI MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3);DWORD APIAddress; /*存储API入口地址的地方的地址*/int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd ){/* 1 */HANDLE hCurrent = GetModuleHandle(NULL);/* 2 */IMAGE_DOS_HEADER *pidh; //DOS头/* 3 */IMAGE_NT_HEADERS *pinh; //NT头/* 4 */IMAGE_DATA_DIRECTORY *pSymbolTable; //数据目录/* 5 */IMAGE_IMPORT_DESCRIPTOR *piid; //输入表/* 6 */pidh = (IMAGE_DOS_HEADER *)hCurrent; /* 7 */pinh = (IMAGE_NT_HEADERS *)((DWORD)hCurrent + pidh->e_lfanew); /* 8 */pSymbolTable = &pinh->OptionalHeader.DataDirectory[1]; //输入表/* 9 */piid =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hCurrent + pSymbolTable->VirtualAddress); //输入表的相对虚拟地址RVA,//0x00cb0000+/*10 */do {/*11 */ IMAGE_THUNK_DATA *pitd,*pitd2;/*12 */ pitd = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->OriginalFirstThunk); //pitd 等于函数名的RVA/*13 */ pitd2 = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->FirstThunk); //pitd2 等于函数的RVA/*14 */ do {/*15 */ IMAGE_IMPORT_BY_NAME *piibn;/*16 */ piibn = (IMAGE_IMPORT_BY_NAME *)((DWORD)hCurrent + *((DWORD *)pitd));/*17 */ PROC *ppfn = (PROC *)(pitd2->u1.Function);/*18 */ if (!strcmp("MessageBoxW",(char *)piibn->Name)) {/*19 */ oldMsg = (MsgBoxType)(ppfn);/*20 */ DWORD addr = (DWORD)MyMessage;/*21 */ DWORD written = 0;/* 改变内存读写状态 *//*22 */ DWORD oldAccess;/*23 */ VirtualProtect(&pitd2->u1.Function,sizeof(DWORD),PAGE_WRITECOPY,&oldAccess);/*24 */ APIAddress = (DWORD)&pitd2->u1.Function;/* 向内存映像写入数据 *//*25 */ WriteProcessMemory(GetCurrentProcess(),&pitd2->u1.Function, &addr,sizeof(DWORD), &written);/*26 */ }/*27 */ pitd++;pitd2++;/*28 */ } while (pitd->u1.Function);/*29 */ piid++;/*30 */} while (piid->FirstThunk + piid->Characteristics + piid->ForwarderChain + piid->Name + piid->TimeDateStamp);MessageBoxW(NULL,L"呵呵",NULL,NULL);return 0;}int WINAPI MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3) {/* 这是用来替换的函数 */return oldMsg(hWnd,L"被修改啦",M2,MB_OK);}
大致过程就是获得指定函数的详细信息, 比较函数名,如果等于你想要HOOK的,就改写内存地址的属性,然后修改 函数的IAT为你自己的,
接下来就是 跨进程 API HOOK ,先给出源码
DLL源码
#include <windows.h>#include <iostream>/*DLL 入口函数*/HHOOK hook;HINSTANCE hIns;HWND wind;DWORD Treeid;LRESULT CALLBACK GetMsgProc(int,WPARAM, LPARAM);//void UnHookAPIHook();typedef int (WINAPI *MsgBoxType)(HWND,LPCWSTR,LPCWSTR,UINT); MsgBoxType oldMsg; /*API原入口地址*/int WINAPI MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3);DWORD APIAddress; /*存储API入口地址的地方的地址*/int HookApi() ;BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason,LPVOID lpvReserved){switch (reason){case DLL_PROCESS_ATTACH://MessageBoxW(NULL,L"加载DLL",NULL,NULL);hIns = hInst;break;case DLL_PROCESS_DETACH://MessageBoxW(NULL,L"装卸DLL",NULL,NULL);break;}return true;}extern "C" __declspec(dllexport) BOOL SetAPIHook(HWND target) {wind = FindWindowW(NULL,L"Dialog");Treeid = GetWindowThreadProcessId(wind,NULL);hook = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hIns,Treeid); //PostThreadMessage(pg_data->idTarget,WM_ENABLEAPIHOOK,0,0);return TRUE;}LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam, LPARAM lParam) {if (nCode == HC_ACTION) {MSG *msg = (MSG *)lParam;//MessageBoxW(wind,L"失去焦点",NULL,NULL);if (msg->message == WM_KEYDOWN){HookApi();MessageBoxW(wind,L"失去焦点",NULL,NULL);}}return CallNextHookEx(hook,nCode,wParam,lParam);}int HookApi() {/* 1 */HANDLE hCurrent = GetModuleHandle(NULL);/* 2 */IMAGE_DOS_HEADER *pidh; //DOS头/* 3 */IMAGE_NT_HEADERS *pinh; //NT头/* 4 */IMAGE_DATA_DIRECTORY *pSymbolTable; //数据目录/* 5 */IMAGE_IMPORT_DESCRIPTOR *piid; //输入表/* 6 */pidh = (IMAGE_DOS_HEADER *)hCurrent; /* 7 */pinh = (IMAGE_NT_HEADERS *)((DWORD)hCurrent + pidh->e_lfanew); /* 8 */pSymbolTable = &pinh->OptionalHeader.DataDirectory[1]; //输入表/* 9 */piid =(IMAGE_IMPORT_DESCRIPTOR *)((DWORD)hCurrent + pSymbolTable->VirtualAddress); //输入表的相对虚拟地址RVA,//0x00cb0000+/*10 */do {/*11 */ IMAGE_THUNK_DATA *pitd,*pitd2;/*12 */ pitd = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->OriginalFirstThunk); //pitd 等于函数名的RVA/*13 */ pitd2 = (IMAGE_THUNK_DATA *)((DWORD)hCurrent + piid->FirstThunk); //pitd2 等于函数的RVA/*14 */ do {/*15 */ IMAGE_IMPORT_BY_NAME *piibn;/*16 */ piibn = (IMAGE_IMPORT_BY_NAME *)((DWORD)hCurrent + *((DWORD *)pitd));/*17 */ PROC *ppfn = (PROC *)(pitd2->u1.Function);/*18 */ if (!strcmp("MessageBoxW",(char *)piibn->Name)) {/*19 */ oldMsg = (MsgBoxType)(ppfn);/*20 */ DWORD addr = (DWORD)MyMessage;/*21 */ DWORD written = 0;/* 改变内存读写状态 *//*22 */ DWORD oldAccess;/*23 */ VirtualProtect(&pitd2->u1.Function,sizeof(DWORD),PAGE_WRITECOPY,&oldAccess);/*24 */ APIAddress = (DWORD)&pitd2->u1.Function;/* 向内存映像写入数据 *//*25 */ WriteProcessMemory(GetCurrentProcess(),&pitd2->u1.Function, &addr,sizeof(DWORD), &written);return 0;/*26 */ }/*27 */ pitd++;pitd2++;/*28 */ } while (pitd->u1.Function);/*29 */ piid++;/*30 */} while (piid->FirstThunk + piid->Characteristics + piid->ForwarderChain + piid->Name + piid->TimeDateStamp);}int WINAPI MyMessage(HWND hWnd ,LPCWSTR M1,LPCWSTR M2, UINT M3) {/* 这是用来替换的函数 */MessageBoxW(hWnd,L"呵呵",NULL,NULL);return oldMsg(hWnd,L"被修改啦",M2,MB_OK);}extern "C" __declspec(dllexport) void UnHookAPIHook(){UnhookWindowsHookEx(hook);}
程序源码
#include <windows.h>#include <iostream>#include "resource.h"typedef BOOL (*PSetAPIHook)(HWND);typedef void (*PUnHookAPIHook)();BOOL CALLBACK DialogProc(HWND hwndDIG , UINT UMsg , WPARAM wParam, LPARAM lParam);HMODULE hDll = NULL;PSetAPIHook SetAPIHook;PUnHookAPIHook UnHookAPIHook;int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPSTR lpCmdLine, __in int nShowCmd ){DialogBoxW(hInstance,(wchar_t*)IDD_DIALOG1 ,NULL,DialogProc);return 0;}BOOL CALLBACK DialogProc(HWND hwndDIG , UINT UMsg , WPARAM wParam, LPARAM lParam){switch (UMsg){case WM_INITDIALOG :return TRUE ;case WM_COMMAND :switch (LOWORD (wParam)){case IDC_BUTTON1 :hDll = LoadLibraryW(L"例子.dll");SetAPIHook = (PSetAPIHook)GetProcAddress(hDll,"SetAPIHook");SetAPIHook(NULL);//MessageBoxW(hwndDIG,L"这是按钮1",NULL,NULL);return TRUE ;case IDC_BUTTON2 ://hDll = LoadLibraryW(L"例子.dll");UnHookAPIHook = (PUnHookAPIHook)GetProcAddress(hDll,"UnHookAPIHook");UnHookAPIHook();//MessageBoxW(hwndDIG,L"这是按钮2",NULL,NULL);//IDOKreturn TRUE ;case IDOK :EndDialog (hwndDIG, 0) ;return TRUE ;case IDCANCEL :EndDialog (hwndDIG, 0) ;return TRUE ;}break ;}return FALSE ;}
稍后给出详解...
- 输入表与HOOK
- Hook与Socket Hook
- Hook与Socket Hook
- 关于HOOK截获中文输入
- 关于HOOK截获中文输入
- 关于HOOK截获中文输入
- Android SO 加载分析与导入表Hook、导出表Hook
- API hook 原理与Windows hook 应用
- API hook 原理与Windows hook 应用
- API hook 原理与Windows hook 应用
- HOOK与回调
- hook 与outlook express
- Hook与AOP
- Hook与AOP
- Dll与Hook
- 关于HOOK截入中文输入
- 关于HOOK截入中文输入
- HOOK截获中文输入的方法
- service组件说明
- macos10.8安装cplex
- 简单,细致的菜单程序讲解
- Mac os 截屏使用
- SQL 代码片段
- 输入表与HOOK
- 栈的实现
- IOS中Json解析的四种方法
- Linux中TCP连接过程状态简介
- 一张图让你记住uml的常用关系的简单图例
- Openssl的安装
- input失去焦点和获得焦点jquery焦点事件
- 在C++代码的陪伴下成长
- Struts2框架安全缺陷