可能是一个很初级的问题,但我真的很感兴趣如何使它工作。
我有以下程序集代码(大量灵感来自于rename()示例here):

[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#'

让我解释一下:这个程序调用syscallrename将文件重命名为节中的字符串。数据包含源文件名和目标文件名。
因为我想避免空值,所以我决定在运行时将其改为而不是空值。然而,程序以segfault终止。似乎确实存在重写数据段中的字符的问题。我的问题是-我应该如何处理它并使它发挥作用?我知道这是个初级问题,也许我遗漏了一些非常重要的东西。
谢谢你的建议。
编辑-用于装配和链接的命令
这是给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

拆卸
这是/tmp/a的反汇编
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)

解决方案
调试表明,该程序工作正常,但在没有要重命名的文件时落入segfault。否则我的代码将按预期工作。很抱歉。

最佳答案

在Strace Show下运行probram:

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

结论:
您的问题与重写.data部分无关——rename syscall将按您预期的方式执行。
exit的设置不正确。
要修复它,请将mov al, 0x01更改为mov eax, 0x01

关于linux - Linux NASM-重写存储在.data段中的字符-segfault,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10258521/

10-11 15:41