1、附加目标进程,

2、CREATE_PROCESS_DEBUG_EVENT附加事件中将目标api处设置为0xcc(INT 3断点)

3、EXCEPTION_DEBUG_EVENT异常事件中,首先判断是否为EXCEPTION_BREAKPOINT 断点异常,然后GetThreadContext、SetThreadContext 进行相关修改操作

#include <iostream>
#include "windows.h"
#include "stdio.h" LPVOID g_pfWriteFile = NULL;
CREATE_PROCESS_DEBUG_INFO g_cpdi;
BYTE g_chINT3 = 0xCC, g_chOrgByte = 0; BOOL OnCreateProcessDebugEvent(LPDEBUG_EVENT pde) {
g_pfWriteFile = GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile");//或取WriteFile的API地址(其实获取的是调试者的地址,但是没有影响)
printf("g_pfWriteFile(0x%08X)\n ", g_pfWriteFile);//g_pfWriteFile(1990541344) 76a54020
memcpy(&g_cpdi, &pde->u.CreateProcessInfo, sizeof(CREATE_PROCESS_DEBUG_INFO));
ReadProcessMemory(g_cpdi.hProcess, g_pfWriteFile,
&g_chOrgByte, sizeof(BYTE), NULL);//g_cpdi.hProcess是被调试进程的句柄,g_pfWriteFile是WriteFile API的地址 ,此函数读取api第一个字节,存储到g_chOrgByte中
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile,
&g_chINT3, sizeof(BYTE), NULL); //以上两个函数对调试进程进行读写, return TRUE;
} BOOL OnExceptionDebugEvent(LPDEBUG_EVENT pde) {
CONTEXT ctx;
PBYTE lpBuffer = NULL;
DWORD64 dwNumOfBytesToWrite, dwAddrOfBuffer;//x64指针8字节
DWORD i;
PEXCEPTION_RECORD per = &pde->u.Exception.ExceptionRecord; if (EXCEPTION_BREAKPOINT == per->ExceptionCode) { //是断点异常时
if (g_pfWriteFile == per->ExceptionAddress) { //断点地址为writefile 的api地址时候
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile, &g_chOrgByte, sizeof(BYTE), NULL);//恢复api第一个字节(unhook) //ctx.ContextFlags = CONTEXT_CONTROL; //或取线程上下文
ctx.ContextFlags = CONTEXT_ALL; //获取线程上下文,CONTEXT_CONTROL缺少一些寄存器的值,这里使用CONTEXT_ALL
GetThreadContext(g_cpdi.hThread, &ctx);
//printf("0x%08X\n", GetLastError());
//x64下系统api使用fastcall调用约定
//ReadProcessMemory(g_cpdi.hProcess, (LPVOID)(ctx.Esp + 0x8),
// &dwAddrOfBuffer, sizeof(DWORD), NULL);//获取api的第二个参数值
//ReadProcessMemory(g_cpdi.hProcess, (LPVOID)(ctx.Esp + 0xC),
// &dwNumOfBytesToWrite, sizeof(DWORD), NULL);//获取取api的第三个参数值
dwAddrOfBuffer = ctx.Rdx;//WriteFile第2个参数 缓冲区:lpBuffer
dwNumOfBytesToWrite = ctx.R8;//WriteFile第3个参数 缓冲区大小:nNumberOfBytesToWrite
lpBuffer = (PBYTE)malloc(dwNumOfBytesToWrite + 1);//分配临时缓冲区
memset(lpBuffer, 0, dwNumOfBytesToWrite + 1); ReadProcessMemory(g_cpdi.hProcess, (LPVOID)dwAddrOfBuffer,
lpBuffer, dwNumOfBytesToWrite, NULL);//将第三个参数值复制到临时缓冲区
printf("\n### original string ###\n%s\n", lpBuffer); for (i = 0; i < dwNumOfBytesToWrite; i++) { //将小写字母转换为大写字母
if (0x61 <= lpBuffer[i] && lpBuffer[i] <= 0x7A)
lpBuffer[i] -= 0x20;
} printf("\n### converted string ###\n%s\n", lpBuffer); WriteProcessMemory(g_cpdi.hProcess, (LPVOID)dwAddrOfBuffer,
lpBuffer, dwNumOfBytesToWrite, NULL);//将变换后的缓冲区复制到writefile缓冲区 free(lpBuffer);//释放临时缓冲区 //将线程上下文的EIP更改为writefile首地址(当前为writefile()+1位置,int3命令之后)
ctx.Rip = (DWORD64)g_pfWriteFile;//x64指针8字节
SetThreadContext(g_cpdi.hThread, &ctx); // 运行被调试进程
ContinueDebugEvent(pde->dwProcessId, pde->dwThreadId, DBG_CONTINUE);//运行被调试进程
Sleep(0); WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile,
&g_chINT3, sizeof(BYTE), NULL); return TRUE;
}
} return FALSE;
} void DebugLoop() {
DEBUG_EVENT de;
DWORD dwContinueStatus;
while (WaitForDebugEvent(&de, INFINITE))//while循环等待被调试者发生事件,并根据不同的事件类型做出不同的反映
{
dwContinueStatus = DBG_CONTINUE;
if (CREATE_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)// 被调试进程生成事件或者附加事件
{
OnCreateProcessDebugEvent(&de);
}
else if (EXCEPTION_DEBUG_EVENT == de.dwDebugEventCode)// 异常事件
{
if (OnExceptionDebugEvent(&de))
continue;
}
else if (EXIT_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)// 被调试进程终止事件
{
break;//调试器终止
}
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);// 再次运行被调试者
}
} int main(int argc, char* argv[]) {
DWORD dwPID;
//if (argc != 2) //验证参数
//{
// printf("\nUSAGE : hookdbg.exe <pid>\n");
// return 1;
//}
printf("input pid\n");
scanf("%d", &dwPID);
//dwPID = atoi(argv[1]); //pid
if (!DebugActiveProcess(dwPID)) //将调试器(本运行文件)附加到运行的进程上,开始调试
{
printf("DebugActiveProcess(%d) failed!!!\n"
"Error Code = %d\n", dwPID, GetLastError());
return 1;
}
DebugLoop();// 调试循环,处理来自被调试者的调试事件
return 0;
}

