我已经将可执行文件转换为某些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)
感谢。
答案 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不支持
LODS
,MOVS
,STOS
,SCAS
,CMPS
,INS
或OUTS
说明,但仅支持LODSB
,MOVSW
和SCASD
等表单,这些表单明确指定要操作的字符串组件的大小。< / 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
指令的字符串长度,分别将EDI
和ESI
初始化为目标和源字符串,确保设置方向标志因此:
label_0000641:
lea edi,[esp+0x164] ;initializing destination?
label_0000648:
rep movsd
label_000064a:
and DWORD [esp+0x168],0x0