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

如何在NASM中获取共享对象文件中函数的内存地址?

在NASM中调用共享库函数(以libm的sqrt为例)

一、共享库函数地址的查找逻辑

共享库的函数地址并非固定值,程序启动时由动态链接器(如ld-linux.so)负责解析加载——因为ASLR(地址空间布局随机化)机制的存在,共享库每次加载的基地址都可能变化,因此无法直接硬编码函数在RAM中的地址,必须通过**PLT(过程链接表)和GOT(全局偏移表)**的间接跳转来获取实际地址。

二、NASM中的实现方式

方式1:依赖工具链自动处理PLT/GOT(推荐)

无需手动编写PLT和GOT段的头结构,直接声明外部函数,链接时指定对应共享库即可,汇编器和链接器会自动生成所需的PLT条目与GOT引用。

示例代码(调用sqrt计算平方根):

; sqrt_demo.asm
section .data
    num     dq      2.0         ; 待计算的数值:sqrt(2.0)
    fmt     db      "sqrt(2.0) = %lf", 0xA, 0

section .text
    extern  sqrt               ; 声明sqrt来自libm库
    extern  printf             ; 声明printf来自libc库
    global  main

main:
    push    rbp
    mov     rbp, rsp

    movsd   xmm0, [num]        ; 浮点数参数放入xmm0(遵循System V AMD64调用约定)
    call    sqrt               ; 调用sqrt,结果存于xmm0

    ; 调用printf输出结果
    mov     rdi, fmt           ; 格式字符串地址放入rdi
    movsd   xmm1, xmm0         ; 将计算结果移至xmm1(printf的第二个浮点参数)
    mov     eax, 1             ; 告知printf有1个浮点参数
    call    printf

    mov     eax, 0             ; 程序返回0
    leave
    ret

编译链接命令:

nasm -f elf64 sqrt_demo.asm -o sqrt_demo.o
gcc sqrt_demo.o -lm -o sqrt_demo  # -lm 选项用于链接libm共享库

方式2:手动编写PLT/GOT段(仅作原理演示)

如果要手动实现符合ELF格式的PLT/GOT结构,以下是64位环境下的简化示例(实际开发完全没必要,工具链会自动完成):

; 手动PLT/GOT示例(原理演示用)
section .plt
    ; sqrt的PLT条目
    plt_sqrt:
        jmp     [GOT_sqrt]     ; 跳转到GOT中存储的实际函数地址
        push    0              ; 重定位索引(由链接器自动填充)
        jmp     plt_resolve    ; 跳转到动态链接器的地址解析函数

section .got
    GOT_sqrt: dq plt_sqrt      ; 初始指向PLT自身,等待动态链接器更新为实际地址

section .text
    global main
    extern _GLOBAL_OFFSET_TABLE_

main:
    push    rbp
    mov     rbp, rsp
    sub     rsp, 8

    movsd   xmm0, [rel num]    ; 加载待计算数值
    call    plt_sqrt           ; 调用PLT中的sqrt条目

    ; 后续输出逻辑同方式1...

section .data
    num dq 2.0

三、能否直接获取sqrt在RAM中的地址?

不行,原因有二:

  • ASLR机制:现代系统默认启用ASLR,每次程序运行时libm的加载基地址都会随机变化,sqrt的RAM地址也会随之改变。
  • 版本兼容性:即使关闭ASLR,不同系统、不同版本的libm库中,sqrt相对于库基地址的偏移也可能不同,硬编码地址会导致程序在其他环境下无法运行。

正确的做法始终是通过PLT/GOT机制,让动态链接器在程序启动时自动解析函数的实际地址。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:22:45