Skip to content

Commit f4e6ff5

Browse files
committed
Refactored code.
1 parent de54c06 commit f4e6ff5

File tree

4 files changed

+117
-89
lines changed

4 files changed

+117
-89
lines changed

ReClass.NET/Forms/ProcessInfoForm.cs

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ namespace ReClassNET.Forms
1414
{
1515
public partial class ProcessInfoForm : IconForm
1616
{
17-
private readonly RemoteProcess process;
17+
private readonly IProcessReader process;
1818

1919
/// <summary>The context menu of the sections grid view.</summary>
2020
public ContextMenuStrip GridContextMenu => contextMenuStrip;
2121

22-
public ProcessInfoForm(RemoteProcess process)
22+
public ProcessInfoForm(IProcessReader process)
2323
{
2424
Contract.Requires(process != null);
2525

@@ -61,11 +61,6 @@ protected override void OnFormClosed(FormClosedEventArgs e)
6161

6262
private async void ProcessInfoForm_Load(object sender, EventArgs e)
6363
{
64-
if (!process.IsValid)
65-
{
66-
return;
67-
}
68-
6964
var sectionsTable = new DataTable();
7065
sectionsTable.Columns.Add("address", typeof(string));
7166
sectionsTable.Columns.Add("size", typeof(string));
@@ -146,11 +141,8 @@ private void createClassAtAddressToolStripMenuItem_Click(object sender, EventArg
146141

147142
private void dumpToolStripMenuItem_Click(object sender, EventArgs e)
148143
{
149-
bool isModule;
150-
string fileName;
151-
var initialDirectory = string.Empty;
152-
IntPtr address;
153-
int size;
144+
Func<SaveFileDialog> createDialogFn;
145+
Action<Dumper, Stream> dumpFn;
154146

155147
if (GetToolStripSourceControl(sender) == modulesDataGridView)
156148
{
@@ -160,11 +152,18 @@ private void dumpToolStripMenuItem_Click(object sender, EventArgs e)
160152
return;
161153
}
162154

163-
isModule = true;
164-
fileName = $"{Path.GetFileNameWithoutExtension(module.Name)}_Dumped{Path.GetExtension(module.Name)}";
165-
initialDirectory = Path.GetDirectoryName(module.Path);
166-
address = module.Start;
167-
size = module.Size.ToInt32();
155+
createDialogFn = () => new SaveFileDialog
156+
{
157+
FileName = $"{Path.GetFileNameWithoutExtension(module.Name)}_Dumped{Path.GetExtension(module.Name)}",
158+
InitialDirectory = Path.GetDirectoryName(module.Path)
159+
};
160+
161+
dumpFn = (d, s) =>
162+
{
163+
d.DumpModule(module, s);
164+
165+
MessageBox.Show("Module successfully dumped.", Constants.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
166+
};
168167
}
169168
else
170169
{
@@ -174,43 +173,41 @@ private void dumpToolStripMenuItem_Click(object sender, EventArgs e)
174173
return;
175174
}
176175

177-
isModule = false;
178-
fileName = $"Section_{section.Start.ToString("X")}_{section.End.ToString("X")}.dat";
179-
address = section.Start;
180-
size = section.Size.ToInt32();
176+
createDialogFn = () => new SaveFileDialog
177+
{
178+
FileName = $"Section_{section.Start.ToString("X")}_{section.End.ToString("X")}.dat"
179+
};
180+
181+
dumpFn = (d, s) =>
182+
{
183+
d.DumpSection(section, s);
184+
185+
MessageBox.Show("Section successfully dumped.", Constants.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
186+
};
181187
}
182188

183-
using (var sfd = new SaveFileDialog())
189+
using (var sfd = createDialogFn())
184190
{
185-
sfd.FileName = fileName;
186191
sfd.Filter = "All|*.*";
187-
sfd.InitialDirectory = initialDirectory;
188192

189-
if (sfd.ShowDialog() == DialogResult.OK)
193+
if (sfd.ShowDialog() != DialogResult.OK)
190194
{
191-
var dumper = new Dumper(process);
195+
return;
196+
}
192197

193-
try
194-
{
195-
using (var stream = sfd.OpenFile())
196-
{
197-
if (isModule)
198-
{
199-
dumper.DumpModule(address, size, stream);
200-
}
201-
else
202-
{
203-
dumper.DumpSection(address, size, stream);
204-
}
205-
206-
MessageBox.Show("Module successfully dumped.", Constants.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
207-
}
208-
}
209-
catch (Exception ex)
198+
var dumper = new Dumper(process);
199+
200+
try
201+
{
202+
using (var stream = sfd.OpenFile())
210203
{
211-
Program.ShowException(ex);
204+
dumpFn(dumper, stream);
212205
}
213206
}
207+
catch (Exception ex)
208+
{
209+
Program.ShowException(ex);
210+
}
214211
}
215212
}
216213

@@ -235,7 +232,7 @@ private IntPtr GetSelectedAddress(object sender)
235232
}
236233
}
237234

238-
private Control GetToolStripSourceControl(object sender)
235+
private static Control GetToolStripSourceControl(object sender)
239236
{
240237
return ((sender as ToolStripMenuItem)?.GetCurrentParent() as ContextMenuStrip)?.SourceControl;
241238
}

ReClass.NET/Memory/Dumper.cs

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ namespace ReClassNET.Memory
66
{
77
public class Dumper
88
{
9-
private readonly RemoteProcess process;
9+
private readonly IRemoteMemoryReader process;
1010

11-
public Dumper(RemoteProcess process)
11+
public Dumper(IRemoteMemoryReader process)
1212
{
1313
Contract.Requires(process != null);
1414
Contract.Ensures(this.process != null);
1515

1616
this.process = process;
1717
}
1818

19-
/// <summary>Dumps a section to the given stream.</summary>
20-
/// <param name="address">The begin of the section.</param>
21-
/// <param name="size">The size of the section.</param>
19+
/// <summary>Dumps a chunk of memory to the given stream.</summary>
20+
/// <param name="address">The begin of the chunk.</param>
21+
/// <param name="size">The size of the chunk.</param>
2222
/// <param name="stream">The stream to dump to.</param>
23-
public void DumpSection(IntPtr address, int size, Stream stream)
23+
public void DumpRaw(IntPtr address, int size, Stream stream)
2424
{
2525
Contract.Requires(size >= 0);
2626
Contract.Requires(stream != null);
@@ -30,54 +30,30 @@ public void DumpSection(IntPtr address, int size, Stream stream)
3030
stream.Write(data, 0, data.Length);
3131
}
3232

33-
/// <summary>Dumps a module to the given stream. The section headers of the pe header get fixed to make a valid pe file.</summary>
34-
/// <param name="address">The begin of the module.</param>
35-
/// <param name="size">The size of the module.</param>
33+
/// <summary>Dumps a section to the given stream.</summary>
34+
/// <param name="section">The section to dump.</param>
3635
/// <param name="stream">The stream to dump to.</param>
37-
public void DumpModule(IntPtr address, int size, Stream stream)
36+
public void DumpSection(Section section, Stream stream)
3837
{
39-
Contract.Requires(size >= 0);
38+
Contract.Requires(section != null);
4039
Contract.Requires(stream != null);
4140

42-
var data = process.ReadRemoteMemory(address, size);
43-
44-
var pe = new SimplePeHeader(data);
45-
46-
// Fix the section headers.
47-
using (var bw = new BinaryWriter(new MemoryStream(data)))
48-
{
49-
for (var i = 0; i < pe.NumberOfSections; ++i)
50-
{
51-
var offset = pe.SectionOffset(i);
52-
bw.Seek(offset + 16, SeekOrigin.Begin);
53-
bw.Write(BitConverter.ToUInt32(data, offset + 8)); // SizeOfRawData = VirtualSize
54-
bw.Write(BitConverter.ToUInt32(data, offset + 12)); // PointerToRawData = VirtualAddress
55-
}
56-
}
57-
58-
stream.Write(data, 0, data.Length);
41+
DumpRaw(section.Start, section.Size.ToInt32(), stream);
5942
}
6043

61-
private class SimplePeHeader
44+
/// <summary>Dumps a module to the given stream. The section headers of the pe header get fixed to build a valid pe file.</summary>
45+
/// <param name="module">The module to dump.</param>
46+
/// <param name="stream">The stream to dump to.</param>
47+
public void DumpModule(Module module, Stream stream)
6248
{
63-
private readonly byte[] data;
64-
65-
private int e_lfanew => BitConverter.ToInt32(data, 60);
66-
67-
private int FileHeader => e_lfanew + 4;
68-
69-
public int NumberOfSections => BitConverter.ToInt16(data, FileHeader + 2);
70-
71-
private int SizeOfOptionalHeader => BitConverter.ToInt16(data, FileHeader + 16);
49+
Contract.Requires(module != null);
50+
Contract.Requires(stream != null);
7251

73-
private int FirstSectionOffset => e_lfanew + 24 + SizeOfOptionalHeader;
52+
var data = process.ReadRemoteMemory(module.Start, module.Size.ToInt32());
7453

75-
public int SectionOffset(int index) => FirstSectionOffset + index * 40;
54+
SimplePeHeader.FixSectionHeaders(data);
7655

77-
public SimplePeHeader(byte[] data)
78-
{
79-
this.data = data;
80-
}
56+
stream.Write(data, 0, data.Length);
8157
}
8258
}
8359
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace ReClassNET.Memory
9+
{
10+
public class SimplePeHeader
11+
{
12+
private readonly byte[] data;
13+
14+
private int e_lfanew => BitConverter.ToInt32(data, 60);
15+
16+
private int FileHeader => e_lfanew + 4;
17+
18+
public int NumberOfSections => BitConverter.ToInt16(data, FileHeader + 2);
19+
20+
private int SizeOfOptionalHeader => BitConverter.ToInt16(data, FileHeader + 16);
21+
22+
private int FirstSectionOffset => e_lfanew + 24 + SizeOfOptionalHeader;
23+
24+
public int SectionOffset(int index) => FirstSectionOffset + index * 40;
25+
26+
private SimplePeHeader(byte[] data)
27+
{
28+
this.data = data;
29+
}
30+
31+
/// <summary>
32+
/// Rewrites the section headers to build a valid pe file.
33+
/// </summary>
34+
/// <param name="data">The memory of a dumped module.</param>
35+
public static void FixSectionHeaders(byte[] data)
36+
{
37+
var pe = new SimplePeHeader(data);
38+
39+
using (var ms = new MemoryStream(data))
40+
{
41+
using (var bw = new BinaryWriter(ms))
42+
{
43+
for (var i = 0; i < pe.NumberOfSections; ++i)
44+
{
45+
var offset = pe.SectionOffset(i);
46+
bw.Seek(offset + 16, SeekOrigin.Begin);
47+
bw.Write(BitConverter.ToUInt32(data, offset + 8)); // SizeOfRawData = VirtualSize
48+
bw.Write(BitConverter.ToUInt32(data, offset + 12)); // PointerToRawData = VirtualAddress
49+
}
50+
}
51+
}
52+
}
53+
}
54+
}

ReClass.NET/ReClass.NET.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@
265265
<Compile Include="Memory\NodeDissector.cs" />
266266
<Compile Include="Memory\Dumper.cs" />
267267
<Compile Include="Memory\Section.cs" />
268+
<Compile Include="Memory\SimplePeHeader.cs" />
268269
<Compile Include="Memory\UnionDataType.cs" />
269270
<Compile Include="Native\INativeMethods.cs" />
270271
<Compile Include="Native\NativeMethods.Unix.cs" />

0 commit comments

Comments
 (0)