首页 > 其他 > 详细

简单调试器的实现(二)使用反汇编引擎&建立第一个程序

时间:2015-03-28 06:24:07      阅读:216      评论:0      收藏:0      [点我收藏+]

让程序停下来:

动态调试器的一个重要特点就是:让程序停下来,这样我们才可以观测到程序的即时情况。

不过现在我们并不需要研究怎么下断点,系统已经帮我们激活了第一个断点。在创建调试进程时,系统会帮我们在ntdll.dll中设置一个INT3断点,我们就让程序在这里断下来。

 

 

switch (DebugEvent->u.Exception.ExceptionRecord.ExceptionCode)//Int3断点的事件
{

  case EXCEPTION_BREAKPOINT: // ((DWORD )0x80000003L)
  // First chance: Display the current
  // instruction and register values.
    BreakPoint_Int3(DebugEvent);//这个函数中我们对被调试程序进行各种处理

}

获得调试程序的寄存器与标志位:

我们只需要使用GetThreadContext 获得被调试进程的上下文环境

BOOL WINAPI GetThreadContext(
     HANDLE hThread,      //线程句柄
     LPCONTEXT lpContext    //结构指针
);

(线程句柄可以在CreateProcess时的pInfo.hThread保存)

对于标志寄存器,比价麻烦,我们需要按位进行与计算。

 

//CF 在第0位
printf(" CF :%d", (context.EFlags & 0x1) != 0);

//PF 在第2位
printf(" PF :%d", (context.EFlags & 0x4) != 0);

 

//AF 在第4位
printf(" AF :%d", (context.EFlags & 0x10) != 0);

 

//ZF 在第6位
printf(" ZF :%d", (context.EFlags & 0x40) != 0);

 

//SF 在第7位
printf(" SF :%d", (context.EFlags & 0x80) != 0);

 

//OF 在第11位
printf(" OF :%d", (context.EFlags & 0x400) != 0);

 

//DF 在第10位
printf(" DF :%d", (context.EFlags & 0x200) != 0);

 

 

反汇编引擎的使用:

 

先介绍一个API:ReadProcessMemory,他读取指定的地址的内容

BOOL WINAPI ReadProcessMemory(
  HANDLE hProcess,                    //进程句柄,在CreateProcess时的pInfo.hProcess保存
     LPCVOID lpBaseAddress,               //要读取的地址
      LPVOID lpBuffer,                         //一个缓冲区的指针,保存读取到的内容
      SIZE_T nSize,                                //要读取的字节数
      SIZE_T* lpNumberOfBytesRead       //一个变量的指针,保存实际读取到的字节数
  );

 

如何使用Disasm这个函数:

在给予反汇编引擎源码中,我们需要的是Disasm这个函数

ulong Disasm(

    char *src,       //需要反汇编的机器码

      ulong srcsize,     //机器码长度

        ulong srcip,       //反汇编机器码地址

            t_disasm *disasm,      //输出

            int disasmmode          //反汇编形式

)

参数:

      src:用ReadProcessMemory获得需反汇编代码地址的机器码内容。

  srcsize:这里直接填写20即可。

  srcip:当前反汇编进程的EIP,这里需要地址是因为一些指令(例如E8 Call)需要计算偏移,否则没法正确显示。

  *disasm:输出的指针。

  disasmmode:就如同例子中使用DISASM_CODE即可.

  (#define DISASM_CODE    4               // Full disassembly)。

 

返回值:

  返回实际处理的机器码的长度。

 

它还有几个需要设置的全局变量:(这里是为1, 否为 0)

ideal:是否使用IDEAL 形式的MODE否则为MASM形式;

lowercase:是否输出小写字母;

putdefseg:是否显示段寄存器。

 

部分代码:

ideal = 0; lowercase = 1; putdefseg = 0;

for (i = 0; i < 5; i++)//输出5行
{
  if (FALSE == ReadProcessMemory(G_Process, DisasmAddr,

                     lpBuff, 10, &bytesRead))//DisasmAddr,反汇编地址
  {
    switch (GetLastError())
    {
    case 299: return 3;  //表示该地址无法被正确读取
    default: return 1;

    }
  }
  l = Disasm(lpBuff, 10, DisasmAddr, &da, DISASM_CODE);
  printf("%-10x %-12s %-12s \n", DisasmAddr, da.dump, da.result);
  DisasmAddr = DisasmAddr + l;
}

 

现在我们可以编写最简单的汇编查看器了:

 

技术分享

简单调试器的实现(二)使用反汇编引擎&建立第一个程序

原文:http://www.cnblogs.com/Windogs/p/4373536.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!