@@ -23,10 +23,11 @@ class R2RDump
2323 private IReadOnlyList < string > _sections = Array . Empty < string > ( ) ;
2424 private bool _diff ;
2525 private IntPtr _disassembler ;
26- private bool _types ;
2726 private bool _unwind ;
2827 private bool _gc ;
28+ private bool _sectionContents ;
2929 private TextWriter _writer ;
30+ private Dictionary < R2RSection . SectionType , bool > _selectedSections = new Dictionary < R2RSection . SectionType , bool > ( ) ;
3031
3132 private R2RDump ( )
3233 {
@@ -51,10 +52,10 @@ private ArgumentSyntax ParseCommandLine(string[] args)
5152 syntax . DefineOptionList ( "k|keyword" , ref _keywords , "Search method by keyword" ) ;
5253 syntax . DefineOptionList ( "r|runtimefunction" , ref _runtimeFunctions , ArgStringToInt , "Get one runtime function by id or relative virtual address" ) ;
5354 syntax . DefineOptionList ( "s|section" , ref _sections , "Get section by keyword" ) ;
54- syntax . DefineOption ( "types" , ref _types , "Dump available types" ) ;
5555 syntax . DefineOption ( "unwind" , ref _unwind , "Dump unwindInfo" ) ;
5656 syntax . DefineOption ( "gc" , ref _gc , "Dump gcInfo and slot table" ) ;
57- syntax . DefineOption ( "v|verbose" , ref verbose , "Dump raw bytes, disassembly, unwindInfo and gcInfo" ) ;
57+ syntax . DefineOption ( "sc" , ref _sectionContents , "Dump section contents" ) ;
58+ syntax . DefineOption ( "v|verbose" , ref verbose , "Dump raw bytes, disassembly, unwindInfo, gcInfo and section contents" ) ;
5859 syntax . DefineOption ( "diff" , ref _diff , "Compare two R2R images (not yet implemented)" ) ;
5960 } ) ;
6061
@@ -64,6 +65,7 @@ private ArgumentSyntax ParseCommandLine(string[] args)
6465 _disasm = true ;
6566 _unwind = true ;
6667 _gc = true ;
68+ _sectionContents = true ;
6769 }
6870
6971 return argSyntax ;
@@ -146,6 +148,12 @@ private void DumpSection(R2RReader r2r, R2RSection section)
146148 if ( _raw )
147149 {
148150 DumpBytes ( r2r , section . RelativeVirtualAddress , ( uint ) section . Size ) ;
151+ _writer . WriteLine ( ) ;
152+ }
153+ if ( _sectionContents )
154+ {
155+ DumpSectionContents ( r2r , section ) ;
156+ _writer . WriteLine ( ) ;
149157 }
150158 }
151159
@@ -162,7 +170,7 @@ private void DumpMethod(R2RReader r2r, R2RMethod method)
162170 _writer . Write ( method . GcInfo ) ;
163171 if ( _raw )
164172 {
165- DumpBytes ( r2r , method . GcInfo . Offset , ( uint ) method . GcInfo . Size ) ;
173+ DumpBytes ( r2r , method . GcInfo . Offset , ( uint ) method . GcInfo . Size , false ) ;
166174 }
167175 }
168176 _writer . WriteLine ( ) ;
@@ -204,9 +212,11 @@ private void DumpRuntimeFunction(R2RReader r2r, RuntimeFunction rtf)
204212 /// <summary>
205213 /// Prints a formatted string containing a block of bytes from the relative virtual address and size
206214 /// </summary>
207- public void DumpBytes ( R2RReader r2r , int rva , uint size )
215+ public void DumpBytes ( R2RReader r2r , int rva , uint size , bool convertToOffset = true )
208216 {
209- uint start = ( uint ) r2r . GetOffset ( rva ) ;
217+ int start = rva ;
218+ if ( convertToOffset )
219+ start = r2r . GetOffset ( rva ) ;
210220 if ( start > r2r . Image . Length || start + size > r2r . Image . Length )
211221 {
212222 throw new IndexOutOfRangeException ( ) ;
@@ -234,14 +244,76 @@ public void DumpBytes(R2RReader r2r, int rva, uint size)
234244 _writer . WriteLine ( ) ;
235245 }
236246
237- private void DumpAvailableTypes ( R2RReader r2r )
247+ private void DumpSectionContents ( R2RReader r2r , R2RSection section )
238248 {
239- WriteDivider ( "Available Types" ) ;
240- foreach ( string name in r2r . AvailableTypes )
249+ switch ( section . Type )
241250 {
242- _writer . WriteLine ( name ) ;
251+ case R2RSection . SectionType . READYTORUN_SECTION_AVAILABLE_TYPES :
252+ uint availableTypesSectionOffset = ( uint ) r2r . GetOffset ( section . RelativeVirtualAddress ) ;
253+ NativeParser availableTypesParser = new NativeParser ( r2r . Image , availableTypesSectionOffset ) ;
254+ NativeHashtable availableTypes = new NativeHashtable ( r2r . Image , availableTypesParser , ( uint ) ( availableTypesSectionOffset + section . Size ) ) ;
255+ _writer . WriteLine ( availableTypes . ToString ( ) ) ;
256+
257+ foreach ( string name in r2r . AvailableTypes )
258+ {
259+ _writer . WriteLine ( name ) ;
260+ }
261+ break ;
262+ case R2RSection . SectionType . READYTORUN_SECTION_METHODDEF_ENTRYPOINTS :
263+ NativeArray methodEntryPoints = new NativeArray ( r2r . Image , ( uint ) r2r . GetOffset ( section . RelativeVirtualAddress ) ) ;
264+ _writer . Write ( methodEntryPoints . ToString ( ) ) ;
265+ break ;
266+ case R2RSection . SectionType . READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS :
267+ uint instanceSectionOffset = ( uint ) r2r . GetOffset ( section . RelativeVirtualAddress ) ;
268+ NativeParser instanceParser = new NativeParser ( r2r . Image , instanceSectionOffset ) ;
269+ NativeHashtable instMethodEntryPoints = new NativeHashtable ( r2r . Image , instanceParser , ( uint ) ( instanceSectionOffset + section . Size ) ) ;
270+ _writer . Write ( instMethodEntryPoints . ToString ( ) ) ;
271+ break ;
272+ case R2RSection . SectionType . READYTORUN_SECTION_RUNTIME_FUNCTIONS :
273+ int rtfOffset = r2r . GetOffset ( section . RelativeVirtualAddress ) ;
274+ int rtfEndOffset = rtfOffset + section . Size ;
275+ int rtfIndex = 0 ;
276+ while ( rtfOffset < rtfEndOffset )
277+ {
278+ uint rva = NativeReader . ReadUInt32 ( r2r . Image , ref rtfOffset ) ;
279+ _writer . WriteLine ( $ "{ rtfIndex } : 0x{ rva : X8} ") ;
280+ rtfIndex ++ ;
281+ }
282+ break ;
283+ case R2RSection . SectionType . READYTORUN_SECTION_COMPILER_IDENTIFIER :
284+ _writer . WriteLine ( r2r . CompileIdentifier ) ;
285+ break ;
286+ case R2RSection . SectionType . READYTORUN_SECTION_IMPORT_SECTIONS :
287+ foreach ( R2RImportSection importSection in r2r . ImportSections )
288+ {
289+ _writer . Write ( importSection . ToString ( ) ) ;
290+ if ( _raw && importSection . Entries . Count != 0 )
291+ {
292+ if ( importSection . SectionRVA != 0 )
293+ {
294+ _writer . WriteLine ( "Section Bytes:" ) ;
295+ DumpBytes ( r2r , importSection . SectionRVA , ( uint ) importSection . SectionSize ) ;
296+ }
297+ if ( importSection . SignatureRVA != 0 )
298+ {
299+ _writer . WriteLine ( "Signature Bytes:" ) ;
300+ DumpBytes ( r2r , importSection . SignatureRVA , ( uint ) importSection . Entries . Count * sizeof ( int ) ) ;
301+ }
302+ if ( importSection . AuxiliaryDataRVA != 0 )
303+ {
304+ _writer . WriteLine ( "AuxiliaryData Bytes:" ) ;
305+ DumpBytes ( r2r , importSection . AuxiliaryDataRVA , ( uint ) importSection . AuxiliaryData . Size ) ;
306+ }
307+ }
308+ foreach ( R2RImportSection . ImportSectionEntry entry in importSection . Entries )
309+ {
310+ _writer . WriteLine ( ) ;
311+ _writer . WriteLine ( entry . ToString ( ) ) ;
312+ }
313+ _writer . WriteLine ( ) ;
314+ }
315+ break ;
243316 }
244- _writer . WriteLine ( ) ;
245317 }
246318
247319 // <summary>
@@ -360,11 +432,6 @@ public void Dump(R2RReader r2r)
360432 QueryMethod ( r2r , "R2R Methods by Keyword" , _keywords , false ) ;
361433 }
362434
363- if ( _types )
364- {
365- DumpAvailableTypes ( r2r ) ;
366- }
367-
368435 _writer . WriteLine ( "=============================================================" ) ;
369436 _writer . WriteLine ( ) ;
370437 }
0 commit comments