首页
社区
课程
招聘
INT3执行后EIP的变化规律[求助]
发表于: 2006-12-6 23:17 7038

INT3执行后EIP的变化规律[求助]

2006-12-6 23:17
7038

//程序目的:调试程序通过修改被调试程序的异常线程的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;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
2
我把所需程序打包发上来,大家帮着看看
上传的附件:
2006-12-6 23:20
0
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
3

可能是我逻辑表达的不是太清楚,再加上大家都有些忙的原因,问题迟迟未解决,我把我的主要疑问补充一下:
我想弄清某一线程中INT3指令执行后EIP的值会怎么变,是等于原先INT3指令的地址还是INT3指令的下一条指令地址?

非常感谢了
2006-12-7 14:41
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
4
int3的下一条指令
2006-12-7 14:55
0
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
5
那WIN9X系统呢?
2006-12-7 15:17
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
6
9x不清楚,没在9x下做过调试程序,你不应该用eip来定位指令,应该用断点异常发生的地址来定位
2006-12-7 15:29
0
雪    币: 380
活跃值: (101)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
7
最初由 xIkUg 发布
9x不清楚,没在9x下做过调试程序,你不应该用eip来定位指令,应该用断点异常发生的地址来定位

软件加密技术内幕中说9X下INT3执行后EIP为其下一条指令地址 我迷糊了~~~
2006-12-7 18:10
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
8
单字节指令int3(机器码0xCC)属于陷阱类异常,执行后保存的CS:EIP指向下一条指令,因为这条指令已经不需要再次执行了,而对于故障类异常来说,控制转移到故障处理程序时,所保存的断点CS:EIP的值指向引起故障的指令,以便在排除故障后恢复执行。
2006-12-8 14:09
0
游客
登录 | 注册 方可回帖
返回
//