hook机制

标准介绍:

hook直意为钩子又叫做回调函数,在程序中设置hook,用来在 malloc , realloc , free 的时候,对其进行检查,可以看到对应的函数调用后的地址是什么

本质

hook本质上就是一个函数指针,可以指向不同的函数,从而自由地完成不同的功能

我们编写一个函数的时候,可能还不知道它会完成什么功能,这时候留下函数指针作为接口,可以挂上不同的函数完成不同的功能

究竟执行什么功能由钩子函数的编写者完成,钩子的出现补全了程序模块化的思想

libc中的hook

ibc中最常见,也是堆利用中最常见的两种hook:malloc_hook,free_hook

接下来以“malloc_hook”为例,感受一下hook机制的作用(现在知道流程是怎么样的就行了。深入的以后再研究)

全局定义

ptmalloc(glibc的堆管理器) 定义了一个全局钩子 malloc_hook,这个钩子被赋值为 malloc_hook_ini 函数(被挂上了)

void *weak_variable (*__malloc_hook)/* 函数指针同样需要返回值和参数列表,但是函数名字前要用"*"标识这段内存是函数指针*/
    (size_t __size, const void *) = malloc_hook_ini;/* malloc_hook_ini(自定义的)应该是一个符合上述参数和返回值类型的函数,这样才能被挂过去 */

malloc_hook_ini的定义

static void *
malloc_hook_ini (size_t sz, const void *caller)
{
  __malloc_hook = NULL; /* 把 malloc_hook 置空 */
  ptmalloc_init ();  /* 对整个ptmalloc框架进行初始化的函数 */
  return __libc_malloc (sz);  /* 返回一个指向分配内存块的指针 */
}

检查函数

void * CheckFunction(size_t size, void * caller)/* caller:表示用malloc申请空间的“可写入地址”( 一般是data段,也可以是fd&bk 所在处) */

调用流程

第一次调用:

malloc-->__libc_malloc-->__malloc_hook-->malloc_hook_ini-->__libc_malloc-->_int_malloc

后续调用:

malloc-->__libc_malloc-->_int_malloc

被置空的malloc_hook最后会指向那个检查函数,使用malloc的时候返回的其实是那块“可写入地址”

hook劫持

hook劫持的基本操作就是:在hook的地址中写入shellcode的地址,但是hook一般在libc中,所以可以把hook的地址写在某个固定地址上,然后在这个地址中写入shellcode

泄露模板:

def heaplibc(libc_base,libc):
    free_hook = libc_base + libc.sym['__free_hook']
    malloc_hook = libc_base + libc.sym['__malloc_hook']
    return free_hook,malloc_hook

还可以用“main_arena”来定位“malloc_hook”(暂时没有接触到)

参考:https://ywhkkx.github.io/tags/hook/