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 


[C#] Using the pipe of monocollector
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Source
View previous topic :: View next topic  
Author Message
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Wed Sep 24, 2014 3:33 am    Post subject: [C#] Using the pipe of monocollector Reply with quote

Has anyone actually tried using the pipe of the monocollector in C#? I'm curious in how it works. I've taken a look at the lua file of the mono collector but it doesn't helped me much at this point.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Wed Sep 24, 2014 4:42 am    Post subject: Reply with quote

Check out the C part of the monocollector
Pipeserver.cpp

Anyhow, it creates a named pipe called :"\\.\pipe\cemonodc_pid#" where # is the current processid of the process it's in

The name is setup at PipeServer.cpp#32
the pipe is created at PipeServer.cpp#47 (based on your previous request for timeouts, this is where you have to change that, and obviously all other places that do not expect timeouts to occur)

The communication protocol is sadly enough pretty much undocumented, but it's a very basic protocol so shouldn't be too hard to figure out.

Message handling happens at PipeServer.cpp#534

two examples:
InitMono: (command 0)
PipeServer.cpp#62 takes no additional parameters, but it returns a QWORD with the address of the mono dll

So to use it send a 0, and then receive 8 bytes

--
Object_GetClass (Command 1)
PipeServer.cpp#187

takes one parameter. An implemented object, whose address is passed in as a QWORD (You'll find all address specifiers are implemented as a qword because it's the lowest common denominator)

If it succeeds it returns the address of the class (qword) the length of the classname (word) and the name of the class (char*classnamelength)

If it fails it only returns the address 0, but NO name. It won't even send a namelength of 0

So to use it:
Send a 1 and then receive 8 bytes (qword)
if it's 0, that's it. if it's not 0, then read 2 bytes (word) allocate space for a string of that size+1, and then read that string into that space(You will have to 0 extend the string yourself, it's not part of the message)

Just check the lua part that has this fully implemented

_________________
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
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Wed Sep 24, 2014 5:03 am    Post subject: Reply with quote

Thanks that was very helpful to understand the theory. Now I need to find out how I call (or read) the pipe after injecting the DLL. The examples on MSDN are either for c++ to c++ or c# to c# but not from c++ to c# or vice versa.

Once I had injected the dll i got the handle of it (also the start address). But from there I have no idea how to communicate over the pipe.

If anyone has an idea, feel free to post it here.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Wed Sep 24, 2014 5:10 am    Post subject: Reply with quote

Just experiment with named pipes in C# and then apply that on the named pipe for the mono data collector

Imagine writing a program in C# that connects a pipe to a closed source application. It doesn't matter that you don't know what language the original program is written it, as long as you manage to send bytes in and receive bytes from it you're fine

Some basic info:
The process the dll is injected in is the pipe server, so you only have to write the c# client
It's setup to use a byte based communication protocol (not message based)
It uses an infinite timeout, so you can take as long as you wish when debugging.

_________________
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
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Wed Sep 24, 2014 5:51 am    Post subject: Reply with quote

When I'm trying to connect to the pipe it says it cannot find the path. Are you sure the pipe server name is "\\.\pipe\cemonodc_pid#" where # is the process ID as integer?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Wed Sep 24, 2014 6:10 am    Post subject: Reply with quote

yes.
Of course, that's the low level name, perhaps you just need cemonodc_pid#

If you do need the path, make sure that the string formatting is done properly. e.g in C string format it'd be "\\\\.\\pipe\\cemonodc_pid#"

_________________
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
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Wed Sep 24, 2014 2:52 pm    Post subject: Reply with quote

"cemonodc_pid3390" (3390 is the PID of the process) I've tried that already as well as "pipe\\ cemonodc_pid3390" and "\\.\\pipe\\cemonodc_pid3390" Everything like that, it still claims that no path like this exist.

is there any way to print out the name?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Wed Sep 24, 2014 7:40 pm    Post subject: Reply with quote

the pipename then has to be \\.\pipe\cemonodc_pid3390

Quote:

is there any way to print out the name?

I recommend printing out the name you are giving and confirm it actually is '\\.\pipe\cemonodc_pid3390' when printed out


also
if treated as a formatted string, then "pipe\\ cemonodc_pid3390" would end up 'pipe\ cemonodc_pid3390'

and "\\.\\pipe\\cemonodc_pid3390" would end up ''\.\pipe\cemonodc_pid3390'

both would be wrong

_________________
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
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Thu Sep 25, 2014 4:18 am    Post subject: Reply with quote

//fixed

Last edited by Hatschi on Sat Oct 25, 2014 3:31 pm; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Thu Sep 25, 2014 4:30 am    Post subject: Reply with quote

Create your own named pipe server in c# and see if you can get that to work

Anyhow, from reading the msdn the servername you provide is testpipe. I think you want to use "." instead , and then give as name cemonodc_pid#
http://msdn.microsoft.com/en-us/library/bb355390(v=vs.110).aspx

Or use the version where you only give the pipename without providing the servername
http://msdn.microsoft.com/en-us/library/bb340152(v=vs.110).aspx

_________________
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
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Sun Oct 05, 2014 5:35 am    Post subject: Reply with quote

//edit: nevermind. It works flawless now.

What do you mean with "An implemented object, whose address is passed in as a QWORD". Can you give me an example what to pass to receive the address of the class?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Sun Oct 05, 2014 5:47 am    Post subject: Reply with quote

open monoscript.lua and replace
Code:

  monoBase=monopipe.readQword()

  if (monoBase~=0) then

with
Code:

  monoBase=monopipe.readQword()
  print(string.format("monoBase=%x", monoBase))

  if (monoBase~=0) then

and check it (restart ce first)

all it means is that it found a modulehandle that had one of the mono exports.

Also, run dbgview from sysinternals and see if the target outputs an error

And read the 8 bytes into a 8 byte integer value(little endian). Do not try to manually convert it into an 1 digit each hexadecimal AOB and then interpret it, as it's very easy to accidentally swap some bytes around then.
e.g:0 0 4c 5 0 0 0 0 = 00 00 4c 05 00 00 00 00 = 00000000054c0000
not 004c50000

_________________
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
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Sun Oct 05, 2014 5:57 am    Post subject: Reply with quote

Quote:

What do you mean with "An implemented object, whose address is passed in as a QWORD". Can you give me an example what to pass to receive the address of the class?


let's say you have found the players health, and by debugging (or just using mono to look through it's heap) you found where the player structure starts

you can then pass that address to this function and get a result.

Anyhow, I recommend starting with the enumeration methods. Enumerate domains, assemblies, getting the image from the assembly, then enumerate all classes in the image

_________________
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
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Sun Oct 05, 2014 6:04 am    Post subject: Reply with quote

So there is no way I could send for example

"HUD_OverheadStatusContainer:Reposition" (as string or converted to array of bytes or whatever) to get the address of this class? I wonder because this way the memory viewer jumps to when I enter this as address. This is what I'm trying to do. Receive the address of the class by knowing its name.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

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

PostPosted: Sun Oct 05, 2014 6:11 am    Post subject: Reply with quote

First split up that string into a classname and methodname
classname=HUD_OverheadStatusContainer
methodname=Reposition

you can use MONOCMD_FINDCLASS to find the class named "HUD_OverheadStatusContainer"

Then call MONOCMD_FINDMETHOD with the class and "Reposition" to get the method describer of Reposition

Then call MONOCMD_COMPILEMETHOD with that method describer to get the address of that method, or to compile it if it wasn't jitted yet

Check monoscript.lua on how it does that

_________________
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
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Source All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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