(如果 BYTE PTR [ebp+0x8] 得到一个大于 1 字节的参数会怎样?比如 0xcdc485c1

Posted

技术标签:

【中文标题】(如果 BYTE PTR [ebp+0x8] 得到一个大于 1 字节的参数会怎样?比如 0xcdc485c1【英文标题】:(What happens if the BYTE PTR [ebp+0x8] get a parameter greater than 1 byte? like 0xcdc485c1 【发布时间】:2020-07-19 06:58:45 【问题描述】:

所以...我有这个 test.S 文件,他在其中获取以下参数:asm3(0xcdc485c1,0xd6bd5e88,0xe4c1548d)

代码:

```asm3:
      <+0>:   push   ebp
      <+1>:   mov    ebp,esp
      <+3>:   xor    eax,eax
      <+5>:   mov    ah,BYTE PTR [ebp+0x8]
      <+8>:   shl    ax,0x10
      <+12>:  sub    al,BYTE PTR [ebp+0xe]
      <+15>:  add    ah,BYTE PTR [ebp+0xc]
      <+18>:  xor    ax,WORD PTR [ebp+0x10]
      <+22>:  nop
      <+23>:  pop    ebp
      <+24>:  ret```

我想知道例如 0xcdc485c1(ebp+0x8) 会发生什么,因为它有超过 1 个字节,对吗?它只会得到重要的字节?或者它将被完整存储,如果是这样,为什么? 如果你也知道,这个“ebp+0xe”在哪里,它不是参数,或者是吗?

【问题讨论】:

由于 x86 是 little-endian,与双字 [ebp+8] 具有相同起始地址的字节与该双字的 最低 有效字节具有相同的值。所以如果双字值是 CDC485C1h 相同起始地址的字节值是 C1h。 谢谢,你真的帮了我 【参考方案1】:

在函数中的&lt;+3&gt;,堆栈如下所示:

               0  1  2  3   byte offsets
     + 0x10 | 8d 54 c1 e4 |
     + 0x0c | 88 5e bd d6 |
     + 0x08 | c1 85 c4 cd |
     + 0x04 | return      |
 ebp + 0x00 | prev. ebp   |

堆栈上有五个 DWORD(32 位值),每个都按照通常的小端顺序。

无论出于何种原因,下面的代码仅从堆栈中挑选几个字节和一个 WORD(16 位)——因此它使用了三个 DWORD 参数中的一小部分。

一切都只是字节;字节加载指令不关心它是如何存储的或它“意味着”什么,只关心当前内存中的内容。


FWIW:shl ax, 0x10 是一种将ax 设置为零的冗长/混淆方式。 x86 shifts 用 &amp; 31 屏蔽它们的计数,即使操作数大小小于 32 位,所以窄移位可以移出所有位,不像 shl eax, 0x20 什么都不做。

【讨论】:

感谢您的回答,所以只是一个快速的问题,移位后的斧头将是 0x0000 对吗?所以这会将 ax 和 al 归零? 是的,效果将为零ax,所以ahal 都将为零(axeax 的第 15..0 位,@987654333 @ 是位 15..8 和 al 是位 7..0)。 xor eax, eaxeax 的所有 32 位归零。我不知道这段代码打算做什么,但说明:mov ah,BYTE PTR [ebp+0x8]shl ax,0x10 似乎完全是多余的。如果换班是shl eax,0x10 可能更有意义...但我只是猜测。 是啊,其实只是个ctf代码,真的一点意思都没有,我只是学逆向工程。我有关于子操作的最后一个问题。因为al 是 0x00 并且减去了 0xc1,所以结果是负数,所以无论如何它都会返回 0xc1?我正在搜索它,似乎是这样,但我不确定。感谢您的帮助 sub al,BYTE PTR [ebp+0xe] 减去0xBD al = 0x00,得到al = 0x42CF = 1。 [给出的代码显然在“Intel Order”中有操作数,其中(在这种情况下,通常)第一个操作数是目标,第二个是源。只是为了让每个人都保持警觉,还有“AT&T 命令”,这是相反的方式——所以保持清醒!] 是的,我确定是0xBD。堆栈确实向下增长。 ebp + 0x0C是DWORD 0xD6BD5E88的字节0的地址,它以little-endian存储在内存中,所以字节0是0x88ebp + 0x0E 是该 DWORD 字节 2 的地址,即 0xBD。在图中,地址从左到右,从下到上递增——DWORDS 以小端顺序显示。

以上是关于(如果 BYTE PTR [ebp+0x8] 得到一个大于 1 字节的参数会怎样?比如 0xcdc485c1的主要内容,如果未能解决你的问题,请参考以下文章

学习汇编语言

启动气体 x86 n 得到段错误?

Hello, CTF

Hello, CTF

使用gdb查看栈帧的情况, 没有ebp

66 汇编改变数值