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. 多线程(一)java并发编程基础知识

    线程的应用 如何应用多线程 在 Java 中,有多种方式来实现多线程.继承 Thread 类.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现带 ...

  2. 记一次 lampiao渗透(Drupal+脏牛提权)

    vulnhub|渗透测试lampiao 题记 最近在打靶机,发现了一个挺有意思的靶机,这里想跟大家分享一下. 环境准备 vulnhub最近出的一台靶机 靶机(https://www.vulnhub.c ...

  3. ES6 Map All In One

    ES6 Map All In One Map 字典/地图 Set 集合 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referenc ...

  4. 如何关闭 iPad Pro 自动开启 wifi 和蓝牙

    如何关闭 iPad Pro 自动开启 wifi 和蓝牙 为了省电,明明关闭了,但是发现每天都会自动开启,什么鬼设计 https://support.apple.com/zh-cn/HT208086 h ...

  5. UX & feedback & instant visual feedback

    UX & feedback & instant visual feedback Select an element on the page https://ant.design/com ...

  6. js & disabled right click & disabled right menu

    js & disabled right click (() => { const log = console.log; log(`disabled copy`); document.bo ...

  7. Mila Fletcher:日常理财应注意的五点

    米拉·弗莱彻于2007年毕业于耶鲁大学,她是一名真正意义上的法学博士,在校期间获得了马歇尔奖学金,毕业后曾在美国多家知名律师事务所任职,目前就职于星盟全球投资公司,专注于帮助公司和客户提供法务咨询,他 ...

  8. Egg.js 是什么?

    Egg.js 是什么? 阿里巴巴出 Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本. 注:Egg.js 缩写为 Egg 设 ...

  9. MySQL -- 内部临时表

    本文转载自MySQL -- 内部临时表 UNION UNION语义:取两个子查询结果的并集,重复的行只保留一行 表初始化 CREATE TABLE t1(id INT PRIMARY KEY, a I ...

  10. 1102 Invert a Binary Tree——PAT甲级真题

    1102 Invert a Binary Tree The following is from Max Howell @twitter: Google: 90% of our engineers us ...