-
Notifications
You must be signed in to change notification settings - Fork 2
/
macho.rb
190 lines (153 loc) · 4.76 KB
/
macho.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
require 'asm/cstruct'
# The MachO module contains constants and structures related to the
# Mach Object format (Mach-O). They are relevant to Darwin on OS X.
#
# Constants and structures as defined in /usr/include/mach-o/loader.h
# on Mac OS X Leopard (10.5.7). Also see <mach-o/stab.h>,
# <mach-o/nlist.h>, and <mach-o/reloc.h>.
module MachO
###############
# Mach header #
###############
# Appears at the beginning of every Mach object file.
class MachHeader < CStruct
uint32 :magic
int32 :cputype
int32 :cpusubtype
uint32 :filetype
uint32 :ncmds
uint32 :sizeofcmds
uint32 :flags
end
# Values for the magic field.
MH_MAGIC = 0xfeedface # Mach magic number (big-endian).
MH_CIGAM = 0xcefaedfe # Little-endian version.
# Values for the filetype field.
MH_OBJECT = 0x1
MH_EXECUTE = 0x2
MH_FVMLIB = 0x3
MH_CORE = 0x4
MH_PRELOAD = 0x5
MH_DYLIB = 0x6
MH_DYLINKER = 0x7
MH_BUNDLE = 0x8
MH_DYLIB_STUB = 0x9
MH_DSYM = 0xa
# CPU types and subtypes (only Intel for now).
CPU_TYPE_X86 = 7
CPU_TYPE_I386 = CPU_TYPE_X86
CPU_SUBTYPE_X86_ALL = 3
############################
# Load commands / segments #
############################
class LoadCommand < CStruct
uint32 :cmd
uint32 :cmdsize
end
# Values for the cmd member of LoadCommand CStructs (incomplete!).
LC_SEGMENT = 0x1
LC_SYMTAB = 0x2
LC_SYMSEG = 0x3
LC_THREAD = 0x4
LC_UNIXTHREAD = 0x5
class SegmentCommand < LoadCommand
string :segname, 16
uint32 :vmaddr
uint32 :vmsize
uint32 :fileoff
uint32 :filesize
int32 :maxprot
int32 :initprot
uint32 :nsects
uint32 :flags
end
# Values for protection fields, maxprot and initprot.
VM_PROT_NONE = 0x00
VM_PROT_READ = 0x01
VM_PROT_WRITE = 0x02
VM_PROT_EXECUTE = 0x04
VM_PROT_NO_CHANGE = 0x08
VM_PROT_COPY = 0x10
class SymtabCommand < LoadCommand
uint32 :symoff # Points to an array of Nlist structs.
uint32 :nsyms # Number of entries in said array.
uint32 :stroff # Offset of the string table.
uint32 :strsize # Size of the string table in bytes.
end
LoadCommandStructMap = {
LC_SEGMENT => SegmentCommand,
LC_SYMTAB => SymtabCommand
}
############
# Sections #
############
class Section < CStruct
string :sectname, 16
string :segname, 16
uint32 :addr
uint32 :size
uint32 :offset
uint32 :align
uint32 :reloff
uint32 :nreloc
uint32 :flags
uint32 :reserved1
uint32 :reserved2
end
# Values for the type bitfield (mask 0x000000ff) of the flags field.
# (incomplete!)
S_REGULAR = 0x0
S_ZEROFILL = 0x1
S_CSTRING_LITERALS = 0x2
###########################
# Relocation info support #
###########################
class RelocationInfo < CStruct
int32 :r_address # offset in the section to what is being relocated
uint32 :r_info
end
# NOTE: r_info is a packed bit field with the following members:
#
# (CStruct should eventually support bitfields, but doesn't right now.)
#
# r_symbolnum : 24 -- symbol index if r_extern == 1 or section ordinal if r_extern == 0
# r_pcrel : 1 -- was relocated pc relative already
# r_length : 2 -- 0=byte, 1=word, 2=long, 3=quad
# r_extern : 1 -- 1 for exported symbols, 0 othewise
# r_type : 4 -- if not 0, machine specific relocation type (always 0)
R_ABS = 0 # Absolute relocation type
# (r_symbolnum == R_ABS for absolute symbols that don't need reloc)
# Relocation types (r_type)
GENERIC_RELOC_VANILLA = 0
########################
# Symbol table support #
########################
# Nlist is used to describe symbols.
class Nlist < CStruct
uint32 :n_strx # Index into string table. Index of zero is the empty string.
uint8 :n_type # Type flag (see below).
uint8 :n_sect # Section number (from 1) or NO_SECT.
uint16 :n_desc # TODO See <mach-o/stab.h>.
uint32 :n_value # The symbol's value (or stab offset).
end
# Type flag (see <mach-o/nlist.h> for more details)
# ---------
#
# This field consists of four bitfields:
#
# uchar N_STAB : 3
# uchar N_PEXT : 1
# uchar N_TYPE : 3
# uchar N_EXT : 1
#
N_STAB = 0xe0 # if any bits set => symbolic debugging info
N_PEXT = 0x10 # private external symbol bit
N_TYPE = 0x0e # mask for the type bits
N_EXT = 0x01 # external symbol bit, set for external symbols (e.g. globals)
# Values for N_TYPE. (incomplete!)
N_UNDF = 0x0 # undefined, n_sect == NO_SECT
N_ABS = 0x2 # absolute, n_sect == NO_SECT
N_SECT = 0xe # defined in section number n_sect
NO_SECT = 0
MAX_SECT = 255
end