Let’s Hook a Library Function
2015-11-24 15:52
344 查看
If you are a developer, and want to change the way a library function works, this article will give you a basic idea of how to get started — just enough knowledge to be able to experiment with your library functions. All code here is in C, and tested with GCC
on Linux.
According to Wikipedia, “In computer programming,
the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, applications, or other software components, by intercepting function calls or messages or events passed between software components. Code that handles
such intercepted function calls, events or messages is called a hook.”
Intercepting a library call, and calling your own wrapper code, is also called Function Interposition.
Hooking has two benefits:
You don’t have to search for the function definition in the library, such as
the GNU C Library, and
and change it. Seriously, this is a very nasty technical task (at least for me!).
You don’t need to recompile the library’s source code.
Please look at Figures 1 and 2 for a graphical representation of what happens when a library function is hooked.
![](http://www.opensourceforu.efytimes.com/wp-content/uploads/2011/08/figure-1-e1322584503522-590x548.jpg)
Figure 1: Library function
![](http://www.opensourceforu.efytimes.com/wp-content/uploads/2011/08/figure-2-e1322584473979-590x381.jpg)
Figure 2: Library function with hook
Now let’s look at hooking a library function. The simple
10 bytes of memory from the heap, and frees it:
When we compile and run the above program, the output is as shown below:
The next program, called
Compiling and running the above, goes like this:
So, let’s take a closer look at our first hook. The
first is a handle returned by
function interposition.
This tells the dynamic linker to find the next reference to the specified function, not the one that is calling
The second parameter is the symbol name (
the address of the symbol specified as the second parameter. While compiling,
create a position-independent object.
The
else. Our use of it will load
Don’t forget to provide an absolute path to the
And, of course, include
C library, because some extensions may not be available on other non-GNU systems and adding this
increase portability.
The above hook method will not work if you want to wrap
that internally call
Yes, but you can’t use the same hook procedure — check the output if you try that. First, create a shared object
Then compile it with
The following
The functions
defined in
Now try to hook
call itself). The following
to itself, which causes a stack overflow and segmentation fault:
Output:
Here is the code (
Output:
I have already interposed other functions like
etc, so you can intercept any function you want. But there are a few limitations:
Do beware of functions that themselves call
symbol) in the hook.
Ensure that the SUID bit is not set, otherwise you can’t use
Also, internal library function calls are resolved before runtime — say, if some function in
it will never call the hook from a different library.
References
Tutorial: Function Interposition in
Linux by Jay Conrod
Linux man pages:
Dangling
Pointers Avoid them Strictly!
Write
Your Own conio.h for GNU/Linux
CodeSport
Analyse
Your Network Packets with LibPCAP
File
Systems A Semester Project-II, Part-19
Tags: C
program, C
standard library, computer
programming, Dynamic
memory allocation, GCC, glibc, GNU
C Library, heap, hooking, LFY
August 2011, Library
(computing), library
functions, malloc, stdio, stdlib, wrapper
code
on Linux.
According to Wikipedia, “In computer programming,
the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, applications, or other software components, by intercepting function calls or messages or events passed between software components. Code that handles
such intercepted function calls, events or messages is called a hook.”
Intercepting a library call, and calling your own wrapper code, is also called Function Interposition.
Hooking has two benefits:
You don’t have to search for the function definition in the library, such as
libc(
glibcis
the GNU C Library, and
libcis almost half of the size of
glibc)
and change it. Seriously, this is a very nasty technical task (at least for me!).
You don’t need to recompile the library’s source code.
Library functions and system calls
Please look at Figures 1 and 2 for a graphical representation of what happens when a library function is hooked.![](http://www.opensourceforu.efytimes.com/wp-content/uploads/2011/08/figure-1-e1322584503522-590x548.jpg)
Figure 1: Library function
![](http://www.opensourceforu.efytimes.com/wp-content/uploads/2011/08/figure-2-e1322584473979-590x381.jpg)
Figure 2: Library function with hook
Now let’s look at hooking a library function. The simple
prog1.cprogram below just allocates
10 bytes of memory from the heap, and frees it:
prog2.c, is a simple hook for the
malloc()function:
dlsym()function takes two parameters: the
first is a handle returned by
dlopen(). Here, we must use
RTLD_NEXTfor
function interposition.
This tells the dynamic linker to find the next reference to the specified function, not the one that is calling
dlsym().
The second parameter is the symbol name (
malloc, in this case), as a character string.
dlsym()returns
the address of the symbol specified as the second parameter. While compiling,
fPICis used to
create a position-independent object.
The
LD_PRELOADenvironment variable gives the loader a list of libraries to load before anything
else. Our use of it will load
libprog2.soand dynamically link it with the
prog1binary.
Don’t forget to provide an absolute path to the
.so, in
LD_PRELOAD.
And, of course, include
_GNU_SOURCEif you want to use certain extensions while using the GNU
C library, because some extensions may not be available on other non-GNU systems and adding this
#definewill
increase portability.
Can we hook every function with dlsym()?
The above hook method will not work if you want to wrap dlsym()itself, or wrap any library functions
that internally call
dlsym(). So, is there any way to interpose
dlsym()?
Yes, but you can’t use the same hook procedure — check the output if you try that. First, create a shared object
libfile.sofrom
file1.cand
file2.c(below).
Then compile it with
gcc -rdynamic -o dl_prog1 dl_prog1.c -ldl. Yes, the output is obvious:
dl_prog1.cis a simple program to show the functionality of
dlopen()and
dlsym().
The functions
file1()and
file2()are
defined in
file1.cand
file2.c.
dlsym(), and you will get a segmentation fault, due to recursive calls (
dlsym()will
call itself). The following
dl_prog2.cwill be a recursive
dlsym()call
to itself, which causes a stack overflow and segmentation fault:
dl_prog3.c) that successfully interposes
dlsym():
What else can we do?
I have already interposed other functions like getaddrinfo(),
open(),
etc, so you can intercept any function you want. But there are a few limitations:
Do beware of functions that themselves call
dlsym(), when you need to call
__libc_dlsym(handle,
symbol) in the hook.
Ensure that the SUID bit is not set, otherwise you can’t use
LD_PRELOAD.
Also, internal library function calls are resolved before runtime — say, if some function in
libccalls
getaddrinfo()or
malloc(),
it will never call the hook from a different library.
References
Tutorial: Function Interposition in
Linux by Jay Conrod
Linux man pages:
dlopen(),
dlsym(),
dlerror(),
dlclose()
Related Posts:
DanglingPointers Avoid them Strictly!
Write
Your Own conio.h for GNU/Linux
CodeSport
Analyse
Your Network Packets with LibPCAP
File
Systems A Semester Project-II, Part-19
Tags: C
program, C
standard library, computer
programming, Dynamic
memory allocation, GCC, glibc, GNU
C Library, heap, hooking, LFY
August 2011, Library
(computing), library
functions, malloc, stdio, stdlib, wrapper
code
相关文章推荐
- 模型视图变换时,法线向量要乘模型视图矩阵的逆转置矩阵
- Linux内核参数(如kernel.shmmax)及Oracle相关参数调整(如SGA_MAX_SIZE)
- Oracle性能调优
- 大部分人都会做错的经典JS闭包面试题
- idea的debug调试快捷键
- Web移动端Fixed布局的解决方案
- SpringMVC、SpringMVC XML配置(纯XML方式)
- poj2891(线性同余方程组)
- Android 图像处理之Bitmap系列2
- spring hadoop之mapreduce batch
- android ListView详解
- [Nginx] nginx提示:500 Internal Server Error错误的解决方法
- 使用SVN在桌面检出导致桌面图标左下角有加号(问号)
- Java基础--初始化顺序
- vagrant
- ucfirst() 函数
- Oracle 分区表
- 移动开发指南:Android Transition框架介绍
- 信息安全系统设计基础——实验二实验报告
- ASP图片格式与base64数据互转方法