Log in

View Full Version : .NET hooking


rendari
January 23rd, 2008, 16:36
Right, so I've had this question kicking around inside my head for quite a while now, and I haven't been able to figure out the answer. So, I'm gonna post it here in hopes someone can help me:

I was reading this article on CodeBreakers awhile ago (its about .NET anti-RCE)
http://www.codebreakers-journal.com/content/view/123/97/

and please note the part where the author mentions calling getJit, and then getting the compileMethod address from there. Now, there are some functions in mscorwks.dll that I would like to hook as well. Is there a similar thing such as getJit(which is in mscorjit.dll) that will give me a pointer to a struct full of the addresses of vital functions in mscorwks.dll? Because I've been searching for some time for something like that. I've already done the obvious, such as going over the sources at www.koders.com, poring over the (limited) MSDN documentation, and reversing the exports of mscorwks.dll in IDA.

So, is there anything I'm missing here? Or does no one have any idea on how to hook functions in mscorwks.dll? I'm gonna keep looking; will post if I figure it out.

PS I already know about dotNet hook, and that's not what I am looking for. The author there isn't hooking mscorwks.dll; he is simply inserting his own code and redirecting the metadata to point to it. Completely different story.

dELTA
January 26th, 2008, 08:56
Hey rendari, more exactly what would the difference be between hooking functions in mscorwks.dll and "normal" DLL/in-memory function hooking do you mean? If you clarify the exact problem I'm sure someone will be able to help you get further along with this.

An interesting old thread on a similar subject/situation can be found below, perhaps it will be of any help to you?

http://www.woodmann.com/forum/showthread.php?t=1692

If it's just a tool/technique problem, you may find following CRCETL category interesting:

http://www.woodmann.com/collaborative/tools/Category:Code_Injection_Tools

Otherwise please explain further.

And if some kind of cool tool comes out of this project of yours in the end, you will of course post it here, right?

rendari
January 26th, 2008, 13:59
hi dELTA,

Thank you for providing those links. They were interesting, but not what I was looking for. Let me try and clarify my problem:

In mscorwks.dll there is a function called PreStubWorker. This function is not exported. Now, my goal is to somehow hook that function. The only other .NET function I have managed to hook is compileMethod(), and this is because .NET keeps a table of pointers to important functions. One of these important functions is compileMethod. You can get the offset of this table by calling getJit. However, this table only applies to functions within mscorjit.dll. The function I am trying to hook is in mscorwks.dll. And, so far, I have not found a getJit equivalent in mscorwks.dll. Therefore, I have no way of finding the offset of Prestub worker, and therefore no way to hook it. Using hardcoded offsets is not an option for me, because this will probably fail on other machines and/or future versions of .NET.

So, pretty much I am looking for a way to find the offset of PreStubWorker in mscorwks.dll.

If anything is unclear, please post again so that I can attempt to better clarify my problem

Quote:


And if some kind of cool tool comes out of this project of yours in the end, you will of course post it here, right?


Of course! ATM, I have a .NET unpackme out in the wild. As soon as someone (cough cough prolly LibX cough) unpacks it, I'll take some time writing a blog post describing the inner workings of my unpackme, and, consequently, .NET. This should be useful for people that want to take a deeper look at .NET, since there is so little info available ATM .

dELTA
January 27th, 2008, 10:55
Sounds very nice with the upcoming blog post on .NET internals rendari, I'm looking forward to it indeed. Nice work on that advanced .NET unpackme too.

Regarding the problem at hand in this thread, I have one initial question to you regarding this "PreStubWorker" function that you want to hook: Exactly how do you know the name of an internal function in a DLL if it's not exported? This is a native DLL, right? What I'm getting at is that if you know the name, you probably got it from some kind of symbols, and if these are always included, you should be able to use these to be able to get the address of the function in a safe way, for each individual version of the DLL? Answer this, and I'll then keep doing my best to help you solve this.

rendari
January 27th, 2008, 13:09
Yes, I am using symbols that I had IDA download off of the M$ symbol sever, so therefore the symbols do not actually come with the dll. Furthermore, I know next to nothing about symbols, or how I'd use them outside of IDA to find the offset for this function Maybe it's something I should read up on...

dELTA
January 28th, 2008, 03:19
Ok, if symbols aren't included to begin with, they might not be a viable way to go.

Then, could you please upload a copy of your mscorwks.dll (+ symbols if possible, but not vital) to this thread (it's ok, it's free software), so that we're sure to be working on the exact same version, and also post the exact address of this PreStubWorker function. I'll then take a look at it and try to find some stable and version independent ways of pinpointing that function.

Oh, also, just so I don't misunderstand anything, exactly why is it important to be able to find the function in a 100% stable way in all future versions of .NET? Is it because you are going to release a tool to the public that you want to be really stable for all time? In the worst case, I guess you can make sure the detection works for all existing versions of .NET, and then release an update to the tool if a new .NET version would come out that breaks your pinpointing algorithm?

blabberer
January 28th, 2008, 10:56
i dont know shit about .net havent framed it yet

