汇编教程 最终:文件管理与内存管理

目录

文件管理

打开一个现有文件

从文件读取

写入文件

关闭文件

更新文件

内存管理


文件管理

实际上我们已经做过了文件管理了。标准输出标准输入以及标准错误的文件描述符实际上就是文件管理的特殊文件描述符。我们现在只需要强调的是获取文件描述符使用的是open系统调用!返回的文件描述符号会放在寄存器eax里。使用结束文件需要做的是关闭文件。提供关闭的文件描述符即可。

与文件处理相关的系统调用:

%eax 名称 %ebx %ecx %edx
3 sys_read unsigned int char * size_t
4 sys_write unsigned int const char * size_t
5 sys_open const char * int int
6 sys_close unsigned int - -
8 sys_creat const char * int -
19 sys_lseek unsigned int off_t unsigned in

相应的,一些标准的打开流程:

打开一个现有文件

要打开现有文件,请执行以下任务-

  • 将系统调用sys_open()5放入EAX寄存器中。

  • 将文件名放在EBX寄存器中。

  • 将文件访问模式放入ECX寄存器。

  • 将文件权限放入EDX寄存器中。

  • 系统调用在EAX寄存器中返回已创建文件的文件描述符,如果发生错误,则错误代码在EAX寄存器中。

在文件访问模式中,最常用的是:只读(0),仅写(1)和读写(2)。

从文件读取

要从文件读取,请执行以下任务-

  • 将系统调用sys_read()3放入EAX寄存器中。

  • 将文件描述符放入EBX寄存器。

  • 将指针放到ECX寄存器中的输入缓冲区。

  • 将缓冲区大小(即要读取的字节数)放入EDX寄存器中。

  • 系统调用返回在EAX寄存器中读取的字节数,如果发生错误,则错误代码在EAX寄存器中。

写入文件

要写入文件,请执行以下任务-

  • 将系统调用sys_write()编号4放入EAX寄存器中。

  • 将文件描述符放入EBX寄存器。

  • 将指针放到ECX寄存器中的输出缓冲区。

  • 将缓冲区大小(即要写入的字节数)放入EDX寄存器中。

  • 系统调用返回写入EAX寄存器的实际字节数,如果发生错误,则错误代码位于EAX寄存器中。

关闭文件

要关闭文件,请执行以下任务-

  • 将系统调用sys_close()编号6放入EAX寄存器中。

  • 将文件描述符放入EBX寄存器。

  • 发生错误时,系统调用将返回EAX寄存器中的错误代码。

更新文件

要更新文件,请执行以下任务-

  • 将系统调用sys_lseek()编号19放入EAX寄存器中。

  • 将文件描述符放入EBX寄存器。

  • 将偏移值放入ECX寄存器中。

  • 将偏移量的参考位置放入EDX寄存器中。

参考位置可以是:

  • 文件开头-值0

  • 当前位置-值1

  • 文件结尾-值2

发生错误时,系统调用将返回EAX寄存器中的错误代码。

; --------------------------------------------------
;   Program written in 10.25 2024
;   Author:             Charlie chen
;   Functionality:      using files
; --------------------------------------------------
​
; fast use of common value
%define MY_SYS_OPEN     5
%define MY_SYS_CLOSE    6
%define MY_SYS_WRITE    4
%define MY_SYS_READ     3
%define MY_STDOUT       1
​
; print string in a simple way
%macro PRINT_STRING 2
    mov edx, %2
    mov ecx, %1
    mov ebx, MY_STDOUT
    mov eax, MY_SYS_WRITE
    int 0x80
%endmacro
​
section .data
    file_name db "demo.txt"
    file_name_new db "copy.txt"
​
section .bss
    show_msg_from_file resb 20
​
section .text
    global _start
_start:
    ; open file with read only and all access for us
    mov eax, MY_SYS_OPEN
    mov ebx, file_name
    mov ecx, 0
    mov edx, 0777
    int  0x80
​
    ; read
    mov ebx, eax
    mov eax, MY_SYS_READ
    mov ecx, show_msg_from_file
    mov edx, 20
    int 0x80
​
    PRINT_STRING show_msg_from_file, 20
​
    mov ebx, 0
    mov eax, 1
    int 0x80
​
​

内存管理

sys_brk的调用号是45,我们返回的地址放在了ebx当中!而后使用即可!

section .bss
    buffer resb 256   ; 预留256字节的空间
​
section .text
    global _start
​
_start:
    ; 获取当前程序段的末尾地址
    mov eax, 45       ; sys_brk
    xor ebx, ebx     ; 传递NULL以获取当前地址
    int 0x80         ; 调用系统
​
    ; 保存当前地址
    mov ebx, eax
​
    ; 分配256字节
    add ebx, 256
    mov eax, 45       ; sys_brk
    int 0x80         ; 调用系统
​
    ; 这里可以使用ebx地址进行操作
​
    ; 释放内存
    mov eax, 45       ; sys_brk
    mov ebx, eax      ; 传递当前地址
    int 0x80         ; 调用系统
​
    ; 退出程序
    mov eax, 1        ; sys_exit
    xor ebx, ebx      ; 返回值0
    int 0x80

上一篇:【系统设计】从HTTP端点到物理服务器:解决路由挑战的BGP-Anycast-CDN方法


下一篇:frida脚本,自动化寻址JNI方法