Pregunta

I am trying to do some assembly calls in C (GCC 4.6.3, x86 (64-bit CPU), Ubuntu 12.04 64-bit) to zero out register values and set the stack pointer, and ultimately call a jump instruction.

This is what I got:

asm("xor %eax, %eax");
asm("xor %ebx, %ebx");
asm("xor %ecx, %ecx");
asm("xor %edx, %edx");

asm("xor %cs, %cs");
asm("xor %ds, %ds");
asm("xor %es, %es");
asm("xor %fs, %fs");
asm("xor %gs, %gs");
asm("xor %ss, %ss");

asm("xor %esi, %esi");
asm("xor %edi, %edi");
asm("xor %ebp, %ebp");
asm("xor %esp, %esp");

asm("xor %cr0, %cr0");
asm("xor %cr1, %cr1");
asm("xor %cr2, %cr2");
asm("xor %cr3, %cr3");
asm("xor %cr4, %cr4");

asm("xor %cr8, %cr8");

It says Error: operand type mismatch for 'xor' for all of the registers except the first four when I try to compile. Basically, I need to zero out all register contents (not sure how to do that). Apparently there is an rdx register of key importance? But I looked around online and can't find a list.

Next, I need to set the stack pointer to a specific memory location. How can I do that?

Finally, I need to call a jump instruction and go to a specific memory location. How can I do this?

Thanks for any and all help!

¿Fue útil?

Solución

You can't directly manipulate the value of cs,ds,es,fs,gs,ss registers, to zero them out move a zero value from registers like eax, ebx, ecx, edx, esi, edi, esp:

asm("xor %eax, %eax");
asm("mov %ds, %eax");

Still if you compiled your binary to 64 bits, by using the E prefix, you are accessing only lower 32 bits of your registers. Upper half will not be zeroed up. To code 64 bit assembly use R prefixes, for example rax. Then if you for example tried to make your own C-style function purely in assembly with it's own call stack and used 32 bit registers and run it in 64 bit mode, it would crash.

You should definitely learn about using push and pop instructions and you should back up all registers you change in your C code before any inline assembly and then restore them after. If you won't your assembly will mess up with your C code and it will more or less randomly crash. For example:

// pack them up
asm("push %eax");
asm("push %ds");
// do something
asm("xor %eax, %eax");
asm("mov %ds, %eax");
// restore them back in opposite order (it's a stack)
asm("pop %ds");
asm("pop %eax");

See here

Next, you can't even move a value into CS:IP registers, but you can indirectly modify their values using jump, call and ret family of instructions, but you can't do that in your code because your code will jump at (random) (a zero if you zero the address out) address and it will crash.

See this link for more info on CS:IP: Change CS:IP in Assembly Language

Otros consejos

The main issue is that xor cannot operate on segment or control registers. Also note that zeroing control registers can only be done in kernel mode and zero might not make sense for them anyway.

Furthermore, gcc inline asm has its own peculiar syntax it would probably be easiest to write this code in a separate asm file.

You should read the intel manuals and the gcc manuals.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top