lldb: call function by address
by admin on Sep.20, 2022, under News
Calling a function by address (vmaddr) in LLDB becomes useful when you don’t have a symbol to the function. Let’s take a look at the following simple example written in C:
#include <stdio.h> char* printText(char* text, int number) { printf("%s: %d\n", text, number); return "ok"; } int addNumbers(int var1, int var2) { return var1 + var2; } int main() { printText("Hello World", 2022); return 0; }
This example program only has 3 functions:
- printText
- addNumbers
- main
Let’s compile and load it into lldb:
clang hello.c -o hello lldb ./hello
In order to execute a function the application must be running so let’s break at main for now and start the program:
(lldb) br set -n main (lldb) r
The program will halt at the breakpoint immediately. From here we may proceed.
Example 1: calling a function by symbol
Let’s call the function printText with some custom arguments:
(lldb) p (void(*)(char*,int))printText("huhu", 2023) huhu: 2023
We told lldb that this is a void (no return value) and that the function has two arguments (char* and int).
Example 2: calling a function by address
Let’s call the function printText again but now we’ll use it’s virtual address instead of the symbol name. Due to Address Space Layout Randomization (ALSR) this address will change whenever we restart the program so we need to find it’s current address first:
(lldb) image lookup -n printText 1 match found in /Users/dan/Desktop/hello: Address: hello[0x0000000100003ef0] (hello.__TEXT.__text + 0) Summary: hello`printText
We found the virtual address: 0x0000000100003ef0. Let’s call it now.
(lldb) p ((void(*)(char*,int))0x0000000100003ef0)("huhu", 2023) huhu: 2023
As you might have noticed we had to wrap the cast prior to calling the function in this example.
Example 3: calling a function and printing its return value
In some cases we might be interested in the return value of a function so let’s print the result of the addNumbers function from the example above:
(lldb) p ((int(*)(int,int))addNumbers)(1330, 7) (int) $46 = 1337
We may proceed similarily to print a char* return value:
(lldb) p ((char*(*)(char*,int))printText)("hi", 1) hi: 1 (char *) $48 = 0x0000000100003fa2 "ok"
That’s it for now folks.