虽然已经有Detour等一批优秀的钩子实现库了,本着学习的原则还是弄了一下,参考了海风月影大神的挂钩库,汇编就学了个皮毛,大侠飘过,提供给需要的人参考参考……

这个库的优点:原始函数地址会作为第一个参数传递给Detour函数,Detour函数的后面参数和原始函数一致,所以很方便实现调用前过滤和调用后过滤,反正就是使用很简单,也不需要自己记录原始函数地址了。为了方便移植到内核里使用,专门增加了fastcall的处理……先上一个例子,原始代码见附件了,看了例子就知道使用有多么简单了……
说一下那个Stub为啥不需要pushad之类的现场保护指令
  __asm
  {
    pop eax
    push OLD_CODE
    push eax///如果使用其它的寄存器可能会失败,一般是在eax里面返回数据,所以这个可以随便用
    _emit 0xE9这个E9指令就是JMP指令,JMP过去的那个函数自己破坏的现场编译器自己会很好的进行保存,那个函数给上层函数暴露的相当于一个标准的API函数,也就是说现场不会因为中途调用了这个函数而被破坏。而原始函数暴露给这个中继函数的也是一个标准的函数,和API无异,所以Detour直接调用不会有什么问题。当然这个库只能用于Release版本,道理很明显,在Debug里面,给出函数名最后编译得到的不是函数的开头地址,而是一个中继地址
                                多个nop
OLD_CODE:
      _emit 0xCC
      nop

代码:
#include"windows.h"
#include"hooklib.h"
#include"stdio.h"
#include"ADE32.h"
////测试时要禁用自动内联函数,不然这里的测试函数太段了,可能会被优化掉……
typedef int (WINAPI *FUN)(char*);

int WINAPI My_LoadLibraryA(FUN f,char* Path)
{
  printf("监控到要加载模块!%s\n",Path);
  return f(Path);
}
typedef int (WINAPI * Message)(ULONG,wchar_t*,wchar_t *,ULONG);

int WINAPI My_MessageBoxW(Message f,ULONG hwnd,wchar_t* Mes,wchar_t * Cap,ULONG Type)
{
  wchar_t mes[]=L"哈哈!函数被HOOK!";
  return f(hwnd,mes,L"HOOK",Type);
}

int __fastcall Test1(int a)
{
  printf("Test1原始函数输出:%d\n",a);
  return 1;
}


typedef  DWORD (__fastcall *Detour_Tun)(int a);

/*
小于两个参数的话也要这样做
*/
int __stdcall Function1(Detour_Tun Fun,int a,int Edx)
{
  printf("Detour Fastcall ^-^\n");
  return Fun(a);
}

void main()
{
  HOOK_INFO Info={0};
  MessageBoxA(NULL,"This is a Test String!","TEST",MB_OK);
  InstallInlineByName("Kernel32.dll","LoadLibraryA",My_LoadLibraryA,&Info);
  InstallInlineByName("user32.dll","MessageBoxW",My_MessageBoxW,NULL);
  MessageBoxW(NULL,L"This is a Test String!",L"TEST",MB_OK);
  LoadLibraryA("Test.dll");
  UnInstallInline(&Info);
  Test1(6);
  InstallInlineForFastCall((unsigned char *)Test1,(unsigned char *)Function1,NULL,1);
  Test1(6);
  system("pause");
}
上传的附件 HooklibEx.rar