20
20
import ghidra .app .util .bin .BinaryReader ;
21
21
import ghidra .app .util .bin .format .macho .MachConstants ;
22
22
import ghidra .app .util .bin .format .macho .MachHeader ;
23
+ import ghidra .app .util .bin .format .macho .commands .dyld .BindOpcode ;
24
+ import ghidra .app .util .bin .format .macho .commands .dyld .BindingTable ;
23
25
import ghidra .app .util .importer .MessageLog ;
24
26
import ghidra .program .flatapi .FlatProgramAPI ;
25
27
import ghidra .program .model .address .Address ;
@@ -45,6 +47,9 @@ public class DyldInfoCommand extends LoadCommand {
45
47
private int exportOff ;
46
48
private int exportSize ;
47
49
50
+ private BindingTable bindingTable ;
51
+ private BindingTable weakBindingTable ;
52
+ private BindingTable lazyBindingTable ;
48
53
private ExportTrie exportTrie ;
49
54
50
55
/**
@@ -72,6 +77,32 @@ public class DyldInfoCommand extends LoadCommand {
72
77
exportOff = loadCommandReader .readNextInt ();
73
78
exportSize = loadCommandReader .readNextInt ();
74
79
80
+ // TODO: rebase
81
+
82
+ if (bindOff > 0 && bindSize > 0 ) {
83
+ dataReader .setPointerIndex (header .getStartIndex () + bindOff );
84
+ bindingTable = new BindingTable (dataReader , header , bindSize , false );
85
+ }
86
+ else {
87
+ bindingTable = new BindingTable ();
88
+ }
89
+
90
+ if (weakBindOff > 0 && weakBindSize > 0 ) {
91
+ dataReader .setPointerIndex (header .getStartIndex () + weakBindOff );
92
+ weakBindingTable = new BindingTable (dataReader , header , weakBindSize , false );
93
+ }
94
+ else {
95
+ weakBindingTable = new BindingTable ();
96
+ }
97
+
98
+ if (lazyBindOff > 0 && lazyBindSize > 0 ) {
99
+ dataReader .setPointerIndex (header .getStartIndex () + lazyBindOff );
100
+ lazyBindingTable = new BindingTable (dataReader , header , lazyBindSize , true );
101
+ }
102
+ else {
103
+ lazyBindingTable = new BindingTable ();
104
+ }
105
+
75
106
if (exportOff > 0 && exportSize > 0 ) {
76
107
dataReader .setPointerIndex (header .getStartIndex () + exportOff );
77
108
exportTrie = new ExportTrie (dataReader );
@@ -151,6 +182,27 @@ public int getExportSize() {
151
182
return exportSize ;
152
183
}
153
184
185
+ /**
186
+ * {@return The binding table}
187
+ */
188
+ public BindingTable getBindingTable () {
189
+ return bindingTable ;
190
+ }
191
+
192
+ /**
193
+ * {@return The lazy binding table}
194
+ */
195
+ public BindingTable getLazyBindingTable () {
196
+ return lazyBindingTable ;
197
+ }
198
+
199
+ /**
200
+ * {@return The weak binding table}
201
+ */
202
+ public BindingTable getWeakBindingTable () {
203
+ return weakBindingTable ;
204
+ }
205
+
154
206
/**
155
207
* {@return The export trie}
156
208
*/
@@ -186,11 +238,10 @@ public DataType toDataType() throws DuplicateNameException, IOException {
186
238
public void markup (Program program , MachHeader header , String source , TaskMonitor monitor ,
187
239
MessageLog log ) throws CancelledException {
188
240
markupRebaseInfo (program , header , source , monitor , log );
189
- markupBindInfo (program , header , source , monitor , log );
190
- markupWeakBindInfo (program , header , source , monitor , log );
191
- markupLazyBindInfo (program , header , source , monitor , log );
241
+ markupBindings (program , header , source , monitor , log );
242
+ markupWeakBindings (program , header , source , monitor , log );
243
+ markupLazyBindings (program , header , source , monitor , log );
192
244
markupExportInfo (program , header , source , monitor , log );
193
-
194
245
}
195
246
196
247
private void markupRebaseInfo (Program program , MachHeader header , String source ,
@@ -199,28 +250,80 @@ private void markupRebaseInfo(Program program, MachHeader header, String source,
199
250
source , "rebase" );
200
251
}
201
252
202
- private void markupBindInfo (Program program , MachHeader header , String source ,
253
+ private void markupBindings (Program program , MachHeader header , String source ,
203
254
TaskMonitor monitor , MessageLog log ) {
204
- markupPlateComment (program , fileOffsetToAddress (program , header , bindOff , bindSize ),
205
- source , "bind" );
255
+ Address bindAddr = fileOffsetToAddress (program , header , bindOff , bindSize );
256
+ markupPlateComment (program , bindAddr , source , "bind" );
257
+ markupBindingTable (program , bindAddr , bindingTable , source , "bind" , log );
206
258
}
207
259
208
- private void markupWeakBindInfo (Program program , MachHeader header , String source ,
260
+ private void markupWeakBindings (Program program , MachHeader header , String source ,
209
261
TaskMonitor monitor , MessageLog log ) {
210
- markupPlateComment (program , fileOffsetToAddress (program , header , weakBindOff , weakBindSize ),
211
- source , "weak bind" );
262
+ Address addr = fileOffsetToAddress (program , header , weakBindOff , weakBindSize );
263
+ markupPlateComment (program , addr , source , "weak bind" );
264
+ markupBindingTable (program , addr , weakBindingTable , source , "weak bind" , log );
265
+
212
266
}
213
267
214
- private void markupLazyBindInfo (Program program , MachHeader header , String source ,
268
+ private void markupLazyBindings (Program program , MachHeader header , String source ,
215
269
TaskMonitor monitor , MessageLog log ) {
216
- markupPlateComment (program , fileOffsetToAddress (program , header , lazyBindOff , lazyBindSize ),
217
- source , "lazy bind" );
270
+ Address addr = fileOffsetToAddress (program , header , lazyBindOff , lazyBindSize );
271
+ markupPlateComment (program , addr , source , "lazy bind" );
272
+ markupBindingTable (program , addr , lazyBindingTable , source , "lazy bind" , log );
273
+ }
274
+
275
+ private void markupBindingTable (Program program , Address addr , BindingTable table ,
276
+ String source , String additionalDescription , MessageLog log ) {
277
+ if (addr == null ) {
278
+ return ;
279
+ }
280
+ try {
281
+ DataType bindOpcodeDataType = BindOpcode .toDataType ();
282
+ for (long offset : table .getOpcodeOffsets ()) {
283
+ DataUtilities .createData (program , addr .add (offset ), bindOpcodeDataType , -1 ,
284
+ DataUtilities .ClearDataMode .CHECK_FOR_SPACE );
285
+ }
286
+ for (long offset : table .getUlebOffsets ()) {
287
+ DataUtilities .createData (program , addr .add (offset ), ULEB128 , -1 ,
288
+ DataUtilities .ClearDataMode .CHECK_FOR_SPACE );
289
+ }
290
+ for (long offset : table .getSlebOffsets ()) {
291
+ DataUtilities .createData (program , addr .add (offset ), SLEB128 , -1 ,
292
+ DataUtilities .ClearDataMode .CHECK_FOR_SPACE );
293
+ }
294
+ for (long offset : table .getStringOffsets ()) {
295
+ DataUtilities .createData (program , addr .add (offset ), STRING , -1 ,
296
+ DataUtilities .ClearDataMode .CHECK_FOR_SPACE );
297
+ }
298
+ }
299
+ catch (Exception e ) {
300
+ log .appendMsg (DyldInfoCommand .class .getSimpleName (),
301
+ "Failed to markup: " + getContextualName (source , additionalDescription ));
302
+ }
218
303
}
219
304
220
305
private void markupExportInfo (Program program , MachHeader header , String source ,
221
306
TaskMonitor monitor , MessageLog log ) {
222
- markupPlateComment (program , fileOffsetToAddress (program , header , exportOff , exportSize ),
223
- source , "export" );
307
+ Address exportAddr = fileOffsetToAddress (program , header , exportOff , exportSize );
308
+ if (exportAddr == null ) {
309
+ return ;
310
+ }
311
+ markupPlateComment (program , exportAddr , source , "export" );
312
+
313
+ try {
314
+ for (long offset : exportTrie .getUlebOffsets ()) {
315
+ DataUtilities .createData (program , exportAddr .add (offset ), ULEB128 , -1 ,
316
+ DataUtilities .ClearDataMode .CHECK_FOR_SPACE );
317
+ }
318
+ for (long offset : exportTrie .getStringOffsets ()) {
319
+ DataUtilities .createData (program , exportAddr .add (offset ), STRING , -1 ,
320
+ DataUtilities .ClearDataMode .CHECK_FOR_SPACE );
321
+ }
322
+ }
323
+ catch (Exception e ) {
324
+ log .appendMsg (DyldInfoCommand .class .getSimpleName (),
325
+ "Failed to markup: " + getContextualName (source , "export" ));
326
+ }
224
327
}
225
328
226
329
@ Override
0 commit comments