Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NASM: parser: instruction expected rep movs

Tags:

x86

assembly

nasm

I've been turning an executable into some NASM shellcode (for windows if it's relevant) but i'm encountering "error: parser: instruction expected" errors all over the place from rep instructions.

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

Is there some special nasm syntax for this? Am I making a stupid mistake? I have no idea how to go about fixing these errors and would really like some guidance.

(I'm compiling with nasm -f bin -o out.bin test.asm)

Thanks.

like image 553
Robert Cass Avatar asked Nov 23 '25 11:11

Robert Cass


2 Answers

NASM will not accept rep movs DWORD es:[edi],DWORD ds:[esi]

From the NASM Manual; 2.2.3 NASM Doesn't Store Variable Types

NASM, by design, chooses not to remember the types of variables you declare. Whereas MASM will remember, on seeing var dw 0, that you declared var as a word-size variable, and will then be able to fill in the ambiguity in the size of the instruction mov var,2, NASM will deliberately remember nothing about the symbol var except where it begins, and so you must explicitly code mov word [var],2.

For this reason, NASM doesn't support the LODS, MOVS, STOS, SCAS, CMPS, INS, or OUTS instructions, but only supports the forms such as LODSB, MOVSW, and SCASD, which explicitly specify the size of the components of the strings being manipulated.

Thus the code to use is rep movsd

like image 114
Sep Roland Avatar answered Nov 25 '25 09:11

Sep Roland


That just looks like some overly verbose outout from a disassembler.

Quoting from Intel's manual (the section named String Instructions):

By default, the ESI register addresses the segment identified with the DS segment register. ... The EDI register addresses the segment identified with the ES segment register.
...
The MOVS instruction moves the string element addressed by the ESI register to the location addressed by the EDI register. The assembler recognizes three “short forms” of this instruction, which specify the size of the string to be moved: MOVSB (move byte string), MOVSW (move word string), and MOVSD (move doubleword string).

So if we apply that information we end up with:

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

Note: in the description for MOVS in Intel's manual, MOVS m32, m32 is listed as supported. They call this the “explicit-operands” form of the instruction. It only serves a documentational purpose, since the only allowed source is [(R|E)SI] and the only allowed destination is [(R|E)DI]. I don't know whether or not NASM supports the explicit-operands form, or what the syntax for it is in that case.

like image 40
Michael Avatar answered Nov 25 '25 09:11

Michael