首页
社区
课程
招聘
[原创]简单易用,并且最全,也适合初学者的API HOOK
发表于: 2016-1-2 02:45 13953

[原创]简单易用,并且最全,也适合初学者的API HOOK

2016-1-2 02:45
13953

// test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include "..\BPHookFunction\BPHookFunction.h"
#include "..\..\testbase\Memory\Memory.h"
typedef int(WINAPI *PMESSAGEBOXA)(
    __in_opt HWND hWnd,
    __in_opt LPCSTR lpText,
    __in_opt LPCSTR lpCaption,
    __in UINT uType);
typedef int(WINAPI *PMESSAGEBOXW)(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType);
DWORD *AddressOfFunctionOffst=0;
#ifdef UNICODE
#define PMESSAGEBOX  PMESSAGEBOXW
PMESSAGEBOXW MyMessageBox = 0;//(PMESSAGEBOXW)GetFunctionAddressByDllExprot(::GetModuleHandle(_T("User32.dll")), "MessageBoxW",&AddressOfFunctionOffst);
#else
#define PMESSAGEBOX  PMESSAGEBOXA
PMESSAGEBOXA MyMessageBox = 0;//(PMESSAGEBOXA)GetFunctionAddressByDllExprot(::GetModuleHandle(_T("User32.dll")), "MessageBoxA");
#endif // !UNICODE
PMESSAGEBOX HookAddress= 0;
//DWORD64 SetThreadStartAddr1(DWORD dwThreadId,DWORD64 dwStaAddr) ;
//DWORD64 GetThreadStartAddr1(DWORD dwThreadId) ;
typedef LONG NTSTATUS; 
/*
 
typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONTHREAD)(  
    HANDLE ThreadHandle,   
    ULONG64 ThreadInformationClass,   
    PVOID64 ThreadInformation,   
    ULONG64 ThreadInformationLength,   
    PULONG64 ReturnLength);  
typedef enum _THREADINFOCLASS {  
    ThreadBasicInformation,  
    ThreadTimes,  
    ThreadPriority,  
    ThreadBasePriority,  
    ThreadAffinityMask,  
    ThreadImpersonationToken,  
    ThreadDescriptorTableEntry,  
    ThreadEnableAlignmentFaultFixup,  
    ThreadEventPair_Reusable,  
    ThreadQuerySetWin32StartAddress,  
    ThreadZeroTlsCell,  
    ThreadPerformanceCount,  
    ThreadAmILastThread,  
    ThreadIdealProcessor,  
    ThreadPriorityBoost,  
    ThreadSetTlsArrayAddress,   // Obsolete  
    ThreadIsIoPending,  
    ThreadHideFromDebugger,  
    ThreadBreakOnTermination,  
    ThreadSwitchLegacyState,  
    ThreadIsTerminated,  
    ThreadLastSystemCall,  
    ThreadIoPriority,  
    ThreadCycleTime,  
    ThreadPagePriority,  
    ThreadActualBasePriority,  
    ThreadTebInformation,  
    ThreadCSwitchMon,          // Obsolete  
    ThreadCSwitchPmu,  
    ThreadWow64Context,  
    ThreadGroupInformation,  
    ThreadUmsInformation,      // UMS  
    ThreadCounterProfiling,  
    ThreadIdealProcessorEx,  
    MaxThreadInfoClass  
} THREADINFOCLASS;
typedef NTSTATUS (*NtSetInformationThreadPtr)(HANDLE threadHandle,
       THREADINFOCLASS threadInformationClass,
       PVOID64 threadInformation,
       ULONG threadInformationLength);
void Test2();
HANDLE hEvent = ::CreateEvent(0,0,0,0);
HANDLE hEvent1 = ::CreateEvent(0,0,0,0);*/
int
WINAPI
CallBackMessageBoxW(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType);
LONG WINAPI MessageBoxTopUnhandledExceptionFilter(
         struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
  //修改EIP 指向HOOK的过滤函数
  #if _WIN64 
  
  ExceptionInfo->ContextRecord->Rip=(DWORD64)CallBackMessageBoxW;
#else
  ExceptionInfo->ContextRecord->Eip=(DWORD)CallBackMessageBoxW;
#endif
         return EXCEPTION_CONTINUE_EXECUTION;
}
DWORD CALLBACK Thread(PVOID)
{
  return 0;
}
DWORD CALLBACK Thread3(PVOID)
{
  return 0;
}
DWORD CALLBACK ThreadCreateCallBack(DWORD Tid,BOOL bCreate,LPTHREAD_START_ROUTINE lpStartAddress,PVOID ThreadData)
{
  if(bCreate)//判断是否是线程创建
  return lpStartAddress(ThreadData);//如果是线程创建,那么我们就需要调用线程入口函数!
  return 0;//不是线程创建,我们就返回0
}//*/

