assembly 调用程序集中动态库中的函数?

oxf4rvwz  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(102)

我可能还差得远,但这就是我所做的,我也试图让它从linux到mac的交叉编译工作
我在C中用write,malloc和realloc做了一个hello world之类的事情。我注意到在汇编中它使用了adrp,但我不知道如何使用那个指令。我一直得到一个标签必须是GOT相对错误。我希望我可以使用部分作为标签,但最后写了一个标签,没有帮助。
基本上,write c存根函数使用adrp,然后使用ldr [x16,#24].由于我无法理解adrp,我使用了mov和movk。它似乎做了同样的事情,但当我执行它时,我得到了一个段错误。单步执行lldb时,代码似乎做了我认为的事情,但GOT部分并没有像我想象的那样在运行时被替换。Objdump让我相信我命名的部分是正确的。我不知道是否弄清楚adrp是我需要得到这个工作的全部,或者是否我做的一切都完全错误

.global _main
.align 2

_main:
    mov X0, #1
    adr X1, hello
    mov X2, #13
    mov X16, #4
    svc 0

    mov     x16, 16384
    movk    x16, 0x1, lsl 32
    ldr     x16, [x16, #24]

    #adrp   x16, HowGOTLabel
    #ldr        x16, [x16, #24]
    br      x16

    mov X0, #0
    mov X16, #1
    svc 0

hello: .ascii  "Hello\n"

.section __DATA_CONST,__got
.align 3
HowGOTLabel:
    .word 0
    .word 0x80100000
    .word 1
    .word 0x80100000
    .word 2
    .word 0x80100000
    .word 3
    .word 0x80000000
ndh0cuux

ndh0cuux1#

arm 64上的达尔文强制所有用户区二进制文件使用ASLR,因此您不能将movz/movk用于PC相对地址。
adrp不能工作的原因是它只能引用0x 1000字节对齐的位置。对于更细粒度的目标,您可以使用adr,但您会遇到指令被限制在± 1 MB的问题。对于Linux目标,编译器在这里似乎更宽松,但对于达尔文目标,adr实际上只能用于同一节中的位置,而您试图从__TEXT.__text引用__DATA_CONST.__got
那么,如何解决这个问题呢?您可以使用@PAGE@PAGEOFF

adrp x16, HowGOTLabel@PAGE
add x16, x16, HowGOTLabel@PAGEOFF

如果目标在范围内,您甚至可以在链接时使用一些asm指令将其修复到adr+nop

Lloh0:
    adrp x16, HowGOTLabel@PAGE
Lloh1:
    add x16, x16, HowGOTLabel@PAGEOFF
.loh AdrpAdd Lloh0, Lloh1

如果第二条指令是ldr而不是add.,也可以使用AdrpLdr执行此操作
但是,一旦解决了这个问题,代码中就会出现另外两个问题:
1.你使用br x16,这意味着你不会返回到调用点,函数调用使用blr
1.你实际上没有任何导入吗?不清楚你认为这将如何结束调用库函数,但实际上你可以这样做:

bl _printf

编译器和链接器将处理导入。

相关问题