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 


Mono - call static method from assembly [SOLVED]

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
[email protected]
Cheater
Reputation: 1

Joined: 26 Oct 2013
Posts: 32
Location: Greece

PostPosted: Fri Apr 07, 2017 5:05 pm    Post subject: Mono - call static method from assembly [SOLVED] Reply with quote

I can't figure out what am I doing wrong.

I am trying to call a c# method from this code:

Code:

usemono()
define(GGetAddress, "G:get")        // static int get(string name);
define(GSetAddress, "G:set")        // static void set(string name, int value);
define(GIncreaseAddress, "G:inc")   // static void inc(string name, int value);


alloc(CallGet,512)
alloc(CallSet,512)
alloc(CallIncrease,512)

registerSymbol(CallGet)
registerSymbol(CallSet)
registerSymbol(CallIncrease)

alloc(VarName, 256)
registerSymbol(VarName)
alloc(VarValue, 4)
registerSymbol(VarValue)

CallGet:
  push VarName                  // push the pointer to the address of the string
                                // variable name
  call GGetAddress              // call the get function
  add esp, 4                    // clean-up the stuck
  mov dword ptr [VarValue], eax // store the return value
  ret                           // return

CallSet:
  push [VarValue]               // push the integer value
  push VarName                  // push the pointer to the address of the string
                                // variable name
  call GSetAddress              // call the get function
  add esp, 8                    // clean-up the stuck
  ret                           // return

CallIncrease:
  push [VarValue]               // push the integer value
  push VarName                  // push the pointer to the address of the string
                                // variable name
  call GIncreaseAddress         // call the get function
  add esp, 8                    // clean-up the stuck
  ret                           // return

VarName:
  // type etc ... (copied from real string)
  db A4 85 1C 04 00 00 00 00
  // length
  dd 5
  // the string
  db 6D 00 6F 00 6E 00 65 00 79 00
  dq 0

VarValue:
  dd 0


The other two methods are working fine, but the get method leads to crash. I am calling them from LUA via:
Code:
autoAssemble("createThread(CallGet)")


The main differences between the functions that I've manage to figure out so far is that the get method first of all returns a value, and that the get method has none-static method calls.

Note that I am not a programmer, so don't go too deep with the explanation because I'll, probably, not understand it.

Any help will be greatly appreciated, thanks in advance.


Last edited by [email protected] on Mon Apr 10, 2017 6:52 am; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 376

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

PostPosted: Fri Apr 07, 2017 5:14 pm    Post subject: Reply with quote

either call that code from a codecave you know is getting executed from a mono thread, or let your thread first attach to mono

e.g something like this:
Code:

alloc(self,4)
call mono.mono_get_root_domain //eax contains the root domain
push eax //give it as parameter to mono_thread_attach
call mono.mono_thread_attach
sub esp,4 //undo the push because cdecl

mov [self],eax

call CallGet


push [self]
call mono.mono_thread_detach
sub esp,4
ret 4



(and make sure the first 4 bytes of VarName are correct. It looks like a vtable address for a String class object, so that can change between runs)

_________________
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
[email protected]
Cheater
Reputation: 1

Joined: 26 Oct 2013
Posts: 32
Location: Greece

PostPosted: Sat Apr 08, 2017 5:09 am    Post subject: Thanks, it works!:D Reply with quote

It works! Very Happy

Replaced call CallGet code with:
Code:

  mov eax,eax
  call mono.mono_get_root_domain //eax contains the root domain
  push eax                       //give it as parameter to mono_thread_attach
  call mono.mono_thread_attach
  sub esp,4                      //undo the push because cdecl

  mov [self],eax

  push VarName                   // push the pointer that points to the address
                                 // of the string variable name
  call GGetAddress               // call the get method
  mov dword ptr [VarValue], eax  // store the return value

  push [self]
  call mono.mono_thread_detach
  add esp,10                     // clean the stack
  ret

and it works as intended.

Thanks! As always, you're a life savior. Very Happy

And thanks for the example, without it it would be very hard for me to understand what you're saying.

You're right about the string; that is a problem that I am aware of, the way I plan on dealing with it is to copy the bytes from a known string literal.(G:get+offset there is a pointer to a string (always))

If I may, I wanted to ask another question. I feel like creating a thread each time I click a button is a bit wasteful. I have another version where I created an infinite loop (with a kill switch) where it sleeps and checks for
a switch every second like:
Code:

  cmp byte ptr [switchesGet],1
  jne _exit
  cmp byte ptr [switchesGet+1],1
  jne _sleep
_callGet:
  blah blah ...
_sleep:
  push #1000
  call KERNEL32.sleep
  jmp main
_exit:
  ret


Is there a real advantage to one of the two methods? Should I even worry about it, or itís an insignificant problem and creating a few dozens of threads in a course of an hour or two doesn't create a problem?
Back to top
View user's profile Send private message
[email protected]
Cheater
Reputation: 1

Joined: 26 Oct 2013
Posts: 32
Location: Greece

PostPosted: Mon Apr 10, 2017 6:52 am    Post subject: Closing Post Reply with quote

I assume that my last question is either idiotic, or too hard to answer, either way I'd like to report that I am using the new thread method and it works fine so far, for several hours of straight gaming.

Also the initial c# string bytes do not actually affect the results of the functions. So, I left them 0 (didn't bother to implement the solution that I had in mind) and everything works fine.

Thanks again for the help Dark-Byte, I wouldn't be able to find the solution on my own.
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