Reverse Engineering RET Homepage RET Members Reverse Engineering Projects Reverse Engineering Papers Reversing Challenges Reverser Tools RET Re-Search Engine Reverse Engineering Forum Reverse Engineering Links

Go Back   Reverse Engineering Team Board > Reverse Engineering Board > .NET Reverse Engineering
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Display Modes
  #1  
Old 10-07-2008, 07:37 AM
ender ender is offline
Member
 
Join Date: Oct 2008
Posts: 9
Question 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.
__________________
if you build a man a fire he will be warm for a day; if you set a man on fire he will be warm for the rest of his life. :rolleyes:

Last edited by ender : 10-07-2008 at 08:20 AM.
Reply With Quote
  #2  
Old 10-07-2008, 10:52 AM
Kurapica Kurapica is offline
Senior Member
 
Join Date: May 2006
Location: Archives
Posts: 357
Default

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 ?
__________________
Life can only be understood backwards but It must be read forwards.
Reply With Quote
  #3  
Old 10-07-2008, 11:13 AM
ender ender is offline
Member
 
Join Date: Oct 2008
Posts: 9
Default

Quote:
Originally Posted by ender View Post
... 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.
__________________
if you build a man a fire he will be warm for a day; if you set a man on fire he will be warm for the rest of his life. :rolleyes:
Reply With Quote
  #4  
Old 10-07-2008, 11:30 AM
ender ender is offline
Member
 
Join Date: Oct 2008
Posts: 9
Default

Quote:
Originally Posted by Kurapica View Post
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
__________________
if you build a man a fire he will be warm for a day; if you set a man on fire he will be warm for the rest of his life. :rolleyes:

Last edited by ender : 10-07-2008 at 02:17 PM.
Reply With Quote
  #5  
Old 10-07-2008, 11:42 AM
LibX LibX is offline
Administrator
 
Join Date: Feb 2007
Location: The Netherlands
Posts: 118
Default

Why dont u just push the ascii value of the char u need and cast it to a char?
Reply With Quote
  #6  
Old 10-07-2008, 02:12 PM
ender ender is offline
Member
 
Join Date: Oct 2008
Posts: 9
Default

Quote:
Originally Posted by LibX View Post
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.
__________________
if you build a man a fire he will be warm for a day; if you set a man on fire he will be warm for the rest of his life. :rolleyes:

Last edited by ender : 10-07-2008 at 02:22 PM.
Reply With Quote
  #7  
Old 10-07-2008, 03:09 PM
Kurapica Kurapica is offline
Senior Member
 
Join Date: May 2006
Location: Archives
Posts: 357
Default

Can you post the MSIL code of the method here ? or maybe the exe itself would be better
__________________
Life can only be understood backwards but It must be read forwards.
Reply With Quote
  #8  
Old 10-08-2008, 11:51 PM
ender ender is offline
Member
 
Join Date: Oct 2008
Posts: 9
Default

Quote:
Originally Posted by Kurapica View Post
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
__________________
if you build a man a fire he will be warm for a day; if you set a man on fire he will be warm for the rest of his life. :rolleyes:

Last edited by ender : 10-09-2008 at 03:33 AM.
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump





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