Skip to content

Instantly share code, notes, and snippets.

@djg
Created November 24, 2013 23:36
Show Gist options
  • Save djg/7633990 to your computer and use it in GitHub Desktop.
Save djg/7633990 to your computer and use it in GitHub Desktop.
crap3a.crap - Supports 4 character labels! (written in crap2 dialect)
#
# CRAP3a for Darwin-i386-MachO
# Copyright (C) 2013, Dan Glastonbury <dan.glastonbury@gmail.com>
#
# Labels are 4 chars. Labels are stores in a symbol table stored in
# BSS section. The labels form a list of 32-bit label name and address
# pairs.
#
# Errors are signaled by return code:
# 1: Syntax Error
# 2: Redefined Label
# 3: Undefined Label
#
# Based on:
# HEX3a 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
74 03 00 00 # filesize
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
10 02 00 00 # size
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
f0 12 00 00 # EIP
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
# +80
# Memory layout for variables:
# 0x2000 | pos |
# 0x2004 | filelen |
# 0x2008 | symtabp |
# 0x200c | symtab |
#
# each entry in symtab is:
# | LABL | ADDR |
# Enter here: = 0x164
# 0x1164
.K # _syscall:
cd 80 # int 80h
c3 # ret
# 0x1167
.X # _exit: # exit code passed on stack
8b 54 24 04 # mov edx, [esp+4]
52 # push edx
b0 01 # mov al, sys_exit
e8 K # call _syscall
# 0x116e
.G # _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 K # call _syscall
85 c0 # test eax, eax
83 f8 00 # cmp eax, 0
75 07 # jne .g
6a 00 # push 0
e8 X # call _exit
# .g
83 c4 0c # add esp, 12
58 # pop eax ; result in eax
c3 # ret
# 0x1188
.P # _putchar: ; write a byte to stdout
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 K # call _syscall
83 c4 0c # add esp, 12
c3 # ret
# read label in form /..../, result in eax
# 0x119e
.R # _read_sym:
e8 G # call _getchar
89 c2 # mov edx, eax
c1 e2 08 # shl edx, 0x8
e8 G # call _getchar
01 c2 # add edx, eax
c1 e2 08 # shl edx, 0x8
e8 G # call _getchar
01 c2 # add edx, eax
c1 e2 08 # shl edx, 0x8
e8 G # call _getchar
01 d0 # add eax, edx
c3 # ret
# Add a symbol to the symbol table. Scan the list and report error if
# symbol exits.
# eax: symbol
# ebp: points to symtab
# edi: current symbol
# ecx: symtabp
# 0x11c4
.A # _add_sym:
8b 4d fc # mov ecx, [ebp-4]
89 ef # mov edi, ebp
# 0x11c9
.i #
39 cf # cmp edi, ecx
74 13 # je .add ; not found, add it
3b 07 # cmp eax, [edi]
74 08 # je .err ; exists already
83 c7 08 # add edi, 8
e9 i # jmp .a
# .err
6a 02 # push 2
e8 X # call _exit
# .add
89 07 # mov [edi], eax ; save symbol
8b 45 f4 # mov eax, [ebp-12]
89 47 04 # mov [edi+4], eax ; save pos
83 c7 08 # add edi, 8
89 7d fc # mov [ebp-4], edi ; update symtabp
c3 # ret
# Write a symbol into the output stream. Scan the symbol table and report error
# if symbol is missing.
# eax: symbol
# ebp: points to symtab
# edi: current symbol
# ecx: symtabp
# 0x11ef
.W # _write_sym:
8b 4d fc # mov ecx, [ebp-4]
89 ef # mov edi,ebp
# 0x11f4
.j #
39 cf # cmp edi, ecx
74 0c # je .err ; not found, error
3b 07 # cmp eax, [edi]
74 0f # je .write ; exists, write
83 c7 08 # add edi, 8
e9 j # jmp .w
# .err
6a 03 # push 3
e8 X # call _exit
# .write
8b 45 f4 # mov eax, [ebp-12]
83 c0 04 # add eax, 4
89 45 f4 # mov [ebp-12], eax
8b 57 04 # mov edx, [edi+4]
29 c2 # sub edx, eax
52 # push edx
e8 P # call _putchar
5a # pop edx
c1 fa 08 # sar edx, 8
52 # push edx
e8 P # call _putchar
5a # pop edx
c1 fa 08 # sar edx, 8
52 # push edx
e8 P # call _putchar
5a # pop edx
c1 fa 08 # sar edx, 8
52 # push edx
e8 P # call _putchar
5a # pop edx
c3 # ret
# 0x123f
.H # _gethex:
e8 G # call _getchar
83 f8 20 # cmp eax, ' '
0f 8e H # jle _gethex
83 f8 23 # cmp eax, '#'
75 13 # jne .l1a
# 0x1252
.k # .comment
e8 G # call _getchar
83 f8 0a # cmp eax, lf
0f 85 k # jne .comment
e9 H # jmp _gethex
# .l1a:
83 f8 3a # cmp eax, ':'
75 0f # jne .l1b
e8 R # call _read_sym
e8 A # call _add_sym
e9 H # jmp _gethex
# .l1b
83 f8 2e # cmp eax, '.'
75 0f # jne .l2
e8 R # call _read_sym
e8 W # call _write_sym
e9 H # 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: ; syntax error
6a 01 # push 1
e8 X # call _exit
# 0x12b0
.S # _start:
# setup
bd 0c 20 00 00 # mov ebp, 0x200c
89 6d fc # mov [ebp-4], ebp
# 0x12b5
.s # main loop
e8 H # call _gethex
c1 e0 04 # sal eax, 4
50 # push eax
e8 H # call _gethex
01 04 24 # add [esp], eax
e8 P # call _putchar
58 # pop eax
ff 45 f4 # inc [ebp-12]
e9 s # jmp _start
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
e9 S # jmp _start
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
# _end:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment