I’ve written a shared object that modifies the arguments to FreeType’s FT_Load_Glyph
and FT_Render_Glyph
functions, currently by interposing it with LD_PRELOAD
and dlsym
.
This works fine, but I’m curious to know whether or not there’s a way to make these changes:
LD_PRELOAD
to all programs on the host;The only two “solutions” that I’ve been able to come up with are ugly hacks:
LD_PRELOAD
all programs, all of the time, which seems slow and fragile; orlibfreetype.so.6.12.3
to libxxxxtype.so.6.12.3
; then
libxxxxtype.so.6.12.3
to libxxxxtype.so.6
;libxxxxtype.so.6
; andlibfreetype.so.6.999
.I’d essentially like to transparently patch a couple of functions in a shared object, while letting the remaining functions through, without necessarily having access to the source of the shared object or the programs that use it, but if I make a fake shared object with the soname libfreetype.so.6
, I can’t see a clean way to link it to (or dlopen
) the real libfreetype.so.6
.
This is my first real experiment with shared libraries, so please bear with me if this question makes some incorrect assumptions, or just makes no sense.
Can you try to use uprobes
to dynamically steal control from some functions?
Check http://www.brendangregg.com/blog/2015-06-28/linux-ftrace-uprobe.html
uprobes: user-level dynamic tracing, which was added to Linux 3.5 and improved in Linux 3.14. It lets you trace user-level functions; for example, the return of the readline() function from all running bash shells, with the returned string:
# ./uprobe 'r:bash:readline +0($retval):string'
Tracing uprobe readline (r:readline /bin/bash:0x8db60 +0($retval):string). Ctrl-C to end.
bash-11886 [003] d... 19601837.001935: readline: (0x41e876 <- 0x48db60) arg1="ls -l"
bash-11886 [002] d... 19601851.008409: readline: (0x41e876 <- 0x48db60) arg1="echo "hello world""
bash-11886 [002] d... 19601854.099730: readline: (0x41e876 <- 0x48db60) arg1="df -h"
bash-11886 [002] d... 19601858.805740: readline: (0x41e876 <- 0x48db60) arg1="cd .."
bash-11886 [003] d... 19601898.378753: readline: (0x41e876 <- 0x48db60) arg1="foo bar"
^C
Ending tracing...
And http://www.brendangregg.com/blog/2015-07-03/hacking-linux-usdt-ftrace.html
There were also other solutions of tracing user-space functions, like ftrace, systemtap, dtrace, lttng. Some of them need recompilation and defining tracing points statically in the program; and uprobes are "user-level dynamic tracing".
Some links about uprobes:
There is handler
of uprobes which has pt_regs
. As said in last link: "Uprobes thus implements a mechanism by which a kernel function can be invoked whenever a process executes a specific instruction location." and it suggests that uprobes may replace some ptrace/gdb based solutions; so there is a possibility to change execution of any program hitting active uprobe, by changing its eip/rip (PC) register.
You may try some other dynamic instrumentation tools, like pin
or dyninst
; but they are designed for per-process usage.