ARTeam Tutorial

Visit: http://cracking.accessroot.com | http://forum.accessroot.com

Asprotect_v2.xx_Reload_by_CondZero


Information E.g. Unpacking ASProtect 1.23-1.3.08.24 RC4
Target Resource Builder v2.4.0.8
Available http://www.resource-builder.com/
Tools OllyDbg 1.10, ImpRec, LordPE, Hide Debugger 1.2
Protection Asprotect v2.11 SKE / 1.34
level Intermediate
Category Loader , cracking.
Author(s) CondZero January 2006
Requirements Windows XP, IE 5.5 and above for best viewing


Introduction

 

Writing Loaders for Asprotected applications is not a new concept. It has been covered in depth in prior Tutorial releases. I did not want to reinvent similar concepts. I became intrigued with the idea of possibly writing a generic debugger loader (yes, that's right) that could patch ANY application that UTILIZES the inherent built-in Registration capabilities of Asprotect with NO changes to code save for the name of the target application to be launched. Of course there are limitations to this approach, namely, applications that are EVALUATION only versions, and/or utilize their own registration method and/or Time limitations or utilize Asprotect as a wrapper. These are not covered here.

I tested this theory on 2 target applications. The one listed above and also Icon Searcher v3.0 here http://www.icontool.com/issetup.exe. Interestingly, during the course of my analysis, both targets updated their software with newer releases and the same loader used for both, WORKED!!  with NO changes. A base of only 2 applications is not sufficient to rest your laurels, however, it is a starting point.

Please note that you can also use the concepts covered here for patching your applications without having to use a loader. The choice is always yours. I will cover most of the concepts in a general way to keep things moving. You can further your studies based on what you learn here.

Neither target utilizes a nag screen. Both are 30 day trials that you can register. I won't cover the applications themselves as this is not the point of this exercise. I will cover the points that led me to my conclusions and how I dealt with them. Finally, I will spend some time on the loader's logic based on the concepts covered.

1. Asprotect and your registry.
2. The approach.
3. Conclusions.
4. Greetings.



1. ASPROTECT AND YOUR REGISTRY

I am sure that most of you have spent some time looking at your registry to see what Asprotect is doing with it. You have probably set BP's on all the relevant API's to analyse the flow. Available are some registry trash cleaners that can help you identify and delete the relevant keys to restore your time limitations. So if you want to follow along you can load your target in OLLY. I take every exception in this case (see below):

Figure 1.

Now click on your E toolbar button to see the executable modules window in Olly. I am interested in the following system module (advapi32.dll). Right click on this and select View names as shown below:

Figure 2.

Scroll down the list of names (api's) to the following and press F2 to set a BP.

Figure 3.

You can close this window. We are ready to run the application so press F9 and we will break at our API see Stack frame below:

Figure 4.

Hmmm. What's so damn important about the Buffer address above and only selecting a BufSize of 1 byte.

Note: The address 014C3AF9 is Asprotect's Virtual memory and main processing block and your machine's address may be different.

So we right click on the address 014C3AF9 to see what the dump shows:

Figure 5.

And the dump window below in Hex.

Figure 6.

The BufSize of 1 is determined by reading this address and continuing reading the bytes sequentially until we find a byte value of hex '00' which in the case above is the first byte, hence, BufSize == 1. Well this is all really strange. What happens if we set a HWBP on access for the first byte above as shown below:

Figure 7.

At this time we can restart the application in Olly. But before we run it, we need to set the following BP. So once again, go to the executable modules window for module advapi32 and this time select RegOpenKeyExA and set a BP (F2) on it.

Press F9 to run our target.

We need to break on this API for a couple reasons. First, it allows for our HWBP to actually break instead of getting passed up by Asprotect's anti-debug protection mechanism. Second, the API break we are interested in holds the KEY to our puzzle. We skip past the BP's reading for the Borland stuff until we come here:

Figure 8.

The Registers will show this:

Figure 9.

Notice Register ECX holds the Ascii value "Key". So the target application wants to know if we are "Registered". This is an indication that our application is using the registration capabilities built-in Asprotect.

Scroll down in the Stack window until you see the following:

Figure 10.

Look at Stack Address 0012FAA4 [ESP+64]. See anything interesting here. Our address from before: 014C3AF9. The address above it: 014EB6D8 also is of interest as this is a reference address for Time Limitation criteria that Asprotect stores AFTER reading the Specdata key in your Registry. At this time follow the 2 addresses above in your dump window. You can toggle back and forth and we will come back to these addresses.

I have found a couple of Sections (or Segments), not sure which, that are of interest with regard to the 2 addresses above and Asprotect's code.

In the interest of saving time and to follow the flow of code more precisely, we can do the following:

Go to Olly's toolbar and press the K button for the [call stack of main thread] window. You should see something similar to the following:

Figure 11.

Double click on the first line which will take us to Asprotect's code. Once inside the code we want to do the following:

Figure 12.

We want to find the following commands.

Figure 13.

Press Find and set a BP (F2) as I have done below on this command:

Figure 14.

Do the same for command: MOV BYTE PTR DS:[EAX],0E7

Why these 2 sections? Section E8 seems to be concerned with whether the target application is using the Registration functionality built-in Asprotect. If so, there is bridge code which is called by Asprotect to the application's code section. Section E7 seems to be concerned with the Trial Limitation criteria that the target application is using from Asprotect's built-in functionality.

At this point we have 3 BP'S and 1 HWBP. We can now continue running our target so press F9. We will find another RegOpenKeyExa to the application's "Key" in the HKEY_LOCAL_MACHINE section. Press F9 to continue. We land at this BP:

Figure 15.

F7 (step into) the code very slowly taking note of the Register / Data values. For address 014DCCD2 above the code pane shows this:

Figure 16.

Now is the value contained in Address 014EB474 above was == 00000000, this application wouldn't be using Asprotect's built-in Registration function. But note, the value here: 005DF62C is a bridge to the Applications's own code section that Asprotect has provided. F7 Step some more to the CALL EAX at address: 014DCCE8 and follow this Call. You land here:

Figure 17.

A strange bit of code until you follow the code to the 2nd RETN on address: 014C3AFF. When you return from this Call what is the value in Register EAX? Exactly: 014C3AF9. Step into (F7) the Call at address: 014DCCE8 and we land here:

Figure 18.

Chances are you will not find this same code in every application. But what is important is that this bridged code sets value's in the application's data to tell if you are registered or not, BASED on the value contained in the 1st byte of address: 014C3AF9 (or whatever it is on your machine).

Step into the code (F7) to address: 005DF62F and the code pane show this:

Figure 19.

Step through further and stop at address: 005DF636. We see that it checks the 1st byte of address: 014C3AF9 for a value of '00', which if you've been following along in your dump window you would see contains '00'. Seeing this, I figured that this code had some importance so I changed the value for address: 014C3AF9 first byte from '00' to '01'. So go ahead and do this if you're following along. This concludes Section E8. You are welcome to analyze further.

We can now press F9 to run our target. We will land here:

Figure 20.

Press F9 again. We land here:

Figure 21.

Step into the code at address: 014DCDF1. The code pane shows the following:

Figure 22.

So again, there is another bridge to some code in the application that Asprotect provides. You can follow this bridge code on your own. Toggle or go to expression address: 014EB6D8 in your dump window, which is about where Asprotect holds some interesting Time Limitation details, and scroll down a bit shown below:

Figure 23.

There are a few bytes of interest. The byte at address 014EB714 contains our Trial Limit of 30 days in hex. The byte at address 014EB718 contains the number of days left in our Trial, which in this case is 24 when converted to decimal. Some of the other values may have something to do with the Specdata key itself. The last byte of interest is at address: 014EB73D. For if this byte contains value '01' it means our application has expired. Go back to figure 21 and step into address: 014DCDFC where it checks if CMP BYTE PTR DS:[EAX+31],0. If you were to put a '01' in this memory address space and run your target, EVEN WITH the 1st byte value change we made earlier to address: 0143AF9, the application would still expire.



2. THE APPROACH

So what to do. Well I found out that if I delete the Specdata registry key prior to running the application, even after the application expires, the value in address: 014EB73D is still '00' and we're good to go. Of course, not many people are going to want to delete a registry key internally in a program when doing inline changes or modifying an unpacked program.

Up to this point, I haven't changed ANY code. Asprotect guards it's code against tampering (memory checks). I also want to refrain from making any application specific changes to code, but instead focus on generic changes to memory that can accomplish our goal. Of course you, the Reverse Engineer, make the final call. I have coded many application specific debug loaders in the past and wanted to see if a generic debug loader would work on Asprotect 2.xx targets based on the concepts discussed in Section 1. I knew they would, I just had to figure out HOW to do it.

The answer actually is quite simple. Using the approach above where we set a BP on the RegOpenKeyExA API is the key. From here, we can deduce the memory location of the address we need to make the 1 byte change from '00' to '01'. We can also delete the Specdata registry key up front in our program, so expiration will not be an issue. The timing of setting the BP's in our debugger must coincide with our processing so I used a simple approach. Since many applications can come packaged with their own modules (dll's) wrapped in Asprotect, I chose to use the CreateProcess Event to set a BP on the target's Entry Point (EP). I deviate from an existing Tutorial's framework and code the program in C because I am familiar with this language. The concepts and code that follow can be converted to ASM or C++ or even VB.

At the top of the program I have set up some arrays used for storing memory address information and setting up the needed patch bytes for creating / undoing BP's and patching memory. See below:

Figure 24.

You can also see that I am using the approach of Shub-Nigurrath and ThunderPwr for hiding the debugger.

Before I create the process I delete the Asprotect Specdata Registry keys. Also notice that we create the process in DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS below:

Figure 25.

CreateProcess allows us to set a BP on the main module's EP. We can easily get this info from the CreateProcessInfo Structure and lpStartAddress see below:

Figure 26.

So we simply read the process memory at the EP location and set our 1st BP there and set our continuation status == DBG_CONTINUE debugging and waiting for events. We eventually land at this BP and get notification via the case EXCEPTION_BREAKPOINT: who's structure will allow us to do the following:

Check to see if this is our BP. If yes, we can change context to put back original byte, reset the eip and continue processing debug events. But, we can also setup new BP's in our process to further examine and/or change data at specified intervals of our choosing.

Figure 27.

Case in point, I used counters in my code example, however, boolean TRUE / FALSE can work equally well in determining / setting up our conditions. Below, I check for I == 0, (first time). If so, we set a BP on the RegOpenKeyExA API. I should point out that since this is a system dll (advapi32.dll) we don't necessarily need the debugged processes mapped address for this dll as it should load in the same memory address space of every process, so we can just get a handle to this module in our current process and get the needed address and set the BP accordingly in our running debugged process.

Figure 28.

Since we are creating the BP and not the application, we need to specify once again, DBG_CONTINUE and NOT, DBG_EXCEPTION_NOT_HANDLED which would stop our process cold.

Having set this BP, we come back and recheck the exception BP returned by case EXCEPTION_BREAKPOINT. We use the condition (I == 1) as follows:

Figure 29.

There are a couple concepts here. First, we need to examine the ECX register to see if we have the ASCII value "Key" stored. If not, we need to reset out BP and continue debug processing with a time parameter of "0" to return immediately back to our breakpoint processing loop so that we can reset the BP for the SAME memory address, hence the dwTime = 0 parameter and the needbreak boolean switch.

When we arrive at our condition, we check the memory offset for the value we want, check for '00' and replace with '01'. You will also note that I change one more memory item which came about in my testing. I move a hex 'C4' to the patch offset + 04 as this seems to have an effect on some apps which recheck the registration status after the program has initially done so. Why the value 'C4', I am still not totally sure, but it works.

After having done this, we can reset our process to DBG_CONTINUE and then depending on if we are running WinXP or greater, break out and detach from the process automatically, or go into an efficient wait state in debug mode, if not.

 



3. Conclusion

Is it possible to create a generic loader for Asprotected apps that utilize the built-in registration capabilities of the product? I think I demonstrate that it is possible. Whether you use this approach, or simply use the concepts learned to apply your changes in some other fashion is strictly up to you, but it is hoped that something new may have been learned.

This Tutorial is for "Educational Purposes" Only.

Remember, if you plan to use this good software you should purchase the product to support the authors to develop other good and best protected ;-P software.

Any suggestions, corrections or criticism is welcome, if you need help about this tutorial or other stuff you can reach me on ARTeam forum.



 
4. Greetingz

Thanks to the [ARTEAM]

[Nilrem] [MaDMAn_H3rCuL3s] [Shub - Nigurrath] [ThunderPwr] [Kruger]
[Gabri3l] [Teerayoot] [R@dier] [Eggi] [EJ12N] [Stickman 373] [Cl0ud]
[Potassium] [Deroko] [Nacho_dj] [Anorganix] [Sigint33]

Thanks to all the people who take time to write tutorials.
Thanks to all the people who continue to develop better tools.
Thanks to all the people at Exetools and Woodmann for providing great places of learning.
Thanks also to The Codebreakers Journal, and the Anticrack forum.
Thanks to all the great teams: SND, TSRH, MP2K, ICU, REA, and all the others.