最小Mach-o 64二进制 [英] Minimal Mach-o 64 binary
问题描述
我认为这是一个奇怪的问题,但是现在我准备手工制作最小的Mach-O 64二进制文件,就像ELF上的相同问题一样( http://timelessname.com/elfbin/).
I thinks this is a strange question, but now I prepare to hand-made a minimal Mach-O 64 binary, like the same problem on ELF (http://timelessname.com/elfbin/).
但是目前,我仍然对如何调试二进制文件感到困惑. otool不会向我显示错误,但是我很讨厌如何调试二进制文件.以下是我在十六进制视图中制作的二进制文件.在目前阶段,我不知道如何继续.有什么建议吗?还是我应该停止这种愚蠢的事情...
But currently I still sucks on how to debug my binary. otool does NOT show me the error, but I get the suck how to debug the binary. The following is the binary I make in hex view. In the current stage I've no idea how to continue. Any suggestion? or I should stop this stupid things...
0000000: cffa edfe 0700 0001 0300 0080 0200 0000 ................
0000010: 0900 0000 0002 0000 8500 0000 0000 0000 ................
0000020: 1900 0000 4800 0000 5f5f 5041 4745 5a45 ....H...__PAGEZE
0000030: 524f 0000 0000 0000 0000 0000 0000 0000 RO..............
0000040: 0000 0000 0100 0000 0000 0000 0000 0000 ................
0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000060: 0000 0000 0000 0000 1900 0000 9800 0000 ................
0000070: 5f5f 5445 5854 0000 0000 0000 0000 0000 __TEXT..........
0000080: 0010 0000 0000 0000 0010 0000 0000 0000 ................
0000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000a0: 0700 0000 0500 0000 0100 0000 0000 0000 ................
00000b0: 5f5f 7465 7874 0000 0000 0000 0000 0000 __text..........
00000c0: 5f5f 5445 5854 0000 0000 0000 0000 0000 __TEXT..........
00000d0: 1010 0000 0000 0000 1000 0000 0000 0000 ................
00000e0: 2002 0000 0100 0000 0000 0000 0000 0000 ...............
00000f0: 0004 0080 0000 0000 0000 0000 0000 0000 ................
0000100: 1900 0000 4800 0000 5f5f 4c49 4e4b 4544 ....H...__LINKED
0000110: 4954 0000 0000 0000 0000 0000 0000 0000 IT..............
0000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000130: 0000 0000 0000 0000 0700 0000 0100 0000 ................
0000140: 0000 0000 0000 0000 2200 0080 3000 0000 ........"...0...
0000150: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000170: 0000 0000 0000 0000 0200 0000 1800 0000 ................
0000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000190: 0b00 0000 5000 0000 0000 0000 0000 0000 ....P...........
00001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00001e0: 1b00 0000 1800 0000 506f 7765 7265 6420 ........Powered
00001f0: 6279 2063 6d6a 0000 2400 0000 1000 0000 by cmj..$.......
0000200: 000a 0a00 000a 0a00 2800 0080 1800 0000 ........(.......
0000210: 2002 0000 0000 0000 0000 0000 0000 0000 ...............
0000220: 48c7 c001 0000 0248 c7c7 0400 0000 0f05 H......H........
0000230: 0a .
[更新] 我的环境是Mac OSX 10.10,在我的情况下,在线信息不可用(例如 https://gist.github .com/softboysxp/1084476 )
[UPDATE] My environment is Mac OSX 10.10 which the online information does not workable in my case (e.g. https://gist.github.com/softboysxp/1084476)
推荐答案
自优胜美地10.10.5起,您不能低于4096字节的限制.现在,对Mach-O内核的检查更加严格.除了dyld和LC_MAIN
,您还可以选择LC_UNIXTHREAD
,并且显然保留您的LC_SEGMENT64
.节不是必需的,将其删除会使得跟踪二进制文件更加困难.
You cannot go below the 4096 byte limit since Yosemite 10.10.5. It's Mach-O kernel checks are more restrictive now. Alternatively to dyld and LC_MAIN
, you can go for LC_UNIXTHREAD
and obviously keeping your LC_SEGMENT64
. Sections are not necessary, dropping them will make tracking the binary harder.
因为El Capitan PAGEZERO
具有64位可执行文件,所以大小非零.
这是一个有效的HelloWorld示例,使用NASM
或YASM
Since El Capitan PAGEZERO
with nonzero size is required for 64 bit executables.
Here is a working HelloWorld example valid Sierra 10.12.2 compiled with NASM
or YASM
; A minimal Mach-o x64 executable for OS X Sierra
; $ nasm -f bin -o tiny_hello tiny_hello.s
; $ chmod +x tiny_hello
; Constants (For readability)
%define MH_MAGIC_64 0xfeedfacf
%define CPU_ARCH_ABI64 0x01000000
%define CPU_TYPE_I386 0x00000007
%define CPU_TYPE_X86_64 CPU_ARCH_ABI64 | CPU_TYPE_I386
%define CPU_SUBTYPE_LIB64 0x80000000
%define CPU_SUBTYPE_I386_ALL 0x00000003
%define MH_EXECUTE 0x2
%define MH_NOUNDEFS 0x1
%define LC_SEGMENT_64 0x19
%define LC_UNIXTHREAD 0x5
%define VM_PROT_READ 0x1
%define VM_PROT_WRITE 0x2
%define VM_PROT_EXECUTE 0x4
%define x86_THREAD_STATE64 0x4
%define x86_EXCEPTION_STATE64_COUNT 42
%define SYSCALL_CLASS_SHIFT 24
%define SYSCALL_CLASS_MASK (0xFF << SYSCALL_CLASS_SHIFT)
%define SYSCALL_NUMBER_MASK (~SYSCALL_CLASS_MASK)
%define SYSCALL_CLASS_UNIX 2
%define SYSCALL_CONSTRUCT_UNIX(syscall_number) \
((SYSCALL_CLASS_UNIX << SYSCALL_CLASS_SHIFT) | \
(SYSCALL_NUMBER_MASK & (syscall_number)))
%define SYS_exit 1
%define SYS_write 4
; NASM directive, not compiled
; Use RIP-Relative addressing for x64
BITS 64
;DEFAULT REL
%define __origin 0x100000000
org __origin
; Mach-O header
DD MH_MAGIC_64 ; magic
DD CPU_TYPE_X86_64 ; cputype
DD CPU_SUBTYPE_LIB64 | CPU_SUBTYPE_I386_ALL ; cpusubtype
DD MH_EXECUTE ; filetype
DD 3 ; ncmds
DD __COMMANDSend - __COMMANDSstart ; sizeofcmds
DD MH_NOUNDEFS ; flags
DD 0x0 ; reserved
__COMMANDSstart:
___PAGEZEROstart:
DD LC_SEGMENT_64 ; cmd
dd ___PAGEZEROend - ___PAGEZEROstart ; command size
hello_str:
db '__PAGEZERO',0x0,0,0,0,0,0 ; segment name (pad to 16 bytes)
DQ 0x0 ; vmaddr
DQ __origin ; vmsize
DQ 0 ; fileoff
DQ 0 ; filesize
DD 0 ; maxprot
DD 0 ; initprot
DD 0x0 ; nsects
DD 0x0 ; flags
___PAGEZEROend:
; Segment and Sections
___TEXTstart:
DD LC_SEGMENT_64 ; cmd
dd ___TEXTend - ___TEXTstart ; command size
db '__TEXT',0,0,0,0,0,0,0,0,0,0 ; segment name (pad to 16 bytes)
DQ __origin ; vmaddr
DQ ___codeend - __origin ; vmsize
DQ 0 ; fileoff
DQ ___codeend - __origin ; filesize
DD VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE ; maxprot
DD VM_PROT_READ | VM_PROT_EXECUTE ; initprot
DD 0x0 ; nsects
DD 0x0 ; flags
___TEXTend:
__UNIX_THREADstart:
; UNIX Thread Status
DD LC_UNIXTHREAD ; cmd
DD __UNIX_THREADend - __UNIX_THREADstart ; cmdsize
DD x86_THREAD_STATE64 ; flavor
DD x86_EXCEPTION_STATE64_COUNT ; count
DQ 0x0, 0x0, 0x00, 0x0 ; rax, rbx , rcx , rdx
DQ 0x01, hello_str, 0x00, 0x00 ; rdi = STDOUT, rsi = address of hello_str, rbp, rsp
DQ 0x00, 0x00 ; r8 and r9
DQ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ; r10, r11, r12, r13, r14, r15
DQ ___codestart, 0x00, 0x00, 0x00, 0x00 ; rip, rflags, cs, fs, gs
__UNIX_THREADend:
__COMMANDSend:
___codestart: ; 24 bytes
; rdi and rsi have already been set in the initial state
mov rdx, 11
mov rax, SYSCALL_CONSTRUCT_UNIX(SYS_write)
syscall
mov rdi, rax
mov rax, SYSCALL_CONSTRUCT_UNIX(SYS_exit)
syscall
___codeend:
times 4096-($-$$) DB 0;
filesize EQU $-$$
这篇关于最小Mach-o 64二进制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!