要去看埃菲尔铁塔的顶
欢迎关注本人微博:t.cn/RGSLVUk
记事本 [ WriteFile ] API 勾取
以debug模式打开记事本,接受调试事件,处理Create Debug事件
修改API起始位置字节为0xCC,保存原始字节,循环等待接受事件
当被调试程序使用API时,会触发EXCEPTION_BREAK事件,处理这个事件
读取此时栈上缓冲区内容(字符串) ESP+0x8 以及长度(ESP+0xC),进行相应处理即可。
#include "windows.h"
/*
BOOL DebugActiveProcess(DWORD dwProcessId)
*/
LPVOID g_pfWriteFile = NULL;
CREATE_PROCESS_DEBUG_INFO g_cpdi;
BYTE g_chINT3 = 0xCC, g_chOrgByte = 0;
BOOL OnCreateProcessDebugEvent(LPDEBUG_EVENT pde)
{
g_pfWriteFile = GetProcAddress(GetModuleHandle("Kernel32.dll"),"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 dwNumOfBytesToWrite, dwAddrBuffer ,i;
PEXCEPTION_RECORD per = &pde->u.Exception.ExceptionRecord;
// if int 3
if (EXCEPTION_BREAKPOINT == per->ExceptionCode)
{
//断点地址为WriteFile时
if (g_pfWriteFile == per->ExceptionAddress)
{
// 1.Uhook
//将0xCC 恢复为 original byte
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile, &g_chOrgByte, sizeof(BYTE), NULL);
// 2.获取上下文
ctx.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(g_cpdi.hThread, &ctx);
//3.获取Write的Param的参数 param 2,3
//ESP + 8
//ESP + C
ReadProcessMemory(g_cpdi.hProcess, (LPVOID)(ctx.Esp + 0x8),
&dwAddrBuffer, sizeof(DWORD), NULL);
ReadProcessMemory(g_cpdi.hProcess, (LPVOID)(ctx.Esp + 0xC),
&dwNumOfBytesToWrite, sizeof(DWORD), NULL);
//4. 分配临时缓冲区
lpBuffer = (PBYTE)malloc(dwNumOfBytesToWrite + 1);
memset(lpBuffer, 0, dwNumOfBytesToWrite + 1);
//5. 复制字符缓冲区
ReadProcessMemory(g_cpdi.hProcess, (LPVOID)dwAddrBuffer,
lpBuffer, dwNumOfBytesToWrite, NULL);
printf("\n##---Notice---##\n %s \n--###--\n", lpBuffer);
//6. 处理一下
// .....
printf("\n ### deal: ###\n");
//7. 重新写入原始地址
WriteProcessMemory(g_cpdi.hProcess, (LPVOID)dwAddrBuffer,
lpBuffer, dwNumOfBytesToWrite, NULL);
//8. 释放临时缓冲区
free(lpBuffer);
//9 切换上下文
// 当前地址WriteFile()+ 1
ctx.Eip = (DWORD)g_pfWriteFile;//原来API地址 貌似EIP -= sizeof(int 3) 也可以...
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 dwCountinueStatus;
while (WaitForDebugEvent(&de ,INFINITE))
{
dwCountinueStatus = DBG_CONTINUE;
// 1.被调试进程生成或附加事件
if (CREATE_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)
{
OnCreateProcessDebugEvent(&de);
}
// 2.异常事件
else if (EXCEPTION_DEBUG_EVENT == de.dwDebugEventCode)
{
if (OnExceptionDebugEvent(&de))
continue;
}
// 3.被调试进程终止
else if (EXIT_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)
{
break;
}
//再次运行被调试着
ContinueDebugEvent(de.dwProcessId,de.dwThreadId,dwCountinueStatus);
}
}
int main(int argc, _TCHAR* argv[])
{
DWORD dwPid;
if (argc != 2)
{
printf("\nUSAGE: %s pid \n",argv[0]);
}
dwPid = atoi(argv[1]);
if (!DebugActiveProcess(dwPid))
{
printf("DebugActiveProcess(%d) failed \n \
Error Code = %d\n",dwPid,GetLastError());
return 1;
}
DebugLoop();
return 0;
}