簡體   English   中英

使用氣體,如何獲得特定標簽的偏移量?

[英]Using gas, how can I get the offset to a particular label?

我正在使用pwnlib編寫一個小的Shellcode來應對挑戰。 我的shellcode需要修改自身才能通過應用程序過濾器。 我首先用nasm編寫它,然后做了類似的事情:

        sub        edx, edx
        mov        dl, 0x82
        add        al, do_mov_rdi_rax
        sub        dword [rax], edx
        mov        dh, 0x82
        add        al, do_syscall - do_mov_rdi_rax
        sub        dword [rax], edx
        shr        edi, 31

    do_mov_rdi_rax:
        ; mov    rsi, rax
        ; (with 0x82 added to first byte to pass validation)
        db         0xca, 0x89, 0xc6
        sub        eax, eax

    do_syscall:
        ; syscall
        ; (with 0x82 added to both bytes to pass validation)
        db         0x91, 0x87

但是,Pwnlib使用gas ,因此我的匯編代碼必須符合其語法。 除了顯而易見的( //而不是; ,. .byte而不是db ),我還有一個問題: nasm高興地將我的標簽轉換為整數(用於add al, do_mov_rdi_raxadd al, do_syscall - do_mov_rdi_rax ), gas一直告訴我它不能代表尋址類型BFD_RELOC_8或類似的東西(我以某種方式最終以法文版gas ,抱歉缺少錯誤消息)。

如何獲得標簽的整數地址? 我的shellcode基於地址0(並通過.org 0x0告知gas)。

由於標簽不起作用,我翻閱了gas文檔,發現也可以創建表達式符號,並且可以使用. 獲取該位置的地址。 事實證明,對於Mach-O輸出格式, gas將接受以下格式:

.set main, .
    sub     edx, edx
    mov     dl, 0x82
    add     al, do_mov_rdi_rax - main
    sub     dword [rax], edx
    mov     dh, 0x82
    add     al, do_syscall - do_mov_rdi_rax
    sub     dword [rax], edx
    shr     edi, 31

.set do_mov_rdi_rax, .
    // mov  rsi, rax
    // (with 0x82 added to first byte to pass validation)
    .byte   0xca, 0x89, 0xc6
    sub     eax, eax

.set do_syscall, .
    // syscall
    // (with 0x82 added to both bytes to pass validation)
    .byte   0x91, 0x87

在第一個添加項上,僅使用do_mov_rdi_rax是行不通的,但是使用它和main之間的差異可以完美地工作。 (但是,用字面的零替換main不會這樣做。)

但是,它還有其他問題:對sub dword [rax], edx似乎缺少sub dword [rax], edx 在Mac上使用gas 2.25時,將其組裝為sub dword [rax+4], edx ,這是非常錯誤的。 Xcode附帶的as版本拒絕匯編,理由是絕對使用32位尋址。 Debian的gas 2.24.90也拒絕匯編它,因為某種程度上會存在太多的內存引用。 因為這都是不正確的,所以我會堅持使用由nasm組裝的shellcode二進制版本,而不是使用pwnlib的asm進行編譯。

您正在執行的操作非常不尋常,並且似乎需要重新定位,而OS X不支持使用Mach-O對象格式。 問題不是您要嘗試將標簽用作整數,而是要嘗試將標簽用作8位整數。 這在實踐中不是很有用,而編譯器則永遠不會做。

如果您確實只想將符號地址的低8位(或兩個符號之間的差)加到RAX的低8位,您將首先使用標簽作為32位整數。

例如,您可以先將其移動到另一個32位寄存器中:

    mov $do_mov_rdi_rax, %ecx
    add %cl, %al
...
    mov $(do_syscall - do_mov_rdi_rax), %ecx
    add %cl, %al

如果沒有免費的寄存器,則從內存中加載它:

    add indirect_do_mov_rdi_rax, %al
...
    add indirect_difference, %al

indirect_do_mov_rdi_rax:
    .long   do_mov_rdi_rax

indirect_difference:
    .long   do_syscall - do_mov_rdi_rax

如果不是真的想使用8位算術並且想要使用地址的所有64位進行加法運算,則可以使用64位寄存器RAX代替:

    add $do_mov_rdi_rax, %rax
...
    add $(do_syscall - do_mov_rdi_rax), %rax

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM