Skip to content

Commit c86a018

Browse files
committed
Added MemoryPage pointer checking
Fixed "offsets" sorting in table Optimized strings reading
1 parent 8d96c91 commit c86a018

15 files changed

Lines changed: 444 additions & 101 deletions

StructureSpiderAdvanced/MainViewModel.cs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.ObjectModel;
55
using System.Windows.Threading;
66
using System.Threading;
7+
using System.Windows.Controls;
78

89
namespace StructureSpiderAdvanced
910
{
@@ -161,10 +162,11 @@ public bool UseMethodTable
161162
RaisePropertyChanged(nameof(UseMethodTable));
162163
}
163164
}
165+
166+
public bool UseMemoryPage { get; set; } = true;
164167

165-
public bool NoLooping { get; set; } = true;
166168

167-
public ushort MethodTableLength { get; set; } = 3;
169+
public bool NoLooping { get; set; } = true;
168170
public ushort StringLength { get; set; } = 256;
169171
public StringCompareType StringCompareType { get; set; } = StringCompareType.Equal;
170172
public bool StringIgnoreCase { get; set; } = false;
@@ -197,7 +199,7 @@ public bool UseEndOffsets
197199
////////////////////////////////////////////////
198200
public List<int> MaxLevels { get; set; } = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
199201
public List<DataType> DataTypes { get; set; } = new List<DataType>();
200-
public List<int> Alignments { get; set; } = new List<int>() { 1, 2, 4, 8 };
202+
public List<ushort> Alignments { get; set; } = new List<ushort>() { 1, 2, 4, 8 };
201203
public List<StringCompareType> StringCompareTypes { get; set; } = new List<StringCompareType>();
202204
}
203205

@@ -251,22 +253,22 @@ public string Value
251253

252254
public List<int> Offsets = new List<int>();
253255

254-
public string Offset0 { get { return GetOffset(0); } set { } }
255-
public string Offset1 { get { return GetOffset(1); } set { } }
256-
public string Offset2 { get { return GetOffset(2); } set { } }
257-
public string Offset3 { get { return GetOffset(3); } set { } }
258-
public string Offset4 { get { return GetOffset(4); } set { } }
259-
public string Offset5 { get { return GetOffset(5); } set { } }
260-
public string Offset6 { get { return GetOffset(6); } set { } }
261-
public string Offset7 { get { return GetOffset(7); } set { } }
262-
public string Offset8 { get { return GetOffset(8); } set { } }
263-
public string Offset9 { get { return GetOffset(9); } set { } }
256+
public int Offset0 { get { return GetOffset(0); } set { } }
257+
public int Offset1 { get { return GetOffset(1); } set { } }
258+
public int Offset2 { get { return GetOffset(2); } set { } }
259+
public int Offset3 { get { return GetOffset(3); } set { } }
260+
public int Offset4 { get { return GetOffset(4); } set { } }
261+
public int Offset5 { get { return GetOffset(5); } set { } }
262+
public int Offset6 { get { return GetOffset(6); } set { } }
263+
public int Offset7 { get { return GetOffset(7); } set { } }
264+
public int Offset8 { get { return GetOffset(8); } set { } }
265+
public int Offset9 { get { return GetOffset(9); } set { } }
264266

265-
private string GetOffset(int index)
267+
private int GetOffset(int index)
266268
{
267269
if (index >= Offsets.Count)
268-
return "";
269-
return Offsets[index].ToString("x");
270+
return -1;// -1 will not be displayed in table due to OffsetConverter
271+
return Offsets[index];
270272
}
271273
}
272274
}

StructureSpiderAdvanced/MainWindow.xaml

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<local:HexConverter x:Key="HexConverter" />
1313
<local:BoolToVisibilityConverter x:Key="BoolToHiddenConverter"/>
1414
<local:ScanTypeToVisibilityConverter x:Key="ScanTypeToVisibilityConverter"/>
15+
<local:OffsetConverter x:Key="OffsetConverter"/>
1516
</ResourceDictionary>
1617
</Window.Resources>
1718
<Grid DataContext="{Binding ElementName=ucMain}">
@@ -34,18 +35,8 @@
3435
<Button Content="Refresh" HorizontalAlignment="Left" VerticalAlignment="Top" MinWidth="80" Margin="5" Click="RefreshProcesses" IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}"/>
3536

