Skip to content

Commit e6ecf63

Browse files
committed
Added heap sections and faster lookup.
1 parent c8d24bb commit e6ecf63

File tree

4 files changed

+84
-38
lines changed

4 files changed

+84
-38
lines changed

Memory/NodeDissector.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,18 +116,18 @@ private static Type GuessPointerType(IntPtr address, MemoryBuffer memory)
116116
var section = memory.Process.GetSectionToPointer(address);
117117
if (section != null) // If the address points to a section it's valid memory.
118118
{
119-
if (section.Category == RemoteProcess.SectionCategory.Code) // If the section contains code, it should be a function pointer.
119+
if (section.Category == RemoteProcess.SectionCategory.CODE) // If the section contains code, it should be a function pointer.
120120
{
121121
return typeof(FunctionPtrNode);
122122
}
123-
else if (section.Category == RemoteProcess.SectionCategory.Data) // If the section contains data, it is at least a pointer to a class or something.
123+
else if (section.Category == RemoteProcess.SectionCategory.DATA) // If the section contains data, it is at least a pointer to a class or something.
124124
{
125125
// Check if it is a vtable. Check if the first 3 values are pointers to a code section.
126126
bool valid = true;
127127
for (var i = 0; i < 3; ++i)
128128
{
129129
var pointee = memory.Process.ReadRemoteObject<IntPtr>(address);
130-
if (memory.Process.GetSectionToPointer(pointee)?.Category != RemoteProcess.SectionCategory.Code)
130+
if (memory.Process.GetSectionToPointer(pointee)?.Category != RemoteProcess.SectionCategory.CODE)
131131
{
132132
valid = false;
133133
break;

Memory/RemoteProcess.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ public class Module
4141
public enum SectionCategory
4242
{
4343
Unknown,
44-
Code,
45-
Data
44+
CODE,
45+
DATA
4646
}
4747

4848
public class Section
@@ -377,20 +377,15 @@ public Section GetSectionToPointer(IntPtr address)
377377
{
378378
lock (sections)
379379
{
380-
return sections
381-
.Where(s => s.Category != SectionCategory.Unknown)
382-
.Where(s => address.InRange(s.Start, s.End))
383-
.FirstOrDefault();
380+
return sections.BinaryFind(s => address.CompareToRange(s.Start, s.End));
384381
}
385382
}
386383

387384
public Module GetModuleToPointer(IntPtr address)
388385
{
389386
lock (modules)
390387
{
391-
return modules
392-
.Where(m => address.InRange(m.Start, m.End))
393-
.FirstOrDefault();
388+
return modules.BinaryFind(m => address.CompareToRange(m.Start, m.End));
394389
}
395390
}
396391

@@ -412,7 +407,14 @@ public string GetNamedAddress(IntPtr address)
412407
var section = GetSectionToPointer(address);
413408
if (section != null)
414409
{
415-
return $"<{section.Category}>{section.ModuleName}.{address.ToString("X")}";
410+
if (section.Category != SectionCategory.Unknown)
411+
{
412+
return $"<{section.Category}>{section.ModuleName}.{address.ToString("X")}";
413+
}
414+
else if (section.Type == NativeMethods.TypeEnum.MEM_PRIVATE)
415+
{
416+
return $"<HEAP>{address.ToString("X")}";
417+
}
416418
}
417419
var module = GetModuleToPointer(address);
418420
if (module != null)
@@ -470,13 +472,13 @@ public Task UpdateProcessInformationsAsync()
470472
{
471473
case ".text":
472474
case "code":
473-
section.Category = SectionCategory.Code;
475+
section.Category = SectionCategory.CODE;
474476
break;
475477
case ".data":
476478
case "data":
477479
case ".rdata":
478480
case ".idata":
479-
section.Category = SectionCategory.Data;
481+
section.Category = SectionCategory.DATA;
480482
break;
481483
}
482484
newSections.Add(section);
@@ -493,6 +495,9 @@ public Task UpdateProcessInformationsAsync()
493495
}
494496
);
495497

498+
newModules.Sort((m1, m2) => m1.Start.CompareTo(m2.Start));
499+
newSections.Sort((s1, s2) => s1.Start.CompareTo(s2.Start));
500+
496501
lock (modules)
497502
{
498503
modules.Clear();

NativeHelper/dllmain.cpp

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -213,32 +213,23 @@ EXTERN_DLL_EXPORT VOID __stdcall EnumerateRemoteSectionsAndModules(HANDLE proces
213213
};
214214
std::vector<SectionInfo> sections;
215215

216-
SYSTEM_INFO sysInfo;
217-
GetSystemInfo(&sysInfo);
218-
219-
MEMORY_BASIC_INFORMATION memInfo;
220-
size_t address = (size_t)sysInfo.lpMinimumApplicationAddress;
221-
while (address < (size_t)sysInfo.lpMaximumApplicationAddress)
216+
MEMORY_BASIC_INFORMATION memInfo = { 0 };
217+
memInfo.RegionSize = 0x1000;
218+
size_t address = 0;
219+
while (VirtualQueryEx(process, (LPCVOID)address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) != 0 && address + memInfo.RegionSize > address)
222220
{
223-
if (VirtualQueryEx(process, (LPCVOID)address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION)) != 0)
224-
{
225-
if (memInfo.State == MEM_COMMIT /*&& memInfo.Type == MEM_PRIVATE*/)
226-
{
227-
SectionInfo section = {};
228-
section.BaseAddress = memInfo.BaseAddress;
229-
section.RegionSize = memInfo.RegionSize;
230-
section.State = memInfo.State;
231-
section.Protection = memInfo.Protect;
232-
section.Type = memInfo.Type;
233-
234-
sections.push_back(std::move(section));
235-
}
236-
address = (ULONG_PTR)memInfo.BaseAddress + memInfo.RegionSize;
237-
}
238-
else
221+
if (memInfo.State == MEM_COMMIT)
239222
{
240-
address += 1024;
223+
SectionInfo section = {};
224+
section.BaseAddress = memInfo.BaseAddress;
225+
section.RegionSize = memInfo.RegionSize;
226+
section.State = memInfo.State;
227+
section.Protection = memInfo.Protect;
228+
section.Type = memInfo.Type;
229+
230+
sections.push_back(std::move(section));
241231
}
232+
address = (size_t)memInfo.BaseAddress + memInfo.RegionSize;
242233
}
243234

244235
auto handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetProcessId(process));

Util/Extensions.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,26 @@ public static bool InRange(this IntPtr address, IntPtr start, IntPtr end)
129129
#endif
130130
}
131131

