一、实验目的:
1.熟练运用汇编语言数据定义伪代码实现数据的定义与分配
2.运用比较指令,实验整数大小的判断
3.运用条件跳转指令,实现不同用户输入情况下实现不同的成绩等级输出
4.运用IDA Pro进行单步调试,并记录寄存器、内存空间值的变化
二、实验原理:
- 运用记事本.txt文本文档对汇编程序进行编写
- 运用Microsoft MASM 615进行汇编语言的编译与链接
- 运用Visual Studio IDE环境进行汇编程序的编辑、编译与链接
- 运用IDA Pro 对可执行程序进行跟踪与调试
三、实验内容:
1.编写一个汇编程序,完成如下要求:
(1)程序包含必要的数据定义语句,保存中间运算结果。
(2)程序通过键盘输入学生的姓名,科目与成绩
(3)程序根据学生的成绩判断成绩等级,90-100为excellent、80-89为good,70-79为medium,60-69为pass,60以下为failed
(4)程序输出的内容为:如果学生成绩在60以上,输入内容为:
congratulations 学生姓名, your 课程名 grade is 等级。
如果学生成绩在60以下,输出内容为:
sorry 学生姓名, your 课程名 grade is 等级。
2.使用IDA Pro对程序进行逆向及调试,要求如下:
(1)在每次用户输入后程序位置设置断点
(2)记录当前寄存器的值,并对于程序代码相关的寄存器值进行解读
(3)记录每次输入后,程序定义的变量空间的值,并结合用户输入情况进行解读
(4)在程序程序跳转前设置断点,记录与程序代码相关的标准寄存器变化
(5)输出汇总结果前设置断点,并对于程序相关的寄存器和内存空间的值进行解读
四、实验仪器及实验软件环境:
笔记本电脑、Windows 10家庭版操作系统、Visual Studio 2010软件、Microsoft MASM 615软件、IDA Pro 7.0软件、Microsoft note 文本编辑软件
五、实验步骤:
1、使用记事本.txt文本文档,完成汇编程序的编译
以下为源代码:
INCLUDE Irvine32.inc ;从Irvine32文件中复制所需要的定义和设置信息
.data ;后面插入变量
st127_name BYTE 20 DUP(?)
st127_kecheng BYTE 20 DUP(?)
st127_score BYTE 20 DUP(?)
;以下定义输出的字符串
congratulations BYTE "congratulations ",0
sorry BYTE "sorry ",0
your BYTE ",your ", 0
grade BYTE " grade is ",0
excellent BYTE "excellent.", 0
good BYTE "good.", 0
medium BYTE "medium.", 0
pass BYTE "pass.", 0
failed BYTE "failed.", 0
.code
main PROC
;存入学生姓名
mov EDX,offset st127_name
mov ECX,lengthof st127_name ;EDX寄存器保存内存空间首地址,ECX保存空间长度
call ReadString
;存入课程名
mov EDX,offset st127_kecheng
mov ECX,lengthof st127_kecheng
call ReadString
;存入分数
mov eax,offset st127_score
call ReadInt
;根据成绩区间跳转
CMP eax,60
JGE p1
mov EDX,OFFSET sorry
call WriteString
mov EDX,OFFSET ST127_name
call WriteString
mov EDX,OFFSET your
call WriteString
mov EDX,OFFSET ST127_kecheng
call WriteString
mov EDX,OFFSET grade
call WriteString
mov EDX,OFFSET failed
call WriteString
exit
p1:CMP eax,70
JGE p2
mov EDX,OFFSET congratulations
call WriteString
mov EDX,OFFSET ST127_name
call WriteString
mov EDX,OFFSET your
call WriteString
mov EDX,OFFSET ST127_kecheng
call WriteString
mov EDX,OFFSET grade
call WriteString
mov EDX,OFFSET pass
call WriteString
exit
p2:CMP eax,80
JGE p3
mov EDX,OFFSET congratulations
call WriteString
mov EDX,OFFSET ST127_name
call WriteString
mov EDX,OFFSET your
call WriteString
mov EDX,OFFSET ST127_kecheng
call WriteString
mov EDX,OFFSET grade
call WriteString
mov EDX,OFFSET medium
call WriteString
exit
p3:CMP eax,90
JGE p4
mov EDX,OFFSET congratulations
call WriteString
mov EDX,OFFSET ST127_name
call WriteString
mov EDX,OFFSET your
call WriteString
mov EDX,OFFSET ST127_kecheng
call WriteString
mov EDX,OFFSET grade
call WriteString
mov EDX,OFFSET good
call WriteString
exit
p4:
mov EDX,OFFSET congratulations
call WriteString
mov EDX,OFFSET ST127_name
call WriteString
mov EDX,OFFSET your
call WriteString
mov EDX,OFFSET ST127_kecheng
call WriteString
mov EDX,OFFSET grade
call WriteString
mov EDX,OFFSET excellent
call WriteString
exit ;结束
main ENDP ;后跟其他子程序
END main ;最后一行
2.修改文档名为st127.asm (注意后缀名为.asm),并且保存在路径E:\HuiBian\03-three之下
注:
编写源代码时极大可能会出错,因此需要提前准备.asm文件,写出部分代码后复制粘贴代码进行编译,若有报错则修改,无错误则继续编写。
3、使用make32.bat 对汇编程序进行编译与链接
(1)进入指定文件路径cd E:\HuiBian\03-three
(2)在Masm安装路径下面使用make32.bat 进行编译,如:
E:\HuiBian\03-three>C:\Masm615\make32.bat st127
指定路径E:\HuiBian\03-three文件夹里面会出现以下内容
4.使用IDA Pro对程序进行反编译与调试,并按实验要求设置断点,并记录程序执行时的寄存器及内存变化,并说明变化的原因
(1)首先打开IDAPro找到需要调试的.exe文件,对其进行调试。
(2)按实验要求设置断点
本次实验需要在每次用户输入后程序位置、在程序程序跳转前以及输出汇总结果前设置断点(如下图:)
也可以通过jump跳转界面,跳转到指定内存位置:
然后进行调试(未输入数值的情况如下,可以通过jump跳转到RAX查看)
结果分析:
(1)通过实验结果,我们可以看到当输入姓名后的情况是(见下图)
RDX寄存器(64位相当于32位的EDX)中此时保存‘姓名’内存空间首地址,输入的字符串就存放到相应的内存空间中去。
RAX内的6是‘肖秀坤’的字节数,一个汉字等于两字节
RCX寄存器保存的是此空间的长度;
RIP寄存器保存的是此断点语句的内存地址
也可通过jump指令跳转到指定寄存器
点击下图按钮后继续运行
继续输入
RAX内的8是指的‘汇编程序’所占的字节数;RDX跳转到‘课程’的首地址;RIP内存地址也随之跳转
同理:继续输入(下文汇编语言同上图的汇编程序的含义一致)
分析:结果得出每一次以call Readstring输入数值都会有参数传递RDX寄存器保存内存空间首地址,RCX保存空间长度,此时每一个RAX内存放的是输入字符串的字节数。
以call Readint无参数传递,读入10进制整数,并保存到RAX寄存器中以十六进制被表示出来
(3)之后进行跳转输出时的寄存器的变化
首先将输入的score分数与60相比较(此处输入81),若大于等于60则跳转执行
发现此时只有RIP的内存地址改变(即此刻处于断点位置)
由于81大于60所以跳转到P1,与70比较若大于等于70则会继续跳转到P2
继续调试:
同理,若大于等于80则会从P2跳转到P3
此时由于81小于90所以不再跳转,能够成功输出语句(见下图)
此时的RDX寄存器由于执行了call writeSting 函数语句,将字符串首地址移动到RDX寄存器中,即此刻保存的是字符串‘good’的首地址。
注:实验过程中可以多次输入多个成绩区间的成绩用以验证实验逻辑是否准确(过程同上)
分析:成绩81在区间[80,90),等级为good
最终成功输出congratulations ***, your 汇编语言 grade is good. ,与真实结果相符合,实验成功。