《逆向工程核心原理》——通过调试方式hook Api
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的更多相关文章
- 《逆向工程核心原理》——API HOOK
编写dll处理hook逻辑,注入到目标进程,实现api hook. Windows10 notepad,通过hook kernel32.dll.WriteFile,实现小写字母转大写保存到文件. ho ...
- 《逆向工程核心原理》——IAThook
hook逻辑写入dll中,注入dll. #include "pch.h" #include <tchar.h> #include "windows.h&quo ...
- 《逆向工程核心原理》Windows消息钩取
DLL注入--使用SetWindowsHookEx函数实现消息钩取 MSDN: SetWindowsHookEx Function The SetWindowsHookEx function inst ...
- 逆向工程核心原理-IA-32寄存器
IA-32由四类寄存器组成:通用寄存器,段寄存器,程序状态与控制寄存器,指令指针寄存器. 通用寄存器:用于传送和暂存数据,也可参与算数逻辑运算,并保存运算结果. EAX(0-31) 32位 ...
- 《逆向工程核心原理》——DLL注入与卸载
利用CreateRemoteThread #include <iostream> #include <tchar.h> #include <Windows.h> # ...
- 《逆向工程核心原理》——TLS回调函数
pe中TLS(thread local storage)中函数的执行时机早于入口函数(entry point), 相关结构: // // Thread Local Storage // typedef ...
- 运用Detours库hook API(原理是改写函数的头5个字节)
一.Detours库的来历及下载: Detours库类似于WTL的来历,是由Galen Hunt and Doug Brubacher自己开发出来,于99年7月发表在一篇名为<Detours: ...
- 反调试技术常用API,用来对付检测od和自动退出程序
在调试一些病毒程序的时候,可能会碰到一些反调试技术,也就是说,被调试的程序可以检测到自己是否被调试器附加了,如果探知自己正在被调试,肯定是有人试图反汇编啦之类的方法破解自己.为了了解如何破解反调试技术 ...
- HOOK API 在多线程时应该注意的问题点
在使用INLINE HOOK API实现对系统API的拦截时,正常情况下并没有太大问题,但一旦涉及到多线程,不管是修改IAT还是JMP,2种方法均会出现不可预料的问题,特别是在HOOK一些复杂的大型系 ...
随机推荐
- Kafka 博文索引
博文索引 KafkaBroker 简析 KafkaConsumer 简析 KafkaProducer 简析 KafkaMirrorMaker 的不足以及一些改进 Kafka 简介 数据是系统的燃料,系 ...
- Ubuntu16.04+wineQQ+解决版本过低
[参考1:] http://blog.csdn.net/sinat_32079337/article/details/72771078? [参考2:] http://blog.csdn.net/qq_ ...
- python 爬取腾讯视频的全部评论
一.网址分析 查阅了网上的大部分资料,大概都是通过抓包获取.但是抓包有点麻烦,尝试了F12,也可以获取到评论.以电视剧<在一起>为例子.评论最底端有个查看更多评论猜测过去应该是 Ajax ...
- Xcode 格式化 SwiftUI代码
Xcode 格式化 SwiftUI 代码 代码缩进 代码缩进 格式化 快捷键 Control + i ⌃ + i how to input mac keyboard symbol key ⌃ cont ...
- js useful skills blogs
js useful skills blogs blogs https://davidwalsh.name/tutorials/javascript https://www.ruanyifeng.com ...
- macOS & Nginx
macOS & Nginx ngnix # 使用 brew 安装(如果没有 brew 命令,需要自行安装 brew) $ brew install nginx $ nginx -h # 查看 ...
- 图片居中的flex实现
文本居中 text-align:center; 如果是图片放在div中,就没办法了.用flex可以很简单实现. display: flex; justify-content: center; /* 图 ...
- Anno&Viper -分布式锁服务端怎么实现
1.Anno简介 Anno是一个微服务框架引擎.入门简单.安全.稳定.高可用.全平台可监控.依赖第三方框架少.底层通讯RPC(Remote Procedure Call)采用稳定可靠经过无数成功项目验 ...
- 微信小程序:小程序中使用Less
配置: 首选项 -> 设置 -> 用户 -> 扩展 (找到EasyLess插件,编辑setting.json文件进行配置) 点击vscode左下角的à设置à点击右上角的à添加以上代码 ...
- React高级
1.React应用 1.1创建应用 创建项目可以使用react脚手架,创建步骤如下 1)安装react脚手架 npm i -g create-react-app 2)创建项目 create-react ...