|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
jgoemat Master Cheater Reputation: 22
Joined: 25 Sep 2011 Posts: 252
|
Posted: Tue Apr 14, 2015 4:47 am Post subject: Working on mono goodies and have some CE/LUA/Form questions |
|
|
Mono dissector source available?
I would love to make it work like the new .NET one and pull fields from base classes in the structure dissector. Is the source available? I didn't see where that was possible looking at the lua code for mono features. What should be possible, but would be totally insane, would be to be able to eventually write scripts using IL or maybe even C# that could get JITed into the game. I'd love have an easy way to call methods or at least see the types of parameters too...
Contributing to CE?
It's hard to search in the mono dissect window, it ends up opening all the tree nodes and it take forever to close them and it's hard to find what I was searching for. I think it would be nice if after a search the treeview only expanded to the nodes that matched the search criteria.
Also it's pretty easy to sort the classes and methods by name and fields by offset in the monoform_EnumXXX methods to make them easier to find:
Code: |
table.sort(classes, function(a, b) return a.classname < b.classname end)
table.sort(fields, function(a,b) return a.offset < b.offset end)
table.sort(methods, function(a,b) return a.name < b.name end)
|
Is there some preferred way to submit code fore review? In a perfect world for me it wo uld be git and using github you could just create your own clone of the main repo for your changes and submit a pull request that dark_byte could review and either accept or reject to get it into the main repo...
Mono AA Features?
It seems that registerAutoAssemblerCommand always shows the unaltered script, is that by design as a security measure? Seems like it wouldn't help since it would get compiled anyway, and anything that could register an AA command would be able to do anything else in CE anyway. Is that the "showmessage(code.text);" in autoassembler.pas? I could see those being handy, especially GETMONOSTRUCT and maybe FINDMONOMETHOD. Now I think this is the proper way to avoid that?
Code: | {$lua}
LaunchMonoDataCollector()
return monoAA_GETMONOSTRUCT("WeaponBase", syntaxcheck)
{$asm} |
New search form
I created a new search form that displays only matching classes/fields/methods to the search term, and has a memo field that right now just shows the structure if anyone is interested. Can these be stored in a cheat table or would someone need to download it separately? It doesn't seem to be in my table and I can't add it as an attachment...
Description: |
|
Filesize: |
229.01 KB |
Viewed: |
15714 Time(s) |
|
Description: |
|
Download |
Filename: |
MonoSearchForm.LUA |
Filesize: |
8.9 KB |
Downloaded: |
810 Time(s) |
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
|
Back to top |
|
|
jgoemat Master Cheater Reputation: 22
Joined: 25 Sep 2011 Posts: 252
|
Posted: Wed Apr 15, 2015 7:07 pm Post subject: |
|
|
Found the project, thanks.
So it seems there are two ways to show a form...
1) Go to add form or edit an existing form. This will make the form show up in the Table menu, and make it accessible as a LUA object using the name. Using the editor, loading replaces the form you are currently editing with the contents from the file, changing the name in the menu possibly.
2) Load the form from a file, default where the cheat table is located or you could use getCheatEngineDir() for example to get a FRM saved in the cheat engine folder (like the mono autorun lua script does) - this seems to be the only option if I want to have multiple instances of my form, right?
It would be nice to break my code into several files and use 'dofile' or 'require' to get them to run from what's stored in the table, but I don't see a way to do that. Are there downsides to doing something like this or is there a better way?
Code: | local files = { "MonoUtility.LUA", "MonoSearch.LUA" }
for i,fileName in ipairs(files) do
local tableFile = findTableFile(fileName)
if tableFile then tableFile.saveToFile(fileName)
end
dofile("MonoSearch.LUA") -- has require("MonoUtility.LUA") in it
|
|
|
Back to top |
|
|
tfigment Advanced Cheater Reputation: 2
Joined: 12 Oct 2012 Posts: 93
|
Posted: Thu Apr 16, 2015 8:35 am Post subject: |
|
|
Looks like some nice work. I will check it out when I have some time. The version Dark Byte included was adequate if a little bare bones so I enhanced a little so I could do what I needed. You took it to the next level so thanks for that.
Here are some things to be aware of that I ran into that need one should be aware of when working with mono/.net and CE. Not all fields are instance level to the class. Some are constants and some are static. There should should be some separation especially when using the monostruct generator since it doesn't make sense to merge them does it? Also be wary of class names as nested classes and names are not handled completely in the current version (I ran into duplicates in Pillars of Eternity for instance where one was a nested class so it was confusing which CharacterStats to use).
The next is it might be useful to walk the class structure to include base classes. There are some interesting behaviors when you start looking at base classes which are generics of the main class that might need to be handled. I've used this mostly to get access to Static fields in a Generic Base class for instance which I think can only be access via walking from the parent class to the child. (I think Wasteland 2 or Kerbal Space Program might have done this.)
I added some helper scripts to my version to resolve static addresses as they are common in several Unity games and act as entry points for tables but they feel slightly out of place and would be good to separate into different files and clean up the code. They are very useful to me though so I can imagine that others would as well if they knew how to use them. I ended up just baking the scripts into the tables because it is easier to redistribute those tables without worrying if someone has my version of monocollector which might not do the right thing.
What would be nice is ability to calculate field offsets automatically and then use field offsets as symbols in the memory record offsets but that is probably a different request really but sort of needs to happen from these scripts. This would allow for pointers which are automatically resolved and dont break when games are updated and the field offsets change since most offsets in mono classes will be field offsets (unless its part of an array).
Regarding loading IL or C# directly, I would worry that a compiler may not be available. I dont remember that being available by default in the mono runtime. In reality almost all Windows machines will have CSC but that is platform dependent and makes assumptions.
I did add the ability to load a compiled assembly and have successfully used that to load my own assemblies into a game and interact with the game via CE. One could probably have Mono load an assembly from a memory rather than disk so its not out of the realm of possibility. I'm sure that a lua script could probably compile code via CSC, ilasm or mono equivalent if found but that is probably going to be fragile.
|
|
Back to top |
|
|
jgoemat Master Cheater Reputation: 22
Joined: 25 Sep 2011 Posts: 252
|
Posted: Thu Apr 16, 2015 7:21 pm Post subject: |
|
|
Good ideas, I added walking to the parent, but I call compile for the method and that crashes the game most times walking up the class parents. I try to stop when I hit 'Object' or 'Component' but it still happens. I added a drop-down to the new version that will let you include fields from the base classes either integrated or with the base classes as separate structs. I've also got it doing defines for the addresses of static variables, which seems to work for the game I was using. Can you give a precise example of the variable you were having problems with so I can take a look? I have both Wasteland 2 and KSP and I was thinking of getting Pillars of Eternity anyway...
I haven't found how to look at enums yet...
For determining classes, what do you think I should do? We could go the full way and use namespaces, but I'm not sure what format to use. The existing routines seem to use ":" as a separator at least for <class>:<method>, but isn't "." the normal way? Maybe it tries to find the class as best it can and uses namespaces if provided. I thought about passing a CSV and options too. What I would really like (if people start using the fixed version where LUA AA commands don't pop up a window when enabling the script) is something like this:
Code: |
// define struct for CharacterStats in pillars of eternity which is a nested class under Character in the Pillars namespace) and the Character class itself, and tell it to include base classes separately (default includes inherited fields) and use the prefix CS_. That way if you have two structs (Character and Monster say) with Health, you could use CS_Health and M_Health for example:
MONOSTRUCT(Pillars.Character.CharacterStats,CS_,include_base_fields)
// or
MONOSTRUCT(Pillars.Character.CharacterStats,option(include_base_classes),prefix(CS_))
|
Maybe a second command for a static address?
Code: |
MONOSTATIC(SELECTED_CHARACTER,Pillars.Character.Selected)
//...
mov edi,[SELECTED_CHARACTER]
|
For methods, I was thinking double-click would open the disassembly window to the method. I want to include parameter names (and type if possible) in a comment in the text, and maybe an option to generate a script that can copied/pasted right away if I can find the time. Till then what about a command like this?
Code: |
MONOMETHOD(TakeDamage,Pillars.Character.TakeDamage)
|
Lastly I'm thinking of re-doing the tree, maybe by assembly/namespace/class with fields and methods under class like the mono dissector, but only populated by the search results with a star or something by the entries that actually matches the results. So only classes that match or that have matching methods/fields would be in the tree...
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Thu Apr 16, 2015 8:12 pm Post subject: |
|
|
I'm going for : because . might be used to specify a specific module/assembly
Also, in C notation, : is the common way to write down class and methods
(And besides, current scripts already make use of : notation )
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
tfigment Advanced Cheater Reputation: 2
Joined: 12 Oct 2012 Posts: 93
|
Posted: Thu Apr 16, 2015 10:20 pm Post subject: |
|
|
I would use the internal strings and not try to come up with your own parsing schemes. That way lies madness. Mono has a couple of methods that probably can be used. I exposed the one that provides the fully qualified path (There are 4 versions but the one that seems best is Namespace.Namespace.OuterClass+InnerClass`1[GenericType].fieldOrMethod. This has problems for parsing as field/method separator and namespace separator are the same. I ended up nixing the : in my version for display purposes because I got a properly fully qualified name from mono.
I presume there are string->type parsing methods in mono that can be exposed and used to search using the names it gives out if not just Type.GetType() equivalent (mono_reflection_parse_type or mono_reflection_type_from_name). Its probably worth creating a partial search in the collector itself for performance reasons.
Examples:
Wasteland 2 uses MonoBehaviourSingleton<T> quite a bit such as "class AchievementManager : MonoBehaviourSingleton<AchievementManager>".
The interesting thing here is that MonoBehaviourSingleton has a "static T m_Instance" which is going to be a valuable entry point into many of the Manager classes which expose a lot of functionality.
I would recommend at least pulling down my version linked by Dark Byte above and seeing what I did. There are some helpers like "Add Static Field Address" which creates a script to find that field when activated and fill in a symbol for it.
If you want a quick test environment for Unity, I created an EXE for testing and linked here: (there is a 64-bit build but I didn't share there).
http://forum.cheatengine.org/viewtopic.php?p=5587505#5587505
In the example, TestBehavior | base class | MonoBehaviorSingleton`1[TestBehavior] | static fields | m_Instance has the "Add Static Field Address" which would find TestBehavior.m_Instance and create a symbol for it.
I also demonstrated in this test the duplicate CharacterStats and Nested Classes.
|
|
Back to top |
|
|
|
|
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
|
|