CREATE_PROCESS_DEBUG_EVENT 创建进程的调试事件。CREATE_PROCESS_DEBUG_INFO结构体描述了该类调试事件的详细信息 OUTPUT_DEBUG_STRING_EVENT 该事件,当被调试进程调用OutputDebugString时就会引发该类调试事件,OUTPUT_DEBUG_STRING_INFO结构体描述了关于该事件的详细信息 LOAD_DLL_DEBUG_EVENT 当DLL被加载时,会调用该回调,LOAD_DLL_DEBUG_INFO结构体描述了它的详细信息,dll的路径被放在了,hfile字段,该字段默认是句柄方式存储的,需要手工转换,
实现简易调试器: 通过调试API实现建议调试器,可以加以改进,变成内存dump工具,等,也可以获取实际OEP作为查壳工具来用。
#include <stdio.h>
#include <Windows.h>
#include <Tlhelp32.h>
#include <imagehlp.h>
#pragma comment (lib, "Dbghelp")
BYTE bCC = '\xCC';
// 这是调试进程第一次被断下后执行操作
void OnException(DEBUG_EVENT *pDebug, BYTE *bCode)
{
CONTEXT context;
DWORD dwNum;
BYTE bTmp;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pDebug->dwProcessId);
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pDebug->dwThreadId);
SuspendThread(hThread);
// 读取出异常首地址
ReadProcessMemory(hProcess, pDebug->u.Exception.ExceptionRecord.ExceptionAddress, &bTmp, sizeof(BYTE), &dwNum);
context.ContextFlags = CONTEXT_FULL;
GetThreadContext(hThread, &context);
printf("EAX = %x EIP = %x \n", context.Eax, context.Eip);
// 将刚才的CC断点取消,也就是会写原始指令集
WriteProcessMemory(hProcess, pDebug->u.Exception.ExceptionRecord.ExceptionAddress, bCode, sizeof(BYTE), &dwNum);
context.Eip--;
SetThreadContext(hThread, &context);
printf("EAX = %x EIP = %x \n", context.Eax, context.Eip);
printf("入口点: %x \n", pDebug->u.CreateProcessInfo.lpBaseOfImage);
ResumeThread(hThread);
CloseHandle(hThread);
CloseHandle(hProcess);
}
int main(int argc, char * argv[])
{
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
DEBUG_EVENT de = { 0 };
// 创建调试进程
BOOL bRet = CreateProcess("c://123.exe", 0, 0, 0, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, 0, 0, &si, &pi);
if (bRet == FALSE)
return bRet;
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
BYTE bCode;
DWORD dwNum;
int dwCC_Count = 0;
// 开始调试循环
while (WaitForDebugEvent(&de, INFINITE))
{
switch (de.dwDebugEventCode)
{
// 当进程创建成功后自动执行的部分
case CREATE_PROCESS_DEBUG_EVENT:
{
// 获取入口地址 0x0 可以增加偏移到入口后任意位置
DWORD dwAddr = 0x0 + (DWORD)de.u.CreateProcessInfo.lpStartAddress;
// 暂停线程
SuspendThread(de.u.CreateProcessInfo.hThread);
// 读取入口地址处的字节码
ReadProcessMemory(de.u.CreateProcessInfo.hProcess, (const void *)dwAddr, &bCode, sizeof(BYTE), &dwNum);
// 在入口地址处写入0xCC 即写入INT 3
WriteProcessMemory(de.u.CreateProcessInfo.hProcess, (void *)dwAddr, &bCC, sizeof(BYTE), &dwNum);
// 恢复线程
ResumeThread(de.u.CreateProcessInfo.hThread);
break;
}
// 当进程产生异常时自动执行这里
case EXCEPTION_DEBUG_EVENT:
{
switch (dwCC_Count)
{
// 第0次是系统断点,这里我们直接跳过
case 0:
dwCC_Count++; break;
// 第一次断点,我们让他执行下面的函数
case 1:
OnException(&de, &bCode); dwCC_Count++; break;
}
}
}
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
}
system("pause");
return 0;
}
获取DLL加载情况:
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>
#include <psapi.h>
void OnDllLoaded(const LOAD_DLL_DEBUG_INFO *pDebug)
{
printf("基址: 0x%-8X --> ", pDebug->lpBaseOfDll);
BOOL bSuccess = FALSE;
TCHAR pszFilename[MAX_PATH + 1];
HANDLE hFileMap;
// Get the file size.
DWORD dwFileSizeHi = 0;
DWORD dwFileSizeLo = GetFileSize(pDebug->hFile, &dwFileSizeHi);
printf("长度: %9d --> ", dwFileSizeLo);
if (dwFileSizeLo == 0 && dwFileSizeHi == 0)
{
return;
}
// 创建内存映射
hFileMap = CreateFileMapping(pDebug->hFile, 0, PAGE_READONLY, 0, 1, 0);
if (hFileMap)
{
void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);
if (pMem)
{
if (GetMappedFileName(GetCurrentProcess(), pMem, pszFilename, MAX_PATH))
{
printf("路径: %s \n", pszFilename);
}
UnmapViewOfFile(pMem);
}
CloseHandle(hFileMap);
}
}
int main(int argc, char * argv[])
{
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
DEBUG_EVENT debug_event = { 0 };
// 创建调试进程
BOOL bRet = CreateProcess("C:/Program Files/Tencent/QQ/Bin/QQ.exe", 0, 0, 0, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, 0, 0, &si, &pi);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
// 开始调试循环
while (WaitForDebugEvent(&debug_event, INFINITE))
{
switch (debug_event.dwDebugEventCode)
{
// 当DLL加载到进程时自动的执行此处代码
case LOAD_DLL_DEBUG_EVENT:
OnDllLoaded(&debug_event.u.LoadDll);
break;
}
ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_CONTINUE);
}
return 0;
}
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有