Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
8627e58
Added AllocatedRange and stubs for actual allocations
Doublevil Apr 11, 2024
b1d154a
Unit tests for the new MemoryRange methods
Doublevil Apr 16, 2024
b230d67
Functional Allocate implementation
Doublevil May 1, 2024
9c71274
New Store methods and partial unit testing for allocations
Doublevil May 4, 2024
047f4c4
Split allocations and reservations and added unit tests
Doublevil May 5, 2024
58938a7
First result implementation
Doublevil May 6, 2024
d18ff47
Full Result implementation on the ProcessMemory API
Doublevil May 20, 2024
44a87ba
Removed type-specific Read methods
Doublevil May 21, 2024
04d803f
Added a benchmark project to test and compare with Memory.dll
Doublevil May 21, 2024
f1baa70
Optimized PointerPath parsing
Doublevil May 24, 2024
3563dd1
Removed type-specific public write methods
Doublevil May 25, 2024
686274a
Added benchmarks for write operations
Doublevil May 25, 2024
1568d35
String rework with FindStringSettings and ReadRawString
Doublevil May 31, 2024
f0393bd
Implemented ProcessMemoryStream, a stream to read/write into the memo…
Doublevil Jun 5, 2024
d326a0b
Full string reading implementation
Doublevil Jun 6, 2024
2f47bad
Removed obsolete primitive type write signatures
Doublevil Jun 6, 2024
f1e49c8
Reorganized write methods to match read methods
Doublevil Jun 6, 2024
7bb2694
StoreString implementation
Doublevil Jun 6, 2024
e4f4f90
New test for string pointer (over)writing
Doublevil Jun 6, 2024
07526e5
Benchmarks & optimizations on string reading
Doublevil Jun 7, 2024
ee0b5b7
First hook method implementation
Doublevil Jun 14, 2024
a51298f
Code extensions unit tests
Doublevil Jun 15, 2024
46a5c36
More reasonable hook options
Doublevil Jun 15, 2024
0ee9593
More Hook signatures and tests
Doublevil Jun 16, 2024
ad55ed9
New InsertCodeAt hook method
Doublevil Jun 17, 2024
85b57bc
New method: ReplaceCodeAt
Doublevil Jun 19, 2024
8232c20
Upgraded Test.TargetApp to .net 8
Doublevil Jun 20, 2024
773ea56
First x86 tests and fixes
Doublevil Jun 21, 2024
ad2e8ba
x86 reading tests
Doublevil Jun 22, 2024
3e04ff1
x86 tests for Attach & Evaluate features
Doublevil Jun 23, 2024
2cda0cc
Injection rework for x86 & threading methods
Doublevil Jun 28, 2024
f802ac3
Various fixes, adjustments and tests
Doublevil Jun 29, 2024
583d1d3
x86 allocation tests
Doublevil Jun 30, 2024
4a5d014
DisposableResult + missing IDisposables
Doublevil Jul 3, 2024
192a68c
More x86 tests
Doublevil Jul 4, 2024
8f6f6f5
x86 hook tests
Doublevil Jul 5, 2024
86ab4ba
Fixed a test adapter test duplicate issue
Doublevil Jul 5, 2024
f588d4f
Evaluate & read x86-specific tests
Doublevil Jul 5, 2024
241b8a8
More x86-specific tests
Doublevil Jul 5, 2024
2d8bbfe
Removed unused Win32 function calls
Doublevil Jul 5, 2024
dad455b
Attach methods use Result
Doublevil Jul 6, 2024
a6735f5
Tentative ValueAnchor implementation
Doublevil Jul 12, 2024
377c942
Tests for anchor Read/Write
Doublevil Jul 13, 2024
5d9b87d
Freezer draft
Doublevil Jul 23, 2024
bb088d0
Reworked freezer implementation
Doublevil Aug 11, 2024
5870955
ValueWatcher implementation
Doublevil Aug 21, 2024
1b7f77c
Full documentation and tons of adjustments
Doublevil May 31, 2025
b87fd15
First commit of a long series on publishing the docs
Doublevil May 31, 2025
090066e
Adjustments to the workflow
Doublevil May 31, 2025
9c4406b
Adjusted workflow and csproj for the test project
Doublevil May 31, 2025
009722c
Fixed test target project path in workflow
Doublevil May 31, 2025
9313d23
Replaced build with publish for the target app in workflow
Doublevil May 31, 2025
20802aa
Added debug step in workflow to help understand errors
Doublevil May 31, 2025
dbb4c25
More debugging on the TargetApp workflow mystery
Doublevil May 31, 2025
1cb24ca
Removed debug listings from workflow. Now debugging tests
Doublevil May 31, 2025
d4de0cf
Trying to address hostfxr.dll issues with self contained target builds
Doublevil May 31, 2025
3e8aa22
Added failure reasons for failed results in tests
Doublevil May 31, 2025
f6f69d4
Fixes to allocations and partial reading
Doublevil Jun 5, 2025
6ce9799
Made the docs publication require tests to pass
Doublevil Jun 5, 2025
4592463
Fixed bitness compatibility check in Write
Doublevil Jun 5, 2025
7a7947e
Changed the allocation range search algorithm
Doublevil Jun 6, 2025
e1d3c7d
Updated docs and MindControl.Code publish yml
Doublevil Jun 6, 2025
0acccb6
Added missing icon and readme for MindControl.Code
Doublevil Jun 7, 2025
6899556
Added DotNet.ReproducibleBuilds to MindControl.Code
Doublevil Jun 7, 2025
7f70891
Fixed a value watcher test
Doublevil Jun 7, 2025
5263d02
Changed version number to 1.0.0
Doublevil Jun 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 45 additions & 10 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4

