You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试NASM x64实现的自定义GLIBC共享库?

解决自定义NASM x64共享库测试问题的可行方案

一、修复LD_PRELOAD符号拦截失效问题

核心问题排查与修正

  1. 确保共享库编译选项正确
    • 汇编编译时必须生成位置无关代码(PIC):
      nasm -f elf64 -o putchar.o putchar.asm -fPIC
      
    • 链接成共享库时,优先用GCC完成(自动补充动态链接必要选项):
      gcc -shared -o libmyc.so putchar.o
      
  2. 验证符号导出正确性
    • 用nm -D libmyc.so检查输出,确保putchar是全局文本符号(标记为T),若为局部符号(t),需在汇编代码开头添加global putchar声明。
  3. 调试时指定断点位置
    • GDB启动前先设置环境变量:
      set environment LD_PRELOAD /绝对路径/libmyc.so
      start
      b libmyc.so:putchar
      
    • 若已启动程序,直接指定库的符号断点:b libmyc.so:putchar,避免命中系统GLIBC的同名符号。
  4. 运行时使用绝对路径
    • 执行测试程序时,LD_PRELOAD必须指定共享库的绝对路径:
      LD_PRELOAD=/path/to/libmyc.so ./test_preload
      

二、正确使用-nostdlib编译测试程序

手动处理入口与依赖链接

  1. 编写合法的_start入口汇编(start.asm)
    global _start
    extern main
    extern exit
    
    _start:
        call main
        mov rdi, rax  ; 将main返回值传递给exit
        call exit
    
    编译命令:nasm -f elf64 -o start.o start.asm
  2. C测试代码(test.c)声明putchar
    int putchar(int c);
    
    int main() {
        putchar('A');
        return 0;
    }
    
  3. 链接时指定动态链接器与依赖库
    • 必须显式指定系统动态链接器,同时链接自定义库:
      gcc -nostdlib -o test_nostdlib test.o start.o -L. -lmyc -dynamic-linker /lib64/ld-linux-x86-64.so.2
      
    • 其中-L.指定当前目录查找库,-lmyc链接自定义的libmyc.so。
  4. 直接运行测试
    无需LD_PRELOAD,直接执行./test_nostdlib即可,GDB断点直接打putchar会命中自定义实现。

三、优化后的Makefile示例

CC = gcc
NASM = nasm
CFLAGS = -Wall
NASMFLAGS = -f elf64 -fPIC

all: libmyc.so test_preload test_nostdlib

# 编译自定义共享库
libmyc.so: putchar.o
	$(CC) -shared -o $@ $^

putchar.o: putchar.asm
	$(NASM) $(NASMFLAGS) -o $@ $<

# LD_PRELOAD测试版本
test_preload: test.c
	$(CC) $(CFLAGS) -o $@ $<

# -nostdlib测试版本
test_nostdlib: test.o start.o
	$(CC) -nostdlib -o $@ $^ -L. -lmyc -dynamic-linker /lib64/ld-linux-x86-64.so.2

test.o: test.c
	$(CC) $(CFLAGS) -c -o $@ $<

start.o: start.asm
	$(NASM) -f elf64 -o $@ $<

clean:
	rm -f *.o libmyc.so test_preload test_nostdlib

四、额外排查技巧

  • 用ldd ./test_preload查看依赖列表,确认自定义库是否被加载(LD_PRELOAD模式下会排在最前面)。
  • 用objdump -d libmyc.so反汇编共享库,验证putchar的实现代码是否正确。
  • GDB中执行info sharedlibrary查看已加载的共享库,确认自定义库已加载后,用disassemble putchar确认断点命中的代码来源。

内容的提问来源于stack exchange,提问作者Nayrosk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:04:53