在上一篇文章中,我们已经知道了如何添加一个空白的工具的主程序(一个工具的executable部分),下面将阐述编写一个空白的工具的动态链接库的简单步骤。

注意,一个工具的动态链接库部分将会作为预载的动态链接库先于其它库注入目标进程的地址空间。

创建空白库文件

一个最简单的待注入的库文件可以不包含任何注入相关的内容,例如

// File name: mytool/mt_inject.c

// Do nothing

创建靶程序

但是为了验证是否成功注入,我们可以先包装一个简单的标准库函数int rand()。因此,我们可以先创建一个靶程序(参照了此教程):

// File name: main.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));
    int i = 10;
    while(i--) printf("%d ", rand() % 100);
    putchar('\n');
    return 0;
}

包装靶程序所使用的标准库函数

现在我们的目的是包装int rand(),并在将结果返回给靶程序前打印出来。为实现此目的,我们可以使用Valgrind在pub_tool_redir.h中提供的VG_WRAP_FUNCTION_ZU宏(其它VG_WRAP_FUNCTION_*宏也可以达到目的):

// File name: mytool/mt_inject.c

#include "pub_tool_redir.h"
#include "valgrind.h"
#include <stdio.h>


int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, rand) (void);
int VG_WRAP_FUNCTION_ZU(VG_Z_LIBC_SONAME, rand) (void) {
    OrigFn fn;
    Word result;
    VALGRIND_GET_ORIG_FN(fn);
    CALL_FN_W_v(result, fn);
    printf("\nInvocation of `int rand()` detected, returning result %d\n", (int) result);
    return (int) result;
}

注意:其它宏(如VALGRIND_GET_ORIG_FN等)需要引入valgrind.h

查看结果

编译靶程序和我们的工具后,先单独运行靶程序(设其文件名为main),一个示例结果如下:

18 79 12 57 90 8 97 82 86 7

然后使用Valgrind,指定工具为我们的自定义工具,再次运行靶程序:

valgrind --tool=mytool ./main

一个示例结果如下:

==5070== Mytool, Valgrind playground
==5070== Copyright (C) 2019, by Untitled.
==5070== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5070== Command: ./main
==5070==

Invocation of `int rand()` detected, returning result 391370024
24
Invocation of `int rand()` detected, returning result 2088978895
95
Invocation of `int rand()` detected, returning result 1444974895
95
Invocation of `int rand()` detected, returning result 831153904
4
Invocation of `int rand()` detected, returning result 1130098802
2
Invocation of `int rand()` detected, returning result 140421164
64
Invocation of `int rand()` detected, returning result 303337835
35
Invocation of `int rand()` detected, returning result 1008928109
9
Invocation of `int rand()` detected, returning result 843439436
36
Invocation of `int rand()` detected, returning result 987839948
48
==5070==

可以看到我们的工具的动态链接库已经成功注入,并且成功包装了libc.so*中的int rand()函数。



# valgrind   # valgrind tool   # inject   # 注入