Search code examples
cgccassemblygnu-assembler

How to Compile a C program which contains 32bit asm into .o file?


Introduction

I'm following through the book "Learning Linux Binary Analysis". I have some experience working with 32 bit assembly and C (however still consider myself a novice). However I'm having trouble and confusion of how to compile a c program , which contains 32 bit assembly into an object file .o. So im guessing this is just a compilation issue on my part.

The Source code is for part of an example of code injection-based binary patching.

Source Code

#include <sys/syscall.h>
int _write (int fd, void *buf, int count)
{
  long ret;
  __asm__ __volatile__ ("pushl %%ebx\n\t"
  "movl %%esi,%%ebx\n\t"
  "int $0x80\n\t""popl %%ebx":"=a" (ret)
                          :"0" (SYS_write), "S" ((long) fd),
  "c" ((long) buf), "d" ((long) count));
    if (ret >= 0) {
        return (int) ret;
 }
 return -1;
}
int evil_puts(void)
{
        _write(1, "HAHA puts() has been hijacked!\n", 31);
}

The problem

I attempt to compile evil_puts.c into .o file. Which will then be used later for injection into another simple program.

gcc -c evil_puts.c

evil_puts.c: Assembler messages:

evil_puts.c:5: Error: invalid instruction suffix for `push'

evil_puts.c:8: Error: invalid instruction suffix for `pop'

I've received this before when working with 32 assembly with gas. And to solve this i put the '-32' flag when compiling and linking. Which i'm guessing is the problem? however not completely sure, and don't have an idea of how to compile it in 32 bit with C and gcc if that's the case?

I also attempted to change it to 64bit to see if it would work, by replacing 'l' of every command to 'q' and changing the registers to begin with 'r'. which seems to work. However the book uses 32 bit. So i wish to keep it that way. Any ideas? Sorry if this is a really basic question.

Also tried '-m32' but receive this:

fatal error: sys/syscall.h: No such file or directory


Solution

  • Use gcc -m32 -c evil_puts.c -o evil_puts.o

    You're getting that error because you don't have the 32-bit libraries installed.

    If using Ubuntu:

    sudo apt-get install gcc-multilib