我不明白为什么您不能直接从堆栈将块转储到磁盘。
从...开始
#include <fcntl.h>
char *block;
int main(void) {
int fd=open("/tmp/myfile", O_WRONLY|O_APPEND|O_CREAT, 0666);
write(fd, block, 0x400000);
close(fd);
}
并继续
gcc -m32 -S b.c
你到达这个 bs 文件
.LC0:
.string "/tmp/myfile"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $438, 8(%esp)
movl $1089, 4(%esp)
movl $.LC0, (%esp) <--- make sure this is the filename string
call open
movl %eax, 28(%esp)
movl block, %eax <--- and this is the address of your buffer
movl $4194304, 8(%esp)
movl %eax, 4(%esp)
movl 28(%esp), %eax
movl %eax, (%esp)
call write
movl 28(%esp), %eax
movl %eax, (%esp)
call close
leave
ret
您只需稍作修改即可将其复制到您的仪器中。(您可能希望保存一些寄存器并在退出时恢复它们)。
或者,使用 gcc -static -m32 bc 和 objdump -d 编译程序生成的可执行文件以找出系统调用是如何实现的,然后用直接系统调用替换库调用。这还有一个额外的好处,即如果您的检测修改了一个完整的可执行文件,您就不必弄乱导入列表。
<push registers you want to save>
mov $438, %edx
mov $1089, %ecx
mov filename, %ebx
mov $0x5, %eax ;5 is system call # for open
call *0x80d66c4 ;this is the system call address pulled from objdump
mov %eax, %esi ;save fd
mov $0x400000, %edx
mov block, %ecx ;your buffer address
mov %eax, %ebx
mov $0x4, %eax ;4 is system call # for write
call *0x80d66c4
mov %esi, %ebx
mov $0x6, eax ;6 is system call # for close
call *0x80d66c4
<pop registers>
这不会进行任何错误检查,但是如果您将文件放在有足够空间的本地硬盘上,您应该没问题。此外,它每次都会附加到文件而不是创建它,因此您必须rm在每次运行之前添加到文件中。