Most of the changes done in the last 3 months were revolving around scripting capabilities. We got new overlays, major improvements in NuGet packages and external assemblies integration, editor improvements and, finally Export and Live Import, which allow to use EA and your favourite IDE of choice together.
Brinding 600+MB executable alongside 200KB scripts seems unnatural, especially considering overall direction with you, users, being able to publish licensed content. Showing new users UI with 100 of buttons/checkboxes and sliders is frigthening to say the least. Plus all the extra luggage which program carries around. In 2025 the goal will be to implement a system which will be automatically disabling those features of UI which are not used. Allow authors to hide EyeAuras UI, disable computer-vision or ML modules, etc. There are many technical challenges in this approach, but they all seem solvable. We'll see in the nearest future.
DMA cards are small devices which allow to read memory of PC without OS involvement via direct hardware-2-hardware communications. This makes process of detection of such reads extremely difficult, which means very good level of security for end-users. Memory API which was added in November targets to unify the process of working with RAM via OS-level commands (ReadProcessMemory), those using drivers and, eventually DMA-cards. You develop something using easy-to-use and convenient RPM. Then switch to much safer DMA. By simply switching one line of code you will allow user to pick whatever level of security he wants to achieve.
Became better in 2024 with the new UI framework overtaking older one in most parts of the program, but still have a long way to go, especially when we're talking about working with large number of auras (500+). Primary focus in 2025 will be making sure that Packs are loading as quickly as possible as this is the primary form of distribution of your scripts. Probably we'll get some slimmed down alternative UI which won't be as feature rich and will focus on just loading everything very quickly and efficiently.
Now, after you've downloaded a pack from the website - be it a fishing bot for Throne&Liberty(1 or 2), Path of Exile Helper or any other one - you can now much-much easier track when it will be updated by the author. You will get a notification in the pack right away - for now it will be a small badge in the folder name. Afterwards, I may add some other form of notification.
But just getting updates is not everything thing feature brings. More often than not, when you started using someone elses pack, you do some changes in it - set up your own keybinds, change window name, change some image, etc. Now you won't be losing those changes even when new version of the pack gets released by the author - EyeAuras will pick your local changes, compare them with author's changes(remote) and will Merge them together. Best case scenario - you get all the new changes which author of the pack did AND you have your previously done changes intact. This mechanism is still fresh out of the oven and could have some problems in it, but now, when this feature finally came into play, those bugs will be discovered(and fixed!) much quicker.
Ideally, you won't have to think about that system ever. We'll see how it goes :-D
Packs are developed by human beings, and we tend to make mistakes. All changes done by authors of the packs are versioned and stored as revisions. For now, you can reset your changes only to the current latest revision, this is equivalent of re-downloading the entire pack, but 1000 times faster. As soon as the mechanism will be polished enough, I will enable ability to switch between revisions.
Another tab allows you to see how the pack looks like without even downloading it. Check hotkeys, general logic, structure. In one of the future updates you'll be able to check out the code and Behavior Trees/Macros as well from that very same window.
And the very last tab is just another form of Event Log - it contains information about changes, current sync status and everything else around it.
Added new feature - now you can specify Similarity range which is required for trigger to be Active. By default, trigger is active only if Similarity is above given threshold, e.g.
Now you can specify range of Min/Max values for similarity, e.g.
In this case, even if Similarity would reach 100%, trigger still will be Inactive, because expected value must be in range 55.95
to 62.94
(inclusively)
Added simple way of randomizing XY. Together with Input Smoothing, this should make inputs appear more humane.
Added a Version History feature, allowing users to view and manage configuration snapshots saved over time. Users can now perform a Soft Reset to restore file states without altering history or a Hard Reset to fully revert to a specific commit, removing all changes made afterward.
p.s. RU version of the doc is available here
Window Selector is that control which allows you to pick/specify Target Window. For many years, it has been filtering-out all windows, which were under EA control.
This is now an optional feature, which could be disabled by adding [ownedBy=any]
to the expression, e.g.
My Window [ownedBy=any]
will filter out and scan through ALL windows, which are present in the system, even if they were created by EyeAuras.
Another filter of a similar type which was added allows to capture so-called Tool windows, e.g. Overlays usually have this type.
By default, such windows are ignored and can add them as potential candidates by appending [type=any]
at the end of match expression, e.g.
My Overlay [ownedBy=any][type=any]
would capture any window/overlay which has title My Overlay
.
Just want to highlight a feature that was added long time ago and is extremely useful in some niche situations, e.g. when you need to capture the color or image of some short-living buff or debuff. I've done several improvements in that part, so it should become more convenient to use.
You just press Replay, the program starts saving the footage into temporary video file.
When done, just press Stop
Preview window will now switch to mode which loads image data from the video file. You can now work with that footage just like if that would be the real captured image - pick pixels, copy regions to clipboard, etc. When no longer needed, just switch to default Image as is
option in bottom right corner.
New major feature entering alpha phase - it is now possible to Export your C# Overlays/Actions (Triggers and Nodes are still not allowing that) into .sln
solution.
Modern IDEs provide a lot of QoL features without which it is inconvenient to do any kind of serious development. EA script editor will never be able to close that gap between "text editor with syntax highlighting and autocompletion" and real IDEs. It is a tool for script development, that is it. But at that point set of features that EA SDK provides has gone far beyond what is required for usual scripting - you can create a full-blown program with NuGet packages
You can then open this solution in JetBrains Rider (recommended) or Microsoft Visual Studio.
Solution which you'll get will consist of one or multiple projects (depending on what you've exported). It is build-able and you can add unit-testshttps://www.jetbrains.com/help/rider/Getting_Started_with_Unit_Testing.html).
Export I've already briefly covered, importing changes back is as simple as selecting Solution file you've previously exported. EA will load changes in source code files which you've made in IDE. As solution can have multiple projects in it (e.g. unit-tests project), EA will try to match projects which you already have in the program (in a form of C# actions) to those in solution and will ignore those which it is not aware of.
Importing changes over and over and over again could be exhausting and is not even close to desired workflow.
That is where another feature comes into play.
Click on Live Import
, select .sln
and EA will start monitoring for any changes made in that directory where solution resides in. As soon as it will detect those changes, it will import them back to EA. Essentially, this make it so the code in C# action/overlay you're working on becomes live. This is especially noticeable for Overlays
, which are inherently recompiled as soon as any changes are made. So as soon as you'll do some changes in Overlay
code, it will be almost instantly picked up by EA, recompiled and loaded. Think of it as of ghetto spin-off of Hot Reload feature, but that works.
Git is a golden standard of version control systems. EA internally uses it for many things such as configuration version control. So it was just natural to set exported projects as git repositories during export. Whenever you're exporting/importing changes back to EA, it automatically creates git repository OR commits changes you've made. This makes it easy to rollback the code in case something goes wrong.
For now, you cannot debug or run the project from IDE. This will be one of the improvements I'll be working on in 2025. Eventually, you should be able to use EA as a script runner. But to make it happen I still have to do some changes.
Major upgrade in the scripting engine - it can now compile Razor components. Blazor (Razor components are part of Blazor infrastructure) is one of the best (my opinion - for desktop apps just the best) UI technology which allows to have full power of C# and at the same time great performance/convenience of Web (HTML/CSS/JS) world.
EyeAuras is also using it under the hood since 2023 and is gradually being rewritten from WPF to Blazor. At some point in the future is expected to become full Blazor-driven app. Parts which are using it - BT editor, Macro editor, EventLog, Bindings, AuraTree. If some part of the program feels snappy you can bet it is using Blazor.
Previously, if you wanted to develop your own user interface for your bot, the only viable option was to use WebUI Overlay which at this point is using very dated text editor and, more importantly, uses older version of the scripting engine (V2) back from April 2023(!). Of course, you could load up the project in your IDE of choice (like Visual Studio or Rider), but that was definitely not very convenient and took some extra steps.
At the same time, BTs, Macros and C# Action/Trigger have been using the newer iteration of scripting engine since Jan 2024, but they newer really had Razor support as it was technically challenging task to add it there without preparing some other systems first. And, finally, today we're getting the first prototype. This is not just new feature - allowing users to create windows straight from the code makes it possible to develop full-blown standalone bots.
Added new type of Overlay, which uses the latest version of EyeAuras scripting engine - same one, that is used in C# Actions/Triggers and BehaviorTrees. For the next few weeks old C# overlay and new one wil co-exist. As soon as I will releat Export/Import functionality, old one will go away as it is worse in everything - performance, flexibility, etc.
Aside from scripting engine changes, this new overlay is using recently added Blazor Windows, which should make overlays more responsive and just in general more pleasant to work/interact with.
IMPORTANT! The overlay is far from being completed - there are still a lot of rough edges which I will work on in the following weeks.
C# Script Action editor (only Action for now, editor in BTs/Triggers/Overlays is still the same) got some love:
Pattern scanning is a method used to search for specific byte sequences in memory. It’s useful for finding functions, data, or code that doesn’t always stay at the same location when a program is running.
BytePattern
The BytePattern
class has been added to support multiple ways of defining patterns. These updates make it easier to work with different types of patterns commonly used in scanning memory.
Pattern scanning is available on any type implementing IMemory
interface, e.g.
using var process = LocalProcess.ByProcessName("pathofexile"); //uses naive RPM under the hood
Log.Info($"Process: {process}");
var modules = process.GetProcessModules(); //enumerate all loaded modules
using var memory = process.MemoryOfModule("pathofexile.exe"); //memory implements IMemory
Log.Info($"Process memory: {memory}, base: {memory.BaseAddress.ToHexadecimal()}");
// will find a singular offset pointing at 4th byte in the sequence
var offset = memory.FindOffset(BytePattern.FromTemplate("55 8B ?? ^ EC 00"));
// will return dictionary with all found offsets for all given patterns
var playerPattern = BytePattern.FromTemplate("55 8B ?? ^ EC 00");
var targetPattern = BytePattern.FromTemplate("BB AA ??");
var offsetsByPattern = memory.FindOffset(playerPattern, targetPattern);
// by using Get* instead of Find* the code will throw an exception in case pattern is not found
var criticalOffset = memory.GetOffset(BytePattern.FromTemplate("55 8B ?? ^ EC 00"));
Byte Arrays:
var pattern = BytePattern.FromPattern(new byte[] {0x55, 0x8B, 0xEC});
matches exactly those bytes.
C-Style Patterns:
\xAA\xBB\xCC
, like in C-Style patterns.var pattern = BytePattern.FromTemplate("\x55\x8B\xEC");
is equivalent to the byte array [0x55, 0x8B, 0xEC]
.
Hexadecimal Strings with Wildcards:
??
for wildcards (any byte).var pattern = BytePattern.FromTemplate("55 8B ?? 83");
matches any sequence starting with 55 8B
, followed by any byte, and then 83
.
Masked Patterns:
x
) and which are wildcards (?
).var pattern = BytePattern.FromMaskedPattern(new byte[] { 0x55, 0x8B, 0xEC, 0x00, 0x08 }, "xxx??");
Matches any sequence starting with 55 8B EC
, followed by any two bytes.Templates with Offsets:
^
.var pattern = BytePattern.FromTemplate("55 8B ?? ^ EC 00");
sets the offset right before EC
(skipping 3
bytes). That means after the pattern is found, final offset will be Offset + 3
For several months we've had the feature in scripts, which allows to reference nuget packages
#r "nuget: Coroutine, 2.1.5"
Log.Info("Hello, World!"); //you can use Coroutine classes in that script
The support has not been extended and you can reference assemblies in 2 other ways now.
Important! This method of referencing assemblies is available only inside Script.csx
which is equivalent of your Program.cs
in "normal" C#
Syntax is very similar.
#r "assemblyPath: D:\Work\EAExile\EAExileAgent.Shared.dll"
Log.Info("Hello, World!"); //you can use EAExileAgent classes in that script
This method of referencing assemblies allows you to reference those assemblies which are either:
Assembly.Load
or via any other means, but they are already part of AssemblyLoadContext/AppDomainHistorically, EA referenced A LOT of assemblies by default, more than 300 assemblies. This allows users to save some type on pre-configuring these dependencies on each and every C# action/BT node/etc, but this is not a good way long-term. Gradually, I'll be de-linking more and more default assemblies and will include a better auto-completion techniques which would allow to easily include those libraries which are needed for your script. In the future, this will make upgrading the program easier for everyone
#r "assemblyName: Grpc.Net.Client"
Log.Info("Hello, World!"); //you can use Grpc.Net.Client classes in that script
As a part of scripting subsystem improvements, there were some changes done in the engine, which now allow you to use NuGets which rely on native libraries, such as ImGui - a lot of programmers out there have experience with it an now you can leverage that knowledge and create ImGui overlays straight from the code.
This is an example of a live clickable ImGui overlay, which can contain any kind of data you want, running inside EA and being able to leverage any functionality - computer vision, neural networks, memory read, input emulation - anything.
Added very useful property called NoActivate
, which, when set, makes it so the window will react to mouse clicks, but will not intercept user focus.
Meaning you can have an overlay with a bunch of controls, allowing user to easily disable and enable some functionality of your bot while game window will remain active.
/// <summary>
/// Gets or sets a value indicating whether the window should NOT be activated when clicked
/// </summary>
bool NoActivate { get; set; }
Added to IBlazorWindow
one new property and one method. Both of those could be used to
provide custom providers for file data. You can pick whichever flavour you want - add your custom file provider either via RegisterFileProvider
or by using AdditionalFileProvider
and any file, which you will be referencing in your custom Blazor code, will have access to that file.
It could be runtime-generated styles, could be images, video or anything you may need to create a really dynamic user interfaces.
For now, I would recommend to use built-in:
ComplexFileProvider
- allows to combine multiple FileProviders together, resolution will happen in order of additionInMemoryFileProvider
- allows to store file data in-memory, files will be cached for better performanceInMemoryFileInfo
- allows to create one in-memory file reference. The data is loaded as soon as FileInfo is constructedLazyInMemoryFileInfo
- allows to create lazy file reference, which will be loaded only when accessedwhich allow you to easily add new content to your pages.
/// <summary>
/// Gets or sets additional file provider which will be used by Blazor
/// </summary>
IFileProvider AdditionalFileProvider { get; set; }
/// <summary>
/// Adds additional file provider which will be used by Blazor. Added to the end of the list.
/// Removed on disposal
/// </summary>
IDisposable RegisterFileProvider(IFileProvider fileProvider);
Example of the code, which will load file from the disk and make it available for use in styles or HTML:
var fileProvider = new InMemoryFileProvider();
fileProvider.AddOrUpdate(new InMemoryFileInfo("hello.png", File.ReadAllBytes(@"D:\hello.png")));
Of course, you can generate the displayed data in runtime as well.
Primary focus - fixed problems with auto-annotation and ensure that Google Collab now properly works. I'll post a video on this soon. Plus several improvements to performance, which are especially noticeable on mid+ sized datasets (5-10k of images).
With Local Training you're training the model using your own hardware. Positive side - you're paying only for electricity, negative - you have to have everything setup and ready to go
With Google Collab you're using cloud infrastructure to do the training, meaning that the actual training code runs elsewhere. You can either use a free tier or a paid one, your choice.
Execute Tree
and Execute Macro
which could be called from Auras. This is a "glue" which allows to wire together two automation approaches which exist in EAScriptingAPIs
, this would correspondingly lead to disposal of OSD/Windows/etc created by scriptIPerformanceMetricsAddon
- could be used to track performance of the app via scriptingCancellationToken
rewriter - it was handling optional arguments incorrectly in some casesLog.Info/Debug/Warn
formatting - now UI properly renders line breakesConsole.WriteLine
now prints output to EventLog. Done this to improve usability of ChatGPT-generated scripts.INotifyPropertyChanged
implementation in scriptingMostly hotfixes of NY release.
IEyeContext
- should fix a problem with older overlays not working properlyMemoryOfModule
(which accept module name OR module descriptor) to IProcess
Added very useful property called NoActivate
, which, when set, makes it so the window will react to mouse clicks, but will not intercept user focus.
Meaning you can have an overlay with a bunch of controls, allowing user to easily disable and enable some functionality of your bot while game window will remain active.
/// <summary>
/// Gets or sets a value indicating whether the window should NOT be activated when clicked
/// </summary>
bool NoActivate { get; set; }
Added to IBlazorWindow
one new property and one method. Both of those could be used to
provide custom providers for file data. You can pick whichever flavour you want - add your custom file provider either via RegisterFileProvider
or by using AdditionalFileProvider
and any file, which you will be referencing in your custom Blazor code, will have access to that file.
It could be runtime-generated styles, could be images, video or anything you may need to create a really dynamic user interfaces.
For now, I would recommend to use built-in:
ComplexFileProvider
- allows to combine multiple FileProviders together, resolution will happen in order of additionInMemoryFileProvider
- allows to store file data in-memory, files will be cached for better performanceInMemoryFileInfo
- allows to create one in-memory file reference. The data is loaded as soon as FileInfo is constructedLazyInMemoryFileInfo
- allows to create lazy file reference, which will be loaded only when accessedwhich allow you to easily add new content to your pages.
/// <summary>
/// Gets or sets additional file provider which will be used by Blazor
/// </summary>
IFileProvider AdditionalFileProvider { get; set; }
/// <summary>
/// Adds additional file provider which will be used by Blazor. Added to the end of the list.
/// Removed on disposal
/// </summary>
IDisposable RegisterFileProvider(IFileProvider fileProvider);
Example of the code, which will load file from the disk and make it available for use in styles or HTML:
var fileProvider = new InMemoryFileProvider();
fileProvider.AddOrUpdate(new InMemoryFileInfo("hello.png", File.ReadAllBytes(@"D:\hello.png")));
Of course, you can generate the displayed data in runtime as well.
Now, after you've downloaded a pack from the website - be it a fishing bot for Throne&Liberty(1 or 2), Path of Exile Helper or any other one - you can now much-much easier track when it will be updated by the author. You will get a notification in the pack right away - for now it will be a small badge in the folder name. Afterwards, I may add some other form of notification.
But just getting updates is not everything thing feature brings. More often than not, when you started using someone elses pack, you do some changes in it - set up your own keybinds, change window name, change some image, etc. Now you won't be losing those changes even when new version of the pack gets released by the author - EyeAuras will pick your local changes, compare them with author's changes(remote) and will Merge them together. Best case scenario - you get all the new changes which author of the pack did AND you have your previously done changes intact. This mechanism is still fresh out of the oven and could have some problems in it, but now, when this feature finally came into play, those bugs will be discovered(and fixed!) much quicker.
Ideally, you won't have to think about that system ever. We'll see how it goes :-D
Packs are developed by human beings, and we tend to make mistakes. All changes done by authors of the packs are versioned and stored as revisions. For now, you can reset your changes only to the current latest revision, this is equivalent of re-downloading the entire pack, but 1000 times faster. As soon as the mechanism will be polished enough, I will enable ability to switch between revisions.
Another tab allows you to see how the pack looks like without even downloading it. Check hotkeys, general logic, structure. In one of the future updates you'll be able to check out the code and Behavior Trees/Macros as well from that very same window.
And the very last tab is just another form of Event Log - it contains information about changes, current sync status and everything else around it.
Primary focus - fixed problems with auto-annotation and ensure that Google Collab now properly works. I'll post a video on this soon. Plus several improvements to performance, which are especially noticeable on mid+ sized datasets (5-10k of images).
With Local Training you're training the model using your own hardware. Positive side - you're paying only for electricity, negative - you have to have everything setup and ready to go
With Google Collab you're using cloud infrastructure to do the training, meaning that the actual training code runs elsewhere. You can either use a free tier or a paid one, your choice.
New major feature entering alpha phase - it is now possible to Export your C# Overlays/Actions (Triggers and Nodes are still not allowing that) into .sln
solution.
Modern IDEs provide a lot of QoL features without which it is inconvenient to do any kind of serious development. EA script editor will never be able to close that gap between "text editor with syntax highlighting and autocompletion" and real IDEs. It is a tool for script development, that is it. But at that point set of features that EA SDK provides has gone far beyond what is required for usual scripting - you can create a full-blown program with NuGet packages
You can then open this solution in JetBrains Rider (recommended) or Microsoft Visual Studio.
Solution which you'll get will consist of one or multiple projects (depending on what you've exported). It is build-able and you can add unit-testshttps://www.jetbrains.com/help/rider/Getting_Started_with_Unit_Testing.html).
Export I've already briefly covered, importing changes back is as simple as selecting Solution file you've previously exported. EA will load changes in source code files which you've made in IDE. As solution can have multiple projects in it (e.g. unit-tests project), EA will try to match projects which you already have in the program (in a form of C# actions) to those in solution and will ignore those which it is not aware of.
Importing changes over and over and over again could be exhausting and is not even close to desired workflow.
That is where another feature comes into play.
Click on Live Import
, select .sln
and EA will start monitoring for any changes made in that directory where solution resides in. As soon as it will detect those changes, it will import them back to EA. Essentially, this make it so the code in C# action/overlay you're working on becomes live. This is especially noticeable for Overlays
, which are inherently recompiled as soon as any changes are made. So as soon as you'll do some changes in Overlay
code, it will be almost instantly picked up by EA, recompiled and loaded. Think of it as of ghetto spin-off of Hot Reload feature, but that works.
Git is a golden standard of version control systems. EA internally uses it for many things such as configuration version control. So it was just natural to set exported projects as git repositories during export. Whenever you're exporting/importing changes back to EA, it automatically creates git repository OR commits changes you've made. This makes it easy to rollback the code in case something goes wrong.
For now, you cannot debug or run the project from IDE. This will be one of the improvements I'll be working on in 2025. Eventually, you should be able to use EA as a script runner. But to make it happen I still have to do some changes.
ScriptingAPIs
, this would correspondingly lead to disposal of OSD/Windows/etc created by scriptAdded simple way of randomizing XY. Together with Input Smoothing, this should make inputs appear more humane.
Execute Tree
and Execute Macro
which could be called from Auras. This is a "glue" which allows to wire together two automation approaches which exist in EAFor several months we've had the feature in scripts, which allows to reference nuget packages
#r "nuget: Coroutine, 2.1.5"
Log.Info("Hello, World!"); //you can use Coroutine classes in that script
The support has not been extended and you can reference assemblies in 2 other ways now.
Important! This method of referencing assemblies is available only inside Script.csx
which is equivalent of your Program.cs
in "normal" C#
Syntax is very similar.
#r "assemblyPath: D:\Work\EAExile\EAExileAgent.Shared.dll"
Log.Info("Hello, World!"); //you can use EAExileAgent classes in that script
This method of referencing assemblies allows you to reference those assemblies which are either:
Assembly.Load
or via any other means, but they are already part of AssemblyLoadContext/AppDomainHistorically, EA referenced A LOT of assemblies by default, more than 300 assemblies. This allows users to save some type on pre-configuring these dependencies on each and every C# action/BT node/etc, but this is not a good way long-term. Gradually, I'll be de-linking more and more default assemblies and will include a better auto-completion techniques which would allow to easily include those libraries which are needed for your script. In the future, this will make upgrading the program easier for everyone
#r "assemblyName: Grpc.Net.Client"
Log.Info("Hello, World!"); //you can use Grpc.Net.Client classes in that script
Pattern scanning is a method used to search for specific byte sequences in memory. It’s useful for finding functions, data, or code that doesn’t always stay at the same location when a program is running.
BytePattern
The BytePattern
class has been added to support multiple ways of defining patterns. These updates make it easier to work with different types of patterns commonly used in scanning memory.
Pattern scanning is available on any type implementing IMemory
interface, e.g.
using var process = LocalProcess.ByProcessName("pathofexile"); //uses naive RPM under the hood
Log.Info($"Process: {process}");
var modules = process.GetProcessModules(); //enumerate all loaded modules
using var memory = process.MemoryOfModule("pathofexile.exe"); //memory implements IMemory
Log.Info($"Process memory: {memory}, base: {memory.BaseAddress.ToHexadecimal()}");
// will find a singular offset pointing at 4th byte in the sequence
var offset = memory.FindOffset(BytePattern.FromTemplate("55 8B ?? ^ EC 00"));
// will return dictionary with all found offsets for all given patterns
var playerPattern = BytePattern.FromTemplate("55 8B ?? ^ EC 00");
var targetPattern = BytePattern.FromTemplate("BB AA ??");
var offsetsByPattern = memory.FindOffset(playerPattern, targetPattern);
// by using Get* instead of Find* the code will throw an exception in case pattern is not found
var criticalOffset = memory.GetOffset(BytePattern.FromTemplate("55 8B ?? ^ EC 00"));
Byte Arrays:
var pattern = BytePattern.FromPattern(new byte[] {0x55, 0x8B, 0xEC});
matches exactly those bytes.
C-Style Patterns:
\xAA\xBB\xCC
, like in C-Style patterns.var pattern = BytePattern.FromTemplate("\x55\x8B\xEC");
is equivalent to the byte array [0x55, 0x8B, 0xEC]
.
Hexadecimal Strings with Wildcards:
??
for wildcards (any byte).var pattern = BytePattern.FromTemplate("55 8B ?? 83");
matches any sequence starting with 55 8B
, followed by any byte, and then 83
.
Masked Patterns:
x
) and which are wildcards (?
).var bytes = ;
var mask = ;
var pattern = BytePattern.FromMaskedPattern(new byte[] { 0x55, 0x8B, 0xEC, 0x00, 0x08 }, "xxx??");
Matches any sequence starting with 55 8B EC
, followed by any two bytes.Templates with Offsets:
^
.var pattern = BytePattern.FromTemplate("55 8B ?? ^ EC 00");
sets the offset right before EC
(skipping 3
bytes). That means after the pattern is found, final offset will be Offset + 3