posted by rendari
Quote:

Yes, I am using symbols that I had IDA download off of the M$ symbol sever, so therefore the symbols do not actually come with the dll.


posted by dELTA
Quote:

Ok, if symbols aren't included to begin with, they might not be a viable way to go.


does .net always come with symbols included in them

isnt it like every other symbols that has to be downloaded via symbol server ?

dELTA
January 28th, 2008, 12:42
Blabberer, I think you might have misunderstood something above?

Read the texts you have quoted again, rendari says that he had to download the symbols separately (i.e. that they were not included with the DLL), and I then said that "ok, then using the symbols for finding the hook point is probably not a good solution", referring to the fact that it would probably not be very desirable for a standalone tool to have to download the symbols for the version of this particular .NET DLL file on the machine it happens to be running on, in order to be able to find the correct hook points.

See, no contradiction there?

rendari
January 28th, 2008, 20:37
Hello dELTA,

thanks for replying. I have managed to find a sort of internal interface for mscorwks.dll, and am using it to hook certain functions in the next version of my unpackme. However, I am still working on finding some way to hook _PreStubWorker and _DecoderInit. The offsets for those functions are 79E7BACA and 79E7E509 respectively, for the version 2 of mscorwks.dll (are you sure we're allowed to share this? And are you sure you don't already have it? .NET is pretty standard these days =/ ):

http://www.filesend.net/download.php?f=323150356a0828285f2a61047ed870aa

Quote:

Oh, also, just so I don't misunderstand anything, exactly why is it important to be able to find the function in a 100% stable way in all future versions of .NET? Is it because you are going to release a tool to the public that you want to be really stable for all time? In the worst case, I guess you can make sure the detection works for all existing versions of .NET, and then release an update to the tool if a new .NET version would come out that breaks your pinpointing algorithm?


Well, you see that is quite an interesting dilemna I have been put in. Here, let me try and tell you a little story, to clarify why I want 100% stable ways to hook a function:

When .NET 1.0 came out, we had in our framework dir mscorwks.dll and mscorjit.dll. These 2 dlls are the JIT interpreter for .NET, and .NET uses them to compile IL code into native code, which it then executes. Pretty simple, right? Well, what happened then is when .NET 2.0 came out, it introduced 2 new builds of mscorwks.dll and mscorjit.dll. In these 2 builds, old offsets and byte patterns no longer applied, and so the only hooks that were working were the ones that went the 100% stable way (that is, call getJit then get offset of compileMethod out of JIT struct). Now, you're probably saying to yourself:

"Well, ok, this is not a problem, since the mscorjit.dll and mscorwks.dll for the 2.0 version of the framework will only be used to interpret the v2.0 .NET exes, and any exes that were built with .NET version 1.0 will be interpreted by the mscorjit.dll and mscorwks.dll of the 1.0 version, right? So, therefore all the 1.0 exes that were protected by my tool will still function, since the old dlls are being loaded, and thus the old offset/byte pattern hooks apply." WRONG.

It turns out, that the new mscorjit.dll and mscorwks.dll in .NET v2.0 completely replaced the old mscorwks.dll and mscorjit.dll. Therefore, when a protected .NET v1.0 exe is launched on a machine that has .NET 2.0 installed, the new mscorwks.dll and mscorjit.dll will be loaded to interpret, and our old offset/byte pattern hooks do not apply on these new dlls. Thus, the .NET 1.0 exes will crash. The only way this can be fixed for any software devs using my protector is that they first must wait for me to release a new version that has v2.0 compatibility, they must reprotect their exe, and then they must resend this new protected exe to all their clients. This is something that Microsoft might make their users go through, but not me. Also consider this: far in the future (15 years from now), when people want to use an exe protected with my protector, and they have .NET v28 installed on their computer, and after both me and the developer of the program in question have stopped releasing patches, they won't be able to use the program solely due to my shitty coding, where I used offset/byte pattern hooks instead of "safe" hooks. Again, this is not something I want to put people through. Therefore, I want to have safe hooks that will work in future versions of .NET without inconveniencing people who happen to use my softie

That, and its kind of fun to trace around the CLR all day in school :P

dELTA
January 30th, 2008, 09:07
I was thinking of pin-pointing the unknown functions by means of combinations of known functions, offsets, byte patterns and call-graph analysis (e.g. if the function is called by two known functions, and also itself calls a third known function etc, it can be identified with relatively high certainty, without any known offsets or byte patterns). This can be done quick and dirty too, by only searching for the call opcode byte patterns etc, without disassembling the entire functions.

If you want it to be 100% sure even through major .NET version upgrades though, I'd say all bets are off other than trying to find some really reliable internal interface pointers etc, but since all undocumented (and even some documented, depending on situation) interfaces can change between versions, I'd say the only 100% secure way is by using public interfaces (and if it's not in there, you're toast).

If you can settle for 99% certainty though, I'd try my suggested methods above.

rendari
January 30th, 2008, 15:59
Well then I guess I'll stick to internal interfaces for now =/