Just a quick post to demonstrate a script that can be used to generate the binary form of a C/C++ function on Linux. It prints both the disassembled code and a “C array” (array of hexadecimal bytes suitable for a .h file) of the function.
#! /bin/bash
# print_function_binary functionName binaryName
# Author: Samuel Ellicott 2022-11-16
# Outputs the disassembled and hex form of a C function to the command line
function_name=$1
binary_name=$2
# Get the function memory offset and length
function_entry=`objdump -t $binary_name | grep -P "$function_name([^@]|$)"`
output=$(echo $function_entry | sed -En -e 's/^(\w*)(\s*[.[:alnum:]]*){3}\s*(\w*).*$/0x\1 0x\3/p')
read begin length <<<$output
end=$(( begin + length ))
# get the function file offset
code_offset=$(readelf -l a.out | grep LOAD | head -n 1 | sed -En -e 's/^\s*LOAD\s*\w*\s*(\w*).*$/\1/p')
file_begin=$(( begin - code_offset ))
echo "Dissembled Output"
objdump -d --start-address=$begin --stop-address=$end $binary_name | tail -n +7
echo ""
echo "C Output"
xxd -i -s $file_begin -l $length $binary_name
When used on an example piece of code
// main.c
int intFunc(void) {
return 42;
}
int main(void) {
int ret_val;
ret_val = intFunc();
return ret_val;
}
We get the following output for “intFunc” and “main” (when compiled to a.out by g++)
$ gcc main.c
$ ./print_function_binary intFunc a.out
Dissembled Output
000000000040050d <_Z7intFuncif>:
40050d: 55 push %rbp
40050e: 48 89 e5 mov %rsp,%rbp
400511: 89 7d fc mov %edi,-0x4(%rbp)
400514: f3 0f 11 45 f8 movss %xmm0,-0x8(%rbp)
400519: 8b 45 fc mov -0x4(%rbp),%eax
40051c: 5d pop %rbp
40051d: c3 retq
C Output
unsigned char a_out[] = {
0x55, 0x48, 0x89, 0xe5, 0x89, 0x7d, 0xfc, 0xf3, 0x0f, 0x11, 0x45, 0xf8,
0x8b, 0x45, 0xfc, 0x5d, 0xc3
};
unsigned int a_out_len = 17;
$
$ ./print_function_binary main a.out
Dissasembled Output
000000000040051e <main>:
40051e: 55 push %rbp
40051f: 48 89 e5 mov %rsp,%rbp
400522: 48 83 ec 10 sub $0x10,%rsp
400526: 0f 57 c0 xorps %xmm0,%xmm0
400529: bf 2a 00 00 00 mov $0x2a,%edi
40052e: e8 da ff ff ff callq 40050d <_Z7intFuncif>
400533: 89 45 fc mov %eax,-0x4(%rbp)
400536: 8b 45 fc mov -0x4(%rbp),%eax
400539: c9 leaveq
40053a: c3 retq
C Output
unsigned char a_out[] = {
0x55, 0x48, 0x89, 0xe5, 0x48, 0x83, 0xec, 0x10, 0x0f, 0x57, 0xc0, 0xbf,
0x2a, 0x00, 0x00, 0x00, 0xe8, 0xda, 0xff, 0xff, 0xff, 0x89, 0x45, 0xfc,
0x8b, 0x45, 0xfc, 0xc9, 0xc3
};
unsigned int a_out_len = 29;