通过调试对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文件。运行结果如下图:

通过调试对WriteFile()API的钩取的更多相关文章

  1. 通过注入DLL修改API代码实现钩取(一)

    通过注入DLL修改API代码实现钩取(一) Ox00 大致思路 通过CreateRemoteThread函数开辟新线程,并将DLL注入进去 通过GetProcessAddress函数找到需钩取的API ...

  2. 调试钩取技术 - 记事本WriteFile() API钩取

    @author: dlive 0x01 简介 本章将讲解前面介绍过的调试钩取技术,钩取记事本的kernel32!WriteFile() API 调试钩取技术能进行与用户更具有交互性(interacti ...

  3. x64 下记事本WriteFile() API钩取

    <逆向工程核心原理>第30章 记事本WriteFile() API钩取 原文是在x86下,而在x64下函数调用方式为fastcall,前4个参数保存在寄存器中.在原代码基础上进行修改: 1 ...

  4. 高级全局API钩取 - IE连接控制

    @author: dlive @date: 2017/02/14 0x01 调试IE进程 常见网络连接库:ws2_32.dll(套接字),wininet.dll,winhttp.dll 使用Proce ...

  5. c#使用easyhook库进行API钩取

    目标:使calc程序输入的数自动加1 (当别人使用时,总会得不到正确的结果,哈哈) 编写注入程序 ————————————————————————————————— class Program中的方法 ...

  6. 通过注入DLL后使用热补丁钩取API

    通过注入DLL后使用热补丁钩取API 0x00 对比修改API的前五个字节钩取API 对前一种方法钩取API的流程梳理如下: 注入相应的DLL 修改原始AI的函数的前五个字节跳往新函数(钩取API) ...

  7. 《逆向工程核心原理》——通过调试方式hook Api

    1.附加目标进程, 2.CREATE_PROCESS_DEBUG_EVENT附加事件中将目标api处设置为0xcc(INT 3断点) 3.EXCEPTION_DEBUG_EVENT异常事件中,首先判断 ...

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

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

  9. Azure DevOps Server: 使用Rest Api获取拉取请求Pull Request中的变更文件清单

    需求: Azure DevOps Server 的拉取请求模块,为开发团队提供了强大而且灵活的代码评审功能.拉取请求中变更文件清单,对质量管理人员,是一个宝贵的材料.质量保障人员可以从代码清单中分析不 ...

随机推荐

  1. MAC/VMware配置双机调试简述

    Configuration 注:建议提前备份所有修改内容,可能会导致无法开机. 我的测试环境: server: windows 10 + windbg client: windows 7 Server ...

  2. Vue使用js鼠标蜘蛛特效

    1. 在src下新建文件夹utils,里面新建文件canvas-nest.js,将代码复制进去.(可以自己定义存放路径) !function() { function n(n, e, t) { ret ...

  3. kibana的Dev Tool中如何对es进行增删改查

    kinaba Dev Tool中对es(elasticSearch)进行增删改查 一.查询操作 查询语句基本语法 以下语句类似于mysql的: select * from  xxx.yyy.topic ...

  4. 新手使用 GitHub 必备的两个神器

    一.Enhanced Github 你可能遇到过这种情况,你仅仅只想下载仓库里面的单个文件而已,但找不到下载链接,所以你只能被迫下载整个仓库. 而因为某些原因,在国内从 GitHub 上面下载代码的速 ...

  5. refs转发 React.forwardRef

    2020-04-01 refs转发 前几天刚总结完ref&DOM之间的关系,并且想通了3种ref的绑定方式 今天总结一下refs转发 这是react中一直困扰我的一个点 示例: 输入: wor ...

  6. CenterOS7 网络配置

    在 centerOS7 中,已经取消了 ifconfig 命令.使用 ip addr来查询网络配置. 网卡需要手动设置一下: 进入路径 /etc/sysconfig/network-scripts/ ...

  7. Python多线程 - threading

    目录 1. GIL 2. API 3. 创建子线程 4. 线程同步 4.1. 有了GIL,是否还需要同步? 4.1.1. 死锁 4.1.2. 竞争条件 4.1.3. GIL去哪儿了 4.2. Lock ...

  8. Excel数据透视表的日常应用技巧

    对工作表中数据进行统计是经常需要的.一般情况我们都是使用菜单命令或函数来进行数据的统计的.可是如果要统计的工作表中记录很多,而且需要统计的项目也很多时,使用这种方法就显得力不从心了.请问还有什么更好的 ...

  9. 0.1---selenium+java自动化测试进阶01---PageObject设计模式

    一.PageObject设计模式   1.简介 PageObject设计模式,又称页面对象模式,是使用Selenium的广大同行最为公认的一种设计模式.在设计测试时,把元素和方法按照页面抽象出来,分离 ...

  10. 数据库整理(三) SQL基础

    数据库整理(三) SQL基础 SQL语言的特点 集数据定义语言(DDL),数据操纵语言(DML),数据控制语言(DCL)功能于一体. 可以独立完成数据库生命周期中的全部活动: ​ ●定义和修改.删除关 ...