日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

通过调试对WriteFile()API的钩取

發布時間:2024/8/26 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 通过调试对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)恢復writeFileEIP信息

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()的第一個字節換成INT30xcc

//并且添加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的值

//param2writeFile()的字符緩沖區地址

//param3WriteFile()的字符緩沖區大小

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.exePID,用管理員權限打開cmd,輸入hookapi1.exe 16576,向notepad中輸入小寫的“war is over!”退出并保存為1.text文件。運行結果如下圖:

?

?

轉載于:https://www.cnblogs.com/2f28/p/9990870.html

總結

以上是生活随笔為你收集整理的通过调试对WriteFile()API的钩取的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。