PDA

View Full Version : Help with a particular function


dotnetresearcher
11-19-2009, 05:07 AM
I'm about half way through cracking some software, very simple stuff, stripping strong names and nop'ing license checks - which is about my limit.

I've hit a problem with a particular function. I can't use reflector, so I'm in Ildasm. I need to stop an exception being thrown and have the correct object returned. I've attached the ildasm view.

I've tried nop'ing the 7A "throw", which broke it (JIT compiler internal limitation) and I've tried nop'ing the switch statement (i don't fully understand how the jump tables work) but that caused a method access exception.

Help would be appreciated. I've cracked this software before, but they've changed the protection on this version.

Edit: I've managed to get a bit further. I changed:

IL_006c: /* 2B | C8 */ br.s IL_0036

to

IL_006c: /* 2B | 10 */ br.s IL_007E

Which I'm *fairly* sure directed the code to the happy path. The next exception certainly indicates that that I've got further, but the exception that is being thrown now is a MethodAccessException, which I suspect means I've fouled up somewhere.

Many thanks,

DNR

kao
11-19-2009, 06:49 AM
I replaced switch with jumps, rearranged the code and removed useless instructions. You can see the program logic now:

.method private hidebysig instance class xxx.yyy.PdfTranslationSession
a(class xxx.yyy.OcrEngine A_0,
class xxx.yyy.OcrDocument A_1) cil managed
{
.maxstack 3
.locals init (class xxx.yyy.PdfTranslationSession V_0,
int32 V_1)

IL_0026: ldarg.1
IL_0027: brtrue.s IL_004c

IL_006e: ldstr "engine"
IL_0073: ldstr "Translate needs a valid OcrEngine object."
IL_0078: newobj instance void [mscorlib]System.ArgumentNullException::.ctor(string,string)
IL_007d: throw

IL_004c: ldarg.1
IL_004d: ldstr "pdftranslator"
IL_0052: callvirt instance object xxx.yyy.OcrEngine::GetLicenseFlag(string)
IL_0057: brtrue.s IL_007e

IL_0036: ldstr "PDF Translator license not found."
IL_003b: newobj instance void [xxx.Shared]xxx.Imaging.xxxLicenseException::.ctor(string)
IL_0040: throw

IL_007e: ldarg.0
IL_007f: newobj instance void xxx.yyy.PdfTranslationSession::.ctor(class xxx.yyy.PdfTranslator)
IL_0084: stloc.0
IL_0085: ldloc.0
IL_0086: ldarg.1
IL_0087: ldarg.2
IL_0088: callvirt instance void xxx.yyy.PdfTranslationSession::ConnectToEngine(cla ss xxx.yyy.OcrEngine, class xxx.yyy.OcrDocument)
IL_008d: ldarg.0
IL_008e: ldarg.2
IL_008f: call instance void xxx.yyy.PdfTranslator::a(class xxx.yyy.OcrDocument)
IL_0094: ldloc.0
IL_0095: ret
}


If you decide to patch something, you must make sure that the stack is right and all instructions are valid. Noping out just "throw" instruction is wrong, you should nop also corresponding "ldstr" instructions. Same restriction applies if the patched instruction is of different size than original one!

Easiest patch I can think of is: IL_0009: br.s IL_007e.

dotnetresearcher
11-19-2009, 06:59 AM
[Please do not reply to yourself, use the Edit button to add to your post]

Hi Kao, thanks for the pointers on nop'ing.

I did pretty much the same thing (albeit further down the method) to jump to the happy path. (see my edit in the original post).

The problem I have is that although this method now seems to complete successfully, when the caller of this method calls the next method, I get a MethodAccessException.

Any suggestions of what this might be?

Thanks again,

DNR

Aar, OK sussed it. The next method that's being called is an internal class with InternalsVisibleToAttribute specified in the manifest.

Obviously the strong names are stripped, so what's the best way of tackling this? How do I make the class public? I'd rather not go through the hassle of resigning and patching the manifests if possible.

OK scrub my last :)

Found how to change class and method visibility within CFF Explorer. God Damn that is a fine tool.