通过调试对WriteFile()API的钩取
通过调试对WriteFile()API的钩取
0x00 目标与思路
目标:钩取指定的notepad.exe进程writeFile()API函数,对notepad.exe进程的写入的字符保存时保存为大写形式
思路:
1)使用DebugActiveProcess函数使调试器附加到指定进程中。
2)使用WaitForDebugEvent函数取得目标进程的调试信息。
3)更改writeFile()函数api的第一个字节为0xcc,使其进入调试区
4)进入调试去后将writeFile()API的第一个字节恢复原状,因为后面还有用。
5)对notepad输入缓冲区的字符串进行大写转换,并保存到缓冲区。
6)恢复writeFile的EIP信息
7)继续运行调试程序
8)再次写入INT3钩子
0x01实现代码
// hookapi1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#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)
{
//获取WriteFile()API地址
g_pfWriteFile = GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteFile");
//将WriteFile()的第一个字节换成INT3即0xcc
//并且添加WriteFile()第一字节的备份,为以后恢复做准备
memcpy(&g_cpdi, &pde->u.CreateProcessInfo, sizeof(CREATE_PROCESS_DEBUG_INFO));
ReadProcessMemory(g_cpdi.hProcess, g_pfWriteFile, &g_chOrgByte, sizeof(BYTE), NULL);
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile, &g_chINT3, sizeof(BYTE), NULL);
return TRUE;
}
//发生异常启动
//发生异常启动
BOOL OnExceptionDebugEvent(LPDEBUG_EVENT pde)
{
CONTEXT ctx;
PBYTE lpBuffer = NULL;
DWORD dwNumofByteToWrite, dwAddrOfBuffer, i;
PEXCEPTION_RECORD per = &pde->u.Exception.ExceptionRecord;
//判断是否是INT3异常
if (EXCEPTION_BREAKPOINT == per->ExceptionCode)
{
//判断是够否是WriteFile()API的地址
if (g_pfWriteFile == per->ExceptionAddress)
{
//1.脱钩,即将writeFile()的首地址恢复,因为后面的用到该函数
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile, &g_chOrgByte, sizeof(BYTE), NULL);
//2.获取进程上下文,其实就是获取各个寄存器的值
//获得进程上下文之后就可以获得进程中函数的各个参数值
ctx.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(g_cpdi.hThread, &ctx);
//3.获取WriteFile()的param2以及param3的值
//param2是writeFile()的字符缓冲区地址
//param3是WriteFile()的字符缓冲区大小
ReadProcessMemory(g_cpdi.hProcess, (LPVOID)(ctx.Esp + 0x8), &dwAddrOfBuffer, sizeof(DWORD), NULL);
ReadProcessMemory(g_cpdi.hProcess, (LPVOID)(ctx.Esp + 0xC), &dwNumofByteToWrite, sizeof(DWORD), NULL);
//4.分配临时缓冲区给存放缓冲区的字符串
lpBuffer = (PBYTE)malloc(dwNumofByteToWrite + 1);
//将新分配的缓冲区的内容清零,以便存放内容
memset(lpBuffer, 0, dwNumofByteToWrite + 1);
//5.复制writeFile()的缓冲区的内容复制到临时缓冲区
ReadProcessMemory(g_cpdi.hProcess, (LPVOID)dwAddrOfBuffer, lpBuffer, dwNumofByteToWrite, NULL);
printf("\n### 初始字符串 ###\n%s\n", lpBuffer);
//6.将临时缓冲区的字符串转换成大写
for (i = 0; i < dwNumofByteToWrite; i++)
{
if (0x61 <= lpBuffer[i] && lpBuffer[i] <= 0x7a)
{
lpBuffer[i] -= 0x20;
}
}
printf("\n ****转换后的字符串为###\n%s\n", lpBuffer);
//7.将变换后的字符串复制到WriteFile()的缓冲区
WriteProcessMemory(g_cpdi.hProcess, (LPVOID)dwAddrOfBuffer, lpBuffer, dwNumofByteToWrite, NULL);
//8.释放临时缓冲区
free(lpBuffer);
//9.更改EIP指针恢复为WriteFile()的首地址
//由于前面更改WriteFile()的首地址为INT3了,后面执行了INT3指令之后EIP增加了1。所以执行完之后要改回去。
ctx.Eip = (DWORD)g_pfWriteFile;
SetThreadContext(g_cpdi.hThread, &ctx);
//10.继续运行被调试程序
ContinueDebugEvent(pde->dwProcessId, pde->dwThreadId, DBG_CONTINUE);
Sleep(0);
//11.再次写入API钩子
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))
{
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;
}
// 将第二个参数转化为long型
dwPID = atoi(argv[1]);
if (!DebugActiveProcess(dwPID))
{
printf("DebugActiveProcess(%d) failed!!!\n"
"Error Code = %d\n", dwPID, GetLastError());
return 1;
}
// 循环等待事件发生
Debugloop();
return 0;
}
编译生成hookapi1.exe文件。将其放入D盘。
0x02 运行查看效果
打开notepad.exe,打开processExploer查看notepad.exe的PID,用管理员权限打开cmd,输入hookapi1.exe 16576,向notepad中输入小写的“war is over!”退出并保存为1.text文件。运行结果如下图:
转载于:https://www.cnblogs.com/2f28/p/9990870.html
通过调试对WriteFile()API的钩取相关推荐
- linux vc 调试方法,VC实现【API钩取】【调试法】附加调试器
最近在学习逆向核心,在论坛也发了几篇帖子说说自己的经验,帮助自己巩固知识,也方便了大家. 如果帖子中有什么疏漏甚至不对的地方,请大牛们指出,我会积极改正的! 废话不多说,还是我[Miss丿小沫],上教 ...
- 逆向工程核心原理读书笔记-API钩取之记事本小写转大写
我们通过一个示例来练习钩取Notepad.exe的WriteFile,保存文件时将小写字母全部转换为大写字母.下面我们先测试一下代码. 运行notepad.exe并查看PID. 在命令行窗口中输入命令 ...
- 逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制
我们通过一个示例来练习钩取IE8的InternetConnect函数,用IE8连接指定网站时,使之连接到另一个网站.和以前钩取CreateProcess不同,这次我们钩取更低级的ZwResumeThr ...
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(二)
上一篇文章我们实现的隐藏进程如果重新打开任务管理器或者被隐藏的进程就没有隐藏的效果了.为了弥补这个问题,我们不仅需要钩取当前运行的所有进程,还要钩取将来运行的所有进程.由于所有的进程都是由父进程使用C ...
- 逆向工程核心原理读书笔记-API钩取之隐藏进程(一)
简评: 整体看了下代码,其实就是应用层的inline hook, 钩子勾住ntdll.dll里面的ZwQuerySystemInformation函数, xp环境测试成功了,win7测试失败了,不知道 ...
- 逆向工程核心原理读书笔记-API钩取之计算器显示中文数字
我们通过一个示例来练习向计算机进程插入用户的DLL文件,钩取负责向计算器显示文本的SetWindowTextW,使得计算器中显示中文数字而不是原来的阿拉伯数字.钩取前后的原理图如下所示. 下面我们先测 ...
- python黑客攻防入门下载-Python键盘钩取的自我理解(来源于《Python黑客攻防入门》)...
最近从图书馆借到一本书<Python黑客攻防入门>,感觉里面的提供的代码模块对自己深有感触(主要我超菜),所以打算尝试写点小分析,希望大家能谅解本人的语言组织与技术分析. 希望有人来讨论. ...
- 逆向工程核心原理——消息钩取
钩子(HOOK) 英文Hook一词,翻成中文是"钩子"."鱼钩"的意思,泛指钓取所需东西而使用的一切工 具."钩子"这一基本含义延伸发展为& ...
- python爬去新浪微博_!如何通过python调用新浪微博的API来爬取数据
python抓取新浪微博,求教 爬手机端 可以参考的代码, #-*-coding:utf8-*- import smtplib from email.mime.text import MIMEText ...
最新文章
- 塑钢瓦图片_塑钢瓦和彩钢瓦哪种好 如何准确选购
- CRMEB删除公众号首页logo动画
- es6 对象中是否有键值_js/es6判断对象是否为空,并判断对象是否包含某个属性...
- python的文件夹_Python遍历文件夹和文件
- JAVA 面向对象的一些基础理解
- JS操作iframe元素
- Prometheus和Grafana监控实践
- 清理服务器挖矿木马病毒
- 在设计软件测试用例的原则,设计软件测试用例需要遵循的四条原则
- Tomcat8+Redis集群解决会话共享
- python色卡识别_用Python帮小姐姐选口红,人人都是李佳琦
- 首届华为开发者大赛沙龙牵手大连-与开发者共话赛事
- 【Android 事件分发】MotionEvent.ACTION_DOWN 按下事件分发流程( Activity | ViewGroup | View )
- 【FND】EBS中Java并发程序开发
- Android Wifi移植
- 下载频道2013上半年超人气精华资源汇总---全都是免积分下载。 十分感谢这些免积分分享精华资源的好人!!...
- microsoft authenticator 华为等手机无谷歌框架使用方法
- APl DOM文档对象模型
- 一文详解计算机网络经典面试题
- HTML写表格记录(二)--如何在HTML中表达“>“,“<“大于号小于号,以及<b>的意思