编写dll处理hook逻辑,注入到目标进程,实现api hook。

Windows10 notepad,通过hook kernel32.dll.WriteFile,实现小写字母转大写保存到文件。

hook前kernel32.dll.WriteFile入口:

kernel32.dll.WriteFile在调用时入口是条jmp指令

跳转后

hook时通过GetProcAddress得到的是jmp处的地址,在jmp指令周边有一些int 3指令,这些空间可以用来做一些跳转操作。

#include "pch.h"
#include <tchar.h>
#define DLLNAME "kernel32.dll"
#define WRITEFILE "WriteFile"
BYTE g_pOrgBytes[6] = { 0 };
FARPROC g_writefile = GetProcAddress(GetModuleHandleA(DLLNAME), WRITEFILE); //此函数用来将api前5个字节改为jmp xxxx
BOOL hook_by_code(FARPROC pfnOrg, PROC pfnNew, PBYTE pOrgBytes) {
DWORD dwOldProtect, dwAddress;
BYTE pBuf[6] = { 0xE9,0,0,0,0, 0x90};
PBYTE pByte;
pByte = (PBYTE)pfnOrg;
if (pByte[0] == 0xE9)//若已被勾取,则返回False
return FALSE;
VirtualProtect((LPVOID)pfnOrg, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);//为了修改字节,先向内存添加“写”的属性
memcpy(pOrgBytes, pfnOrg, 6);//备份原有代码
dwAddress = (DWORD64)pfnNew - (DWORD64)pfnOrg - 5;//计算JMP地址 => XXXX = pfnNew - pfnOrg - 5
memcpy(&pBuf[1], &dwAddress, 4);//E9,剩下后面4个字节为跳转的地址
memcpy(pfnOrg, pBuf, 6);//复制指令,跳转到hook逻辑 memcpy(&pByte[6], pOrgBytes, 6);//后面的int 3指令进行修改,跳转到原api逻辑
pByte[8] -= 6;//修正跳转偏移 VirtualProtect((LPVOID)pfnOrg, 12, dwOldProtect, &dwOldProtect);//恢复内存属性
return TRUE;
} BOOL unhook_by_code(FARPROC pFunc, PBYTE pOrgBytes) { DWORD dwOldProtect;
PBYTE pByte;
pByte = (PBYTE)pFunc;
if (pByte[0] != 0xE9)//若已脱钩,则返回False
return FALSE;
VirtualProtect((LPVOID)pFunc, 6, PAGE_EXECUTE_READWRITE, &dwOldProtect);//向内存添加“写”的属性,为恢复原代码做准备
memcpy(pFunc, pOrgBytes, 6);//脱钩
VirtualProtect((LPVOID)pFunc, 6, dwOldProtect, &dwOldProtect);//恢复内存属性
return TRUE;
}
//WINBASEAPI
//BOOL
//WINAPI
//WriteFile(
// _In_ HANDLE hFile,
// _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
// _In_ DWORD nNumberOfBytesToWrite,
// _Out_opt_ LPDWORD lpNumberOfBytesWritten,
// _Inout_opt_ LPOVERLAPPED lpOverlapped
//);
typedef BOOL(WINAPI* PFWriteFile)(
_In_ HANDLE hFile,
_In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
BOOL WINAPI MyWriteFile(
_In_ HANDLE hFile,
_In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer,
_In_ DWORD nNumberOfBytesToWrite,
_Out_opt_ LPDWORD lpNumberOfBytesWritten,
_Inout_opt_ LPOVERLAPPED lpOverlapped) {
PBYTE ptr = (PBYTE)g_writefile;
//unhook_by_code(g_writefile, g_pOrgBytes);
BOOL ret = TRUE;
char* pc = (char*)lpBuffer;
while (*pc)
{
if (*pc >= 'a' && *pc <= 'z') {
*pc -= 0x20;
}
pc++;
}
ret = ((PFWriteFile)(ptr+6))(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);//原入口偏移+6处是修正的原jmp指令
//hook_by_code(g_writefile, (PROC)MyWriteFile, g_pOrgBytes);
return ret;
} BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hook_by_code(g_writefile,(PROC)MyWriteFile, g_pOrgBytes);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
unhook_by_code(g_writefile,g_pOrgBytes);
break;
}
return TRUE;
}

hook效果:

最新文章

  1. 兼容性测试-如何使用IE11做低版本IE的兼容性测试
  2. mybatis实战教程(mybatis in action)之七:实现mybatis分页
  3. [转载]sed 简明教程
  4. POJ 2049 Finding Nemo bfs 建图很难。。
  5. 一品楼论坛www.ep6.info一品楼论坛
  6. python开发环境安装
  7. java 常用的包 默认导入的包
  8. geom设置—条形图
  9. Dapper数据库相关操作
  10. SQL---约束---add constraint方法添加约束
  11. sublime text package control 被墙的解决办法
  12. 剑指offer(javascript实现)
  13. c/c++ 用克鲁斯卡尔(kruskal)算法构造最小生成树
  14. poj 3666 Making the Grade(离散化+dp)
  15. .net nancy
  16. Ubuntu 安装微信
  17. 使用Mockito时遇到的一些问题
  18. Maven学习二:使用Nexus搭建Maven私服及相关配置
  19. javascript debugger
  20. 和我一起学python

热门文章

  1. sql-libs(6) 双引号的报错注入
  2. Python_K-means算法
  3. 如何取消一个 Ajax 请求
  4. AMP ⚡
  5. push notifications
  6. c++ DWORD和uintptr_t
  7. 「NGK每日快讯」2021.2.11日NGK公链第100期官方快讯!
  8. NGK与AOFEX交易所达成战略合作,BGV即将上线A网!
  9. vue路由理解
  10. SpringCloud之服务配置