最小Mach-o 64二进制 [英] Minimal Mach-o 64 binary

查看:125
本文介绍了最小Mach-o 64二进制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这是一个奇怪的问题,但是现在我准备手工制作最小的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示例,使用NASMYASM

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屋!

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