Still Shines.

汇编实验(一)

Word count: 527 / Reading time: 2 min
2018/08/30 Share

分析一个奇怪的程序

程序源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

assume cs:codesg
codesg segment

mov ax,4c00h
int 21h

start: mov ax,0
s: nop
nop

mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax

s0: jmp short s
s1: mov ax,0
int 21h
mov ax,0

s2: jmp short s1
nop

codesg ends
end start

分析过程

猜测结果:
  首先看到这个程序发现程序结束的特定语句写在了开头,但是程序入口在start处,还是算是正常。跟着指令往下发现,程序把s处的指令换成了s2处的指令,此时的s处不再是nop,而是s2的那条语句,所以应该在s0运行结束后跳转到s,此时运行的是s2的语句,所以顺序是s->s0->s2->s1,那到底是不是真的就是这样运行的呢,下面用debug调试。

程序编译完成后debug打开,按u查看指令发现程序的入口在start所指的语句:

此时076A:0016所指的是076A:0008处的地址也就是s处,此时的寄存器状态如下:

接下去都是正常运行:

此处把0008处的内容修改为0020给他的内容F6EB,下一条语句跳转到0008处,此时0008处的指令就是s2处的指令,十六进制表示为F6EB。但是接下去运行时发现,又是一个跳转的指令,直接跳到了0000即程序段的开头。

继续运行下去,程序就结束了。

发现问题

我们看源程序知道运行0020处既s2的指令时,是跳到s1,但是在运行时却直接跳到了程序开头呢?这就是程序奇怪的地方。

原因分析

  原来我们忽略了此时的jmp指令时更具位移进行转移,原来的s2是要转移到s1处,s1处和s2处的位移是8,既向上8移动个内存单元。当把s处的指令改为s2处的指令时,执行的也是向上8个内存单元,刚刚就在程序段的开头,也就执行程序结束指令了。

CATALOG
  1. 1. 分析一个奇怪的程序
    1. 1.1. 分析过程
    2. 1.2. 发现问题
    3. 1.3. 原因分析