int
WINAPI
CallBackMessageBoxW(
    __in_opt HWND hWnd,
    __in_opt LPCWSTR lpText,
    __in_opt LPCWSTR lpCaption,
    __in UINT uType)
{
  TCHAR *Buffer = 0;
  static int i =0;
  int Return = 0;
  SetHardWareBP(::GetCurrentThreadId(),(DWORD64)MyMessageBox,MessageBoxTopUnhandledExceptionFilter,1,0,1,0);
  //第一次调用MessageBoxW 大家可以试着使用钩子恢复工具恢复!\nTest IAT HOOK 原函数"
  if(i ==0)
  {
  Buffer = (TCHAR *)AllocMemory((wcslen(lpText)+wcslen(_T("第一次调用MessageBoxW 大家可以试着使用钩子恢复工具恢复!\n%s\r\n%sMessageBoxW函数已经被IAT HOOK EAX HOOK 和 inLine Hook 硬件寄存器挂钩\n")))*sizeof(WCHAR)+10);
  
  ::wsprintf(Buffer,L"第一次调用MessageBoxW 大家可以试着使用钩子恢复工具恢复!\n%s\r\n%s",lpText,L"MessageBoxW函数已经被IAT HOOK EAT HOOK 和 inLine Hook 硬件寄存器挂钩\n");
  }else
  {
  Buffer = (TCHAR *)AllocMemory((wcslen(lpText)+wcslen(_T("第二次调用MessageBoxW 纳尼?为什么还会被挂钩?\n%s\r\n%sMessageBoxW函数已经被IAT HOOK EAX HOOK 和 inLine Hook 硬件寄存器挂钩\n")))*sizeof(WCHAR)+10);
  
  ::wsprintf(Buffer,L"调用MessageBoxW 纳尼?为什么还会被挂钩?\n%s\r\n%s",lpText,L"MessageBoxW函数已经被IAT HOOK EAT HOOK 和 inLine Hook 硬件寄存器挂钩\n");
  Return= HookAddress(hWnd,Buffer,lpCaption,uType);
  FreeMemory(Buffer);
  if(i>1)
  {
  Return=HookAddress(hWnd,L"因为这是混合挂钩,同时修改了导入表,导出表,函数头5字节,修改了调试寄存器,截获了线程的创建,并且在线程开始的时候自动挂钩对应线程的入口点!",lpCaption,0);
  }
  i++;
  SetHardWareBP(::GetCurrentThreadId(),(DWORD64)MyMessageBox,MessageBoxTopUnhandledExceptionFilter,1,0,1,1);
  return Return;
  }
  i++;
  
  Return= HookAddress(hWnd,Buffer,lpCaption,uType);
  SetHardWareBP(::GetCurrentThreadId(),(DWORD64)MyMessageBox,MessageBoxTopUnhandledExceptionFilter,1,0,1,1);
  FreeMemory(Buffer);
  return Return;
}
int _tmain(int argc, _TCHAR* argv[])
{
  
  typedef int(WINAPI *PTest)();//一个测DLL中的函数
  ::InitHook();//初始化寄存器HOOK
  SetThreadCreateCallBack(ThreadCreateCallBack);//设置线程创建回调函数
  ::CreateThread(0,0,Thread,0,0,0);//创建线程
  MessageBoxW(0,L"Test IAT HOOK 原函数",L"IAT HOOK",0);
  char buffer[100] = {0};
  //设置寄存器HOOK SetHardWareBP 用法 ThreadId =需要HOOK的线程的ID,dwAddr=需要HOOK的函数的地址,lpTopLevelExceptionFilter=
  //调试陷阱回调函数指针,dwDrIndex = 需要设置的断点寄存器的序号 范围为0到3,nType = 0 保留,必须设置为0,nLen = 1保留,必须设置为1,bSet = TRUE 或者FALSE TRUE表示为需要HOOK FALSE表示需要卸载HOOK
    SetHardWareBP(::GetCurrentThreadId(),(DWORD64)MessageBoxW,MessageBoxTopUnhandledExceptionFilter,1,0,1,1);
/*导入表HOOK
    HookFunctionByDllImprot 用法
    DllHandle=需要HOOK导入表的模块,
    DllName = HOOK函数所在模块的文件名,不是文件全名,
    FunctionName = 需要HOOK的函数名,不支持序号导出方式的文件名
    AddressOfFunction = HOOK的过滤函数
    如果成功,返回原函数地址,不成功就返回0
    如果需要卸载HOOK ,只需将AddressOfFunction设置为原函数地址,然后调用HookFunctionByDllImprot就行
    */
MyMessageBox=(PMESSAGEBOX)HookFunctionByDllImprot(GetModuleHandle(0),"User32.dll","MessageBoxW",&CallBackMessageBoxW);
/*导出表HOOK
HookFunctionByDllExprot 用法
DllHandle=需要HOOK导出表的模块,
FunctionName = 需要HOOK的函数名,不支持序号导出方式的文件名
AddressOfFunction = HOOK的过滤函数
如果成功,返回原函数地址,不成功就返回0
如果需要卸载HOOK ,只需将AddressOfFunction设置为原函数地址,然后调用HookFunctionByDllExprot就行
*/
MyMessageBox=(PMESSAGEBOX)HookFunctionByDllExprot(GetModuleHandle(L"User32.dll"),"MessageBoxW",CallBackMessageBoxW);
PMESSAGEBOX HookAddress2 = 0;
HookAddress=MyMessageBox;
/*InlineHook
SetInlineHook用法
ppSystemFunction 输入被HOOK函数的地址,返回一个新的指针,调用这个新的指针,就可以调用原函数,UnInlineHook,需要用到这个指针
pHookFunction HOOK的过滤函数
返回BOOL类型
*/
SetInlineHook((PVOID*)&HookAddress,CallBackMessageBoxW);
HookAddress2=CallBackMessageBoxW;

//SetInlineHook((PVOID*)&HookAddress2,CallBackMessageBoxW2);
HMODULE m=::LoadLibrary(L"Testmsg.dll");//调用测试DLL
PTest m_Test = (PTest)::GetProcAddress(m,"Test");
MessageBoxW(0,L"Test IAT HOOK 原函数",L"IAT HOOK",0);
m_Test();
MyMessageBox(0,L"Test IAT HOOK 原函数",L"IAT HOOK",0);

//卸载InlineHook 
//ppHookedFunction = SetInlineHook函数第一个参数返回的指针
UnInlineHook((PVOID*)&HookAddress);

//卸载导入表HOOK
HookFunctionByDllImprot(GetModuleHandle(0),"User32.dll","MessageBoxW",MyMessageBox);
//卸载导出表HOOK
HookFunctionByDllExprot(GetModuleHandle(L"User32.dll"),"MessageBoxW",MyMessageBox);
//卸载寄存器HOOK
SetHardWareBP(::GetCurrentThreadId(),(DWORD64)MessageBoxW,MessageBoxTopUnhandledExceptionFilter,1,0,1,0);
MessageBoxW(0,L"Test IAT HOOK 原函数",L"IAT HOOK",0);
//  GetFunctionAddressByDllExprot(::GetModuleHandle(_T("User32.dll")), "MessageBoxW");
debug;//DEBUG断点调试宏
//反初始化寄存器HOOK
UnInitHook();
//::ExitThread(5);
   //exit(0);
   return(0);
}