# Create the NuGet package in the folder from the environment variable NuGetDirectory
- run: dotnet pack src/MindControl/MindControl.csproj --configuration Release --output ${{ env.NuGetDirectory }}
# Create the NuGet packages in the folder from the environment variable NuGetDirectory
- name: Create NuGet packages
run: |
dotnet pack src/MindControl/MindControl.csproj --configuration Release --output ${{ env.NuGetDirectory }}
dotnet pack src/MindControl.Code/MindControl.Code.csproj --configuration Release --output ${{ env.NuGetDirectory }}

# Publish the NuGet package as an artifact, so they can be used in the following jobs
# Publish the NuGet packages as an artifact, so they can be used in the following jobs
- uses: actions/upload-artifact@v4
with:
name: nuget
Expand Down Expand Up @@ -77,16 +80,26 @@ jobs:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4

# Build the InjectedLibrary C++ project that is required by the test project.
- name: Restore NuGet packages
run: dotnet restore

# Build the InjectedLibrary C++ project in both x64 and x86 configurations
- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2
- name: Build the C++ injection test DLL
run: msbuild test/MindControl.Test.InjectedLibrary/MindControl.Test.InjectedLibrary.vcxproj /p:Configuration=Release /p:Platform=x64 /p:OutDir=../MindControl.Test/bin/Release/

- name: Build the C++ injection test DLL x64
run: msbuild test/MindControl.Test.InjectedLibrary/MindControl.Test.InjectedLibrary.vcxproj /p:Configuration=Release /p:Platform=x64 /p:OutDir=../MindControl.Test/bin/Release/InjectedLibrary/x64/
- name: Build the C++ injection test DLL x86
run: msbuild test/MindControl.Test.InjectedLibrary/MindControl.Test.InjectedLibrary.vcxproj /p:Configuration=Release /p:Platform=x86 /p:OutDir=../MindControl.Test/bin/Release/InjectedLibrary/x86/

# Build the test target project in x64 and x86
- name: Build the test target project x64
run: dotnet publish test/MindControl.Test.TargetApp/MindControl.Test.TargetApp.csproj --configuration Release --runtime win-x64 --self-contained true --output ${{ github.workspace }}/test/MindControl.Test/bin/Release/TargetApp/x64/
- name: Build the test target project x86
run: dotnet publish test/MindControl.Test.TargetApp/MindControl.Test.TargetApp.csproj --configuration Release --runtime win-x86 --self-contained true --output ${{ github.workspace }}/test/MindControl.Test/bin/Release/TargetApp/x86/