3637
<CheckBox Content="No Looping Pointers" ToolTip="Removing duplicates, preventing application to stuck in closed cycle." Margin="5" IsChecked="{Binding Path=ViewModel.NoLooping}" IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}" Foreground="#FFC8C8C8"/>
37-
<CheckBox ToolTip="pro: Filter out incorrect/unstable pointers con: Works buggy while scanning strings" Content="Use Virtual Method Table" Margin="5" IsChecked="{Binding Path=ViewModel.UseMethodTable}" IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}" Foreground="#FFC8C8C8"/>
38-
<TextBox ToolTip="Recommended value is 3.Bigger structures has bigger VMT. You can change this if you know what you doing." materialDesign:HintAssist.Hint="Min VMT Length" Style="{StaticResource MaterialDesignFloatingHintTextBox}"
39-
VerticalContentAlignment="Center" Margin="5" MinWidth="50" Foreground="#FFC8C8C8"
40-
IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}" Visibility="{Binding Path=ViewModel.UseMethodTable, Converter={StaticResource BoolToHiddenConverter}}">
41-
<TextBox.Text>
42-
<Binding Path="ViewModel.MethodTableLength" UpdateSourceTrigger="PropertyChanged">
43-
<Binding.ValidationRules>
44-
<local:StringToIntValidationRule ValidationStep="RawProposedValue"/>
45-
</Binding.ValidationRules>
46-
</Binding>
47-
</TextBox.Text>
48-
</TextBox>
38+
<CheckBox ToolTip="pro: Filter out incorrect/unstable pointers. con: Works buggy while scanning strings" Content="Use Virtual Method Table" Margin="5" IsChecked="{Binding Path=ViewModel.UseMethodTable}" IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}" Foreground="#FFC8C8C8"/>
39+
<CheckBox ToolTip="Strongly recommended for x64 process, can be buggy for x32 process" Content="Use memory pages for checking pointer" Margin="5" IsChecked="{Binding Path=ViewModel.UseMemoryPage}" IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}" Foreground="#FFC8C8C8"/>
4940
</StackPanel>
5041
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" Height="10"></GridSplitter>
5142
<StackPanel Grid.Row="2" Orientation="Horizontal">
@@ -92,18 +83,9 @@
9283
</TextBox.Text>
9384
</TextBox>
9485

95-
<TextBox materialDesign:HintAssist.Hint="Alignment" ToolTip="Scan step. For x32 bit process pointers and strings recommended alignment value is 4, for x64 recommended value is 8" Style="{StaticResource MaterialDesignFloatingHintTextBox}"
96-
VerticalContentAlignment="Center" Margin="5" MinWidth="50" Foreground="#FFC8C8C8"
97-
IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}"
98-
Visibility="{Binding Path=ViewModel.SelectedDataType, Converter={StaticResource ScanTypeToVisibilityConverter}, ConverterParameter=PointerAlighment}">
99-
<TextBox.Text>
100-
<Binding Path="ViewModel.Alignment" UpdateSourceTrigger="PropertyChanged">
101-
<Binding.ValidationRules>
102-
<local:StringToIntValidationRule ValidationStep="RawProposedValue"/>
103-
</Binding.ValidationRules>
104-
</Binding>
105-
</TextBox.Text>
106-
</TextBox>
86+
<ComboBox materialDesign:HintAssist.Hint="Alignment" ToolTip="Scan step. For x32 bit process pointers and strings recommended alignment value is 4, for x64 recommended value is 8" Style="{StaticResource MaterialDesignFloatingHintComboBox}"
87+
ItemsSource="{Binding Path=ViewModel.Alignments}" SelectedValue="{Binding Path=ViewModel.Alignment}" IsEnabled="{Binding Path=ViewModel.InterfaceEnabled}"
88+
MinWidth="50" Margin="5" Foreground="#FFC8C8C8"/>
10789

10890
<TextBox materialDesign:HintAssist.Hint="String Length" ToolTip="Maximum length of string bytes to read" Style="{StaticResource MaterialDesignFloatingHintTextBox}"
10991
VerticalContentAlignment="Center" Margin="5" MinWidth="50" Foreground="#FFC8C8C8"
@@ -129,8 +111,21 @@
129111

