eunseo
eunseo

Reputation: 31

Unsupported instruction `mov`

I'm studying about basic shell code with orw code.
But, in the process, I've got this error message:

Error: unsupported instruction mov

This is my skeleton code in C and assembly:

// File name: orw.c
// Compile: gcc -o orw orw.c -masm=intel

__asm__(

    ".global run_sh\n"
    "run_sh:\n"

    "push 0x67\n"
    "mov rax, 0x616c662f706d742f \n"
    "push rax\n"
    "mov rdi, rsp\n"
    "xor rsi, rsi\n"
    "xor rdx, rdx\n"
    "xor eax, eax\n"
    "mov eax, 2\n"
    "syscall"
    "\n"
    "mov rdi, eax\n"
    "mov rsi, rsp\n"
    "sub rsi, 0x30\n"
    "mov rdx, 0x30\n"
    "xor eax, eax\n"
    "syscall"
    "\n"
    "mov rdi,1\n"
    "mov eax,1\n"
    "syscall" 
);

void run_sh();

int main() { run_sh(); }

I have put movq and movl but they didn't work.

Why does this problem occur with my code?
What is the solution?

Upvotes: 1

Views: 2324

Answers (1)

Peter Cordes
Peter Cordes

Reputation: 364200

Use gcc -save-temps to save compiler output to a file so you can match up the line number with the actual asm line. (Or put your asm into a .s file to feed directly to as).

It's the mov rdi, eax that's the problem; the problem is the operands, not the mnemonic.

There are a couple different forms of mov (which is perhaps why you get such a useless error message1), but the one that takes general-purpose integer regs for both operands needs them to both be the same size.

To zero-extend int fd = open(...) from EAX into RDI, use mov edi, eax.
See MOVZX missing 32 bit register to 64 bit register for more about why that's the instruction for zero-extending.

Footnote 1: GP and segment regs, mov to/from control regs, mov to/from debug regs, and also mnemonics like movq xmm, xmm/mem that need to be disambiguated from mov with and AT&T-syntax q suffix. See What does AT&T syntax do about ambiguity between other mnemonics and operand-size suffixes?


Also, you can optimize mov rsi, rsp ; sub rsi, 0x30 into lea rsi, [rsp-0x30].
And yes, x86-64 SysV has a red-zone, so it is fully safe in user-space to use up to 128 bytes of space below RSP, even across syscall on Linux.

If not for that, you'd want to sub rsp, 0x30 / mov rsi, rsp. (But if you want to eventually ret, you'd need to undo that to point RSP back at the return address.)

Upvotes: 6

Related Questions