各位要是下载,编译中遇到没有定义的结构或者函数,请你自己在目录下的winternl.h文件中寻找,
另外,我自己实现了GetModuleFileName(我自己实现的函数的函数名,下面的括号中,如果没有特殊说明,都是指我自己实现的函数的函数名,函数名 :GetDllModuleFileName)
LoadLibrary(OtherLoadLibrary)
GetModuleHandle(GetDllModuleHandle)
FreeLibrary(OtherFreeLibrary)
OpenProcess(OpenProcessByProcessId)
OpenThread(OpenThreadByThreadId)
GetProcAddress(GetFunctionAddressByDllExprot,这个函数比原函数多了一个参数,这个参数返回了,被寻找函数的条目在导出表中的地址,借助修改这个地址就可以进行导出表HOOK)

在FileSystem工程中使用了网上收集的WINDOWS代码
实现了部分WINDOWS文件操作函数,文件名为以FileSystem为前缀加上WINDOWS原函数的函数名!可代替WINDOWS部分函数!大家HOOK这些WINDOWS函数时,可直接调用工程中对应已经实现的函数,不必调用原函数!
被程序在WINDOWS 7 X64中实验通过,编译环境为VS2010+WDK 7,要是在别的版本中出现如没有在NTDLL中找到某函数的错误的话,请尝试动态调用,否则请删除对对应函数的调用,或者在这里将错误反馈给我,嘿嘿!有些结构和函数在VS中没有声明的,如遇到没有声明的函数和结构,请到目录下的winternl.h文件红复制,要是还没有的,请到MSDN,或者是WDK中复制!


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 3
支持
分享
最新回复 (23)
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
没有注意上传文件的尺寸限制,本来是想上传整个工程的,可是因为尺寸问题,把编译好的文件给删除了,只剩下源代码了!
2016-1-2 02:59
0
雪    币: 251
活跃值: (302)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
感谢分享~
2016-1-2 10:46
0
雪    币: 60
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
+1 支持
2016-1-2 10:54
0
雪    币: 49
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
顶一下
2016-1-2 11:55
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2016-1-2 14:07
0
雪    币: 191
活跃值: (848)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2016-1-2 15:58
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
8
忘了说一个问题了,OtherLoadLibrary函数不会自己寻找相关路径,用的时候得设定绝对路径,相关的DLL也必须在相关路径之下,至于为什么不会寻找路径,那是因为我懒得做了,就没做!
2016-1-2 16:31
0
雪    币: 1696
活跃值: (2297)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢楼主,前来学习
2016-1-2 16:54
0
雪    币: 6
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢楼主分享。
2016-1-2 19:00
0
雪    币: 16
活跃值: (68)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
thx for share~
2016-1-2 21:53
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
12
自己顶一下
2016-1-2 23:14
0
雪    币: 221
活跃值: (2326)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
谢谢楼主分享!!但是编译会出现提示。无法编译,啥问题?
2016-1-3 09:00
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
14
出现什么问题呢?能发来看看么?这个程序用到了许多底层的API,也许会有一些版本的IDE会报错的
2016-1-3 10:10
0
雪    币: 225
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
感谢楼主
2016-1-3 12:47
0
雪    币: 3944
活跃值: (2380)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
谢谢分享!
2016-1-3 23:49
0
雪    币: 225
活跃值: (218)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
这个跟windows系统版本相关吧,不同的系统部分数据结构是不一样的
2016-1-4 08:48
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
18
是的,不过大部分数据是用那些在VC没有公开,但是已经在WDK,MSDN,中公开的数据结构和函数,只有一部分是使用未公开的函数和结构,以及WRK的结构,所以,大部分是兼容的,只有小部分不兼容,所以我才会说,要是遇到什么问题,直接在这里发问,就是因为里面的未公开数据
2016-1-4 09:43
0
雪    币: 18
活跃值: (118)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
谢谢分享
2016-1-5 15:56
0
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
谢谢分享~
2016-1-7 08:08
0
雪    币: 156
活跃值: (107)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
mark。。。感谢分享
2016-1-12 11:41
0
雪    币: 53
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
感谢楼主
2016-1-27 14:21
0
雪    币: 441
活跃值: (1055)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
24
感谢分享!!!
2018-1-17 17:12
0
雪    币: 2644
活跃值: (5088)
能力值: ( LV9,RANK:225 )
在线值:
发帖
回帖
粉丝
25
thanks. 
2018-1-17 21:42
0
游客
登录 | 注册 方可回帖
返回
//