钩子由系统调用
Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。
你的钩子只是被push到了栈顶 为了不妨碍后面钩子的进行 应该把消息传给下一个钩子(return CallNextHookEx),如果钩子return 非0值 则表示截断这个消息

GetMessage 可以实现消息循环(类似于利用线程),可以在接收到特定消息前让程序运行在当前行(必定接收WM_QUIT消息,返回0)

改跳转表、改导入表、改函数开头

相对地址 = 目标地址 – 下一条指令地址 = 目标地址 – 当前地址 – JMP指令长度(jmp指令长度 = jmp机器码 + 相对地址)

GetModuleHandle(NULL)返回当前exe的句柄
可以强制转换成PIMAGE_DOS_HEADER 得到NT头(二进制文件中”PE”的位置) 结构:PIMAGE_NT_HEADERS
NT头中有各个导入模块的偏移地址(导入表)//第0个导入模块 == 当前exe句柄 + NT头->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress 结构:PIMAGE_IMPORT_DESCRIPTOR(是个指针)(20字节) //NAME字段为模块名; OriginalFirstThunk字段有函数名 结构:PIMAGE_THUNK_DATA; FirstThunk字段为指向函数开头的指针///通过模块名+函数名寻找函数, 返回函数开头

#pragma code_seg([“section-name”[,”section-class”]])
它能够设置程序中函数代码存放的代码段

#pragma pack(n)
将结构对齐到n字节
#pragma pop()
结束对齐

/1.查找窗口,获取窗口句柄/

/*2.根据窗口句柄,获得进程的PID*/

/*3.根据进程的PID,获得进程的句柄*/

/*4.根据进程的句柄,给进程申请额外内存空间*/

/*5.调用WriteProcessMemory,给进程写入DLL的路径*/

/*6.创建远程线程,执行我们的代码*/

/*7.调用退出代码,释放远程线程的dll*/