Log in

View Full Version : Problem with an app and ASProtect


tanis
October 5th, 2004, 10:21
I am trying to work my way through an application that is protected with ASProtect and a custom serial + activation code combination.

I found out how to get through ASProtect (it's used in some DLLs instead of the EXE) and have a look at the full code using OllyDbg.

I tried bypassing the serial number check and the activation code check and I successfully got into the real application and at a first glance it seems to work.

I tried working with the app and I noticed that there's a component that's actually behaving differently than it was when I was using it as an evaluation version.

Now whta I wonder is if this could be something that has to do with the protection itself or if there's anything else I should check to clear my mind. Maybe this is a known issue that affects applications protected with ASProtect or some other generic protection that I didn't recognize.

Thanks!

-tanis

JMI
October 5th, 2004, 10:37
It is likely that the serial protection decrypts a part of the code and it is not working properly as a result of what you have done, but it is not possible to make a reliable guess, based upon the little information you provide. Remember that you may post NO code which identifies your target or ANY code if you do identify it.

REgards,

tanis
October 5th, 2004, 10:54
Yes, it could be that way. What makes me wonder is that there's only a toolbox panel that has some selectable components that you can place in a view that's behaving erratically.

I already tried tracing through the actual code that does the serial number check and the real problem is that it's a very long function (and I really mean that it's got a lot of lines of code) with jumps every few lines.
I would love to use the same code to build a keygen but I found it damn hard. I'm pasting a few lines to give you an idea. Keep in mind that this kind of code repeats many (MANY!!) times

Code:

012951A6 66:8B45 D4 MOV AX,WORD PTR SS:[EBP-2C]
012951AA 8B7D D2 MOV EDI,DWORD PTR SS:[EBP-2E]
012951AD 66:C1E8 03 SHR AX,3
012951B1 66:894D F2 MOV WORD PTR SS:[EBP-E],CX
012951B5 66:8945 A8 MOV WORD PTR SS:[EBP-58],AX
012951B9 66:C16D F2 06 SHR WORD PTR SS:[EBP-E],6
012951BE 8A55 F2 MOV DL,BYTE PTR SS:[EBP-E]
012951C1 83E7 04 AND EDI,4
012951C4 83E0 04 AND EAX,4
012951C7 83E2 04 AND EDX,4
012951CA 0BC7 OR EAX,EDI
012951CC 897D C4 MOV DWORD PTR SS:[EBP-3C],EDI
012951CF 25 FCFF0000 AND EAX,0FFFC
012951D4 3BD0 CMP EDX,EAX
012951D6 0F85 04040000 JNZ CCPROJ~1.012955E0
012951DC 66:8B45 D2 MOV AX,WORD PTR SS:[EBP-2E]
012951E0 66:C1E9 07 SHR CX,7
012951E4 661E8 SHR AX,1
012951E7 8AD1 MOV DL,CL
012951E9 66:8945 EA MOV WORD PTR SS:[EBP-16],AX
012951ED 32D0 XOR DL,AL
012951EF 8B45 D6 MOV EAX,DWORD PTR SS:[EBP-2A]
012951F2 32D0 XOR DL,AL
012951F4 F6C2 08 TEST DL,8
012951F7 0F85 E3030000 JNZ CCPROJ~1.012955E0
012951FD 8B7D D0 MOV EDI,DWORD PTR SS:[EBP-30]
01295200 83E1 10 AND ECX,10
01295203 66:C1E8 04 SHR AX,4
01295207 8AD0 MOV DL,AL
01295209 83E7 10 AND EDI,10
0129520C 83E2 10 AND EDX,10
0129520F 897D BC MOV DWORD PTR SS:[EBP-44],EDI
01295212 0BD7 OR EDX,EDI
01295214 81E2 F0FF0000 AND EDX,0FFF0
0129521A 3BCA CMP ECX,EDX
0129521C 0F85 BE030000 JNZ CCPROJ~1.012955E0


CCPROJ~1.012955E0 is the location where the message box saying invalid serial gets constructed.

dELTA
October 5th, 2004, 14:41
Quote:
Yes, it could be that way. What makes me wonder is that there's only a toolbox panel that has some selectable components that you can place in a view that's behaving erratically.
Exactly what do you mean with this, and why does it make you wonder?

tanis
October 5th, 2004, 15:32
It's just that I was not sure that this behaviour was due to the protection itself instead of anything else.

Today I searched and asked around about that and I found out that yes, it's happening only with a version that has not been completely unprotected.
There's some code that is deciding wether the components will work the right way or not, but I have no clue where to look at.

At this time I think that the best way is to write a keygen. I guess it would be much better and maybe that way the protection itself is going to believe that everything's fine.

Now what I'm asking is for some tips on converting the code up there into a keygen.
I can easily have a look at the various memory references around EBP and see what's going on.

