Skip to content

Instantly share code, notes, and snippets.

@djg
Created November 24, 2013 23:33
Show Gist options
  • Save djg/7633959 to your computer and use it in GitHub Desktop.
Save djg/7633959 to your computer and use it in GitHub Desktop.
crap2a.crap - support for single character labels.
#
# CRAP2a for Darwin-i386-MachO
# Copyright (C) 2013, Dan Glastonbury <dan.glastonbury@gmail.com>
#
# Uses BSS section for data storage.
#
# Based on:
# HEX2a for Linux-i386-ELF
# Copyright (C) 2001, Edmund GRIMLEY EVANS <edmundo@rano.org>
#
# _mach_header: # struct mach_header
ce fa ed fe # magic
07 00 00 00 # cputype (CPU_TYPE_X86_TYPE_X86)
03 00 00 00 # cpusubtype (CPU_SUBTYPE_I386_ALL)
02 00 00 00 # filetype (MH_EXECUTE)
03 00 00 00 # ncmds
48 01 00 00 # sizeofcmds = 328
00 00 00 00 # flags
# +28
# Text Segment # struct segment_command
01 00 00 00 # cmd (LC_SEGMENT)
7c 00 00 00 # cmdsize = 124
5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 # segname[16] = '__TEXT'
00 10 00 00 # vmaddr = 0x1000
00 10 00 00 # vmsize = 0x1000
00 00 00 00 # fileoff
5e 02 00 00 # filesize = 605
07 00 00 00 # maxprot
05 00 00 00 # initprot
01 00 00 00 # nsects
00 00 00 00 # flags
# +56
# Text section # struct section
5f 5f 74 65 78 74 00 00 00 00 00 00 00 00 00 00 # sectname[16] = '__text'
5f 5f 54 45 58 54 00 00 00 00 00 00 00 00 00 00 # segname[16] = '__TEXT'
64 11 00 00 # addr = 0x10E8
fa 00 00 00 # size = 0xF9 (249)
64 01 00 00 # offset = 0x164 (356)
02 00 00 00 # align
00 00 00 00 # reloff
00 00 00 00 # nreloc
00 00 00 00 # flags
00 00 00 00 # reserved1
00 00 00 00 # reserved2
# +68
# Data Segment # struct segment_command
01 00 00 00 # cmd (LC_SEGMENT)
7c 00 00 00 # cmdsize = 124
5f 5f 44 41 54 41 00 00 00 00 00 00 00 00 00 00 # segname[16] = '__DATA'
00 20 00 00 # vmaddr = 0x1000
00 10 00 00 # vmsize = 0x1000
00 00 00 00 # fileoff
00 00 00 00 # filesize = 484
07 00 00 00 # maxprot
03 00 00 00 # initprot
01 00 00 00 # nsects
00 00 00 00 # flags
# +56
# BSS section # struct section
5f 5f 62 73 73 00 00 00 00 00 00 00 00 00 00 00 # sectname[16] = '__text'
5f 5f 44 41 54 41 00 00 00 00 00 00 00 00 00 00 # segname[16] = '__DATA'
00 20 00 00 # addr = 0x2000
04 04 00 00 # size = 0x0404 (1028)
00 00 00 00 # offset
02 00 00 00 # align
00 00 00 00 # reloff
00 00 00 00 # nreloc
01 00 00 00 # flags
00 00 00 00 # reserved1
00 00 00 00 # reserved2
# +68
# Unix Thread # struct thread_command
05 00 00 00 # cmd (LC_UNIXTHREAD)
50 00 00 00 # cmdsize = 80
01 00 00 00 # flavor = i386_THREAD_STATE
10 00 00 00 # count
# state: dd 0, 0, 0, 0, 0, 0, 0, 0
# dd 0, 0, _start, 0, 0, 0, 0, 0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 3f 12 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# +80
# Enter here: = 0x164
# _syscall:
cd 80 # int 80h
c3 # ret
# _exit:
31 c0 # xor eax, eax
50 # push eax ; return 0
b0 01 # mov al, sys_exit
e8 f3 ff ff ff # call _syscall
# _getchar: ; read a byte from stdin
31 c0 # xor eax, eax
50 # push eax ; storage for ch
89 e1 # mov ecx, esp ; &ch
6a 01 # push 1 ; read 1 byte
51 # push ecx ; into [ecx]
6a 00 # push stdin_fileno ; from standard input
b0 03 # mov al, sys_read
e8 e2 ff ff ff # call _syscall
85 c0 # test eax, eax
74 e1 # je _exit
83 c4 0c # add esp, 12
58 # pop eax ; result in eax
c3 # ret
# _putchar:
8d 4c 24 04 # lea ecx, [esp+4]
31 c0 # xor eax, eax
6a 01 # push 1 ; write 1 byte
51 # push ecx ; from [ecx]
6a 01 # push stdout_fileno ; into standard output
b0 04 # mov al, sys_write
e8 c7 ff ff ff # call _syscall
83 c4 0c # add esp, 12
c3 # ret
# _gethex:
e8 cb ff ff ff # call _getchar
83 f8 20 # cmp eax, ' '
7e f6 # jle _gethex
83 f8 23 # cmp eax, '#'
75 0c # jne .l1
# .loop: ; comment
e8 bc ff ff ff # call _getchar
83 f8 0a # cmp eax, lf
75 f6 # jne .loop
eb e5 # jmp _gethex
# .l1: ; if .x, store position into label[x]
83 f8 2e # cmp eax, '.'
75 1b # jne .l2
e8 ab ff ff ff # call _getchar
25 ff 00 00 00 # and eax, 0xff
8d 3c 85 00 20 00 00 # lea edi, [labels+4*eax]
8b 15 00 24 00 00 # mov edx, [pos]
89 17 # mov [edi], edx
eb c5 # jmp _gethex
# .l2: ; check for 0-9
83 f8 30 # cmp eax, '0'
7c 09 # jl .l3
83 f8 3a # cmp eax, ':'
7d 04 # jge .l3
83 e8 30 # sub eax, '0'
c3 # ret
# .l3: ; check for a-f
83 f8 61 # cmp eax, 'a'
7c 09 # jl .l4
83 f8 67 # cmp eax, 'g'
7d 04 # jge .l4
83 e8 57 # sub eax, 0x57
c3 # ret
# .l4: ; handle single char label
25 ff 00 00 00 # and eax, 0xff
8d 34 85 00 20 00 00 # lea esi, [labels+4*eax]
8b 16 # mov edx, [esi] ; .x position
a1 00 24 00 00 # mov eax, [pos] ; current position
83 c0 04 # add eax, 4
a3 00 24 00 00 # mov [pos], eax ; update position
29 c2 # sub edx, eax
52 # push edx
e8 70 ff ff ff # call _putchar
5a # pop edx
c1 fa 08 # sar edx, 8
52 # push edx
e8 66 ff ff ff # call _putchar
5a # pop edx
c1 fa 08 # sar edx, 8
52 # push edx
e8 5c ff ff ff # call _putchar
5a # pop edx
c1 fa 08 # sar edx, 8
52 # push edx
e8 52 ff ff ff # call _putchar
5a # pop edx
e9 62 ff ff ff # jmp _gethex
# _start:
e8 5d ff ff ff # call _gethex
c1 e0 04 # sal eax, 4
50 # push eax
e8 54 ff ff ff # call _gethex
01 04 24 # add [esp], eax
e8 36 ff ff ff # call _putchar
58 # pop eax
ff 05 00 24 00 00 # inc dword [pos]
eb e1 # jmp _start
# _end:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment