Reverse Engineering Team Board

Reverse Engineering Team Board (http://www.reteam.org/board/index.php)
-   .NET Reverse Engineering (http://www.reteam.org/board/forumdisplay.php?f=28)
-   -   Can a string object be created in place (http://www.reteam.org/board/showthread.php?t=1131)

ender 10-07-2008 07:37 AM

Can a string object be created in place
 
First off, I just wanted to thank everyone who has taken time to contribute to this board. This is really one of the best (and definitely most active) resources on .net reversing I've been able to find.

All ass kissing aside ;) , I had a quick (noobish) question.

I've been studying the protection scheme of a certain .net app, and it looks like the license key is encrypted using public-key cryptography. However, at the end of the day, the program ultimately uses some very simple checks against hard coded int values to see if the program is registered. The catch is, the "decoded" value that the program is constantly checking against is supposed to be a string (that holds the value "3" if the prog is registered).

I've searched through the CLI specification docs to see if there is anyway I can patch a certain method with a hard coded string value (which in this case would always be "3"), but it seems that strings can only be pushed onto the stack by reference. I tried to use the "box" instruction in conjunction with the ldc.i4.3 instruction, but that doesn't seem to work. I get an "object reference not set to instance of object" error.

So if anyone happens to know a way that I could push a string object with the value "3" onto the evaluation stack without having to mess around with the metadata tables, I'd be much obliged.

If it's not possible, any guidance on how to actually modify the metadata tables (without mucking everything up), so I can insert a string with the value "3" and then access it via reference would be equally appreciated.

Kurapica 10-07-2008 10:52 AM

I hope I understand your problem.

does this mean that you have a string-returning function that should return the string "3" and then all is ok ?

Is there a string with the value "3" somewhere in the metadata ?

ender 10-07-2008 11:13 AM

Quote:

Originally Posted by ender (Post 10056)
... if anyone happens to know a way that I could push a string object with the value "3" onto the evaluation stack without having to mess around with the metadata tables, I'd be much obliged.

Well, I googled around some more and found that it's possible to load a constant into a local variable (given that one of the appropriate type is available). After that, the local variable can be indirectly pushed onto the stack with the "ldloca" instruction, and a call to the int32::toString method can be made. That will return a string object with whatever int value was set.

I was able to get around the protection using the above technique, but given that the code for the workaround takes up more bytes than the code it replaces, I'm still very interested to know if there are any good tools or resources to learn more about modifying/adding string constants to the metadata tables of an app. If anyone could point me in the right direction, I'd really appreciate it.

ender 10-07-2008 11:30 AM

Quote:

Originally Posted by Kurapica (Post 10066)
I hope I understand your problem.

does this mean that you have a string-returning function that should return the string "3" and then all is ok ?

Is there a string with the value "3" somewhere in the metadata ?

Thanks for the response Kurapica; you must have sent it when I was responding to my own post, lol.

And yes, you understand the problem correctly, and no I don't think there were any strings with the value "3" from looking over the stream data, although I honestly don't know of a good way to search the actual values of the md streams effectively/efficiently. Largely because I'm not exactly sure how the data in the streams is delimited.

I'm using CFF Explorer to look at the streams, and while CFF has a listing of the various metadata tokens with corresponding #blob index values, I'm not exactly sure how the indexing works (is it referring to an absolute byte location in the stream or to a number of elements from the beginning of the stream).

Is there a way to view a flat listing/indexed view of the elements in the metadata streams? ... because all I've been able to see is the hex/ascii view when I click on the stream, and I have to imagine there's a more efficient way to view the strings encoded in the blob than to have to scan through the jumbled clutter of text in the hex view one at a time.

Thanks :)

LibX 10-07-2008 11:42 AM

Why dont u just push the ascii value of the char u need and cast it to a char?

ender 10-07-2008 02:12 PM

Quote:

Originally Posted by LibX (Post 10069)
Why dont u just push the ascii value of the char u need and cast it to a char?

I don't think you can cast a value (the cast instruction requires an object reference). However, pushing the appropriate ascii value and boxing it to a char seems to do the trick. Thanks for the suggestion :)

That being said, I'm still curious about using the metadata streams (or some other method) to accomplish this because pushing an ascii value and boxing it still takes up more bytes (7 bytes total) than the method calls i want to replace. It would be ideal if i could use a piece of code that was 5 bytes or less, so I can just do a find and replace rather than have to replace the method calls by hand one at a time due to the likelihood of overwriting something important.

Kurapica 10-07-2008 03:09 PM

Can you post the MSIL code of the method here ? or maybe the exe itself would be better

ender 10-08-2008 11:51 PM

Quote:

Originally Posted by Kurapica (Post 10073)
Can you post the MSIL code of the method here ? or maybe the exe itself would be better

The program is called Video Thumbnails Maker by Scorp. It's donationware so it's a fairly harmless "target" as far as that goes.

Anyway, if you dotfuckscate the program to decode the encrypted strings and take a look at the IL code, the decoding method for the registration key is at [h.a() : string]. It checks the registry for the registration string and passes it to a decoder method and then returns the decoded string to the [f.a(int32) : string] method. I just nop'd out the decoding instructions and set h.a() to simply return the registry value at "HKCU\\Software\\SUU Design\\key" as is.

Digging around in the IL I determined that the decoded key must contain 6 elements delimited by the ';' char, with the 4th value being a number from 0-3 indicating the registration status of the program (0=common, 1=silver, 2=gold, 3=platinum).

I also noticed what looks like the key encryption method at h.a(String)... the author seemed to leave it in even though it is never called from within the app, so making a keygen should be fairly trivial.

Well, not to drag this out too long, my point is that I found several fairly easy ways to circumvent the protection for the specific app I was looking into. Notwithstanding, I'm still very interested to know if anyone knows of a good way or is aware of any good tools to easily modify/manipulate strings stored in the metadata streams of .net apps. A resource editor for stream data essentially. All of the resource editors I'm aware of only allow you to access/modify resources stored as part of the native/compiled part of the PE.

As always, any help/advice/nudge in the right direction is much appreciated (any good reference/documentation on interpreting metadata streams would be very helpful).

Thanks


All times are GMT -4. The time now is 07:43 AM.

Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.