Debug -e
上面说的都是查看内存中指定位置或者区域的值,下面我们要来改写一下内存值。
使用 -e
可以改写内存值,比如我们想要改写 1000:0 ~ 1000:f 中的内容,可以使用 -e 1000:0 0 1 2 3 4 5 6 7 8 9 0 a b c d e f 这种方式,如下图所示。
这里需要注意下,在进行 -e 改写的时候,每个值中间都有一个空格,如果没有空格的话,会当做一个内存值来看待。
然后用 -d 1000:0 看到我们刚改写的内存值。
还可以使用提问的方式来逐个修改从某一地址开始的内存单元的内容。
还是用 1000:100 来举例子,输出 -e 1000:100 后按下回车键。
如上图所示,可以看到我们先输入了一次 -e 1000:100 这个指令,然后按下了回车键。
注意,如果这里你按下了回车键,就相当于整个 -e 改写的过程已经完成。
如果你想要继续改写后面内存中的值,你需要按下空格键。
我们改写了 1000:100 之后的内存值,然后使用 -d 1000:100 查看我们改写的内容是否生效。
-e 命令还可以支持写入字符,比如我们可以向 1000:0 这个位置开始写入数值和字符,-e 1000:0 1 'a' 2 'b' e 'c' 。
如上图所示,当我们向内存写入字符 'a' 'b' 'c' 的时候,会自动转换为 ASCII 码进行存储,在最右侧可以找到刚刚写入的字符。
Debug -u
如何向内存中写入一段机器码呢?比如我们想要在内存中写入一段机器码。
我们可以使用 -e 来进行写入,向内存中写入 b8 01 00 b9 02 00 01 c8 这个机器码,如下所示
我们使用 -e 写入之后,使用 -d 查看内存值,可以发现我们刚刚写入的值,但是却看不到机器码,所以机器码该如何看呢?
别急,还有个 -u 命令,这个就是看机器码的,如下图所示,我们使用 -u 命令显示我们写入的机器码。
可以看到 1000:0000 ~ 1000:0006 这个内存地址使我们写入的机器码,-u 这个命令就是将内存单元的内容翻译为汇编指令并显示。
-u 输出的结果分为三部分显示:
- 最左侧是每一条机器指令的地址;
- 中间是机器指令;
- 最右侧是机器指令执行的汇编指令。
1000:0 处存放的是写入的机器码 B8 01 00 组成的机器指令,对应的汇编指令是 MOV AX,0001。
1000:0003 处存放的是写入的机器码 B9 02 00 组成的机器指令,对应的汇编指令是 MOV CX,0002。
1000:0006 处存放的是写入的机器码 C1 C8 所组成的机器指令,对应的汇编指令是 add ax,cx。
Debug -t
上面介绍的一系列指令包括我们上面提到的 Debug -e 机器码都是向内存中进行写入,那么如何执行这些指令呢?
我们可以使用 Debug -t 来执行写入的指令。使用 Debug -t 可以执行由 CS:IP 指向的指令。
既然是 -t 能够执行从 CS:IP 指向的命令,所以我们有必要将 CS:IP 指向 1000:0(因为我们前面将指令写在了 1000:0 处)。
首先我们需要执行 -r cs 1000 ,-r ip 0 把 CS:IP 赋值为 1000:0。
然后执行 -t 指令,下图是已经执行过的指令截图。
可以看到,执行完 -t 指令之后,MOV AX,0001 这条指令被执行,当前 AX 寄存器的内容变为了 0001,这条汇编指令的意思就是把 0001 移动到 AX 寄存器中。
继续执行 -t 之后,我们可以看到寄存器的变化。
Debug -a
毕竟机器指令不是那么好懂,写入很不方便,所以有没有办法能够支持我们直接写入汇编指令呢?还真有,Debug 提供了 -a 这种方式来实现汇编指令的写入。如下图所示
可以看到,我们使用了 -a 命令来对 1000:0 进行写入,分别输入 mov ax,1 mov bx,2 mov cx,3 add ax,bx add ax,cx add ax,ax 指令,然后按回车进行确定执行。
我们使用 -d 1000:0 f 可以看到从偏移地址 0 处开始的第 f 个内存指令(因为最大写入的地址只是 f)。
上图中的 1000:000F 为什么有值呢,因为我们上面已经执行过这个写入了。
另外,使用 -a 可以从一个预设的地址处开始输入指令。
总结
今天和大家聊了一下 Debug 的基本用法,主要包括
- -r 查看、修改寄存器中的内容
- -d 查看内存中的指令
- -e 修改内存中的内容
- -u 可以将内存中的内容解释为机器指令和对应的汇编指令
- -t 执行 CS:IP 处的指令
- -a 以汇编得形式向内存写入内容
汇编指令的选项有很多,上面介绍的这些属于经常用到的指令,这些指令要能够熟练使用。