如何调试运行时库插入的进程? [英] How can I debug runtime library interpositioned process?

查看:84
本文介绍了如何调试运行时库插入的进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在正在研究在Ubuntu 18.04中使用C进行库插入的情况,并且正在测试两个简单的代码来包装 strlen : mystrlen.c, mystrlenTest。 c。

I'm now studying library interpositioning with C in Ubuntu 18.04, and I'm testing two simple codes to wrap strlen: "mystrlen.c", "mystrlenTest.c".

这是我写的代码:mystrlen.c

Here is the code I wrote: mystrlen.c

#ifdef RUNTIME
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>

/* strlen wrapper function */
size_t strlen(const char *str) {
    size_t (*strlenp)(const char *) = NULL;
    printf("%s\n", *str);

    strlenp = dlsym(RTLD_NEXT, "strlen");   // Get address of libc strlen
    printf("length: %ld\n", strlenp(str));

    return strlenp(str);
}
#endif

和mystrlenTest.c:

And mystrlenTest.c:

#include <stdio.h>
#include <string.h>

int main(void) {
    char testString[] = "Hello World!";
    printf("length of the testString: %ld\n", strlen(testString));

    return 0;
}

我试图在运行时使用以下命令进行注入:

I tried to inject during runtime with the command below:

$ gcc -DRUNTIME -shared -fpic -g -o mystrlen.so mystrlen.c -ldl
$ gcc -g -o mystrlenTest mystrlenTest.c
$ LD_PRELOAD=./mystrlen.so ./mystrlenTest

这是我得到的全部信息:分段错误(核心已转储)
所以我尝试了 dmesg 命令来查找发生了什么,结果如下所示:

And this is all I get: Segmentation fault (core dumped) So I tried dmesg command to find out what happened, and the result was like below:

[842291.658267] mystrlenTest[51446]: segfault at 48 ip 00007f7b918e35a1 sp 00007ffdd7158c88 error 4 in libc-2.27.so[7f7b91755000+1e7000]
[842291.658272] Code: 2e 0f 1f 84 00 00 00 00 00 31 c0 c5 f8 77 c3 66 2e 0f 1f 84 00 00 00 00 00 89 f9 48 89 fa c5 f9 ef c0 83 e1 3f 83 f9 20 77 1f <c5> fd 74 0f c5 fd d7 c1 85 c0 0f 85 df 00 00 00 48 83 c7 20 83 e1

我想问的是,如何使用 gdb 进行调试?
还是有其他调试方法?
我知道如何使用gdb调试单个程序,但是调试运行时库插入的进程时遇到了困难。如果我能找到 00007f7b918e35a1 中的内容,那将是很大的帮助。

What I wanted to ask was, how can I debug this with gdb? Or is there any other way to debug it? I know how to debug a single program with gdb, but I'm having difficulty with debuging the runtime library interpositioned process. If I can find out what is in 00007f7b918e35a1, it would be a great help.

推荐答案

调用gdb时,可以传递要设置的环境变量,例如:

When invoking gdb, you can pass the environment variables you want to set, like:

gdb --args env LD_PRELOAD=./mystrlen.so ./mystrlenTest

现在您可以像往常一样使用get backtrace gdb。

Now you can use get the backtrace as usual in gdb.

您还可以使用系统调用来打印调试消息,例如:

You can also use system calls to print debug messages, such as:

write(2, "message", sizeof "message" - 1);

根本不调用任何库函数。 (尽管大多数系统调用在glibc中都使用了薄包装器,但这与它的用户无关。)
在您的特定情况下,可能的问题是 printf 本身称为 strlen ,如Andrew Henle所述,

Which doesn't call any of the library functions at all. (Although, most system calls have thin wrappers in glibc,this is largely irrelevant for its users). In your specific case, the likely issue is that printf itself calls strlen as noted by Andrew Henle, thus resulting in infinite recursion.

插入时,您需要注意从插入函数中调用的内容,并始终问自己是否会从插入函数内部进行任何调用回调相同的插入函数或任何其他插入函数,并采取必要的步骤来处理此类情况。例如,许多标准函数可能通过 malloc 族函数在内部分配内存,并且如果您插入 malloc 和朋友,这可能会导致意外的问题。

When interposing, you need to careful about what you call from the interposed functions and always ask yourself whether any calls from inside the interposed function might result in call back to the same interposed function or any other interposed function(s) and take necessary steps to handle such cases. For example, a lot of standard functions might internally allocate memory via malloc family functions and if you're interposing malloc and friends, this could cause unexpected problems.

这篇关于如何调试运行时库插入的进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