Ale*_*ara 4 assembly x86-64 mach-o nasm data-segment
简而言之,当我db
在我的.data
部分中有多个部分时,编译的地址/标签在NASM编译时关闭.在我的测试中,它们在得到的Mach-O二进制文件中关闭了256个字节.
我使用的软件:
nasm
NASM版本2.11.08,根据x84_64 ASM的要求通过Homebrew安装gobjdump
GNU objdump(GNU Binutils)2.25.1,通过Homebrew安装clang
Apple LLVM版本6.1.0(clang-602.0.53)(基于LLVM 3.6.0svn)以下面的"hello world"NASM程序集为例.
main.s
global _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msg]
mov rdx, len
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msg: db "Hello, world!", 10
len: equ $ - msg
Run Code Online (Sandbox Code Playgroud)
编译并运行:
/usr/local/bin/nasm -f macho64 -o main.o main.s
clang -o main main.o
./main
Run Code Online (Sandbox Code Playgroud)
这很好用,并产生以下输出:
Hello, world!
Run Code Online (Sandbox Code Playgroud)
现在,要添加另一条消息,我们只需要在数据部分添加另一个字符串,另一个syscall
.很简单.
main.s
global _main
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msga]
mov rdx, lena
syscall
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel msgb]
mov rdx, lenb
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
section .data
msga: db "Hello, world!", 10
lena: equ $ - msga
msgb: db "Break things!", 10
lenb: equ $ - msgb
Run Code Online (Sandbox Code Playgroud)
编译并运行,和以前一样,我们得到:
Break things!
Run Code Online (Sandbox Code Playgroud)
什么?!?我们不应该得到吗?:
Hello, world!
Break things!
Run Code Online (Sandbox Code Playgroud)
显然出了点问题.是时候拆解生成的二进制文件,看看我们得到了什么.
$ gobjdump -d -M intel main
Run Code Online (Sandbox Code Playgroud)
产生以下内容_main
:
0000000100000f7c <_main>:
100000f7c:b8 04 00 00 02 mov eax,0x2000004
100000f81:bf 01 00 00 00 mov edi,0x1
100000f86:48 8d 35 73 01 00 00 lea rsi,[rip+0x173] # 100001100 <msgb+0xf2>
100000f8d:ba 0e 00 00 00 mov edx,0xe
100000f92:0f 05 syscall
100000f94:b8 04 00 00 02 mov eax,0x2000004
100000f99:bf 01 00 00 00 mov edi,0x1
100000f9e:48 8d 35 69 00 00 00 lea rsi,[rip+0x69] # 10000100e <msgb>
100000fa5:ba 0e 00 00 00 mov edx,0xe
100000faa:0f 05 syscall
100000fac:b8 01 00 00 02 mov eax,0x2000001
100000fb1:bf 00 00 00 00 mov edi,0x0
100000fb6:0f 05 syscall
Run Code Online (Sandbox Code Playgroud)
从注释中# 100001100 <msgb+0xf2>
,我们可以看到它指向的不是msga
符号,而是指向0xf2
过去msgb
,或者100001100
(在此地址处有空字节,导致无输出).在十六进制编辑器中检查二进制文件,我msga
在偏移量1000
或地址处找到实际的字符串100001000
.这意味着编译后的二进制文件中的地址现在被0x100
/ 256
字节关闭,这只是因为现在有第二个db
标签.什么?!?
作为一个实验,我决定尝试将两个db
部分放入单独的ASM /目标文件中,并将所有3个部分链接在一起.这样做有效.
main.s
global _main
extern _msga
extern _lena
extern _msgb
extern _lenb
section .text
_main:
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel _msga]
mov rdx, _lena
syscall
mov rax, 0x2000004
mov rdi, 1
lea rsi, [rel _msgb]
mov rdx, _lenb
syscall
mov rax, 0x2000001
mov rdi, 0
syscall
Run Code Online (Sandbox Code Playgroud)
msga.s
global _msga
global _lena
section .data
_msga: db "Hello, world!", 10
_lena: equ $ - _msga
Run Code Online (Sandbox Code Playgroud)
msgb.s
global _msgb
global _lenb
section .data
_msgb: db "Break things!", 10
_lenb: equ $ - _msgb
Run Code Online (Sandbox Code Playgroud)
编译并运行:
/usr/local/bin/nasm -f macho64 -o main.o main.s
/usr/local/bin/nasm -f macho64 -o msga.o msga.s
/usr/local/bin/nasm -f macho64 -o msgb.o msgb.s
clang -o main msga.o msgb.o main.o
./main
Run Code Online (Sandbox Code Playgroud)
结果是:
Hello, world!
Break things!
Run Code Online (Sandbox Code Playgroud)
虽然这确实有效,但我发现很难相信这是最好的解决方案.
当然必须有一种方法db
在一个ASM文件中有多个标签?我在编写ASM的方式上做错了吗?这是NASM中的错误吗?是这种预期的行为,在哪种情况下为什么?我的解决方法是额外的工作和混乱,所以我非常感谢任何帮助.
归档时间: |
|
查看次数: |
405 次 |
最近记录: |