大家好,我是程序员徐CX宣!在本文中,我们来做一个实际的调试。
我们以后会用到很多Debug命令,所以先熟悉一下。
接下来我们会用到很多debug命令,但是使用这些命令的前提是你需要在电脑上安装debug,Windows/Mac都可以安装。我已经为你找到了链接。啊,忘了说了,我们用Dosbox来模拟汇编的运行环境。
门户(Mac和Windows):https://www.dosbox.com/download.php?主=1
下载完成后打开DosBox,打开后是这样的。
此时,当我们输入debug命令时,我们应该提示
因为我们还没有连接和挂载,此时我们执行。
MountcD:\debug在执行这个命令的时候,需要在当前的D盘下创建一个debug文件夹,然后我们会挂载到debug下。
并执行C:切换到c盘路径。
此时,我们可以执行debug命令。
这里需要注意的是,我在Windows10系统下设置调试环境时,挂载完成后键入debug,仍然提示Illegalcommand:debug。这时,你需要下载另一个debug.exe,我也给了你下载地址。
下载地址:https://pan.baidu.com/s/177arSA34plWqV-iyffWpEw#list/path=/密码:3kd
你需要下载里面的debug.exe,然后把它放在你挂载的路径下。我在这里挂载的路径是D drive下的debug文件夹。
放置完成后,进入debug即可。
因为每次打开Dosbox都会执行这些命令,真的很烦。我该怎么办?一个简单的方法是在Dosbox的安装路径下找到。
打开后,在末尾键入。
好了,下次我直接打开Dosbox,默认会执行这三个命令。至此,我在构建Dosbox时遇到的所有问题都是。
玩汇编,要学会使用Debug,这是一种调试程序.通过Debug,我们可以看到内存值,跟踪堆栈情况,看到寄存器中暂存的内容,同时可以帮助我们更好的理解汇编代码,所以学习Debug和非常重要是不可或缺的实践能力。
下面我们将使用几个调试命令,下面简单介绍一下。
调试命令有很多,但常用的一般是上面这几种。
好了,现在我们开门见山,开始在Dosbox上调试。首先,打开Dosbox。
嗯。这个接口我们已经开放过很多次了。
如果我写订单呢?好吧,我没演示过,就在这里!
查看寄存器的内容。
注意这里-r的情况。Debug-r用于检查寄存器内容。并且-R是无效指令。
上图中列出了许多寄存器。你可能会觉得无从下手。不要乱。先说最基础的,也就是CS和IP。CS(CodeSegment)是一个代码段寄存器,通常也称为段基址。可以认为是程序访问的入口。CPU需要从CS中找出从哪里开始取和执行,但是我们不知道取哪个段。这时候IP的作用就体现出来了。IP(InstructionPointer)是指令指针寄存器,也称为偏移地址,它将告诉我们从段基址中取哪个段地址。
段基址:的偏移地址可用于确定存储器中的指定地址。
这里我们只是简单讲一下这两个寄存器的概念。要了解这两个寄存器的具体作用,可以看作者上一篇文章。
使用-r还可以修改寄存器的内容,如下所示
-r的一般格式是-r寄存器,然后系统会用冒号提示您,后面跟着您想要修改的内容。
默认情况下,输出存储器值从CS:IP地址开始。由于CS的值默认为073F,IP默认为0100,所以-d的内存值为073F:0100。
有许多格式的-D。这里只是一些常用的格式。
-d段基址偏移地址格式,看起来像-d1000:0,可以产生以下输出。
如上图所示,Debug列出了指定内存单元中的内容。上图中每个00代表8位。如果是4A,那么这八位就是00101011。每行有16个8位,所以构成128位。
内存地址。为什么都是00呢,因为内存单元的值没有被改写,说白了就是这块内存区域没有存值,如何改写我们后面会说。
每一行的中间都有一个-,这个是为了便于我们阅读来设置的,-号前后都有8个内存单元,这样便于查看。
右侧几个......表示每个内存单元可显示的ASCII码字符,因为内存没有值,所以也没有对应的ASCII码。我们可以数一下,每行有16个.,这表示每一个00都对应了一个ASCII码。
我们可以使用-d1000:9这种-d段基址:起始偏移地址格式来显示从1000的第几位开始。
Debug从1000:9开始,一直到1000:88,一共是128个字节,第一行中的1000:0~1000:8中的内容没有显示。
还可以使用-d1000:09这种-d段基址:起始偏移地址结尾偏移地址的格式来输出。
还可以是使用-d偏移地址来在不指定段基址的情况下,查看内存值。
上面说的都是查看内存中指定位置或者区域的值,下面我们要来改写一下内存值。
使用-e可以改写内存值,比如我们想要改写1000:0~1000:f中的内容,可以使用-e1000:001234567890abcdef这种方式,如下图所示。
这里需要注意下,在进行-e改写的时候,每个值中间都有一个空格,如果没有空格的话,会当做一个内存值来看待。
然后用-d1000:0看到我们刚改写的内存值。
还可以使用提问的方式来逐个修改从某一地址开始的内存单元的内容。
还是用1000:100来举例子,输出-e1000:100后按下回车键。
如上图所示,可以看到我们先输入了一次-e1000:100这个指令,然后按下了回车键。
注意,如果这里你按下了回车键,就相当于整个-e改写的过程已经完成。
如果你想要继续改写后面内存中的值,你需要按下空格键。
我们改写了1000:100之后的内存值,然后使用-d1000:100查看我们改写的内容是否生效。
-e命令还可以支持写入字符,比如我们可以向1000:0这个位置开始写入数值和字符,-e1000:01'a'2'b'e'c'。
如上图所示,当我们向内存写入字符'a''b''c'的时候,会自动转换为ASCII码进行存储,在最右侧可以找到刚刚写入的字符。
如何向内存中写入一段机器码呢?比如我们想要在内存中写入一段机器码。
我们可以使用-e来进行写入,向内存中写入b80100b9020001c8这个机器码,如下所示
我们使用-e写入之后,使用-d查看内存值,可以发现我们刚刚写入的值,但是却看不到机器码,所以机器码该如何看呢?
别急,还有个-u命令,这个就是看机器码的,如下图所示,我们使用-u命令显示我们写入的机器码。
可以看到1000:0000~1000:0006这个内存地址使我们写入的机器码,-u这个命令就是将内存单元的内容翻译为汇编指令并显示。
-u输出的结果分为三部分显示:
最左侧是每一条机器指令的地址;中间是机器指令;最右侧是机器指令执行的汇编指令。1000:0处存放的是写入的机器码B80100组成的机器指令,对应的汇编指令是MOVAX,0001。
1000:0003处存放的是写入的机器码B90200组成的机器指令,对应的汇编指令是MOVCX,0002。
1000:0006处存放的是写入的机器码C1C8所组成的机器指令,对应的汇编指令是addax,cx。
上面介绍的一系列指令包括我们上面提到的Debug-e机器码都是向内存中进行写入,那么如何执行这些指令呢?
我们可以使用Debug-t来执行写入的指令。使用Debug-t可以执行由CS:IP指向的指令。
既然是-t能够执行从CS:IP指向的命令,所以我们有必要将CS:IP指向1000:0(因为我们前面将指令写在了1000:0处)。
首先我们需要执行-rcs1000,-rip0把CS:IP赋值为1000:0。
然后执行-t指令,下图是已经执行过的指令截图。
可以看到,执行完-t指令之后,MOVAX,0001这条指令被执行,当前AX寄存器的内容变为了0001,这条汇编指令的意思就是把0001移动到AX寄存器中。
继续执行-t之后,我们可以看到寄存器的变化。
毕竟机器指令不是那么好懂,写入很不方便,所以有没有办法能够支持我们直接写入汇编指令呢?还真有,Debug提供了-a这种方式来实现汇编指令的写入。如下图所示
可以看到,我们使用了-a命令来对1000:0进行写入,分别输入movax,1movbx,2movcx,3addax,bxaddax,cxaddax,ax指令,然后按回车进行确定执行。
我们使用-d1000:0f可以看到从偏移地址0处开始的第f个内存指令(因为最大写入的地址只是f)。
上图中的1000:000F为什么有值呢,因为我们上面已经执行过这个写入了。
另外,使用-a可以从一个预设的地址处开始输入指令。
今天和大家聊了一下Debug的基本用法,主要包括
-r查看、修改寄存器中的内容-d查看内存中的指令-e修改内存中的内容-u可以将内存中的内容解释为机器指令和对应的汇编指令-t执行CS:IP处的指令-a以汇编得形式向内存写入内容汇编指令的选项有很多,上面介绍的这些属于经常用到的指令,这些指令要能够熟练使用。
下一篇:特种车辆操作证怎么考