lodsd / stosd 汇编说明:反转书中可能存在的勘误表

lodsd / stosd assembly instructions : possible errata in reversing book

在 "Practical Reverse Engineering x86 - x64 ARM, Kernel & Obfuscation" 的第 25 页中,我发现了一个重新翻译为粗略 C 的汇编代码示例,其中 lodsd 和 stosd 指令 "translations" 似乎颠倒了。因为我是汇编语言的新手,所以我想知道它是否真的是一个勘误表,或者我可能没有考虑在内的更多内容。 这是简单的代码:

程序集

01: 8B CA     mov ecx, edx
02:           loc_CFB8F:
03: AD        lodsd
04: F7 D0     not eax
05: AB        stosd
06: E2 FA     loop loc_CFB8F

粗C

while (ecx != 0) {
eax = *edi;
edi++;
*esi = ~eax;
esi++;
ecx--;
}

在我读到的关于 lods 指令的每一个在线解释中,都指出 SI/ESI 中的任何值都存储在 AL/AX/EAX 中,然后递增 ESI。

类似地,stos 应该代表一个粗略的高级别 "memset",其中 AL/AX/EAX 中的任何内容都会写入 DI/EDI,然后递增寄存器。

但看来我错了,因为在上面的翻译中,eax 被分配了 EDI 而不是 ESI 的取消引用,并且在 ESI 指向的值正下方获得了带有 stos 的反转 eax。我在这里遗漏了什么吗?

你是对的,C "translation" 似乎交换了 ediesi。但即便如此,翻译仍然存在一些问题。首先,汇编代码总是复制一份,所以相应的 C 结构实际上是 do ... while。其次,指针是递增还是递减实际上是由方向标志决定的,不指示方向标志的状态。我将代码翻译为:

// note: this assumes that the direction flag is clear (increment mode)
do {
    eax = *esi;
    esi++;
    *edi = ~eax;
    edi++;
    ecx--;
} while (ecx != 0);