130112
</StackPanel>
131113
<GridSplitter Grid.Row="3" HorizontalAlignment="Stretch" Height="10"></GridSplitter>
132-
<DataGrid Grid.Row="4" Name="ResultsList" ItemsSource="{Binding Path=ViewModel.VisibleResults}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False">
133-
114+
<DataGrid Grid.Row="4" Name="ResultsList" ItemsSource="{Binding Path=ViewModel.VisibleResults}" CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" AutoGenerateColumns="False">
115+
<DataGrid.Columns>
116+
<DataGridTextColumn Header="Level" Binding="{Binding Level}" />
117+
<DataGridTextColumn Header="Value" Binding="{Binding Value}" />
118+
<DataGridTextColumn Header="Offset0" Binding="{Binding Offset0, Converter={StaticResource OffsetConverter}}" />
119+
<DataGridTextColumn Header="Offset1" Binding="{Binding Offset1, Converter={StaticResource OffsetConverter}}" />
120+
<DataGridTextColumn Header="Offset2" Binding="{Binding Offset2, Converter={StaticResource OffsetConverter}}" />
121+
<DataGridTextColumn Header="Offset3" Binding="{Binding Offset3, Converter={StaticResource OffsetConverter}}" />
122+
<DataGridTextColumn Header="Offset4" Binding="{Binding Offset4, Converter={StaticResource OffsetConverter}}" />
123+
<DataGridTextColumn Header="Offset5" Binding="{Binding Offset5, Converter={StaticResource OffsetConverter}}" />
124+
<DataGridTextColumn Header="Offset6" Binding="{Binding Offset6, Converter={StaticResource OffsetConverter}}" />
125+
<DataGridTextColumn Header="Offset7" Binding="{Binding Offset7, Converter={StaticResource OffsetConverter}}" />
126+
<DataGridTextColumn Header="Offset8" Binding="{Binding Offset8, Converter={StaticResource OffsetConverter}}" />
127+
<DataGridTextColumn Header="Offset9" Binding="{Binding Offset9, Converter={StaticResource OffsetConverter}}" />
128+
</DataGrid.Columns>
134129
</DataGrid>
135130

136131
<GridSplitter Grid.Row="5" HorizontalAlignment="Stretch" Height="10"></GridSplitter>

StructureSpiderAdvanced/Memory.cs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,18 @@ public class Memory
1212
protected long PointerMaxValue;
1313

1414
protected readonly IntPtr ProcHandle;
15+
public readonly ProcessSections SectionsController;
1516

1617
public int PointerLength { get; protected set; }
1718
public bool Is64Bit { get; protected set; }
1819

19-
public Memory(IntPtr procHandle)
20+
public Memory(IntPtr procHandle, ProcessSections sectionsController)
2021
{
22+
SectionsController = sectionsController;
2123
PointerStaticMinValue = 0x10000000;
2224
PointerStaticMaxValue = 0xF0000000;
23-
PointerMinValue = 0x10000;
24-
PointerMaxValue = 0xF0000000;
25+
PointerMinValue = 0x10000;
26+
PointerMaxValue = 0xF0000000;
2527
PointerLength = 4;
2628
ProcHandle = procHandle;
2729
}
@@ -64,7 +66,7 @@ public long ReadLong(IntPtr addr)
6466
public virtual IntPtr ReadPointer(IntPtr addr)//will be overrided by Memory_x64 class
6567
{
6668
var bytes = ReadMem(addr, 4);
67-
var intptrNum = BitConverter.ToInt32(bytes, 0);
69+
var intptrNum = BitConverter.ToUInt32(bytes, 0);
6870
return new IntPtr(intptrNum);
6971
}
7072

@@ -104,27 +106,47 @@ private static string RTrimNull(string text)
104106
return num > 0 ? text.Substring(0, num) : text;
105107
}
106108

107-
public PointerType CheckPointer(IntPtr pointer)
109+
public SectionCategory CheckPointer(IntPtr pointer)
108110
{
109-
var address = pointer.ToInt64();
111+
if (pointer.IsNull())
112+
return SectionCategory.Unknown;
110113

111-
if (address >= PointerStaticMinValue && address <= PointerStaticMaxValue)
112-
return PointerType.StaticPointer;
113-
if (address >= PointerMinValue && address <= PointerMaxValue)
114-
return PointerType.Pointer;
115-
return PointerType.NotPointer;
114+
if(!MainViewModel.Instance.UseMemoryPage)
115+
{
116+
var address = pointer.ToInt64();
117+
if (address >= PointerStaticMinValue && address <= PointerStaticMaxValue)
118+
return SectionCategory.CODE;
119+
if (address >= PointerMinValue && address <= PointerMaxValue)
120+
return SectionCategory.HEAP;
121+
return SectionCategory.Unknown;
122+
}
123+
124+
Section section;
125+
try
126+
{
127+
section = SectionsController.GetSectionToPointer(pointer);
128+
}
129+
catch
130+
{
131+
return SectionCategory.Unknown;
132+
}
133+
134+
if(section != null)
135+
return section.Category;
136+
137+
return SectionCategory.Unknown;
116138
}
117139

