1

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

digitalXmage
  • 147
  • 8
  • 1
    I guess you should use **`-m32`...** – Antti Haapala -- Слава Україні Sep 13 '17 at 22:45
  • 1
    Don't change 32b to 64b while you are just learning, it takes usually lot more effort than just replacing registers, in this particular case the `int 0x80` shouldn't be used in 64b, and there's no simple replacement. The proper `syscall` can replace that `int 0x80`, but it will expect different arguments, so you still need to rewrite it all. So your effort to work with 32b binaries to follow the book is good decision, porting 32b to 64b target platform requires quite some experience and time. – Ped7g Sep 14 '17 at 00:28
  • @Ped7g: Also important, you can't safely `push` / `pop` from inline asm in 64-bit code, because that clobbers the red-zone. https://stackoverflow.com/questions/34520013/using-base-pointer-register-in-c-inline-asm. For `int $0x80` in 64-bit mode, see https://stackoverflow.com/questions/46087730/what-happens-if-you-use-the-32-bit-int-0x80-linux-abi-in-64-bit-code – Peter Cordes Sep 14 '17 at 22:53

2 Answers2

3

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

Wyllow Wulf
  • 410
  • 4
  • 23
1

Knowledge specific to 32-bit x86 is of limited usefulness these days since basically everybody has switched to 64-bit (this is a good thing - 32-bit has a lot of register pressure and address space pressure).

Luckily, you don't actually need any asm for what you're doing. I've also made a couple sanity fixes:

#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>

#define write_str(fd, s) my_write(fd, s, strlen(s))
static ssize_t my_write(int fd, const void *buf, size_t count)
{
    return syscall(SYS_write, (long)fd, (long)buf, (long)count);
}

int puts(const char *s __attribute__((unused)))
{
    write_str(STDOUT_FILENO, "HAHA puts() has been hijacked!\n");
    return strlen(s) + 1;
}

I'm not sure exactly why you're avoiding write(2). But if you really need to avoid syscall(2) as well, it will still be far easier to implement that single function in assembly than write assembly everywhere.

o11c
  • 15,265
  • 4
  • 50
  • 75