二进制方式修改libpthread.so中的pthread_attr_setstacksize最小限制

       最近有个mips平台的嵌入式linux项目,官方提供了工具链,但发现他们所提供的libpthread.so库对线程的最小栈空间设置的是128K,造成程序运行时显示虚拟内存占用很高,虽然没太大影响,但是对我这样有洁癖的人感觉很不爽,所以我想把它改小,重新编译glibc感觉麻烦,好像也不安全,所以就想着直接修改库的二进制文件,下面是修改过程:

先写个测试代码如下:

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

static void *func(void *arg)  
{ 
    printf("I am a thread\n");
    return NULL;
}

int main(int argc,char *argv[])
{
    pthread_t thread_id;
    int ret ,stacksize = 20480; 
    pthread_attr_t attr;
    
    if(argc > 1){
        stacksize = atoi(argv[1]);
    }
    
    printf("stacksize = %d\n",stacksize);
    
    ret = pthread_attr_init(&attr); 
    if (ret != 0){
        printf("pthread_attr_init fail\n");
        return -1;
    }
    ret = pthread_attr_setstacksize(&attr, stacksize);
    if(ret != 0){
        printf("pthread_attr_setstacksize fail\n");
        return -1;
    }
    ret = pthread_create (&thread_id, &attr, &func, NULL);
    if(ret != 0){
        printf("pthread_create fail\n");
        return -1;
    }
    ret = pthread_attr_destroy(&attr);
    if(ret != 0){
        printf("pthread_attr_destroy fail\n");
        return -1;
    }
    
    pthread_join(thread_id, NULL);
    
    printf("exit\n");
}

编译测试程序:

注意,建议使用-fno-omit-frame-pointer参数,不然gdb可能无法进入函数pthread_attr_setstacksize

mips-linux-gnu-gcc -g -EL -mips32r2 -fno-omit-frame-pointer -o thread_test thread_test.c -I/opt/mips-linux-gnu/libc/usr/include -L/opt/target/lib -lpthread

GDB调试测试程序:


gdb用到的几条命令:

target remote 192.168.1.125:1234

#连接远程目标(gdbserver)

set solib-search-path /buildroot-6.6.1.6/output/target/lib

#设置动态库路径,方便gdb加载调试符号

set heuristic-fence-post 100000

#不设置这个单步的时候可能停不到函数上,我理解的大概的原因就是函数的标准入口格式被优化掉了,gdb不能简单识别了,它要找找看。

b pthread_attr_setstacksize

#这个大家都懂,设置断点

disassemble

#反汇编当前段代码

x /5fx 0x77fabce0

#显示内存中的内容,我用它看当前的指令字节。


当断点停下来了,用disassemble反汇编查看代码和查看寄存器内容

lui     v0,0x2:这条指令是把立即数0x2放到v0的高16位,也就是0x20000,就是libpthread-2.18.so设置的最小线程栈128kBtye。

sltu    v0,a1,v0:这条指令是比较我们设置的堆栈大小和0x20000进行比较,如果我们传入的值大于这个值,程序继续运行,反之返回错误。我们可以看到a1中是我们代码中传入的0x5000。

接下来我们使用x /5fx 0x77fabce0看看lui v0,0x2的指令码:

我们看到的是0x3c020002,3c02是指令码,0002是立即数。

好了,现在我们要修改这条指令了,但是我发现个问题,如果只修改后面的立即数的话,我只有两个选择,一个是改成1,一个是改成0,改1的话限制大小变成64K,还是有点大,如果是0的话完全失去了限制,这都是我不想样要的。所有要想办法把整条指令改掉,但查mips指令手册太麻烦,直接用代码测试吧 。

int main(int argc,char *argv[])
{
    int a = 0;
    a = 0x2800;
    printf("I am a thread %d\n",a);
    return 0;
}

用mips-linux-gnu-gcc编译上面的代码,然后使用mips-linux-gnu-objdump -d查看


24022800     li    v0,10240

这句就是我们想要的,把立即数10240传给v0。

现在我们用UE打开libpthread-2.18.so文件,然后根据前面x /5fx 0x77fabce0看到的内容进行搜索和替换修改,注意大小端的问题,这样就搞定了。


把0200023c替换成00280224,完美收工。

谢谢观赏!



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值