140+
// If the section contains data, it is at least a pointer to a class or something.
118141
public bool IsSimplePointer(IntPtr pointer)
119142
{
120-
var address = pointer.ToInt64();
121-
return address >= PointerMinValue && address <= PointerMaxValue;
143+
var pointerType = CheckPointer(pointer);
144+
return pointerType == SectionCategory.HEAP || pointerType == SectionCategory.DATA;
122145
}
123146

124147
public static bool ReadProcessMemory(IntPtr handle, IntPtr baseAddress, byte[] buffer)
125148
{
126-
IntPtr bytesRead;
127-
return ReadProcessMemory(handle, baseAddress, buffer, buffer.Length, out bytesRead);
149+
return ReadProcessMemory(handle, baseAddress, buffer, buffer.Length, out IntPtr bytesRead);
128150
}
129151

130152
[DllImport("kernel32.dll", SetLastError = true)]
@@ -134,16 +156,10 @@ private byte[] ReadMem(IntPtr addr, int size)
134156
{
135157
var array = new byte[size];
136158
ReadProcessMemory(ProcHandle, addr, array);
137-
//if (!ReadProcessMemory(ProcHandle, addr, array))
138-
// throw new InvalidOperationException("Unable to read memory.");
139159
return array;
140-
}
141-
}
160+
}
142161

143-
public enum PointerType
144-
{
145-
NotPointer,
146-
StaticPointer,
147-
Pointer
162+
163+
148164
}
149165
}

StructureSpiderAdvanced/Memory_x64.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ namespace StructureSpiderAdvanced
44
{
55
public class Memory_x64 : Memory
66
{
7-
public Memory_x64(IntPtr procHandle) : base(procHandle)
7+
public Memory_x64(IntPtr procHandle, ProcessSections sectionsController) : base(procHandle, sectionsController)
88
{
9-
PointerStaticMinValue = 0x7FF000000000;
9+
PointerStaticMinValue = 0x7FF000000000;
1010
PointerStaticMaxValue = 0x7FFF00000000;
11-
PointerMinValue = 0x100000000;
12-
PointerMaxValue = 0xF000000000;
13-
//
11+
PointerMinValue = 0x100000000;
12+
PointerMaxValue = 0xF000000000;
13+
1414
PointerLength = 8;
1515
Is64Bit = true;
1616
}

StructureSpiderAdvanced/ProcessManager.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22
using System.ComponentModel;
33
using System.Diagnostics;
44
using System.Runtime.InteropServices;
5+
using System.Windows.Forms;
56

67
namespace StructureSpiderAdvanced
78
{
89
public class ProcessManager : IDisposable
910
{
11+
public static ProcessManager Instance;
1012
public IntPtr ProcHandle { get; private set; }
1113
public bool X64Process { get; private set; }
1214
public Process Process { get; private set; }
1315
public bool FoundProcess { get; private set; }
16+
17+
public readonly ProcessSections SectionsController = new ProcessSections();
18+
1419
public void SetProcess(int pId)
1520
{
1621
try
@@ -23,12 +28,16 @@ public void SetProcess(int pId)
2328
_closed = false;
2429

2530
Process.Exited += Process_Exited;
31+
32+
SectionsController.UpdateProcessInformations(ProcHandle);
2633
}
2734
catch (Win32Exception ex)
2835
{
36+
MessageBox.Show("You should run program as an administrator");
2937
throw new Exception("You should run program as an administrator", ex);
3038
}
3139
}
40+
3241
private void Process_Exited(object sender, EventArgs e)
3342
{
3443
Dispose();
@@ -39,12 +48,13 @@ public Memory GetMemoryForProcess()
3948
{
4049
if(!FoundProcess)
4150
{
51+
MessageBox.Show("Process handle is not initialized. (Program is exited)");
4252
throw new InvalidOperationException("Process handle is not initialized.");
4353
}
4454
if (X64Process)
45-
return new Memory_x64(ProcHandle);
55+
return new Memory_x64(ProcHandle, SectionsController);
4656

47-
return new Memory(ProcHandle);
57+
return new Memory(ProcHandle, SectionsController);
4858
}
4959

5060
~ProcessManager()

0 commit comments

Comments
 (0)