如何测试NASM x64实现的自定义GLIBC共享库?
解决自定义NASM x64共享库测试问题的可行方案
一、修复LD_PRELOAD符号拦截失效问题
核心问题排查与修正
- 确保共享库编译选项正确
- 汇编编译时必须生成位置无关代码(PIC):
nasm -f elf64 -o putchar.o putchar.asm -fPIC - 链接成共享库时,优先用GCC完成(自动补充动态链接必要选项):
gcc -shared -o libmyc.so putchar.o
- 汇编编译时必须生成位置无关代码(PIC):
- 验证符号导出正确性
- 用
nm -D libmyc.so检查输出,确保putchar是全局文本符号(标记为T),若为局部符号(t),需在汇编代码开头添加global putchar声明。
- 用
- 调试时指定断点位置
- GDB启动前先设置环境变量:
set environment LD_PRELOAD /绝对路径/libmyc.so start b libmyc.so:putchar - 若已启动程序,直接指定库的符号断点:
b libmyc.so:putchar,避免命中系统GLIBC的同名符号。
- GDB启动前先设置环境变量:
- 运行时使用绝对路径
- 执行测试程序时,LD_PRELOAD必须指定共享库的绝对路径:
LD_PRELOAD=/path/to/libmyc.so ./test_preload
- 执行测试程序时,LD_PRELOAD必须指定共享库的绝对路径:
二、正确使用-nostdlib编译测试程序
手动处理入口与依赖链接
- 编写合法的_start入口汇编(start.asm)
编译命令:global _start extern main extern exit _start: call main mov rdi, rax ; 将main返回值传递给exit call exitnasm -f elf64 -o start.o start.asm - C测试代码(test.c)声明putchar
int putchar(int c); int main() { putchar('A'); return 0; } - 链接时指定动态链接器与依赖库
- 必须显式指定系统动态链接器,同时链接自定义库:
gcc -nostdlib -o test_nostdlib test.o start.o -L. -lmyc -dynamic-linker /lib64/ld-linux-x86-64.so.2 - 其中
-L.指定当前目录查找库,-lmyc链接自定义的libmyc.so。
- 必须显式指定系统动态链接器,同时链接自定义库:
- 直接运行测试
无需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
相关产品推荐
相关产品推荐

