NASM:解析器:指令预期rep movs

时间:2015-07-12 04:21:51

标签: assembly x86 nasm

我已经将可执行文件转换为某些NASM shellcode(对于Windows而言,如果它相关)但我遇到了错误:解析器:指令预期"从代表说明到处都是错误。

label_0000641:
lea    edi,[esp+0x164]                      
label_0000648:
rep movs DWORD es:[edi],DWORD ds:[esi]
label_000064a:
and    DWORD [esp+0x168],0x0    

是否有一些特殊的nasm语法?我犯了一个愚蠢的错误吗? 我不知道如何修复这些错误,并且非常想要一些指导。

(我用nasm -f bin编译-o out.bin test.asm)

感谢。

3 个答案:

答案 0 :(得分:6)

NASM不接受rep movs DWORD es:[edi],DWORD ds:[esi]

来自NASM Manual; 2.2.3 NASM Doesn't Store Variable Types

  

NASM根据设计选择不记住您声明的变量类型。虽然MASM在看到var dw 0时会记得你将var声明为一个字大小的变量,然后能够填写指令mov var,2大小的模糊性,NASM会故意记住除了它开始的位置之外没有任何关于符号var的内容,所以你必须明确地编码mov word [var],2

     

出于这个原因,NASM不支持LODSMOVSSTOSSCASCMPSINSOUTS说明,但仅支持LODSBMOVSWSCASD等表单,这些表单明确指定要操作的字符串组件的大小。< / p>

因此,使用的代码是rep movsd

答案 1 :(得分:1)

这看起来好像是一个反汇编者的过分冗长。

引自Intel's manual(名为字符串说明的部分):

  

默认情况下,ESI寄存器用于通过DS段寄存器标识的段。 ...... EDI注册   解决用ES段注册标识的段   ...
  MOVS指令将ESI寄存器寻址的字符串元素移动到EDI寄存器寻址的位置。汇编程序识别该指令的三个“简短形式”,它指定字符串的大小   移动:MOVSB(移动字节字符串),MOVSW(移动字符串)和MOVSD(移动双字符串)。

因此,如果我们应用该信息,我们最终会:

; DWORD operands means movsd, ds:[esi] is the default source, and
; es:[edi] is the default destination
rep movsd

注意:在英特尔手册中MOVS的说明中,MOVS m32, m32列为支持。他们称之为指令的“显式操作数”形式。它仅用于记录目的,因为唯一允许的来源是[(R|E)SI],唯一允许的目标是[(R|E)DI]。我不知道NASM是否支持显式操作数形式,或者在这种情况下它的语法是什么。

答案 2 :(得分:0)

我确保将ECX初始化为rep指令的字符串长度,分别将EDIESI初始化为目标和源字符串,确保设置方向标志因此:

label_0000641:
lea    edi,[esp+0x164] ;initializing destination?                   
label_0000648:
rep movsd
label_000064a:
and    DWORD [esp+0x168],0x0