Log in

View Full Version : Tough .NET protection


naides
August 18th, 2008, 22:09
I have a question for the .NET gurus here.
As a disclaimer I already defeated the protection using quite convoluted tricks so please bear with me.
There is this .NET program protected with a HASP dongle. I did not attacked the dongle code but went around it: This is an image processing software, which includes some demo images for the tutorials. demo images open in demo mode, so if I am able to convince the program that my images are demo, it goes its merry way and open them. OK?

Now I opened the program with Lutz Reflector, the assemblies were not obfuscated, but it tried to load and asked me to manually locate certain modules, with very revealing names such as "licenseCheck", files that do NOT exist in my computer: I searched for them, not in the app folder, windows folder, the GAC, nowhere.
When you further analyze the app, you realize that the salt of the protection is contained in such ghost modules: for instance, a bool function named IsImageDemo. Lutz places a red ! sign besides them, because they are not available, meaning the name of the function is known to the calling module but the callee code and the module that contains it, is not.

I searched for the method names in memory while the application was running under Olly, and BAM! I found that a full valid image of the PE module licenseCheck.dll loaded into a nameless segment of memory. I dumped it to disk and was able to analyze it with Lutz and IDA, eventually defeating the protection, but I had to do some inelegant tricks to achieve it.

Now my questions: Where could those modules be in the first place??
How do they get loaded?
Is this .NET protection method known by any of you??

I am sorry if I do not provide enough details, (licenseCheck.dll is a fake name to protect the innocent).
I am open to suggestions, I am just trying to get a grasp on this protection system, which I think I reversed by sheer luck.

FrankRizzo
August 19th, 2008, 00:36
Could they be packed onto the .exe as an "invisible overlay". Kinda like in the old DOS days? Then, at runtime, they open the file, read the data in memory somewhere, and "LoadLibrary" it?

Is that even possible?

Naides, if you haven't, grep the application directory for the function name, and see if you get more than a couple of hits.

FWIW, I'm interested to hear where it is as much as you are!

naides
August 19th, 2008, 05:28
Hi Frank.
I did grep for pieces of the files in question through out the computer. (inside a VM, so it does not take for ever). Nada, if they are there, they are crypted/packed. I placed bp on LoadLibrary. Called often but not to load my ghost dll. One thing curious,which allowed me to break the protection: If the "unpacked" .dll exists in the GAC, or in the app folder, it is loaded from there instead of "unpacking" ( Priority scale: GAC >> folder>> Ghost/packed). I have studied some of .NET packers out there, but they seem rather primitive, and leave obvious clues. In fact they are conceived more for convenience than protection. Perhaps I have not found the right one. . .

TQN
August 19th, 2008, 10:56
You can place a breakpoint on method AssemblyNative::LoadImage of mscorwks.dll. [ECX + 8] point to the .NET PE memory, [ECX + 4] is the real size.

rendari
August 19th, 2008, 13:20
^ What he said

Also check modules in Olly. It shows where each module is loaded from, even .NET modules I believe.

omega_red
August 20th, 2008, 07:10
Nice trick is to actually assemble code in runtime, but I guess it's not used here.

FrankRizzo
September 6th, 2008, 15:53
From the target that I'm working on now, it COULD be that they're the "Unmanaged" half on a mixed mode assembly. So it loads the file (presumably a .DLL) normally, (as a .NET assembly), and has a 2nd half which is the UnManaged half is around as well.

In my case, the Managed code makes calls to the UnManaged code, which made it obvious as to what was happening. In YOUR case, it sounds a bit more mysterious. (Hmm.. I wonder if you could PACK the unmanaged chunk of code, thus hiding it from grepping, and then unpack it at runtime.)

gd0
October 6th, 2008, 11:31
Quote:
[Originally Posted by FrankRizzo;76871]
In my case, the Managed code makes calls to the UnManaged code, which made it obvious as to what was happening. In YOUR case, it sounds a bit more mysterious. (Hmm.. I wonder if you could PACK the unmanaged chunk of code, thus hiding it from grepping, and then unpack it at runtime.)


So if you mix managed and unmanaged the unmanaged portion is wrapped in the assembly somehow? I was wondering about this also.. so I coded a crackme and included an unmanaged class I wrote for the serial routine. and no dll is produced in the projects dir, just the exe. I havent given a real go at my own crackme yet, but in reflector you obviously cannot view anything thats done after i instantiate the unmanaged class, it just shows some things that are returned to the managed portion. its interesting to protect this way, i thought it would be at least a trick of sorts, but also thought it would totally segregate the .net from the unmanaged stuff, therefore making it easier to find.

FrankRizzo
October 6th, 2008, 19:48
I've messed with a protection like this. You load it into IDA, and it asks you to choose if it's a NORMAL file, or a .NET file. If you choose .NET, you get IL code, if you choose regular, you get the ASM code. So, there IS a way in, but the tracing is difficult for me at least.

In case anyone cares, the thing that I'm looking at is the .Net version of Protection Plus. They have the normal .DLL for their protection functions, and have a .NET interface to it. Some of the functions exist solely in the .NET side, while the others are just a stub in .NET that calls the assembly side.

gd0
October 20th, 2008, 10:29
Here's an simple example if anyone's interested in mixed managed/unmanaged crackme:

http://reversing.us/CrkMe.exe ("http://reversing.us/CrkMe.exe")

post or email me (g0dmoney ( at) reversing.us) a solution if ya want, its super easy, just the mixed portion can be the tricky part. gives a good example of what i mean tho.

cheers