汇编代码中的Syscalls

时间:2015-03-06 21:05:44

标签: assembly system-calls

我写了一个小程序来理解系统调用。在下文中,您将找到creat(...)和write(...)。应该很容易。所以,正如你可能猜到的,程序所做的是先创建一个文件,然后用文本填充它。它也应该是位置无关的代码。因此,我使用“jump-call-pop”组合来编写它。

所以看起来像:

   Section  .text

             global  _start

_start:
        jmp short   GoToFileName

fileCreation:
        pop       esi              ; address of file name
        xor       eax, eax         ; clear eax
        mov byte  [esi+13], al     ; terminate file name string with NULL
        mov       cx, 0x309        ; create file with all possible permissions
        mov       ebx, esi         ; ebx gets address of file name
        mov       al, 0x8          ; al gets syscall number 8 of creat()
        int       0x80             ; create the file
        mov       edx, eax         ; write resulting file descriptor in edx
       jmp short TextInput

copyProcess:
       pop       esi              ; address of input string
       xor       eax, eax         ; clear eax
       mov byte  [esi+23], al     ; terminate input string with NULL
       mov       dl, 0x17         ; dl gets number of bytes to write
       mov       ecx, esi         ; ecx gets address of input string
       mov       ebx, edx         ; ebx gets file descriptor of created file
       mov       al, 0x4          ; al gets syscall number of write
       int       0x80             ; write that input string


GoToFileName:
     call     fileCreation
     db       '/tmp/file.text'

TextInput:
    call     copyProcess
    db       'This the output file'

当我编译它时,链接它然后运行它...没有任何反应/ tmp目录。仅创建文件。但它是空的。 作为比较,我在C中写相同.C代码有效。在/ tmp中,突然创建了一个file.txt。但是使用汇编代码它不起作用。 另一点是以下内容: 当我只接受创建部分(fileCreation)时,组装工作。但是当我将它与写入部分(copyProcess)结合起来时,整体就不起作用了。因此,我认为我的错误在copyProcess部分的某处。但我找不到它。

有人能帮助我吗?

1 个答案:

答案 0 :(得分:3)

你的代码有一些错误:

  1. 您正在破坏 EDX
  2. 中存储的文件描述符
  3. 在x86上,写入 DL NOT 清除 DH ,写入 DX NOT 清除 EDX
  4. 的上半部分。
  5. 文件权限以八进制指定,即基数8.因此,八进制0777为十六进制0x1ff
  6. 通过调用create()代替open(..., O_CREAT),您无法处理文件已存在的情况。
  7. 最好先使用NULL终止文件名字符串,因为文本部分通常是不可写的。我知道你正在尝试编写shellcode,但这一点仍然存在。
  8. 您将错误的缓冲区长度传递给write()
  9. 此代码有效:

    Section  .text
    
                 global  _start
    
    _start:
            jmp short   GoToFileName
    
    open:
            pop       esi              ; address of file name
            mov       edx, 0x1ff       ; 0777
            mov       ecx, 0x41        ; O_CREAT | O_WRONLY
            mov       ebx, esi         ; ebx gets address of file name
            mov       eax, 0x5         ; SYS_open
            int       0x80             
            mov       ebx, eax         ; write resulting file descriptor in EBX
            jmp short TextInput
    
    write:
           pop       esi              ; address of input string
           mov       edx, 20          ; edx gets number of bytes to write
           mov       ecx, esi         ; ecx gets address of input string
           mov       eax, 0x4         ; SYS_write
           int       0x80
    
    exit:
           mov       ebx, 0
           mov       eax, 1
           int       0x80
    
    
    GoToFileName:
         call     open
         db       '/tmp/file.text',00
    
    TextInput:
        call     write
        db       'This the output file'
    

    后续问题

    当我在字符串的末尾添加NULL-terminator时,我是否还要计算NULL?

    答案

    • 您在这里进行两次系统调用:
      • open()采用NULL终止文件名
      • writ()采用字节数组和长度
    • NULL终止仅适用于open()write()不关心NULL终止,因为它只是尝试写 LENGTH 字节。