132+
[Pure]
133+
public static int CompareTo(this IntPtr lhs, IntPtr rhs)
134+
{
135+
#if WIN64
136+
return ((ulong)lhs.ToInt64()).CompareTo((ulong)rhs.ToInt64());
137+
#else
138+
return ((uint)lhs.ToInt32()).CompareTo((uint)rhs.ToInt32());
139+
#endif
140+
}
141+
142+
[Pure]
143+
public static int CompareToRange(this IntPtr address, IntPtr start, IntPtr end)
144+
{
145+
if (InRange(address, start, end))
146+
{
147+
return 0;
148+
}
149+
return CompareTo(address, start);
150+
}
151+
132152
#endregion
133153

134154
#region String
@@ -259,6 +279,36 @@ public static bool IsNearlyEqual(this double val, double other, double epsilon)
259279

260280
#endregion
261281

282+
#region List
283+
284+
public static T BinaryFind<T>(this IList<T> tf, Func<T, int> comparer)
285+
{
286+
var lo = 0;
287+
var hi = tf.Count - 1;
288+
289+
while (lo <= hi)
290+
{
291+
var median = lo + (hi - lo >> 1);
292+
var num = comparer(tf[median]);
293+
if (num == 0)
294+
{
295+
return tf[median];
296+
}
297+
if (num > 0)
298+
{
299+
lo = median + 1;
300+
}
301+
else
302+
{
303+
hi = median - 1;
304+
}
305+
}
306+
307+
return default(T);
308+
}
309+
310+
#endregion
311+
262312
#region Linq
263313

264314
[DebuggerStepThrough]

0 commit comments

Comments
 (0)