Binary Output from a C/C++ Function

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;

STM32Cube library – Part 1 Toolchain

This series of posts will hopefully help someone looking to set up and use the STM32Cube libraries provided by st-micro. This first post will cover setting up a development toolchain on a Linux system and the next post will cover making a hello world application.

What is this Cube library anyway?

The Cube library is a HAL (Hardware Abstraction Layer) developed by st-microelectronics to take some of the pain out of development with ARM microcontrollers. Their success in goal is debatable, but it does make porting code from other microcontrollers in their products easier. My main gripe is that it has a large memory footprint, and coming from the very space limited world of 8-bit microcontrollers I find the wastefulness annoying. That being said, I have come to use it as it considerably decreases my development time.

Continue reading “STM32Cube library – Part 1 Toolchain”