博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
调试器第二讲,单步步入/步过功能实现,以及基本的断点功能实现
阅读量:5098 次
发布时间:2019-06-13

本文共 3587 字,大约阅读时间需要 11 分钟。

           调试器第二讲,单步步入/步过功能实现,以及基本的断点功能实现

昨天,我们实现了调试器的基本框架,那么今天我们实现单步功能,还有断点功能,以及使用反汇编引擎

作者:IBinary

出处:
版权所有,欢迎保留原文链接进行转载:)

一丶反汇编引擎的编译,生成LIB

首先,我们有一个反汇编引擎的代码,现在我们编译连接一下(注意,可以使用GitHub下载,或者百度Google下载)

关于反汇编引擎的介绍: 请参考转载博客 

先编译成OBJ文件,(不连接),上面两个函数就是我们需要的使用的,准确的来说,是下面的这个,因为上面那个不会给你二进制数据.

比如我们反汇编的结果是

00401000    CC         int 3  那么这样就是用下面这个,有二进制代码显示

如果使用上面那个则是

00401000  int3      具体爱好看你使用那个,这里具体讲解第二个

先编译成OBJ

需要的就这有3个,  除了stdafx.obj 还有MyDisasm.obj 其余的都是我们用的

现在我们使用lib工具,讲编译好的obj打包成一个lib(当然你也可以写)

关于lib工具的使用,请参考我写的博客,32位汇编第七讲,混合编程 连接: 

现在回车,生成我们的lib

 

 

然后我们还需要这两个函数的头文件.

现在准备齐全了,准备开始我们的代码编写.

注意: 这里我们是生成的静态lib,你也可以生成动态链接库 (也就是俗称的 DLL)

二丶使用反汇编引擎API

直接看代码吧

新建一个工程,控制台的(随你便,啥都行,能写代码,调用API的就可以)

把我们的lib,和.h文件,拷贝到我们的程序目录下(静态使用)

#include "stdafx.h"#include 
#include
#include "Decode2Asm.h"#pragma comment(lib,"MyDisAsm.lib")int main(int argc, char* argv[]){ BYTE OpCode[] = {
0xcc,0x90};      //解析的地址,地址里面有机器码,我们不知道是什么(这里举例子我们知道) char szAsm[256] = {NULL};        //通过地址,得出反汇编字符串,放到这个缓冲区中 char szBin[256] = {NULL};        //通过地址,得出二进制机器码,放到这个缓冲区中 UINT binSize = NULL;           //每次只解析一个指令长度,所以我们要遍历数组,加上这个长度,接着输出出来. BYTE *pCurCode = OpCode;         //遍历的时候需要给个指针 do { Decode2AsmOpcode(pCurCode,szAsm,szBin,&binSize,(UINT)pCurCode);//调用API,解析, printf("%-16p%-20s%-20s\r\n",pCurCode,szBin,szAsm);       //输出 pCurCode = pCurCode + binSize;                    //地址 + 指令长度 = 下一次需要解析的指令的地址 } while (pCurCode < (OpCode + sizeof(OpCode)));            //判断是否数组越界 system("pause"); return 0;} Decode2AsmOpcode的各个参数意思: 第一个参数: 地址,你要给我一个地址,我去解析 第二个参数: 反汇编代码的缓冲区,通过地址,解析的反汇编会放到这个缓冲区当中 第三个参数: 二进制代码缓冲区,通过地址,解析二进制,放到这个缓冲区当中 第四个参数: 是否计算偏移 关于这个参数,其实是给EIP的值,(也就是地址),例如我们上面的给的. 这个参数的作用是 比如你有一个 JMP 指令 00401000 JMP 000010 这个是正常的汇编代码,我们知道JMP是JMP的偏移 而后面给了这个参数,它则会给我们计算出来 00401000 JMP 00401010

看下输出结果

配合我们昨天写的,则可以反汇编出来调试进程的代码了.

三丶汇编调用反汇编引擎API,显示调试进程的汇编代码.

在上面,我们对API有了一个认识.

下面我们就结合我们昨天写的汇编代码,接着写,显示出来断点位置的反汇编代码.

