Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Using Lua to find all instances of a .NET class

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
ralfonat
Newbie cheater
Reputation: 0

Joined: 03 Nov 2022
Posts: 14

PostPosted: Tue Sep 09, 2025 4:48 am    Post subject: Using Lua to find all instances of a .NET class Reply with quote

Hi there,

much like

forum.cheatengine.org/viewtopic.php?p=5777647

I am tring to find a way to emulate the "Lookup Instances" functionality in the .NET Info dialog with a Lua script.

I've tried various ways but just generally -> is it even possible? or is that a heap search in CE that can't be emulated or is not exposed in Lua?

What do I want to do? I have a HealthPlayer class, I am looking up the first instance and then theres the PLAYER_HEALTH field. So I just want to use Lua to lookup the instance, find the right one, and add the address+offset as a variable in the AddressList.

Is this possible? Is this even the right/smart way to do this?

Thanks!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4702

PostPosted: Tue Sep 09, 2025 1:08 pm    Post subject: Reply with quote

Look at the file `autorun\dotnetinfo.lua` in the main CE directory. Particularly the function `getClassInstances` and `getClassFields`. You won't be able to use these functions yourself, but it should give you some idea of what you'd have to do.

I'd do a code injection to get the instance (search "injection copy") and simply hope the offsets don't change.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
ralfonat
Newbie cheater
Reputation: 0

Joined: 03 Nov 2022
Posts: 14

PostPosted: Wed Sep 10, 2025 9:42 am    Post subject: Reply with quote

Hi there,

I had a thorough look at the code but I am unsure as to how I could make use of that when you say "you won't be able to use these functions".

How would I use code injection to get the instance? and what is "injection copy"? I'm sorry for sounding stupid but it seems people use these terms very loosely and I don't want to misinterpret your answer.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4702

PostPosted: Wed Sep 10, 2025 12:28 pm    Post subject: Reply with quote

You can learn from those functions. More specifically, look at the implementation of those script-local functions and re-implement them yourself.

e.g. from the `getClassInstances` function, you can learn that mono code is handled differently from dotnet code. Assuming your target doesn't use mono, you can ignore the mono part of it and only focus on the section that handles dotnet. Look for `DataSource.DotNetDataCollector` and you'll see it comes from `getDotNetDataCollector`, a function with a bit of documentation in celua.txt. The method `enumAllObjectsOfType` is what you'd use to find instances of a particular type/class. Then you'd track down what `Class` is, and eventually figure out it comes from `DataSource.Domains.Images.Classes`. The classes in an image are initialized from `getClasses`, the images in a domain are initialized from `getImages`, and the domains are initialized from `getDomains`. These three functions show how to use various methods in the DotNetDataCollector class to collect dotnet information in the target process.

You can try to reuse the code that's already written. The gigantic function `miDotNetInfoClick` that calls `getDomains` also exposes some script-local functions in DataSource (e.g. `DataSource.getClassFields=getClassFields`)- a weird thing to do if DataSource was also script local. As it turns out, DataSource is a global and can be accessed everywhere in Lua. It just needs to be initialized by the `miDotNetInfoClick` function, which is also a global and can be executed at any time (the `sender` parameter seems to be unused). The images and classes are lazily initialized, so you'll have to check for that manually: i.e. `if Domain.Images == nil then getImages(Domain) end`; classes are more difficult.

The file `autorun\dotnetsearch.lua` searches through dotnet info for specific classes / fields / methods. It mostly handles GUI and some thread-synchronization stuff so as to not block the main thread while the search is executing.

There's also the invasive data collector you might want to use: see the function `LaunchDotNetInterface` as well as the file `autorun\DotNetInterface.lua`. I'm not going to spend more time analyzing this myself.

A good part of programming is being able to read someone else's code and understand it enough to do similar things yourself.

ralfonat wrote:
How would I use code injection to get the instance?
That's why I said "search 'injection copy'". By "search", I mean open a search engine and search for that term. You'll find plenty of posts on these forums and several videos on youtube covering it.
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
ralfonat
Newbie cheater
Reputation: 0

Joined: 03 Nov 2022
Posts: 14

PostPosted: Mon Sep 15, 2025 12:20 pm    Post subject: Reply with quote

ParkourPenguin wrote:
You can learn from those functions. More specifically, look at the implementation of those script-local functions and re-implement them yourself.

<snip>

Wow, I did not expect such a thorough help here. Many thanks for that. I will dive into all you have touched on and try to find my way. Many thanks.

ParkourPenguin wrote:
ralfonat wrote:
How would I use code injection to get the instance?
That's why I said "search 'injection copy'". By "search", I mean open a search engine and search for that term. You'll find plenty of posts on these forums and several videos on youtube covering it.


I have searched that term again, and as I had written I am not sure what exactly it means. From the first fiew hits I would say it's simply the standard cheat engine way of injecting code with the "copy" meaning get relevant address and put them somewhere, either with Lua or with "globalalloc" to store it in a variable/memory record.

Anyway, still what I am lost if how would I even go to find instances this way? My only access to the game is the .net route via the "lookup instances" button so first I would need to have good enough assembler knowledge to find a way to lookup instances of a specific PlayerHealth class. I simply do not know how to progress here unless again I am not seeing the obvious.

But nevertheless, thank you so much for your help so far!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4702

PostPosted: Mon Sep 15, 2025 12:58 pm    Post subject: Reply with quote

ralfonat wrote:
From the first fiew hits I would say it's simply the standard cheat engine way of injecting code with the "copy" meaning get relevant address and put them somewhere...
Yes, that's pretty much it.
Find some code that accesses an instance of the class you want. Inject code to copy a pointer to the instance and store it in some memory CE knows about (registersymbol or globalalloc). When the game runs that code, you now have a pointer to the instance.

There's two main problems you can have when doing this: first, the code might not access only the instance you want. e.g. if you want the player's data but the code also accesses enemies' data, it's a bit annoying to filter out the enemies (see step 9 of the tutorial). It's often easier to inject elsewhere. Second, the game must run the code for your injection to do anything. e.g. if you inject at code that's only run when you buy something from a shop, then you'll have to buy something from a shop for your code injection to run. If you need it run under different circumstances, inject elsewhere. If the injection is simply copying a pointer, an "update" function that's run every frame is perfect. Analyzing dotnet info can help you find such a function.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites