鱼C论坛

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

[已解决]问题3.12???

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

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

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

x
将10000h-1001fh设置为代码段,并输入如下代码:

mov ax,1000
mov ss,ax
mov sp,0020
mov ax,cs
mov ds,ax
mov ax,[0]
add ax,[2]
mov bx,[4]
add bx,[6]
push ax
push bx
pop ax
pop bx

设置CS=1000H,IP=0 一直执行到mov bx,[4]变成了mov bx,[c804]|随后的代码全变了.....,请问是什么原因???
最佳答案
昨天 16:20
宝子把栈放在了代码段正中央,还开着单步/断点,结果“调试陷阱中断(单步 INT1/断点 INT3)”和你后面的 push 把数据写回了同一个段里的那些地址,把指令字节给改写了,所以 mov bx,[4] (8B 1E 04 00) 被把最后一个字节 00 覆盖成了 C8,逆向器/调试器就把它反汇编成了 mov bx,[C804],后面的指令也都“跟着变了”。

你是单步到 mov bx,[4] 的。每执行完一条指令,CPU会触发单步中断 INT1,它会在当前 SS:SP 上压栈6字节(FLAGS, CS, IP),也就是把数据写到 1000:001A..001F。

而 mov bx,[4] 这条指令的4个字节在 0013..0016,它的“最后一个字节 00”正好挨着。

前面几次单步的压栈把 001A..001F 改了,再加上你后续自己的 push ax/push bx(从 SP=0020 开始往下写 001E..),统统落在同一片 0000..0020 的代码区域,于是把指令字节覆盖,反汇编就“花”了——8B 1E 04 00 的 00 被写成了 C8,显示成了 [C804](小端序 04 C8)。

简单说:

SS=DS=CS=1000h 且 SP=0020h,栈顶正砸在你的代码上;单步/中断/push 都会把“数据”写到“代码”上 → 代码被改。


把栈放到别的段,就可以

  1. mov ax,2000h
  2. mov ss,ax
  3. mov sp,0100h
复制代码

(注意先 mov ss,ax 再设 sp,而且在改 ss 附近最好避免中断)

同一段也行,但把 SP 设远一点,别压到代码:

  1. mov ss,cs
  2. mov sp,0100h    ; 甚至 0FFF0h 都行,只要不碰 0000..0020 的指令区
复制代码

调试时别用单步在那么低的 SP:先把 SS:SP 调好,再开始单步;或者先一次性运行到安全位置再单步。

如果你故意要读代码里的字(mov ax,[0] 之类),那没问题,但务必保证栈不覆盖这片区域。

照以上改一下,你就不会再看到 mov bx,[4] 变成奇怪的指令了。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 昨天 16:20 | 显示全部楼层    本楼为最佳答案   
宝子把栈放在了代码段正中央,还开着单步/断点,结果“调试陷阱中断(单步 INT1/断点 INT3)”和你后面的 push 把数据写回了同一个段里的那些地址,把指令字节给改写了,所以 mov bx,[4] (8B 1E 04 00) 被把最后一个字节 00 覆盖成了 C8,逆向器/调试器就把它反汇编成了 mov bx,[C804],后面的指令也都“跟着变了”。

你是单步到 mov bx,[4] 的。每执行完一条指令,CPU会触发单步中断 INT1,它会在当前 SS:SP 上压栈6字节(FLAGS, CS, IP),也就是把数据写到 1000:001A..001F。

而 mov bx,[4] 这条指令的4个字节在 0013..0016,它的“最后一个字节 00”正好挨着。

前面几次单步的压栈把 001A..001F 改了,再加上你后续自己的 push ax/push bx(从 SP=0020 开始往下写 001E..),统统落在同一片 0000..0020 的代码区域,于是把指令字节覆盖,反汇编就“花”了——8B 1E 04 00 的 00 被写成了 C8,显示成了 [C804](小端序 04 C8)。

简单说:

SS=DS=CS=1000h 且 SP=0020h,栈顶正砸在你的代码上;单步/中断/push 都会把“数据”写到“代码”上 → 代码被改。


把栈放到别的段,就可以

  1. mov ax,2000h
  2. mov ss,ax
  3. mov sp,0100h
复制代码

(注意先 mov ss,ax 再设 sp,而且在改 ss 附近最好避免中断)

同一段也行,但把 SP 设远一点,别压到代码:

  1. mov ss,cs
  2. mov sp,0100h    ; 甚至 0FFF0h 都行,只要不碰 0000..0020 的指令区
复制代码

调试时别用单步在那么低的 SP:先把 SS:SP 调好,再开始单步;或者先一次性运行到安全位置再单步。

如果你故意要读代码里的字(mov ax,[0] 之类),那没问题,但务必保证栈不覆盖这片区域。

照以上改一下,你就不会再看到 mov bx,[4] 变成奇怪的指令了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 18:20 | 显示全部楼层
本帖最后由 jackz007 于 2025-9-23 18:45 编辑

       堆栈和代码使用了同一块只有 20H 字节(mov sp,0020)的存储空间,只要有数据进出堆栈,都会改变 sp 指针下方的内容,我们知道,在程序运行期间,不只是程序本身会使用堆栈,操作系统、调试器在我们不知情的情况下也会 "偷偷" 使用,假如在我们调试程序期间,操作系统和调试器曾经使用过 10H 的字节的堆栈空间,那么,从 SP 向下 10H 字节的存储区的内容就会被改变,而这个区域恰好储存有代码,这就是楼主代码被莫名其妙改变的直接原因。只要把堆栈空间放到足够大(mov sp,200h),足以避免覆盖代码数据即可解决问题。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 19:54 | 显示全部楼层
jackz007 发表于 2025-9-23 18:20
堆栈和代码使用了同一块只有 20H 字节(mov sp,0020)的存储空间,只要有数据进出堆栈,都会改变 sp ...

thanks
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-24 10:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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