# Run the tests
- name: Run tests
run: dotnet test test/MindControl.Test/MindControl.Test.csproj --configuration Release
run: dotnet test test/MindControl.Test/MindControl.Test.csproj --configuration Release --logger "console;verbosity=detailed"

deploy:
# Publish only when creating a GitHub Release
Expand All @@ -110,4 +123,26 @@ jobs:
run: |
foreach($file in (Get-ChildItem "${{ env.NuGetDirectory }}" -Recurse -Include *.nupkg)) {
dotnet nuget push $file --api-key "${{ secrets.NUGET_APIKEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate
}
}
publish_docs:
if: github.event_name == 'release'
runs-on: windows-latest
needs: [run_test]
steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4

- name: Install DocFX
run: dotnet tool install -g docfx

- name: Build documentation
run: docfx docs/docfx.json

- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/_site
publish_branch: gh-pages
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,7 @@ MigrationBackup/
FodyWeavers.xsd
/CommandCenter.App/.config
/CommandCenter.App/Plugins/

# docfx
docs/_site/
docs/api/
85 changes: 83 additions & 2 deletions MindControl.sln
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,111 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MindControl.Test.TargetApp"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MindControl.Test.InjectedLibrary", "test\MindControl.Test.InjectedLibrary\MindControl.Test.InjectedLibrary.vcxproj", "{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindControl.Benchmark", "test\MindControl.Benchmark\MindControl.Benchmark.csproj", "{5C1B693D-D176-41B2-A47A-E78E098171CB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindControl.Code", "src\MindControl.Code\MindControl.Code.csproj", "{BF166555-9220-42C6-A93E-EC9FBA9AC38C}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{751C861A-AA2D-454F-8910-E27040CDEF6B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libraries", "libraries", "{1D218910-68CD-4D94-B928-A0ADE5A600D5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{0923ADDB-5517-4ABF-A38E-CC3776C85A71}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindControl.Samples.SrDemoConsoleApp", "samples\MindControl.Samples.SrDemoConsoleApp\MindControl.Samples.SrDemoConsoleApp.csproj", "{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindControl.Samples.SrDemoWpfApp", "samples\MindControl.Samples.SrDemoWpfApp\MindControl.Samples.SrDemoWpfApp.csproj", "{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindControl.Samples.SlimeRancherDemo", "samples\MindControl.Samples.SlimeRancherDemo\MindControl.Samples.SlimeRancherDemo.csproj", "{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MindControl.Samples.SrDemoBlazorApp", "samples\MindControl.Samples.SrDemoBlazorApp\MindControl.Samples.SrDemoBlazorApp.csproj", "{125FFA82-F622-4981-8D9F-C5FB7CE87D56}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A13C976F-5866-48C4-904E-2C1960220FAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A13C976F-5866-48C4-904E-2C1960220FAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A13C976F-5866-48C4-904E-2C1960220FAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A13C976F-5866-48C4-904E-2C1960220FAC}.Release|Any CPU.Build.0 = Release|Any CPU
{A13C976F-5866-48C4-904E-2C1960220FAC}.Debug|x86.ActiveCfg = Debug|Any CPU
{2BE5C902-70EC-4DBE-B782-FB0623518F96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2BE5C902-70EC-4DBE-B782-FB0623518F96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2BE5C902-70EC-4DBE-B782-FB0623518F96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2BE5C902-70EC-4DBE-B782-FB0623518F96}.Release|Any CPU.Build.0 = Release|Any CPU
{2BE5C902-70EC-4DBE-B782-FB0623518F96}.Debug|x86.ActiveCfg = Debug|Any CPU
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Release|Any CPU.Build.0 = Release|Any CPU
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Debug|x86.ActiveCfg = Debug|x86
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Debug|x86.Build.0 = Debug|x86
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Release|x86.ActiveCfg = Release|x86
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F}.Release|x86.Build.0 = Release|x86
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Debug|Any CPU.ActiveCfg = Debug|x64
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Debug|Any CPU.Build.0 = Debug|x64
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Release|Any CPU.ActiveCfg = Release|Win32
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Release|Any CPU.Build.0 = Release|Win32
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Release|Any CPU.ActiveCfg = Release|x64
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Release|Any CPU.Build.0 = Release|x64
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127}.Debug|x86.ActiveCfg = Debug|Win32
{5C1B693D-D176-41B2-A47A-E78E098171CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C1B693D-D176-41B2-A47A-E78E098171CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C1B693D-D176-41B2-A47A-E78E098171CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C1B693D-D176-41B2-A47A-E78E098171CB}.Release|Any CPU.Build.0 = Release|Any CPU
{5C1B693D-D176-41B2-A47A-E78E098171CB}.Debug|x86.ActiveCfg = Debug|Any CPU
{BF166555-9220-42C6-A93E-EC9FBA9AC38C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF166555-9220-42C6-A93E-EC9FBA9AC38C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF166555-9220-42C6-A93E-EC9FBA9AC38C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF166555-9220-42C6-A93E-EC9FBA9AC38C}.Release|Any CPU.Build.0 = Release|Any CPU
{BF166555-9220-42C6-A93E-EC9FBA9AC38C}.Debug|x86.ActiveCfg = Debug|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Release|Any CPU.Build.0 = Release|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Debug|x86.ActiveCfg = Debug|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Debug|x86.Build.0 = Debug|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Release|x86.ActiveCfg = Release|Any CPU
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824}.Release|x86.Build.0 = Release|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Release|Any CPU.Build.0 = Release|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Debug|x86.ActiveCfg = Debug|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Debug|x86.Build.0 = Debug|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Release|x86.ActiveCfg = Release|Any CPU
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090}.Release|x86.Build.0 = Release|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Release|Any CPU.Build.0 = Release|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Debug|x86.ActiveCfg = Debug|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Debug|x86.Build.0 = Debug|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Release|x86.ActiveCfg = Release|Any CPU
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35}.Release|x86.Build.0 = Release|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Release|Any CPU.Build.0 = Release|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Debug|x86.ActiveCfg = Debug|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Debug|x86.Build.0 = Debug|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Release|x86.ActiveCfg = Release|Any CPU
{125FFA82-F622-4981-8D9F-C5FB7CE87D56}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5C1B693D-D176-41B2-A47A-E78E098171CB} = {751C861A-AA2D-454F-8910-E27040CDEF6B}
{2BE5C902-70EC-4DBE-B782-FB0623518F96} = {751C861A-AA2D-454F-8910-E27040CDEF6B}
{AA8C9AF6-7C31-43D1-A519-DBB1C3252127} = {751C861A-AA2D-454F-8910-E27040CDEF6B}
{9FE5EF8E-1230-42DB-A6B2-0C2633D32A1F} = {751C861A-AA2D-454F-8910-E27040CDEF6B}
{A13C976F-5866-48C4-904E-2C1960220FAC} = {1D218910-68CD-4D94-B928-A0ADE5A600D5}
{BF166555-9220-42C6-A93E-EC9FBA9AC38C} = {1D218910-68CD-4D94-B928-A0ADE5A600D5}
{B7E8F1B0-F5D2-4943-B780-CB1C0C248824} = {0923ADDB-5517-4ABF-A38E-CC3776C85A71}
{09A4F714-3F5A-4CD8-94D9-902BBDE5A090} = {0923ADDB-5517-4ABF-A38E-CC3776C85A71}
{8E00D032-5E48-4DA3-B2BF-C3DC3C57EA35} = {0923ADDB-5517-4ABF-A38E-CC3776C85A71}
{125FFA82-F622-4981-8D9F-C5FB7CE87D56} = {0923ADDB-5517-4ABF-A38E-CC3776C85A71}
EndGlobalSection
EndGlobal
47 changes: 15 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# MindControl

