【问题标题】:Writing from text section on text section data从文本部分写入文本部分数据
【发布时间】:2021-10-05 04:06:11
【问题描述】:

我正在尝试将字符串 s1 复制到汇编中的 s2 中,这是我的代码:

global main

main:
  .init:
    ; push r8, r9, r12, rcx

  .strcpy:
    lea r8, [rel s1]
    lea r9, [rel s2]
    mov rcx, 0
    .copy:
    cmp rcx, 7
    je .fini
    xor r12, r12
    mov r12b, [byte r9]
    mov [r8], r12b
    inc r8
    inc r9
    inc rcx
    jmp .copy

  .fini:
    ; pop rcx, r12, r9, r8
    ret

  .data:
    s1 db "coucou"
    s2 db "bonjour"

我得到了第 16 行的段错误 (mov [r8], r12b)。我在gdb的这一行设置了一个断点,寄存器r12很好包含0x62('b'),寄存器r8/r9分别包含s1s2的地址.

我做错了吗?我一开始以为是权限问题,但是在我的真实程序中(这个非常简化),我将写入权限添加到mprotect的文本部分(并检查它是否成功)。

请注意,我知道 .data 标签在文本部分,但我必须这样做。

为了清楚起见,我注释掉了实际推送/弹出操作的简短版本。


编辑:

这是失败的代码,包含更多上下文:

global main

;##############################################################################

; Just some macros to avoid heavy push / pop boilerplates in the code

%macro pushx 1-*
 %rep %0
   push %1
   %rotate 1
 %endrep
%endmacro

%macro popx 1-*
  %rep %0
    %rotate -1
    pop %1
  %endrep
%endmacro

;##############################################################################

main:

.init:
    pushx rdi, rsi, rdx, rax, r10, r11

    mov r10, 0xff   ; base addr of the first page containing the .text section
    mov r11, 0xff   ; len for mrpotects calls

.addrights:
    pushx r10, r11

    mov rdi, r10    ;
    mov rsi, r11    ;
    mov rdx, 7      ; PROT_WRITE | PROT_READ | PROT_EXEC
    mov rax, 10     ; sys_mprotect
    syscall         ;
    cmp rax, 0      ; check for return value
    jl .err         ; infinite loop on error

    popx r10, r11

.matcpy:
    call matcpy
    
.removerights:
    mov rdi, r10    ;
    mov rsi, r11    ;
    mov rdx, 5      ; PROT_EXEC | PROT_READ 
    mov rax, 10     ; sys_mprotect
    syscall

.fini:
    popx rdi, rsi, rdx, rax, r10, r11
    ret

.err:
    jmp $

;##############################################################################

.data:
    
    mat dd  0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, \
            0x00000000, 0x00000000, 0x00000000, 0x00000000, \
            0x00000000, 0x00000000, 0x00000000, 0x00000042, \
            0x00000000, 0x00000000, 0x00000042, 0x00000042

    cpy dd  0, 0, 0, 0 ,\
            0, 0, 0, 0, \
            0, 0, 0, 0, \
            0, 0, 0, 0

;##############################################################################

matcpy:

.init:
    pushx r10, r11, r12, rcx

.code:

    lea r10, [rel mat]
    lea r11, [rel cpy]
    mov rcx, 0
    .copy:
    cmp rcx, 64
    je .fini
    xor r12, r12
    mov r12b, byte [r10]
    mov [r11], r12b
    inc r10
    inc r11
    inc rcx
    jmp .copy

.fini:
    popx r10, r11, r12, rcx
    ret

r10r11 是我在创建段时替换的硬编码值(我正在做一个打包程序并且必须注入代码)。 以下是他们在运行时的内容示例:(在matcpy 调用之前)

r10            0x401000            4198400
r11            0x215               533

这是我的程序的映射:

00400000-00401000 r--p 00000000 00:36 31195213     /mnt/nfs/homes/...
00401000-00402000 rwxp 00001000 00:36 31195213     /mnt/nfs/homes/...
00402000-00403000 r--p 00002000 00:36 31195213     /mnt/nfs/homes/...
00403000-00404000 r--p 00002000 00:36 31195213     /mnt/nfs/homes/...
00404000-00405000 rw-p 00003000 00:36 31195213     /mnt/nfs/homes/...
0c001000-0c002000 r-xp 00005000 00:36 31195213     /mnt/nfs/homes/...

此外,程序不会循环,这意味着rax 不是负数(mprotect 成功)。

请注意,如果我在 .data 部分尝试相同的操作,它会起作用。即使我在代码部分设置了写访问模式,这似乎也是一个权限问题。

【问题讨论】:

  • 感谢您的支持。我知道这是一个标签,但我必须写在文本部分的“数据”上(即使它们被解释为指令而不是真实数据)。
  • 我应该更仔细地阅读:) 好吧,这个简化的程序没有mprotect,所以它失败了,因为.text 是只读的。尝试显示一个包含mprotect 并且仍然失败的不太简化的程序。
  • .text 部分不可写。而是将数据放入.data 部分。为什么你必须这样做?也许有了一些动力,我也许可以为您提出更好的解决方案。
  • 如果您可以调试您的真实程序,只需检查 gdb 中的实际权限即可。好吧,info proc mappings 似乎没有显示它们,因此您需要在外部查看 /proc/pid/mappings
  • 我将在几分钟后发布我的实际程序的简化版本,并检查映射

标签: linux string assembly copy x86-64


【解决方案1】:

是的,又一个愚蠢的错误。

我在运行时为.text 部分添加了写入权限。 但是我注入的代码在另一个部分,使用的数据也是如此。 我刚刚在相应段的程序头的p_flags 字段中添加了一个PF_W 标志,它就像一个魅力。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    相关资源
    最近更新 更多