如何使用x86-64 Linux系统调用附加到文件? [英] How to append to a file using x86-64 Linux system calls?

查看:103
本文介绍了如何使用x86-64 Linux系统调用附加到文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个文件,然后使用系统调用将其打开.

I'm creating a file and then opening it using system calls.

创建:

mov rax, 85
mov rdi, path
mov rsi, 400
syscall

开幕:

mov rax, 2
mov rdi, path
mov rsi, 2 ; I found somewhere that I should use 400 to append
syscall
mov r8, rax ; save the file handle

写作:

mov rax, 1
mov rdi, r8
mov rsi, output
mov rdx, length
syscall

完成这些步骤后,我自然关闭了文件,但是我无法追加文件,并且每次执行这些操作时,它只会重写文件的内容,但是例如,我计算了前n个素数并存储了将它们存储在一些内存中,现在我想在文件中写下这n个素数,但是如果不添加更多行就无法这样做.

After I complete these steps I close the file naturally, however I am unable to append to it and each time I perform these actions it just rewrites the content of the file, but for example I calculated the first n prime numbers and stored them away in some chunk of memory and now I'd like to write those n prime numbers down in the file, but I'm not able to do so without appending more lines.

还有一种方法可以不为rdx中的write指定字符串的长度,而是用/0终止字符串吗?

Also is there a way to not specify the length of the string for write in rdx, but instead have the string be terminated by a /0?

推荐答案

要附加到文件,请使用O_APPEND = 0x400标志作为rsi中的int flags参数.所以您接近了:它的值是十六进制的400,而不是您怀疑的十进制的400.

For appending to a file use the O_APPEND = 0x400 flag as int flags parameter in rsi. So you were close: it's a value of hexadecimal 400 and not decimal 400 as you suspected.

以下是十六进制原始int flags值的列表:

Here is a list of the raw int flags values in hexadecimal:

O_ACCMODE                        = 0x3
O_APPEND                         = 0x400
O_ASYNC                          = 0x2000
O_CLOEXEC                        = 0x80000
O_CREAT                          = 0x40
O_DIRECT                         = 0x4000
O_DIRECTORY                      = 0x10000
O_DSYNC                          = 0x1000
O_EXCL                           = 0x80
O_FSYNC                          = 0x101000
O_LARGEFILE                      = 0x0
O_NDELAY                         = 0x800
O_NOATIME                        = 0x40000
O_NOCTTY                         = 0x100
O_NOFOLLOW                       = 0x20000
O_NONBLOCK                       = 0x800
O_RDONLY                         = 0x0
O_RDWR                           = 0x2
O_RSYNC                          = 0x101000
O_SYNC                           = 0x101000
O_TRUNC                          = 0x200
O_WRONLY                         = 0x1

所以这应该起作用:

mov   rax, 2
lea   rdi, [rel path]
mov   rsi, 0x441        ; O_CREAT| O_WRONLY | O_APPEND
mov   edx, 0q666        ; octal permissions in case O_CREAT has to create it
syscall
mov   r8, rax      ; save the file descriptor

如果文件不存在,我添加了三个值来创建文件;如果文件存在,则以write_only模式打开它.您可以将它们定义为汇编时equ常量,以便实际上可以在源代码中编写mov esi, O_CREAT| O_WRONLY | O_APPEND.

I added the three values to create the file if it doesn't exist or open it in write_only mode if it does exist. You could define them as assemble-time equ constants so you could actually write mov esi, O_CREAT| O_WRONLY | O_APPEND in your source.

此外,请确保在每次包含O_CREAT时都为第三个arg(权限)提供一个值.否则,该文件可能会因其权限(可能包括setuid + exec)而被随机垃圾创建.通常,您传递八进制666(NASM 0q666),然后让用户的umask取消对其他(可选)组的写入权限.

Also, make sure to supply a value for the 3rd arg (permissions) any time you include O_CREAT. Otherwise the file could get created with random garbage for its permissions, including possibly setuid + exec. Normally you pass octal 666 (NASM 0q666) and let the user's umask knock off write permission for other and optionally group.

如果您实际上不希望打开它(如果尚不存在),请省略O_CREAT.然后它将返回-ENOENT.

If you don't actually want open to create it if it doesn't already exist, omit O_CREAT. Then it will return -ENOENT.

还有一种方法不指定rdx中字符串的长度,而是用/0终止字符串吗?

Also is there a way to not specify the length of the string in rdx, but instead have the string be terminated by a /0?

简而言之:No.
创建一个strlen函数,并将结果传递到rdx中.内核系统调用将要在文件描述符上读取/写入的数据作为缓冲区+长度,而仅将路径名作为C隐式长度字符串.

In short: No.
Create a strlen function and pass the result in rdx. Kernel system calls take data to be read/written on file descriptors as buffer + length, only pathnames as C implicit-length strings.

这篇关于如何使用x86-64 Linux系统调用附加到文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