【问题标题】:NASM: parser: instruction expected rep movsNASM:解析器:指令预期代表 movs
【发布时间】:2015-07-12 04:21:51
【问题描述】:

我一直在将可执行文件转换为一些 NASM shellcode(如果相关,则适用于 windows),但是我在所有地方都遇到了来自 rep 指令的“错误:解析器:预期指令”错误。

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 编译)

谢谢。

【问题讨论】:

标签: assembly x86 nasm


【解决方案1】:

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,它们明确指定被操作字符串的组件的大小。

因此要使用的代码是rep movsd

【讨论】:

    【解决方案2】:

    这看起来像是反汇编程序的一些过于冗长的输出。

    引用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 是否支持显式操作数形式,或者在这种情况下它的语法是什么。

    【讨论】:

    • 它没有,根据a recent duplicate question。有了 a32/a16 助记符前缀,就不需要了。不过,GNU .intel_syntax 确实支持显式操作数(如果您使用了错误的寄存器,则会发出警告)。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-07-19
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 2016-09-13
      相关资源
      最近更新 更多