我正在尝试编写64位shellcode来读取名为“ / proc / flag”的文件。但是,在编译程序集时出现一些随机错误,不知道为什么会发生。
这是我的汇编文件readflag.S
:
.intel_syntax noprefix
.global _start
.type _start, @function
_start:
mov dword [rsp], '/pro' /* build filename on stack */
mov dword [rsp+4], 'c/fl'
push 'ag'
pop rcx
mov [rsp+8], ecx
lea rdi, [rsp] /* rdi now points to filename '/proc/flag' */
xor rsi, rsi /* rsi contains O_RDONLY, the mode with which we'll open the file */
xor rax, rax
inc rax
inc rax /* syscall open = 2 */
syscall
mov rbx, rax /* filehandle of opened file */
lea rsi, [rsp] /* rsi is the buffer to which we'll read the file */
mov rdi, rbx /* rbx was the filehandle */
push byte 0x7f /* read 127 bytes. if we stay below this value, the generated opcode will not contain null bytes */
pop rdx
xor rax, rax /* syscall read = 0 */
syscall
lea rsi, [rsp] /* the contents of the file were on the stack */
xor rdi, rdi
inc rdi /* filehandle; stdout! */
mov rdx, rax /* sys_read() returns number of bytes read in rax, so we move it to rdx */
xor rax, rax
inc rax
syscall /* syscall write = 1 */
push byte 60 /* some bytes left... */
pop rax /* exit cleanly */
syscall
这些是我编译程序集时遇到的错误:
readflag.S: Assembler messages:
readflag.S:7: Error: junk `pro10mov dword [rsp+4]' after expression
readflag.S:21: Error: junk `0x7f' after expression
readflag.S:33: Error: junk `60' after expression
objcopy: 'readflag.o': No such file
我认为这push byte 60
是Intel语法中的有效指令。我不确定错误来自何处。将不胜感激。
指定.intel_syntax noprefix
选项后,您将指示Gnu汇编程序将使用MASM语法。实际上,您编写的是NASM语法,它在许多方面与MASM语法相似,但在其他方面却稍有不同。
有关差异的完整讨论,请参见NASM手册的本部分。
有关NASM与MASM语法的快速概述,请参阅本文档。
(第二个文档以前是在此处以更具可读性的HTML格式在线托管,但是链接已断开,很遗憾,我无法在Wayback Machine中找到副本。)
需要在代码中进行更改的大事情是,您需要PTR
在每个大小说明符之后都包含指令。因此,例如,代替:
mov dword [rsp], '/pro'
mov dword [rsp+4], 'c/fl'
您需要写:
mov dword ptr [rsp], '/pro'
mov dword ptr [rsp+4], 'c/fl'
同样,尽管MASM语法通常会写一个带有尾随的十六进制常量h
,而不是前导0x
,但Gas的“ MASM”模式不支持此0x
格式,即使使用Intel语法,也需要使用C样式表示法。
我认为这
push byte 60
是Intel语法中的有效指令。
不,不是。唯一的大小值可以PUSH
和POP
从堆栈是处理器的原生寄存器宽度。因此,在32位二进制文件中,必须推送和弹出32位值,而在64位二进制文件中,必须推送和弹出64位值。*这意味着这些代码行在技术上是错误的:
push 'ag'
push byte ptr 0x7f
push byte ptr 60
对于后面两个已明确指定大小的指令,MASM会向您发出警告,指出无效的操作数大小,但是它将隐式地将这些常量扩展为64位值,并且仍然可以成功进行汇编。我假设Gnu汇编器也可以执行此自动值扩展,因此您应该删除size指令:
push 'ag'
push 0x7f
push 60
__
*从技术上讲,您可以使用操作数大小覆盖前缀来允许以32位和64位模式将16位立即数压入堆栈。但是您确实不应该这样做,因为它会使堆栈不对齐,从而导致性能问题(并且,如果您要与其他语言编译的代码进行互操作,则会破坏ABI)。编写16位代码时,仅将16位值压入堆栈。如果要在32位或64位模式下推送16位值,只需让汇编器将其相应地扩展为32位或64位即可。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句