x64下要注意api的调用约定以及指针大小为8字节;

《逆向工程核心原理》——通过调试方式hook Api的更多相关文章

  1. 《逆向工程核心原理》——API HOOK

    编写dll处理hook逻辑,注入到目标进程,实现api hook. Windows10 notepad,通过hook kernel32.dll.WriteFile,实现小写字母转大写保存到文件. ho ...

  2. 《逆向工程核心原理》——IAThook

    hook逻辑写入dll中,注入dll. #include "pch.h" #include <tchar.h> #include "windows.h&quo ...

  3. 《逆向工程核心原理》Windows消息钩取

    DLL注入--使用SetWindowsHookEx函数实现消息钩取 MSDN: SetWindowsHookEx Function The SetWindowsHookEx function inst ...

  4. 逆向工程核心原理-IA-32寄存器

    IA-32由四类寄存器组成:通用寄存器,段寄存器,程序状态与控制寄存器,指令指针寄存器. 通用寄存器:用于传送和暂存数据,也可参与算数逻辑运算,并保存运算结果. EAX(0-31) 32位      ...

  5. 《逆向工程核心原理》——DLL注入与卸载

    利用CreateRemoteThread #include <iostream> #include <tchar.h> #include <Windows.h> # ...

  6. 《逆向工程核心原理》——TLS回调函数

    pe中TLS(thread local storage)中函数的执行时机早于入口函数(entry point), 相关结构: // // Thread Local Storage // typedef ...

  7. 运用Detours库hook API(原理是改写函数的头5个字节)

    一.Detours库的来历及下载: Detours库类似于WTL的来历,是由Galen Hunt and Doug Brubacher自己开发出来,于99年7月发表在一篇名为<Detours: ...

  8. 反调试技术常用API,用来对付检测od和自动退出程序

    在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...

  9. HOOK API 在多线程时应该注意的问题点

    在使用INLINE HOOK API实现对系统API的拦截时,正常情况下并没有太大问题,但一旦涉及到多线程,不管是修改IAT还是JMP,2种方法均会出现不可预料的问题,特别是在HOOK一些复杂的大型系 ...

随机推荐

  1. msf 信息收集

    MSF信息收集 转载自天堂空气 一 MSF主机发现 0x1:搜索arp 0x2:使用use auxiliary/scanner/discovery/arp_sweep 模块,然后show option ...

  2. HTTP in depth

    HTTP in depth https://developer.mozilla.org/en-US/docs/Web/HTTP https://developer.mozilla.org/en-US/ ...

  3. SVG viewBox & coordinate system

    SVG viewBox & coordinate system https://codepen.io/xgqfrms/pen/abOOrjp <html> <body> ...

  4. js operate svg

    js operate svg js dynamic create svg https://stackoverflow.com/questions/20539196/creating-svg-eleme ...

  5. WebAssembly JavaScript APIs

    WebAssembly JavaScript APIs https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScrip ...

  6. 解析js字符串

    myEval export const evalExp = /[!\&\|\+\-\*\%=\/<\>\^\(\)\~\:\?\;]/g; export function myEv ...

  7. Win10安装VSCode并配置Python环境 完整版超详细简单【原创】

    我们分为三个步骤进行: 一.下载VSCode 二.配置Python环境 三.测试Python 一.下载VSCode 1.打开国内镜像vscode下载地址,即可自动下载:https://vscode.c ...

  8. LoveWord

    个人喜欢的句子汇总! 我告诉你我喜欢你,并不是一定要和你在一起,只是希望今后的你,在遭遇人生低谷的时候,不要灰心,至少曾经有人被你的魅力所吸引,曾经是,以后也会是----村上村树

  9. 🎊 Element UI 新春快报

    新年好,Element UI 开发团队给各位支持我们的开发者们拜个晚年,祝大家在新的一年里工作没 bug, 天天不加班. 在过去一年里,Element UI 团队在稳定维护 Vue 2.x 版本的同时 ...

  10. Debian 基本使用进阶

    系统安装好了我们,迫不及待的想要在Linux系统中肆意翱翔.如果是刚刚接触Linux的系统的话,可能一时间还无法适应Linux的系统环境.对于使用Debian来做服务器的选择,最好的练习方式的就是使用 ...