【问题标题】:Linux NASM - rewriting character stored in .data segment - segfault [closed]Linux NASM - 重写存储在.data段中的字符 - segfault [关闭]
【发布时间】:2012-05-02 18:21:05
【问题描述】:

可能是一个非常初学者的问题,但我真的很想知道如何让它发挥作用。

我有以下汇编代码(灵感来自here,rename() 示例):

[SECTION .text]
global _start

_start:
    mov             esi, msg        ; saves pointer to string to ESI
    xor             eax, eax
    mov byte        [esi+6], al     ; terminates first string with NULL char
    mov byte        [esi+13], al    ; terminates second string with NULL char
    mov byte        al, 38          ; syscall number (38 = rename)
    lea             ebx, [esi]      ; put the adress of /tmp/a in EBX
    lea             ecx, [esi+7]    ; put the adress of /tmp/b in ECX
    int             0x80            ; syscall execution

    mov             al, 0x01        ; prepare to exit!
    xor             ebx, ebx
    int             0x80            ; exit!

[SECTION .data]
msg:            db '/tmp/a#/tmp/b#'

让我解释一下:这个程序调用系统调用rename将文件/tmp/a重命名为/tmp/b .data部分中的字符串包含源文件的名称和目标文件的名称。

因为我想避免 NULL,所以我决定用 # 代替 NULL 并在运行时更改它。但是,程序以 SEGFAULT 终止。重写 .data 段中的 # 字符似乎确实存在问题。我的问题是 - 我应该如何处理它并让它发挥作用?我知道这是一个初学者的问题,也许我错过了一些非常重要的东西。

感谢您的建议。

EDIT - 用于组装和链接的命令

这是为 NASM 准备的:

nasm -f elf -o ThisWorks.o ThisWorks.asm

这用于链接器(请注意,我将其构建为 32 位,虽然我有 64 位 Phenom II)。

ld -melf_i386 -o ThisWorks.aout ThisWorks.o

比我执行它:

./ThisWorks.aout

结果是:

Segmentation fault

反汇编

这是objdump -D ThisWorks.aout的反汇编

ThisWorks.aout:     file format elf32-i386


Disassembly of section .text:

08048080 <_start>:
 8048080:   be 9c 90 04 08          mov    $0x804909c,%esi
 8048085:   31 c0                   xor    %eax,%eax
 8048087:   88 46 06                mov    %al,0x6(%esi)
 804808a:   88 46 0d                mov    %al,0xd(%esi)
 804808d:   b0 26                   mov    $0x26,%al
 804808f:   8d 1e                   lea    (%esi),%ebx
 8048091:   8d 4e 07                lea    0x7(%esi),%ecx
 8048094:   cd 80                   int    $0x80
 8048096:   b0 01                   mov    $0x1,%al
 8048098:   31 db                   xor    %ebx,%ebx
 804809a:   cd 80                   int    $0x80

Disassembly of section .data:

0804909c <msg>:
 804909c:   2f                      das    
 804909d:   74 6d                   je     804910c <_end+0x60>
 804909f:   70 2f                   jo     80490d0 <_end+0x24>
 80490a1:   61                      popa   
 80490a2:   23 2f                   and    (%edi),%ebp
 80490a4:   74 6d                   je     8049113 <_end+0x67>
 80490a6:   70 2f                   jo     80490d7 <_end+0x2b>
 80490a8:   62 23                   bound  %esp,(%ebx)

解决方案

调试显示,该程序运行正常,但在没有文件可重命名时陷入段错误。否则我的代码按预期工作。很抱歉。

【问题讨论】:

  • 你试过用gdb运行它,看看是哪条指令导致了段错误?
  • 用什么东西砸我的头。 Debuggin 显示,段错误发生在程序结束时,经过我的小研究后​​发现,文件 /tmp/a 丢失,这导致了 SEGFAULT。这意味着,汇编代码没问题。很抱歉。

标签: linux assembly segmentation-fault nasm


【解决方案1】:

假设您正在编写 shellcode:您无法从您的 shellcode 访问 .data 段中的任何内容,因为您的 shellcode 将在被利用的软件的过程中执行,并且那里不会有数据段(或者更准确地说,只有被利用进程的数据段)。 Shellcode 没有分段结构,它通常只是字节的线性缓冲区。在任何情况下,您都必须将数据放在 shellcode 的末尾。

【讨论】:

  • 是的,这是理解shellcode的准备。但是,我首先想了解汇编代码是如何独立执行的,因此我很好奇如何修复我的代码以使其正常工作。
  • 你能告诉我们你是如何组装和执行你的代码的吗?
  • 当然,我已经更新了问题。
【解决方案2】:

在 strace show 下运行你的程序:

execve("./a.out", ["./a.out"], [/* 67 vars */]) = 0
[ Process PID=7054 runs in 32 bit mode. ]
rename("/tmp/a", "/tmp/b")              = -1 ENOENT (No such file or directory)
syscall_4294967041(0, 0x80490a3, 0, 0x804909c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) = -1 (errno 38)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault

结论:

  1. 您的问题与重写 .data 部分无关 -- rename 系统调用按您的预期执行。
  2. exit 的设置不正确。

    要修复它,请将mov al, 0x01 更改为mov eax, 0x01

【讨论】:

  • 好发现!如果重命名在eax 中返回 0,则该错误不会被注意到并且代码将起作用,而当它在 eax 中返回 -1 时,因为文件不存在,仅设置 al 将导致 eax 包含 0xFFFFFF01这是4294967041,strace 输出中的系统调用号。
猜你喜欢
  • 2012-03-14
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多