鱼C论坛

 找回密码
 立即注册
查看: 51|回复: 3

考古——逆向16位DOS程序

[复制链接]
发表于 前天 23:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
学校作业要求用一个历代学生传承的祖传软件,是16位DOS可执行程序,在现今的电脑上还得安装DOSBox才能用,遂有逆向之用高级语言重新编写的想法。
奈何本人也是一个萌新,目前正在突击小甲鱼的8086汇编视频,已经突击一半左右。
该程序用DIE检测后发现为Pascal编写,无壳

DIE检测结果

DIE检测结果

然后我打开IDA开始硬着头皮分析,由于是16位程序,无法使用OD等进行动态调试,用debug跟踪会导致没有用户输入,程序一直在某个块内打转,所以只能静态分析,IDA各种辅助插件也用不了
程序名叫ABR.EXE,是光学领域的相差计算和人工修改程序,虽然程序运行的过程很简单,就是读取存储有用户写好的数据的txt文件,进行运算,并输出存有运算结果的txt文件,但是其运算过程却非常复杂
我的目标是分析出程序是如何运算的,目前是找到了程序利用int 21h中断读取文件的相关指令,但是这些指令后面指向了一个retf,我想请问各位大佬如何定位这些retf将程序又指向了哪里?逆向究竟应该遵循一个怎样的过程?
ida.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 23:20 | 显示全部楼层
对于16位DOS程序的逆向分析,特别是遇到`retf`指令后的定位问题,以下是详细解答和逆向步骤建议:

### 一、关于`retf`指令的定位方法
`retf`是远返回指令,会从栈中弹出**CS:IP**两个值作为返回地址。定位方法:
1. **静态分析栈操作**:
   - 在`retf`前的代码中,观察`push`指令(尤其是`push cs`/`push offset`)
   - 例如:
   

  1.      push cs       ; 将CS压栈
  2.      push offset loc_1234 ; 将偏移地址压栈
  3.      call sub_proc ; 调用子程序
  4.      ...
  5.      sub_proc proc far
  6.        ...
  7.        retf ; 此时会弹出CS和offset_loc_1234
复制代码

   - 返回地址就是`push`的两个值组合(CS:offset)

2. **IDA交叉引用**:
   - 在IDA中选中`retf`所在函数
   - 按`Ctrl+X`查看交叉引用(Xrefs),找到所有`call`这个函数的位置
   - 重点关注`call far ptr`指令(远调用)

3. **栈帧回溯**:
   - 在函数开头找典型序言:
   

  1.      push bp
  2.      mov bp, sp
复制代码

   - 计算栈中参数/返回地址的位置:
     返回地址IP = [bp+2]
     返回段CS = [bp+4]

### 二、DOS程序逆向标准流程
#### 阶段1:前期准备
1. **运行程序观察行为**
   - 在DOSBox中运行,记录输入/输出文件格式
   - 尝试不同输入数据触发分支

2. **基础分析工具**
   - IDA(静态反汇编)
   - DOS调试器:DEBUG.EXE(动态跟踪)
   - 二进制查看器:WinHex/HxD

#### 阶段2:关键功能定位
1. **定位文件I/O**
   - 搜索`int 21h`中断:
     - 文件打开:`mov ah, 3Dh`
     - 文件读取:`mov ah, 3Fh`
     - 文件关闭:`mov ah, 3Eh`
   - 示例代码特征:
   

  1.      mov dx, offset filename ; 文件名指针
  2.      mov al, 0 ; 只读模式
  3.      mov ah, 3Dh ; 打开文件
  4.      int 21h
复制代码


2. **定位核心算法**
   - 搜索浮点指令(Pascal常用):
     - `FADD`/`FSUB`/`FMUL`/`FDIV`
     - `FLD`/`FSTP`
   - 搜索数据转换指令:
     - `AAM`/`AAD`(BCD运算)
     - `CBW`/`CWD`(符号扩展)

#### 阶段3:动态调试技巧(DEBUG.EXE)
1. **关键断点设置**:
  

  1.    -g 程序入口点  ; 先运行到入口
  2.    -b CS:IP       ; 在文件读取函数设断点
  3.    -g             ; 执行到断点
复制代码


2. **绕过输入阻塞**:
   - 在文件读取函数后断点
   - 手动修改AX寄存器为文件句柄
   - 提前准备输入文件到虚拟磁盘

#### 阶段4:Pascal程序特征
1. **函数识别**:
   - 标准序言:`push bp` + `mov bp,sp`
   - 参数访问:[bp+4]起(16位near call)

2. **运行时库函数**:
   - 文件操作:`Assign`/`Reset`/`Rewrite`
   - 数学函数:`Sqrt`/`Sin`等(搜索`call far ptr`到固定地址)

### 三、针对你的任务建议
1. **优先破解文件格式**
   - 用不同数据生成输入文件
   - 对比输出文件变化
   - 逆向解析比逆向算法更简单

2. **分模块逆向**
  
  1. 主流程 → 文件读取 → 数据解析 → 计算核心 → 结果输出
复制代码

   从两端(文件I/O)向中间(算法)推进

3. **实用技巧**:
   - 在IDA中标记所有`int 21h`调用
   - 对文件读写函数重命名(如`FileRead`)
   - 记录浮点寄存器状态变化(`ST(0)-ST(7)`)

> 逆向本质:通过**数据流跟踪**(输入→处理→输出)和**控制流还原**(函数调用链)重建逻辑。遇到复杂算法时,先用黑盒测试推测数学关系,再验证反汇编结果。

建议从文件读取函数向后追踪,重点关注数据如何从文件缓冲区传递到计算模块。Pascal程序通常有清晰的模块边界,坚持每天分析2-3个函数,很快就能掌握全貌!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 10:11 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-10 13:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表