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. HTML教程(看完这篇就够了)

    HTML教程 超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言.您可以使用 HTML 来建立自己的 WEB 站点,HTML 运 ...

  2. js & document.execCommand

    js & document.execCommand click copy document.execCommand 已废弃 过时的 此功能已过时.尽管它可能在某些浏览器中仍然可以使用,但不建议 ...

  3. vue & less bug

    vue & less bug bezierEasingMixin(); ^ Inline JavaScript is not enabled. Is it set in your option ...

  4. Keep Fitness

    Keep Fitness 健身 keep health 训练流程 Part 1 热身 5-10分钟 Part 2 肌肉力量训练 30分钟 大肌群包括:胸.背.腿.臀: 小肌群包括:肩.二头肌.三头肌. ...

  5. Transporter iOS App

    Transporter iOS App apple store app store connect https://appstoreconnect.apple.com/ Transporter &am ...

  6. Raspberry Pi & Raspberry Pi 4

    Raspberry Pi & Raspberry Pi 4 pdf https://www.raspberrypi.org/magpi/issues/beginners-guide-2nd-e ...

  7. dark theme website

    dark theme website css var dark theme prefers-color-scheme https://developer.mozilla.org/en-US/docs/ ...

  8. 如何通过NGK数字增益平台实现兑换算力

    最近币圈里有一个新项目NGK非常火热,很多朋友在经过了了解以后纷纷表示很看好这个项目,那么除了二级市场之外,是否还能有其他的方式可以更低成本地获得NGK代币呢? 答案是肯定的,NGK数字增益平台便是低 ...

  9. TYLER ADAMS BRADBERRY的私人投资分享

    TYLER ADAMS BRADBERRY是星盟全球投资公司(USA International Covenant 公司编号:20091457685)的创始人.投资委员会发起了15支项目基金,通过多方 ...

  10. 离场定高转弯DF与CF的对比

    也许是刚学会CAD的缘故,配合风螺旋插件,画图的感觉真是蛮爽的,忍不住画了一张又一张. 接着昨天的离场保护区,我们来聊一下PBN指定高度转弯保护区的画法.指定高度转弯的计算本身没有太多复杂的地方,真正 ...