YLLEN

要去看埃菲尔铁塔的顶

欢迎关注本人微博:t.cn/RGSLVUk

WriteFile Api 勾取初探


  • 记事本 [ 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;

}


评论

© YLLEN | Powered by LOFTER