[![NuGet Version](https://img.shields.io/nuget/v/mindcontrol?style=for-the-badge)](https://www.nuget.org/packages/mindcontrol)[![Downloads](https://img.shields.io/nuget/dt/mindcontrol?style=for-the-badge)](https://www.nuget.org/packages/mindcontrol)[![License](https://img.shields.io/github/license/Doublevil/mind-control?style=for-the-badge)](https://github.com/Doublevil/mind-control/blob/main/LICENSE)

MindControl is a .net hacking library for Windows that allows you to manipulate a game or any other process and its internal memory.

> **DO NOT use this library to cheat in online competitive games. Cheaters ruins the fun for everyone. If you ignore this warning, I will do my best to shut down your project.**
Expand All @@ -9,58 +11,39 @@ MindControl is a .net hacking library for Windows that allows you to manipulate
Here is a quick example to get you started.

```csharp
var myGame = ProcessMemory.OpenProcess("mygame.exe"); // A process with this name must be running
var myGame = ProcessMemory.OpenProcess("mygame").Result; // A process with this name must be running
var hpAddress = new PointerPath("mygame.exe+1D005A70,1C,8"); // See the docs for how to determine these

// Read values
int currentHp = myGame.ReadInt(hpAddress);
var currentHp = myGame.Read<int>(hpAddress);
Console.WriteLine($"You have {currentHp}HP"); // Example output: "You have 50HP"

// Write values
myGame.WriteInt(hpAddress, 9999);
myGame.Write(hpAddress, 9999);

// Find the first occurrence of a pattern in memory, with wildcard bytes
UIntPtr targetAddress = myGame.FindBytes("4D 79 ?? ?? ?? ?? ?? ?? 56 61 6C 75 65")
.FirstOrDefault();

// ... And many more features
```

See [the documentation](doc/GetStarted.md) for more information.
See [the documentation](https://doublevil.github.io/mind-control/guide/introduction.html) to get started, whether you already dabble in memory hacking or are completely new to it.

## Features

- Attach to any process easily by name or PID
- Address memory either through simple pointer addresses, or through dynamic pointer paths (e.g. `mygame.exe+1D005A70,1C,8`)
- Read a memory address as a byte array, boolean, or any basic number types
- Read a memory address as a string as simply as possible, or as complex as you need
- Write byte arrays, booleans and basic number types at any memory address
- Read and write byte arrays, booleans, numbers of any kind, strings and structures
- Inject DLLs to execute arbitrary code in the target process
- Search for byte patterns in the target process memory
- Search for byte sequences or patterns in the target process memory
- Manage memory allocations manually or automatically, to store data or code in the target process
- Insert assembly code with hooks
- Replace or remove existing code
- Start threads in the target process
- Designed for performance and simplicity of use
- Unit tested and made with care

## Comparison with other libraries

MindControl is a small library that focuses on the most common use cases for hacking.

It is not as feature-rich as the most used .net hacking library, [memory.dll](https://github.com/erfg12/memory.dll/), but it aims to be easier to use, have comparable performance, and most importantly to be more reliable and maintainable.

If you are considering MindControl but unsure if it has the features you need, here is a comparison table.

| Feature | MindControl | memory.dll
|-----------------------------|--- |--- |
| **Handle pointer paths** | ✔️ | ✔️ |
| **Read primitive types** | ✔️ | ✔️ |
| **Write primitive types** | ✔️ | ✔️ |
| **Read strings** | ✔️ | ✔️ |
| **Write strings** | ❌ | ✔️ |
| **Array of bytes scanning** | ✔️ | ✔️ |
| **Inject DLLs** | ✔️ | ✔️ |
| **State watchers** | ✔️ | ❌ |
| **Create code caves** | ❌ | ✔️ |
| **Bind to UI elements** | ❌ | ✔️ |
| **Freeze values** | ❌ | ✔️ |
| **Set focus to process** | ❌ | ✔️ |
| **Load from .ini file** | ❌ | ✔️ |
| **Suspend process** | ❌ | ✔️ |
| **Dump process memory** | ❌ | ✔️ |
| **Manipulate threads** | ❌ | ✔️ |
MindControl has a lot in common with other .net hacking libraries, the most popular one being [memory.dll](https://github.com/erfg12/memory.dll/). While the latter focuses on practicality and has some bias towards a specific use-case (game trainers), MindControl primarily aims to be more generic, reliable and maintainable, generally easier to understand and to use, and with similar or better performance.
Loading