Skip to content

Commit 0fd848b

Browse files
committed
Added comments.
1 parent 264157f commit 0fd848b

File tree

1 file changed

+77
-34
lines changed

1 file changed

+77
-34
lines changed

Memory/Disassembler.cs

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,17 @@ public Disassembler(NativeHelper nativeHelper)
1919
this.nativeHelper = nativeHelper;
2020
}
2121

22+
/// <summary>
23+
/// Disassembles the code in the given range (<paramref name="address"/>, <paramref name="lenght"/>) in the remote process.
24+
/// </summary>
25+
/// <param name="process">The process to read from.</param>
26+
/// <param name="address">The address of the code.</param>
27+
/// <param name="length">The length of the code.</param>
28+
/// <returns>A list of <see cref="DisassembledInstruction"/>.</returns>
2229
public List<DisassembledInstruction> RemoteDisassembleCode(RemoteProcess process, IntPtr address, int length)
2330
{
2431
Contract.Requires(process != null);
32+
Contract.Ensures(Contract.Result<List<DisassembledInstruction>>() != null);
2533

2634
var buffer = process.ReadRemoteMemory(address, length);
2735

@@ -39,9 +47,16 @@ public List<DisassembledInstruction> RemoteDisassembleCode(RemoteProcess process
3947
}
4048
}
4149

50+
/// <summary>
51+
/// Disassembles the code in the given range (<paramref name="address"/>, <paramref name="lenght"/>).
52+
/// </summary>
53+
/// <param name="address">The address of the code.</param>
54+
/// <param name="length">The length of the code.</param>
55+
/// <param name="virtualAddress">The virtual address of the code. This allows to decode instructions located anywhere in memory even if they are not at their original place.</param>
56+
/// <returns>A list of <see cref="DisassembledInstruction"/>.</returns>
4257
public IEnumerable<DisassembledInstruction> DisassembleCode(IntPtr address, int length, IntPtr virtualAddress)
4358
{
44-
var instructions = new List<DisassembledInstruction>();
59+
Contract.Ensures(Contract.Result<IEnumerable<DisassembledInstruction>>() != null);
4560

4661
var eip = address;
4762
var end = address + length;
@@ -62,14 +77,22 @@ public IEnumerable<DisassembledInstruction> DisassembleCode(IntPtr address, int
6277
Instruction = instruction.Instruction
6378
};
6479

65-
eip = eip + instruction.Length;
66-
virtualAddress = virtualAddress + instruction.Length;
80+
eip += instruction.Length;
81+
virtualAddress += instruction.Length;
6782
}
6883
}
6984

85+
/// <summary>
86+
/// Disassembles the code in the given range (<paramref name="address"/>, <paramref name="lenght"/>) in the remote process until the first 0xCC instruction.
87+
/// </summary>
88+
/// <param name="process">The process to read from.</param>
89+
/// <param name="address">The address of the code.</param>
90+
/// <param name="length">The length of the code.</param>
91+
/// <returns>A list of <see cref="DisassembledInstruction"/>.</returns>
7092
public List<DisassembledInstruction> RemoteDisassembleFunction(RemoteProcess process, IntPtr address, int length)
7193
{
7294
Contract.Requires(process != null);
95+
Contract.Ensures(Contract.Result<List<DisassembledInstruction>>() != null);
7396

7497
var buffer = process.ReadRemoteMemory(address, length);
7598

@@ -87,75 +110,95 @@ public List<DisassembledInstruction> RemoteDisassembleFunction(RemoteProcess pro
87110
}
88111
}
89112

113+
/// <summary>
114+
/// Disassembles the code in the given range (<paramref name="address"/>, <paramref name="lenght"/>) until the first 0xCC instruction.
115+
/// </summary>
116+
/// <param name="address">The address of the code.</param>
117+
/// <param name="length">The length of the code.</param>
118+
/// <param name="virtualAddress">The virtual address of the code. This allows to decode instructions located anywhere in memory even if they are not at their original place.</param>
119+
/// <returns>A list of <see cref="DisassembledInstruction"/>.</returns>
90120
public IEnumerable<DisassembledInstruction> DisassembleFunction(IntPtr address, int length, IntPtr virtualAddress)
91121
{
122+
Contract.Ensures(Contract.Result<IEnumerable<DisassembledInstruction>>() != null);
123+
92124
// Read until first CC.
93125
return DisassembleCode(address, length, virtualAddress)
94126
.TakeUntil(i => i.Length == 1 && i.Data[0] == 0xCC);
95127
}
96128

