WitchHunt 1.0.2

Suggested Alternatives

WitchHunt 1.0.3

Additional Details

Searching for a pattern with no addition instructions like "Add #" can result in an overflow in these versions. Version 1.0.3 fixes this.

There is a newer version of this package available.
See the version list below for details.
dotnet add package WitchHunt --version 1.0.2
                    
NuGet\Install-Package WitchHunt -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WitchHunt" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WitchHunt" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="WitchHunt" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WitchHunt --version 1.0.2
                    
#r "nuget: WitchHunt, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WitchHunt@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WitchHunt&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=WitchHunt&version=1.0.2
                    
Install as a Cake Tool

WitchHunt

A byte pattern matching library which uses the GreyMagic style of patterns.

Pattern Format

Expects pattern to be in the following format:

{Pattern} {Commands} (Wild card bytes can be single ? or ?? or half bytes 4?)

Don't use half bytes, they just make bad patterns but it can match them

48 8D 05 ?? ?? ?? ?? 48 C7 43 ?? ?? ?? ?? ?? 48 8D 4B ?? 48 89 03 66 C7 43 ?? ?? ?? Add 3 TraceRelative

Available Commands:

Add # - Shifts the searcher this # is from the start of the pattern. So add 1 moves us to byte 2. add 2 moves to byte 3 etc.

Sub # - Shifts the searcher this # is from the start of the pattern. so sub 1 moves us to byte -1. sub 2 moves us to byte -2 etc.

Read8 - Reads a byte from the resulting address

Read16 - Reads 2 bytes (16bits) from the resulting address

Read32 - Reads 4 bytes (32bits) from the resulting address

Read64 - Reads 8 bytes (64bits) from the resulting address

TraceRelative - Follow the relative address used in calls and lea's

Main Functions

IntPtr Search(string pattern)

Searches for the first match of the given pattern from the start of the data

IntPtr Search(string pattern, IntPtr start, int maxSearchLength)

Searches for the pattern with a given starting point in the data and a max length of bytes to search. Useful for searching for a pattern within a certain function, passing the function address as start.

IntPtr[] SearchMany(string pattern)

Returns all the matches of a given pattern across all the data bytes.

Examples

From an executable

To run the pattern search on an exe (like ffxiv_dx11.exe) you'll need the .text portion of PE. Easiest way I've found is to use the nuget package PeNet to get the pointer to the raw data of the header and the .text header's address. Then load the file into a Memory<byte> and slice out the .text portion. Can also be done for .rdata/.data etc.

Memory<byte> file = new Memory<byte>(File.ReadAllBytes(@"C:\Program Files (x86)\SquareEnix\FINAL FANTASY XIV - A Realm Reborn\game\ffxiv_dx11.exe"));
PeFile peHeader = new PeFile(file.Span.ToArray());
var text = peHeader.ImageSectionHeaders[0];
var WitchHuntSearcher = new WitchHunt(file.Slice((int) text.PointerToRawData, (int) text.SizeOfRawData), new IntPtr(text.VirtualAddress));
IntPtr result = WitchHuntSearcher.Search("48 8D 05 ?? ?? ?? ?? 48 C7 43 ?? ?? ?? ?? ?? 48 8D 4B ?? 48 89 03 66 C7 43 ?? ?? ?? Add 3 TraceRelative");

Though you'd want to only do everything above WitchHuntSearcher.Search() once to prevent loading the file into memory multiple times.

From a process

Using the pattern searcher on a process's memory is very easy. This example is assuming it's be run while injected in the process.

var bytes = new byte[Process.GetCurrentProcess().MainModule.ModuleMemorySize];
IntPtr outBytes = IntPtr.Zero;
var read = ReadProcessMemory(
                             Process.GetCurrentProcess().Handle,
                             new UIntPtr((ulong)Process.GetCurrentProcess().MainModule.BaseAddress.ToInt64()),
                             bytes,
                             new UIntPtr((uint)Process.GetCurrentProcess().MainModule.ModuleMemorySize),
                             outBytes);

var WitchHuntSearcher = new WitchHunt(bytes, Process.GetCurrentProcess().MainModule.BaseAddress);

The constructor for WitchHunt can take a byte[], Span<byte> or Memory<byte> and their ReadOnly versions

Product Compatible and additional computed target framework versions.
.NET net5.0 is compatible.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net5.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.4 903 6/28/2021
1.0.3 852 6/24/2021
1.0.2 1,073 5/21/2021 1.0.2 is deprecated because it has critical bugs.
1.0.1 1,051 5/20/2021 1.0.1 is deprecated because it has critical bugs.

Small memory optimization