11using System ;
22using System . Collections . Generic ;
33using System . Diagnostics . Contracts ;
4+ using System . Linq ;
45using System . Runtime . InteropServices ;
56using ReClassNET . Native ;
67using ReClassNET . Util ;
@@ -9,43 +10,73 @@ namespace ReClassNET.Memory
910{
1011 public class Disassembler
1112 {
12- public List < DisassembledInstruction > DisassembleRemoteCode ( RemoteProcess process , IntPtr address , int length )
13+ private readonly NativeHelper nativeHelper ;
14+
15+ public Disassembler ( NativeHelper nativeHelper )
1316 {
14- Contract . Requires ( process != null ) ;
17+ Contract . Requires ( nativeHelper != null ) ;
1518
16- var instructions = new List < DisassembledInstruction > ( ) ;
19+ this . nativeHelper = nativeHelper ;
20+ }
21+
22+ public List < DisassembledInstruction > RemoteDisassembleCode ( RemoteProcess process , IntPtr address , int length )
23+ {
24+ Contract . Requires ( process != null ) ;
1725
1826 var buffer = process . ReadRemoteMemory ( address , length ) ;
1927
2028 var handle = GCHandle . Alloc ( buffer , GCHandleType . Pinned ) ;
2129 try
2230 {
23- var eip = handle . AddrOfPinnedObject ( ) ;
24- var end = eip + length ;
25- var virtualAddress = address ;
26-
27- var instruction = new InstructionData ( ) ;
28- while ( true )
31+ return DisassembleCode ( handle . AddrOfPinnedObject ( ) , length , address ) . ToList ( ) ;
32+ }
33+ finally
34+ {
35+ if ( handle . IsAllocated )
2936 {
30- if ( ! process . NativeHelper . DisassembleCode ( eip , end . Sub ( eip ) . ToInt32 ( ) , virtualAddress , out instruction ) )
31- {
32- break ;
33- }
37+ handle . Free ( ) ;
38+ }
39+ }
40+ }
3441
35- instructions . Add ( new DisassembledInstruction
36- {
37- Address = virtualAddress ,
38- Length = instruction . Length ,
39- Instruction = instruction . Instruction
40- } ) ;
42+ public IEnumerable < DisassembledInstruction > DisassembleCode ( IntPtr address , int length , IntPtr virtualAddress )
43+ {
44+ var instructions = new List < DisassembledInstruction > ( ) ;
4145
42- eip = eip + instruction . Length ;
43- if ( eip . CompareTo ( end ) >= 0 || buffer [ eip . Sub ( handle . AddrOfPinnedObject ( ) ) . ToInt32 ( ) ] == 0xCC )
44- {
45- break ;
46- }
47- virtualAddress = virtualAddress + instruction . Length ;
46+ var eip = address ;
47+ var end = address + length ;
48+
49+ var instruction = new InstructionData ( ) ;
50+ while ( eip . CompareTo ( end ) == - 1 )
51+ {
52+ if ( ! nativeHelper . DisassembleCode ( eip , end . Sub ( eip ) . ToInt32 ( ) , virtualAddress , out instruction ) )
53+ {
54+ break ;
4855 }
56+
57+ yield return new DisassembledInstruction
58+ {
59+ Address = virtualAddress ,
60+ Length = instruction . Length ,
61+ Data = instruction . Data ,
62+ Instruction = instruction . Instruction
63+ } ;
64+
65+ eip = eip + instruction . Length ;
66+ virtualAddress = virtualAddress + instruction . Length ;
67+ }
68+ }
69+
70+ public List < DisassembledInstruction > RemoteDisassembleFunction ( RemoteProcess process , IntPtr address , int length )
71+ {
72+ Contract . Requires ( process != null ) ;
73+
74+ var buffer = process . ReadRemoteMemory ( address , length ) ;
75+
76+ var handle = GCHandle . Alloc ( buffer , GCHandleType . Pinned ) ;
77+ try
78+ {
79+ return DisassembleFunction ( handle . AddrOfPinnedObject ( ) , length , address ) . ToList ( ) ;
4980 }
5081 finally
5182 {
@@ -54,8 +85,13 @@ public List<DisassembledInstruction> DisassembleRemoteCode(RemoteProcess process
5485 handle . Free ( ) ;
5586 }
5687 }
88+ }
5789
58- return instructions ;
90+ public IEnumerable < DisassembledInstruction > DisassembleFunction ( IntPtr address , int length , IntPtr virtualAddress )
91+ {
92+ // Read until first CC.
93+ return DisassembleCode ( address , length , virtualAddress )
94+ . TakeUntil ( i => i . Length == 1 && i . Data [ 0 ] == 0xCC ) ;
5995 }
6096
6197 public DisassembledInstruction GetPreviousInstruction ( RemoteProcess process , IntPtr address )
@@ -134,6 +170,9 @@ public class DisassembledInstruction
134170 {
135171 public IntPtr Address ;
136172 public int Length ;
173+ public byte [ ] Data ;
137174 public string Instruction ;
175+
176+ public override string ToString ( ) => $ "{ Address . ToString ( Constants . StringHexFormat ) } - { Instruction } ";
138177 }
139178}
0 commit comments