通过调试对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的钩取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 23-Python3 File
- 下一篇: Redis学习笔记之二 :在Java项目