//程序目的:调试程序通过修改被调试程序的异常线程的EIP,来直接跳到
//异常线程中对第二个MessageBoxA调用的入口
/*被调试程序(目标文件命名为debugapi_test.exe)
#include "windows.h"
int main(int argc, char* argv[])
{
__asm
{
PUSHAD ;
INT 3 ;
POPAD ;
}
::MessageBox(
NULL,
"OK",
"BOX1",
MB_OK);
::MessageBox(
NULL,
"OK",
"BOX2",
MB_OK);
return 0;
} */
//调试程序
#include "windows.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HANDLE hThread=NULL;
char szCommandLine[20] = "debugapi_test.exe";
STARTUPINFO si = {sizeof(si)};
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = TRUE;
BOOL breturn= ::CreateProcess (
NULL,
szCommandLine,
NULL,
NULL,
FALSE,
DEBUG_ONLY_THIS_PROCESS||CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
if(!breturn)
{
::MessageBox(NULL,"CREATE ERROR","",0);
::ExitProcess(-1);
}
DEBUG_EVENT DE;
int i=0;
do
{
::WaitForDebugEvent(&DE,INFINITE);
switch(DE.dwDebugEventCode)//switch_1
{
case EXCEPTION_DEBUG_EVENT:
switch(DE.u.Exception.ExceptionRecord.ExceptionCode)//switch_2
{
case EXCEPTION_BREAKPOINT:
{
i++;
if(i==1) //以DEBUG方式创建进程时系统会调用DebugBreak()产生中断断点
{
char szbuffer[30]={'\0'};
::wsprintf(
szbuffer,
"ExceptionAddress=%.8X",
DE.u.Exception.ExceptionRecord.ExceptionAddress);
//弹出异常发生地址提示
::MessageBox(NULL,szbuffer,"BREAK――POINT",0);
::ContinueDebugEvent(
pi.dwProcessId,
pi.dwThreadId,
DBG_CONTINUE);
}
if(i==2) //第二个断点是被调试的程序中的int3指令产生
{
char szbuffer[30]={'\0'};
::wsprintf(
szbuffer,
"ExceptionAddress=%.8X",
DE.u.Exception.ExceptionRecord.ExceptionAddress);
//弹出异常发生地址提示
::MessageBox(NULL,szbuffer,"BREAK――POINT",0);
CONTEXT cn;
cn.ContextFlags=CONTEXT_FULL;
::GetThreadContext(
hThread,
&cn);
::wsprintf(
szbuffer,
"IP=%.8X",
cn.Eip);
//提示异常发生线程的EIP
不知为什么这里提示的地址总是INT3后面指令的地址??不是说只有在WIN9X系统中执行INT3后EIP才会为INT3后面指令的址?
而我在另一个测试程序(测试程序见example.rar)中发现执行INT3后EIP仍然为INT3指令地址?不知我表达的清楚不清楚
::MessageBox(NULL,szbuffer,"",0);
DWORD ADDD=(DWORD)::GetProcAddress(
::GetModuleHandle("USER32.dll"),
"MessageBoxA");
/*被调试程序的ESI寄存器中存放的是MessageBoxA函数的地址
在被调试程序中存在两个对MessageBoxA调用的地方,因此我们
先对esi寄存器进行修改*/
cn.Esi=ADDD;
//EIP向后跳0X16字节跳到第二个调用MessageBoxA的入口
cn.Eip+=0x16;
//然后修改产生异常线程的上下文
::SetThreadContext(
hThread,
&cn);
::ContinueDebugEvent(
pi.dwProcessId,
pi.dwThreadId,
DBG_CONTINUE);
}
}
break;
}//switch_2
break;
case EXIT_PROCESS_DEBUG_EVENT:
{
::MessageBox(NULL,"被调试程序退出","",0);
::ContinueDebugEvent(
pi.dwProcessId,
pi.dwThreadId,
DBG_EXCEPTION_NOT_HANDLED);
::MessageBox(NULL,"调试器退出","",0);
::CloseHandle(pi.hProcess);
::CloseHandle(pi.hThread);
::ExitProcess(-1);
break;
}
case CREATE_PROCESS_DEBUG_EVENT:
{ hThread=DE.u.CreateProcessInfo.hThread;
::MessageBox(NULL,"Process_Created","",0);
break;
}
}//switch_1
::ContinueDebugEvent(
pi.dwProcessId,
pi.dwThreadId,
DBG_EXCEPTION_NOT_HANDLED);
}
while(1);
return 0;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!