For what I can say, the serial number gets dissected (it's a 16 characters code in the form XXXX-XXXX-XXXX-XXXX) and pieces of the code are being transformed and compared and in some cases written in memory to use the results later for further checks.

The real problem is that if I find a couple of values satisfying the first check and I go on and on like that, there's a point where the results of the first check are being used to do more checks on the serial and this time it fails because my values should satisfy both requirements. I know that my words probably make no sense.. I am not English mothertongue and explaining that kind of stuff is very hard for me.

I hope you've got the idea of what I'm trying to say. Any hint is very appreciated.
Till now I've been doing all the math by hand writing down the results and restarting from scratch every time I had to modify a value that was already checked before.

Thanks again!

dELTA
October 5th, 2004, 17:32
About the keygen stuff:
You should try to fully reverse and understand the key checking algo before trying to implement any keygen, IDA Pro is very good for this task for example. Experimenting with random values in a live debugger could leave you in the dark codewoods forever.

About the different behavior:
A good bet would be that envelope checks are used, it sounds like it.

tanis
October 6th, 2004, 10:34
I'm getting IDA and try to see how the code looks like with it. I have never used it before.

What do you mean by "envelope check"? Is it something like CRC?

dELTA
October 6th, 2004, 14:44
Envelope checks are special functions offered on SDK level by packers. They return one value when the wrapper is still there, and another when the wrapper has been removed, so that easy and clean control flow redirection can be done when the program has been unpacked.

tanis
October 7th, 2004, 13:47
This means that it is very hard to find out where this kind of control is made.

There isn't a message box or anything that pops up to tell me that my copy has been messed with.

All I get is that a panel (just like a toolbar) has all the right objects displayed but when I click on one of them, the result of what should happen is different than what happens with the regular version (evaluation).

It could be that the check is made when I click on one of the items of the panel, but I doubt it. It sounds more like the control is made beforehand and the icons displayed are the same.. it's just that the events associated with the icons are different and I have no idea of how to check it out.

I still think that the keygen is the best way to go, but the code is driving me mad. If I should use the same assembly stuff, I should still write something like a bruteforce trial & error like application.

Do you mind if I post the full code of the check so that you can have a look at it, too?

dELTA
October 7th, 2004, 15:23
Quote:
Do you mind if I post the full code of the check so that you can have a look at it, too?
Yes, please don't. We don't want any mile long code listings here, noone will sit down and reverse a complex algo for you anyway, there simply is no other solution than for you to take the needed time and reverse the algo yourself (did you try in IDA yet?). If you have technical questions about small snippets of code you are welcome to ask them though.

tanis
October 7th, 2004, 15:37
Ok, no list

I have tried IDA but I've encountered a new problem.

I dumped the unpacked DLL from within OllyDbg and I checked it with PEditor to make sure that import tables are fine and they do.

So I went on and tried loading the DLL into IDA and here's what happens:
it's just like if the DLL is being executed and a message box pops up saying that my trial period of 30 days is over and go to purchase the product at blablabla.

I did a search of the exact message with google and I noticed that this same message box appears in different apps and games, mainly due to virus infecting the app's executable.

I'm almost sure it's one of those "envelope checks" as you call them. I have not yet found out where in the DLL's code this check is made. I'm hunting it down right now.

Next I tried to replace the original DLL with this one and in fact the same message box pops up and the application terminates.

Is it ok that the DLL gets executed in some way when I drag and drop it into IDA?

Anyway the real difficult task is to merge the various checks here and there and build the exact rules to validate the serial number.

Let's say that the serial is like: A-B-C

The code goes like this:

Sum A and C and place into EAX
shr EAX, 5
Sum B and C and place into ECX
shr ECX, 2
write ECX into memory location 1
compare EAX and ECX
jnz error location
...

and it goes on that way until you stumble in

Sum C and B into EAX
Read the memory in location 1 into ECX
shr ECX, 3
compare EAX, ECX
jnz error location

So you have to go over the whole code to find references to values computed before and therefore write an algorithm that in the first check also takes into account this other condition. It's really a pain to rebuild everything in the correct order

dELTA
October 7th, 2004, 16:01
As long as you find all these checks, it should be a fairly straight forward task to create an equation system out of them, which could then be solved for the "least dependent" variable (i.e. some kind of seed). Then it should be quite easy to write a keygen after that. Don't stare yourself blind on the code, you must extract and understand the algorithm "mathematically" before you can write a keygen.

The two equations for your example above will be:

Code:

/ ((A + C) shr 5) = ((B + C) shr 2) = X
<
\ (B + C) = (X shr 3)

----> ((B + C) shr 5) = (B + C)

----> (B + C) = 0

----> ((A + C) shr 5) = 0

----> / B = -C
<
\ (A + C) <= 31
Which ends up being the resulting only constraint of your example (with reservation for three hundred possible slip-ups while doing this example in 30 seconds )