首先在处理异常的事件中,我们要调用

先加载我们的LIB,以及INC文件(INC文件中,是那个两个API的函数声明,你可以自己通过LIB生成,

具体请参考上面的混合编程的博客链接)

1.加载LIB,以及INC文件

2.使用ReadProcessMemory,和我们的API配合使用

首先使用Read..读取.然后放到我们的数组中,

然后使用API,获取反汇编的各种信息

invoke ReadProcessMemory,g_hProcess,                             [ebx].u.Exception.pExceptionRecord.ExceptionAddress,                             @OpCode,sizeof @OpCode,                              NULLinvoke ShowAsm,addr @OpCode,[ebx].u.Exception.pExceptionRecord.ExceptionAddress

当然,Read的时候,需要注意要保存g_hProcess句柄.这样才可以.

下面的ShowAsm是封装的函数,内部还是调用的Decode2AsmOpco

ShowAsm proc pCode :ptr byte, pAddr:ptr Byte    LOCAL  @szAsmCode[256]:BYTE    LOCAL  @szOpCode[256]:BYTE    LOCAL  @CodeSize1:DWORD        invoke Decode2AsmOpcode, pCode, addr @szAsmCode, addr @szOpCode,                             addr @CodeSize1, pAddr    invoke crt_printf, offset g_szDcode, pAddr, addr @szOpCode, addr @szAsmCode    retShowAsm endp

这里提一下简单思路,因为真正的都写出来,汇编代码很多,影响观看,所以都是简单思路,没有完整代码,完整代码,在每天的课件资料中,可以去看,这里这说一下核心代码的思路

四丶汇编设置F2断点,以及单步(步入,步过)

简单思路

1.断点的设置:

  1.首先,系统断点第一次来,然后在创建进程的时候会有一个地址,我们使用Read...读取地址内容,然后反汇编出来显示

  2.读取出来之前,使用VirtualProtectEx将保护属性去除,(注意保存旧的)

  3.使用WriteProcessMemory往地址写入CC(注意保存以前的值)

  4.重新修改保护属性,改回去(使用旧的)

然后一个断点即完成了,具体代码,请看课件.

2.单步的设置(步入,进函数)

如果是单步,我们要判断断点是我们设置的还是系统设置的.

1.判断是否使我们设置的断点

2.修改内存保护属性(注意保存旧的)

3.写入CC,(int 3断点)

4.读取内存数据

5.显示反汇编

设置单步(步入)异常

1.打开线程获得线程句柄

2.使用GetThreadContext获取寄存器的值

3.设置单步标志,单步表示是要我们设置的,他是第9个标志

or [esi].regflag,0100h 这样设置即可.设置第九位为1

4.设置寄存器环境 SetThreadContext

设置单步步过异常

但步步过和单步步入一样

只不过遇到Call的时候我们要把他的下一条指令设置一个int3断点才可以.

课堂资料: 链接: 密码:5dw9

作者:IBinary
出处:
版权所有,欢迎保留原文链接进行转载:)

 

转载于:https://www.cnblogs.com/iBinary/p/7609213.html

你可能感兴趣的文章
安装使用eclipse
查看>>
VC6.0调试技巧(一)(转)
查看>>
django 王中王8之踏青撒花
查看>>
linux命令
查看>>
类库与框架,强类型与弱类型的闲聊
查看>>
webView添加头视图
查看>>
字符环(openjudge 2755)
查看>>
php match_model的简单使用
查看>>
在NT中直接访问物理内存
查看>>
Intel HEX 文件格式
查看>>
SIP服务器性能测试工具SIPp使用指导(转)
查看>>
php_扑克类
查看>>
回调没用,加上iframe提交表单
查看>>
(安卓)一般安卓开始界面 Loding 跳转 实例 ---亲测!
查看>>
Mysql 索引优化 - 1
查看>>
LeetCode(3) || Median of Two Sorted Arrays
查看>>
JSDoc规范
查看>>
大话文本检测经典模型:EAST
查看>>
文本主题模型之LDA(一) LDA基础
查看>>
linux基础命令-chgrp/chown/chomd
查看>>