97-
public DisassembledInstruction GetPreviousInstruction(RemoteProcess process, IntPtr address)
129+
/// <summary>
130+
/// Disassembles the instruction prior to the given address.
131+
/// </summary>
132+
/// <param name="process">The process to read from.</param>
133+
/// <param name="address">The address of the code.</param>
134+
/// <returns>The prior instruction.</returns>
135+
public DisassembledInstruction RemoteGetPreviousInstruction(RemoteProcess process, IntPtr address)
98136
{
99137
var buffer = process.ReadRemoteMemory(address - 80, 80);
100138

101139
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
102140
try
103141
{
104-
var eip = handle.AddrOfPinnedObject();
105-
var end = eip + 80;
106-
var virtualAddress = address;
142+
return GetPreviousInstruction(handle.AddrOfPinnedObject(), address);
143+
}
144+
finally
145+
{
146+
if (handle.IsAllocated)
147+
{
148+
handle.Free();
149+
}
150+
}
151+
}
107152

108-
var instruction = new InstructionData();
153+
private DisassembledInstruction GetPreviousInstruction(IntPtr address, IntPtr virtualAddress)
154+
{
155+
var end = address + 80;
156+
157+
var instruction = new InstructionData();
109158

110-
var x = GetPreviousInstructionHelper(process, end, 80, ref instruction);
159+
var x = GetPreviousInstructionHelper(end, 80, virtualAddress, ref instruction);
160+
if (x != end)
161+
{
162+
x = GetPreviousInstructionHelper(end, 40, virtualAddress, ref instruction);
111163
if (x != end)
112164
{
113-
x = GetPreviousInstructionHelper(process, end, 40, ref instruction);
165+
x = GetPreviousInstructionHelper(end, 20, virtualAddress, ref instruction);
114166
if (x != end)
115167
{
116-
x = GetPreviousInstructionHelper(process, end, 20, ref instruction);
168+
x = GetPreviousInstructionHelper(end, 10, virtualAddress, ref instruction);
117169
if (x != end)
118170
{
119-
x = GetPreviousInstructionHelper(process, end, 10, ref instruction);
120-
if (x != end)
171+
for (var i = 1; i < 20; ++i)
121172
{
122-
for (var i = 1; i < 20; ++i)
173+
x = end - i;
174+
if (nativeHelper.DisassembleCode(x, end.Sub(x).ToInt32(), virtualAddress, out instruction))
123175
{
124-
x = end - i;
125-
if (process.NativeHelper.DisassembleCode(x, end.Sub(x).ToInt32(), virtualAddress, out instruction))
126-
{
127-
break;
128-
}
176+
break;
129177
}
130178
}
131179
}
132180
}
133181
}
134-
135-
return new DisassembledInstruction
136-
{
137-
Address = address - instruction.Length,
138-
Length = instruction.Length,
139-
Instruction = instruction.Instruction
140-
};
141182
}
142-
finally
183+
184+
return new DisassembledInstruction
143185
{
144-
if (handle.IsAllocated)
145-
{
146-
handle.Free();
147-
}
148-
}
186+
Address = address - instruction.Length,
187+
Length = instruction.Length,
188+
Instruction = instruction.Instruction
189+
};
149190
}
150191

151-
private IntPtr GetPreviousInstructionHelper(RemoteProcess process, IntPtr address, int distance, ref InstructionData instruction)
192+
private IntPtr GetPreviousInstructionHelper(IntPtr address, int distance, IntPtr virtualAddress, ref InstructionData instruction)
152193
{
153194
var x = address - distance;
195+
var y = virtualAddress - distance;
154196
while (x.CompareTo(address) == -1) // aka x < address
155197
{
156-
if (process.NativeHelper.DisassembleCode(x, address.Sub(x).ToInt32(), IntPtr.Zero, out instruction))
198+
if (nativeHelper.DisassembleCode(x, address.Sub(x).ToInt32(), y, out instruction))
157199
{
158200
x += instruction.Length;
201+
y += instruction.Length;
159202
}
160203
else
161204
{

0 commit comments

Comments
 (0)