Beginner Tutorial #6 Packers theory v1.1 |
| The Target: none |
| The Tools: Ollydbg 1.10 |
| The Protection: packers |
Other Information: |
Best viewed in Firefox at 1280x1024
|
Introduction: |
|
Reading a lot of tutorials I realized that some of them do not simply contains complex tricks and solutions, but also very elegant descriptions of some basic concepts. The problem is that these descriptions are not read often with the proper attention: beginners will not read those tutorials and experienced crackers most of the times already know those concepts. So, those little "gems" remains mostly unknown to who could benefits from them most. I then decided to collect some of these descriptions into an unique tutorial about the packing of exe application and the theory of what happens behind. Moreover this arguments perfectly fits into the secuence of the arguments already described in the previous beginner tutorials... so as usual fasten your seat belts.. I integrated the text coming from different papers to make an organic text and I will cite the original sources only if needed and only in the final references section..
|
|
Description of a Packer: |
|
A packer is a program aimed to prevent somebody else from examining how our program works or from modifying it. Typically, the entry point of the protected program is diverted to run the packer first. When it runs, the packer will carry out the following (main) steps:
The first step, sections decryption, isn’t important for us. Normally,
it doesn’t use to be much of a problem to await until they are decrypted
in memory and simply dump them to a file and glue them up together.
However, points 2 and 3 are crucial. The imports protection can be done
with several degrees
It’s amazing to see how many ”commercial” products don’t comply neither with (1) nor with (3). What about 4 (API redirection)?. Let’s try to see what ”API
redirection” means: Open any application, it’s sure call [XXXXXXXXh]
; call to kernel32.ExitProcess XXXXXXXXh inside the IAT The other most common possibility is to have a call XXXXXXXXh instead, the argument would be the same. The Windows loader ”sees” the imports table and fills the IAT with the addresses of the imported APIs. Packers destroy the information at the imports table of the protected program, therefore the IAT will have incorrect values when the packer yields control to the target. Then, the consequence is that the packer needs to fill the IAT of the target with the right values. If you take a packed program, under a packer satisfying (4) - examples: Asprotect, Slovak Protector,...- the IAT looks like:
The packer mixes the first instructions of the API with some garbage code (in the example, those instructions having a ”*” beside were in the original API code), it can include some trivial anti-debug trick too, and finally writes a jump (or something similar) to the entry point of the API + k, where k is the number of original instructions already run among the garbage code. This way, it is essentially impossible to find the actual API called through ZZZZZZZZh or to hook it. The imports table is not a straightforward structure, going into details is out of the scope of this tutorial, see [2] for more references. Some programs, called import rebuilders, are able to emulate a few instructions to search for the address in the DLL we jump to. Then, you can retrieve the API name from the exports table. However, import rebuilders are usually very limited in what they can sniff and will not overcome the latest packers (which, obviously, are tested against them before their release). Let’s see what’s the matter with the entry point. As we commented,
the packer - once it has done its job (decrypted the target, reconstruct
the IAT,...)- has to give control to the protected application. This can
be done running it as a new thread, with
kernel32.CreateThread, or
simply jumping to it in some exotic way. Running it as a new thread is
not a good idea, the starting address of the thread will be too evident
and so, we (again) suppose the worst case: Stolen Bytes
Now, it removes the call and, on every startup, substitutes the mov [handle], eax by a simple mov [handle], harcoded_value, where hardcoded_value was returned before by the packer’s call to GetModuleHandleA. If the cracker doesn’t detect this trick then the unpacked program will not run on all OS versions or will have another defect. These bytes the packer removes are called ”stolen bytes”. A full description of a packer is well out the scope of this tutorial, please refer to [1] for a detailed explanation. Understanding the problem of stolen bytes ; not changed entry point of ; example of instructions you could Packers are the preferred way to protect middle-price applications, virtually all shareware depends on their security. Thus, studying their advantages and disadvantages is an important field in RCE (Reverse Code Engineering)
|
|
How AsProtect works: |
|
ASProtect, from ASPack Software (http://www.aspack.com), isn't just
another commercial anti-cracking program; it is a truly revolutionary
advance in software protection. It may be the prepackaged solution to
software protection for those who don't want to spend long hours
studying and programming custom protection for their own software. ASProtect's creator Alexey Solodovnikov learned a lot from his work on ASPack and applied that experience to ASProtect. He claims that because all anti-cracking defenses can be defeated, the only important thing is under what circumstances they can be broken. While it was created especially for shareware developers, ASProtect can be used for professional software as well. While it's not as versatile as FLEXlm (discussed later in this chapter), and it works only under Windows, I daresay that it is currently the most difficult commercial software protection to break. Its only weakness is that it doesn't have the best anti-debugging tricks. Compared to other commercial software protection, ASProtect is simple and well-programmed, reflecting the simple but wonderful idea behind it. Like similar programs, the original program is compressed and then uncompressed by ASProtect before it is run. ASProtect's compression is based on the ASPack algorithm, which is among the best. While it adds about 60KB of code to the original program, this additional code doesn't matter at all, since the resulting compressed program is much smaller then the original one. ASProtect's decompression routine checks to see whether there have
been attempts to change the file, and it tries to prevent changes in
memory. Naturally, without decompression, the original program can't be
disassembled, and it isn't easy to decompress ASProtect because it tries
to prevent memory dumps by programs like ProcDump. Once the import
section has been dumped from memory, the PE file will not be correct.
Still, there is a way to decompress ASProtect (not by just dumping), but
ASProtect is still not defeated even after successful decompression. There are three ways to secure an application with ASProtect. The
first way uses classic compression and The second possibility is much more interesting, though still not the best. With this method, the original protection is first authenticated after the ASProtect API is called with a constant for decoding the encoded part of the program. You might use this method if, for example, the program you want to protect already has its own registration control and you don't want to change it. This method would be a poor choice if the original protection is weak, since it would not prevent the cracker from getting the correct constant. The third and best possibility doesn't add any protection to your
program (although additional protections are possible). Basically, when
using this third method, you specify in the Registration Keys tab in
ASProtect that you want your project to contain a registration key (as
shown in Figure 6.3 on page 80). The program then creates a basic
constant that will serve as a base for other keys, and that will also be
used to encode the protected part of the program. You can generate the
keys according to user names, and you can also save them. Finally, you
determine where the registration key will be saved in the registry
following registration. Finally, in the program code you specify the parts of the program that you want to encode—this is a simple procedure that can be performed by almost any programmer. Currently ASProtect contains code examples for Delphi, Visual C++, and Visual Basic. For instance, here's a short example in Visual C++: include <windows.h> Next, you need only call the procedure and the rest will be done for you. If a program isn't registered, the encoded part will be skipped, or else an error will occur. If the program is registered, this part will be decoded at the start of the program, and it will be used later when it is called. You can get the user's name with the apiGetRegInfo() API function. Should you need to create many registration keys at once, ASProtect makes it easy by supplying the library keygen.dll. You can generate registration keys with its two functions. The GenerateKeyAsRegFile() function creates a registration file based on user information. Alternatively, the GenerateKeyAsString() function returns the memory pointer to where the registration key was created. ASProtect allows you to set the number of times that a program can be
run or the number of days it will be useable. Unlike similar commercial
programs, all protection is placed in the PE file, and not in added DLL
or OCX files. |
|
References: |
|
I suggest the following further readings from now on to complete your beginner's training, than you'll be free to specialize in anything you like most, unpacking protectors, writing loaders or other things..
and obviously our tutorial's page ^__^ |
|
Conclusion: |
|
[Nilrem] [JDog45] [Shub - Nigurrath] [MaDMAn_H3rCuL3s] [Ferrari] [Kruger] [Teerayoot] [R@dier] [ThunderPwr] [Eggi] [EJ12N] [Stickman 373] [Bone Enterprise] [KaGra] Thanks to all the people who take time to write tutorials. Thanks to all the people who continue to develop better tools. Thanks to Exetools, Woodmann, SND, TSRH, MP2K, TEAMICU and all the others for being a great place of learning. Thanks also to The Codebreakers Journal, and the Anticrack forum. If you have any suggestions, comments or corrections contact me in usual places.. |