Skip to content

Commit 6226ea5

Browse files
committed
Added Dumper class.
1 parent f08f3d7 commit 6226ea5

File tree

3 files changed

+99
-6
lines changed

3 files changed

+99
-6
lines changed

Forms/ProcessInfoForm.cs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ private void createClassAtAddressToolStripMenuItem_Click(object sender, EventArg
152152

153153
private void dumpToolStripMenuItem_Click(object sender, EventArgs e)
154154
{
155+
bool isModule;
155156
string fileName = string.Empty;
156157
string initialDirectory = string.Empty;
157158
IntPtr address;
158-
IntPtr size;
159+
int size;
159160

160161
if (GetToolStripSourceControl(sender) == modulesDataGridView)
161162
{
@@ -165,10 +166,11 @@ private void dumpToolStripMenuItem_Click(object sender, EventArgs e)
165166
return;
166167
}
167168

169+
isModule = true;
168170
fileName = $"{Path.GetFileNameWithoutExtension(module.Name)}_Dumped{Path.GetExtension(module.Name)}";
169171
initialDirectory = Path.GetDirectoryName(module.Path);
170172
address = module.Start;
171-
size = module.Size;
173+
size = module.Size.ToInt32();
172174
}
173175
else
174176
{
@@ -178,22 +180,32 @@ private void dumpToolStripMenuItem_Click(object sender, EventArgs e)
178180
return;
179181
}
180182

183+
isModule = false;
181184
fileName = $"Section_{section.Start.ToString("X")}_{section.End.ToString("X")}.dat";
182185
address = section.Start;
183-
size = section.Size;
186+
size = section.Size.ToInt32();
184187
}
185188

186189
using (var sfd = new SaveFileDialog())
187190
{
188191
sfd.FileName = fileName;
192+
sfd.Filter = "All|*.*";
189193
sfd.InitialDirectory = initialDirectory;
190194

191195
if (sfd.ShowDialog() == DialogResult.OK)
192196
{
193-
var data = process.ReadRemoteMemory(address, size.ToInt32());
194-
using (var bw = new BinaryWriter(sfd.OpenFile()))
197+
var dumper = new Dumper(process);
198+
199+
using (var stream = sfd.OpenFile())
195200
{
196-
bw.Write(data);
201+
if (isModule)
202+
{
203+
dumper.DumpModule(address, size, stream);
204+
}
205+
else
206+
{
207+
dumper.DumpSection(address, size, stream);
208+
}
197209
}
198210
}
199211
}

Memory/Dumper.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.Diagnostics.Contracts;
3+
using System.IO;
4+
5+
namespace ReClassNET.Memory
6+
{
7+
public class Dumper
8+
{
9+
private readonly RemoteProcess process;
10+
11+
public Dumper(RemoteProcess process)
12+
{
13+
Contract.Requires(process != null);
14+
15+
this.process = process;
16+
}
17+
18+
/// <summary>Dumps a section to the given stream.</summary>
19+
/// <param name="address">The begin of the section.</param>
20+
/// <param name="size">The size of the section.</param>
21+
/// <param name="stream">The stream to dump to.</param>
22+
public void DumpSection(IntPtr address, int size, Stream stream)
23+
{
24+
Contract.Requires(stream != null);
25+
26+
var data = process.ReadRemoteMemory(address, size);
27+
28+
stream.Write(data, 0, data.Length);
29+
}
30+
31+
/// <summary>Dumps a module to the given stream. The section headers of the pe header get fixed to make a valid pe file.</summary>
32+
/// <param name="address">The begin of the module.</param>
33+
/// <param name="size">The size of the module.</param>
34+
/// <param name="stream">The stream to dump to.</param>
35+
public void DumpModule(IntPtr address, int size, Stream stream)
36+
{
37+
Contract.Requires(stream != null);
38+
39+
var data = process.ReadRemoteMemory(address, size);
40+
41+
var pe = new SimplePeHeader(data);
42+
43+
// Fix the section headers.
44+
using (var bw = new BinaryWriter(new MemoryStream(data)))
45+
{
46+
for (var i = 0; i < pe.NumberOfSections; ++i)
47+
{
48+
var offset = pe.SectionOffset(i);
49+
bw.Seek(offset + 16, SeekOrigin.Begin);
50+
bw.Write(BitConverter.ToUInt32(data, offset + 8)); // SizeOfRawData = VirtualSize
51+
bw.Write(BitConverter.ToUInt32(data, offset + 12)); // PointerToRawData = VirtualAddress
52+
}
53+
}
54+
55+
stream.Write(data, 0, data.Length);
56+
}
57+
58+
private class SimplePeHeader
59+
{
60+
private readonly byte[] data;
61+
62+
private int e_lfanew => BitConverter.ToInt32(data, 60);
63+
64+
private int FileHeader => e_lfanew + 4;
65+
66+
public int NumberOfSections => BitConverter.ToInt16(data, FileHeader + 2);
67+
68+
private int SizeOfOptionalHeader => BitConverter.ToInt16(data, FileHeader + 16);
69+
70+
private int FirstSectionOffset => e_lfanew + 24 + SizeOfOptionalHeader;
71+
72+
public int SectionOffset(int index) => FirstSectionOffset + index * 40;
73+
74+
public SimplePeHeader(byte[] data)
75+
{
76+
this.data = data;
77+
}
78+
}
79+
}
80+
}

ReClass.NET.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@
154154
</Compile>
155155
<Compile Include="Memory\Module.cs" />
156156
<Compile Include="Memory\NodeDissector.cs" />
157+
<Compile Include="Memory\Dumper.cs" />
157158
<Compile Include="Memory\Section.cs" />
158159
<Compile Include="Memory\UnionDataType.cs" />
159160
<Compile Include="Nodes\BoolNode.cs" />

0 commit comments

Comments
 (0)