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 


Working on mono goodies and have some CE/LUA/Form questions

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
jgoemat
Master Cheater
Reputation: 22

Joined: 25 Sep 2011
Posts: 252

PostPosted: Tue Apr 14, 2015 4:47 am    Post subject: Working on mono goodies and have some CE/LUA/Form questions Reply with quote

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...



monostruct.png
 Description:
 Filesize:  229.01 KB
 Viewed:  15714 Time(s)

monostruct.png



MonoSearchForm.LUA
 Description:

Download
 Filename:  MonoSearchForm.LUA
 Filesize:  8.9 KB
 Downloaded:  810 Time(s)

Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25296
Location: The netherlands

PostPosted: Tue Apr 14, 2015 6:04 am    Post subject: This post has 1 review(s) Reply with quote

the injected dll sourcecode is at https://code.google.com/p/cheat-engine/source/browse/trunk/Cheat+Engine/MonoDataCollector/MonoDataCollector/

as for contributing, tfigment has provided some patches here http://forum.cheatengine.org/viewtopic.php?p=5587497#5587497
(which i still need to add to the svn when/if i'm able to concentrate again)

that showmessage on registered aa commands is a debug message i forgot to remove. it's fixed in the svn though

you can add form files to a table (in the conponent bar click file load)

_________________
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
View user's profile Send private message MSN Messenger
jgoemat
Master Cheater
Reputation: 22

Joined: 25 Sep 2011
Posts: 252

PostPosted: Wed Apr 15, 2015 7:07 pm    Post subject: Reply with quote

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
View user's profile Send private message
tfigment
Advanced Cheater
Reputation: 2

Joined: 12 Oct 2012
Posts: 93

PostPosted: Thu Apr 16, 2015 8:35 am    Post subject: Reply with quote

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
View user's profile Send private message
jgoemat
Master Cheater
Reputation: 22

Joined: 25 Sep 2011
Posts: 252

PostPosted: Thu Apr 16, 2015 7:21 pm    Post subject: Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25296
Location: The netherlands

PostPosted: Thu Apr 16, 2015 8:12 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
tfigment
Advanced Cheater
Reputation: 2

Joined: 12 Oct 2012
Posts: 93

PostPosted: Thu Apr 16, 2015 10:20 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine 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