Mac OS X 上的 64 位程序集运行时错误:“dyld:无可写段";和“跟踪/BPT陷阱" [英] 64 bit assembly on Mac OS X runtime errors: "dyld: no writable segment" and "Trace/BPT trap"

查看:20
本文介绍了Mac OS X 上的 64 位程序集运行时错误:“dyld:无可写段";和“跟踪/BPT陷阱"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试运行以下汇编程序时:

When attempting to run the following assembly program:

.globl start

start:
    pushq $0x0 
    movq $0x1, %rax
    subq $0x8, %rsp
    int $0x80

我收到以下错误:

dyld: no writable segment
Trace/BPT trap

知道是什么原因造成的吗?32 位汇编中的类似程序运行良好.

Any idea what could be causing this? The analogous program in 32 bit assembly runs fine.

推荐答案

OSX 现在要求您的可执行文件具有包含内容的可写数据段,以便它可以动态地重新定位和链接您的代码.不知道为什么,也许是安全原因,也许是由于新的 RIP 寄存器.如果您在其中放置一个 .data 段(带有一些虚假内容),您将避免无可写段"错误.IMO 这是一个 ld 错误.

OSX now requires your executable to have a writable data segment with content, so it can relocate and link your code dynamically. Dunno why, maybe security reasons, maybe due to the new RIP register. If you put a .data segment in there (with some bogus content), you'll avoid the "no writable segment" error. IMO this is an ld bug.

关于 64 位系统调用,您可以通过两种方式进行.GCC 样式,它使用来自 libSystem.dylib 或原始的 _syscall PROCEDURE.Raw 使用 syscall 指令,而不是 int 0x80 陷阱.int 0x80"在 64 位中是非法指令.

Regarding the 64-bit syscall, you can do it 2 ways. GCC-style, which uses the _syscall PROCEDURE from libSystem.dylib, or raw. Raw uses the syscall instruction, not the int 0x80 trap. "int 0x80" is an illegal instruction in 64-bit.

GCC 方法"将负责为您分类系统调用,因此您可以使用在 sys/syscall.h 中找到的相同 32 位数字.但是,如果您采用原始方法,则必须通过将其与类型 ID 进行 ORing 来对它是哪种系统调用进行分类.这是两者的示例.请注意,调用约定是不同的!(为 NASM 语法道歉;gas 惹恼了我)

The "GCC method" will take care of categorizing the syscall for you, so you can use the same 32-bit numbers found in sys/syscall.h. But if you go raw, you'll have to classify what kind of syscall it is by ORing it with a type id. Here is an example of both. Note that the calling convention is different! (apologies for NASM syntax; gas annoys me)

; assemble with
; nasm -f macho64 -o syscall64.o syscall64.asm && ld -lc -ldylib1.o -e start -o syscall64 syscall64.o
extern _syscall
global start

[section .text align=16]
start:
    ; do it gcc-style
    mov rdi, 0x4 ; sys_write
    mov rsi, 1 ; file descriptor
    mov rdx, hello
    mov rcx, size
    call _syscall ; we're calling a procedure, not trapping.

    ;now let's do it raw
    mov rax, 0x2000001 ; SYS_exit = 1 and is type 2 (bsd call)
    mov rdi, 0 ; Exit success = 0
    syscall ; faster than int 0x80, and legal!


[section .data align=16]
hello: db "hello 64-bit syscall!", 0x0a
size: equ $-hello

查看 http://www.opensource.apple.com/source/xnu/xnu-792.13.8/osfmk/mach/i386/syscall_sw.h 了解有关如何键入系统调用的更多信息.

check out http://www.opensource.apple.com/source/xnu/xnu-792.13.8/osfmk/mach/i386/syscall_sw.h for more info on how a syscall is typed.

这篇关于Mac OS X 上的 64 位程序集运行时错误:“dyld:无可写段";和“跟踪/BPT陷阱"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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