我有一个由工具生成的x86_64架构的gnu汇编程序代码,并且有以下指令:
movq %rsp, %rbp
leaq str(%rip), %rdi
callq puts
movl $0, %eax
Run Code Online (Sandbox Code Playgroud)
我找不到关于"callq"指令的实际文档.
我查看了http://support.amd.com/TechDocs/24594.pdf,这是"AMD64架构程序员手册第3卷:通用和系统指令",但它们只描述了CALL近距离和远距离指令.
我查看了gnu汇编程序https://sourceware.org/binutils/docs/as/index.html的文档,但找不到详细说明它支持的说明部分.
我理解它是对函数的调用,但我想知道细节.我在哪里可以找到它们?
让我们考虑以下程序,它计算参数的无符号平方:
.global foo
.text
foo:
mov %rdi, %rax
mul %rdi
ret
Run Code Online (Sandbox Code Playgroud)
这是由适当编译as,但反汇编
0000000000000000 <foo>:
0: 48 89 f8 mov %rdi,%rax
3: 48 f7 e7 mul %rdi
6: c3 retq
Run Code Online (Sandbox Code Playgroud)
有什么区别ret和retq?
如何使用 MASM 编写远绝对 JMP 或 CALL 指令?具体来说,我如何让它使用 EA 和 CA 操作码发出这些指令,而不是使用 DB 或其他数据指令手动发出它们?
例如,考虑跳转到引导扇区中 FFFF:0000 处的 BIOS 重置入口点的情况。如果我使用 NASM,我可以以一种显而易见的方式在一条指令中对此进行编码:
jmp 0xffff:0
Run Code Online (Sandbox Code Playgroud)
使用 GNU 汇编器,语法不太明显,但以下内容可以完成这项工作:
jmp 0xffff, 0
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用 MASM 的明显解决方案时:
jmp 0ffffh:0
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
t206b.asm(3) : error A2096:segment, group, or segment register expected
Run Code Online (Sandbox Code Playgroud)
我可以在 MASM 中使用许多可能的解决方法,例如以下任何一种:
手动组装指令,手动发出机器代码:
jmp 0xffff:0
Run Code Online (Sandbox Code Playgroud)
使用远间接跳转:
jmp 0xffff, 0
Run Code Online (Sandbox Code Playgroud)
或者将地址压入堆栈并使用远 RET 指令“返回”它:
jmp 0ffffh:0
Run Code Online (Sandbox Code Playgroud)
但是无论如何我可以使用实际的 JMP 指令并让 MASM 生成正确的操作码 (EA)?
我正在尝试为不允许 0x00 字节的 CTF 挑战编写 shellcode(它将被解释为终止符)。由于挑战的限制,我必须做这样的事情:
[shellcode bulk]
[(0x514 - sizeof(shellcode bulk)) filler bytes]
[fixed constant data to overwrite global symbols]
[shellcode data]
Run Code Online (Sandbox Code Playgroud)
它看起来像这样
.intel_syntax noprefix
.code32
shellcode:
jmp sc_data
shellcode_main:
#open
xor eax, eax
pop ebx //file string
xor ecx, ecx //flags
xor edx, edx //mode
mov al, 5 //sys_OPEN
int 0x80
... // more shellcode
.org 514, 0x41 // filler bytes
.long 0xffffffff // bss constant overwrite
sc_data:
call shellcode_main
.asciz "/path/to/fs/file"
Run Code Online (Sandbox Code Playgroud)
如果sc_data在shellcode. 在这种情况下,汇编器 …
有了这个简单的组装:
.text
.globl main
str:
.asciz "%i\n"
add:
push %rbp
mov %rsp, %rbp
movl %esi, %eax
addl %edi, %eax
pop %rbp
ret
main:
mov $1, %esi
mov $2, %edi
lea add(%rip), %rax
call %rax #what is wrong here? the rax should contain first instruction of add
mov %eax, %esi
xor %eax, %eax
lea str(%rip), %rdi
call printf
xor %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
我收到错误:
foo.s:17: Warning: indirect call without `*'
Run Code Online (Sandbox Code Playgroud)
为什么?应该%rax包含函数的地址(如注释中所示),这不是c,其中有带有 的指针*,而是包含地址的寄存器。那么这里出了什么问题呢?