Introduction
This article is a quick start generic info for the beginner developers to know how their software maybe cracked and what idea should try to avoid that.
Software locking methods
- Fixed Serial Number: In this method the software will ask for a serial number on installation or during the 1st run. Serial number could be distributed easily. Indeed the serial number is just to inform the user this is none free software and he should bought it.
- Activation Code: In this method the software will generate a machine id and required an activation code from the user which could be getting from the vendor. Cracking of the software may be performed by debugger or by partial decompiling.
- Internet Activation: Same as activation code put the activation will run through internet. Cracking may be done by injecting wrong interties in host file to forward the activation page to local or wrong page, or even by a custom DNS forwarder
- Dongle: the provider will provide a small hardware piece with could be detected by the software. The dongle will contains some info to be used for a special version or software. Cracking maybe done by hacking the communicating library between software and dangle.
- Protected CD: The installation can be run only from the original protected CD which maybe protected by laser generated bad sectors or some invalid contents or writing data after CD end mark. Cracking maybe done by coping the CD using special program or by cracking installation process.
- Flash USB memory: The software may use the physical number of the flash memory and compare it to database before run or write a part of the software code on none assigned area of the flash disk. Cracking may be done by hacking the software.
- After sell support: Some software provider provides a very good support so the buyer will not try to get cracked software.
- Direct installing method: some provider will install the software by a developing company employee and no install application is distributed.
Software cracking
It is the modification of software to remove or disable features which are considered undesirable especially
- Disable copy protection features
- Remove limitation of use for unregistered user
- Disable ad-ware associated with the software for unregistered user
Cracking maybe done by:
- Redistributed serial number,
- Key-gen,
- Patch,
- Loader.
The most common software crack consists of the modification of an application's binary to cause or prevent execution specific part of the program. This is accomplished by reverse engineering. This could be done by:
- Run the program code using a debugger until the software cracker reaches the subroutine that contains the primary method of protecting the software
- Disassembling or decompiling an executable file.
- Cracking some time done by monitoring the registry or file system changes done by the installation and 1st run of the application.
Software developers are constantly developing techniques such as code obfuscation, encryption, and self-modifying code to make cracking difficult.
Assembly Cracking
Disassembly
- Disassembly is a type of reverse engineering.
- To disassemble is to convert a program in its executable (ready-to-run) form into assembly language
- Assembly language is readable by a human.
- A program used to accomplish this is called a disassembler.
- Another program, called a de-compiler, converts object code back into the code of a higher-level language.
Assembly language
- An assembly language is a low-level programming language for a programmable device.
- A program written in assembly language consists of a series of (mnemonic) processor instructions and meta-statements, comments and data.
- Assembly language instructions usually consist of an op code mnemonic followed by a list of data
Assembly Language example:
.486p
.model flat,STDCALL
include win32.inc
extrn MessageBoxA:PROC
extrn ExitProcess:PROC
.data
HelloWorld db "Hello, world!",0
msgTitle db "Hello world program",0
.code
Start:
push MB_ICONQUESTION + MB_APPLMODAL + MB_OK
push offset msgTitle
push offset HelloWorld
push 0
call MessageBoxA
push 0
call ExitProcess
ends
end Start
Assembly Control Flow & Cracking
The most used technique for cracking is to
- Run the debugger such as OllyDbg
- Open the application in the debugger and run it
- Note the last jump before the application ended
- Modify the interested jump function
The modification code be done by
- Invert jump condition. Ex.: convert Ja to Jna
- Change the jump code to number of Nops. Ex.: specify the cods in the debugger and right click and choose fill with
- Change conditional jump to none conditional jump with the same length
Assembly Instructions links
Assembly unconditional jump Instructions
Function | OP Code | Hex |
Creates a stack frame
| enter
| C8 i0 i1 i0
|
Halts the processor
| hlt
| F4
|
Destroys the current stack
| leave
| C9
|
Lock prefix on next instruction
| lock
| F0
|
Waits for the FPU to finish its last calculation
| wait
| 9B
|
Jump sl | Jmp | EB r0 |
JMP np | Jmp | E9 o0 o1 |
JMP rmw | Jmp | FF /4 d0 d1 |
JMP DWORD PTR [rmw] | Jmp | FF /5 d0 d1 |
JMP FAR PTR fp | Jmp | EA o0 o1 s0 s1 |
CALL np | Call | E8 o0 o1 |
CALL rw | Call | FF /2 d0 d1 |
CALL DWORD PTR[rw] | Call | FF /3 d0 d1 |
CALL FAR PTR fp | Call | 9A o0 o1 sl sh |
RET | Ret | C3 |
RET iw | Ret | C2 i0 i1 |
RETF | Ret | CB |
RETF iw | Ret | CA i0 i1 |
Conditional Jumps
Function | OP Code | Hex &
2Byte Address | Hex &
1Byte Address |
Jump if Above, unsigned comparison
| Ja
| 0F 87 r0 r1
| 77 r0 |
Jump if not above
| Jna
| 0f 86 r0 r1
| 76 r0 |
Jump if Above or equal, unsigned comparison
| Jae
| 0F 83 r0 r1
| 73 r0 |
Jump if not above or equal
| Jnae
| 0f 82 r0 r1
| 72 r0 |
Jump if bellow, unsigned comparison
| Jb
| 0f 82 r0 r1
| 72 r0 |
Jump if not bellow, unsigned comparison
| Jnb
| 0F 83 r0 r1
| 73 r0 |
Jump if bellow or equal, unsigned comparison
| Jbe
| 0F 86 r0 r1
| 76 r0 |
Jump if not bellow or equal, unsigned comparison
| Jnbe
| 0f 87 r0 r1
| 77 r0 |
Jump on Equality
| Je
| 0f 84 r0 r1
| 74 r0 |
Jump on Inequality
| Jne
| 0f 85 r0 r1
| 75 r0 |
Jump if greater
| Jg
| 0f 8f r0 r1
| 7F r0 |
Jump if not greater
| Jng
| 0f 8e r0 r1
| 7E r0 |
Jump if greater or equal
| Jge
| 0f 8d r0 r1
| 7D r0 |
Jump if not greater or equal
| Jnge
| 0f 8c r0 r1
| 7C r0 |
Jump if less
| Jl
| 0f 8c r0 r1
| 7C r0 |
Jump if not less
| Jnl
| 0f 8d r0 r1
| 7D r0 |
Jump if less or equal
| Jle
| 0f 8e r0 r1
| 7E r0 |
Jump if not less or equal | Jnle | 0f 8f r0 r1 | 7F r0 |
Jump on overflow
| Jo
| 0F 80 r0 r1
| 70 r0 |
Jump on not overflow
| Jno
| 0F 81 r0 r1
| 71 r0 |
Jump on sign
| Js
| 0F 88 r0 r1
| 78 r0 |
Jump on no sign
| Jns
| 0F 89 r0 r1
| 79 r0 |
Jump on zero
| Jz
| 0F 84 r0 r1
| 74 r0 |
Jump on not zero
| Jnz
| 0F 85 r0 r1
| 75 r0 |
Loop
| loop
| /
| E2 r0 |
Loop if equal
| loope
| /
| E1 r0 |
loop if not equal
| loopne
| /
| E0 r0 |
loop if zero
| loopz
| /
| E1 r0 |
loop if not zero
| loopnz
| /
| E0 r0 |
Decompiling
- To decompile is to convert executable (ready-to-run) program code into some form of higher-level programming language.
- The resulting code can be read by a human.
- De-compilation is a type of reverse engineering that does the opposite of what a compiler does.
- The tool that accomplishes this is called a de-compiler.
- A similar tool, called a disassembler, translates object code into assembler language.
- De-compilation was first used in the 1960s to facilitate the migration of a program from one platform to another.
- De-compilation is not always successful.
- De-compilation is sometimes used unethically, to reproduce source code for reuse or adaptation without permission of the copyright holder.
- Programs can be designed to be resistant to de-compilation through protective means such as obfuscation.
Other Uses for de-compilation and disassembly
- Understanding a program,
- Recovering the source code for purposes of archiving or updating,
- Finding virus,
- Debugging programs,
- Translating obsolete code.
De-compilation fail rezones
- It is not possible to decompile all programs,
- Data and code are difficult to separate,
- Both data and code are represented similarly in most current computer systems.
- The meaningful names that programmers give variables and functions (to make them more easily identifiable) are not always stored in an executable file, so they are not always recovered in de-compiling.
De-compiling as cracking method
- Although disassembler is well known as a cracking method but decompiling is much power.
- Disassembler normally attacks the program that is running on the system.
- Decompiling is mostly done on none running application, it could cover the whole application,
- It will convert the program to its own programming language,
- The resulting code is easy to be edit and patched.
- Cracker search for the error message that may your application show where pad registration or activation code.
- Then they will search for the code use this string and try to understand it and edit as required.
- Decompiling take much time and work than other cracking methods, but it give more flexible result.
Protecting from unlocking codes
Bad Protection Codes
Direct input compare
If input_serial_nimber = real_serial_number Then
Unlock
Else
MsgBox("Wrong serial number")
End if
To bypass this code
- Run the debugger such as OllyDbg
- Open the program to cracked in the debugger
- Rub code until the serial is requested.
- Put a wrong serial
- Step with the code until you find the assembly compare code that take the serial you entered
- Reverse the comparison
Software debugging prevention
A lot of new software have a debugger detection techniques and will act by deferent way if the debugger is detected. Debuggers are the most used technique for cracking; many crackers will not try to de-compile your code. Putting anti debug code will increase your software protection even if you don't want to use obfuscation. Combining obfuscation and debugging prevention the right work. Many crackers use de-compiling before debugging. Without obfuscation they can jump to another place in code and go around the debugger check.
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, ref bool isDebuggerPresent);
public static void Test()
{
bool isDebuggerPresent = false;
CheckRemoteDebuggerPresent(Process.GetCurrentProcess().Handle, ref isDebuggerPresent);
}
Software packing
Much software are packing the software code in special format and the application will unpack the code in the memory to prevent decompiling or debugging. Cracking will unpack the software 1st or debug or decompile the code in memory.
Obfuscation (Compiled code obfuscation)
Obfuscation Method
- You develop your application as normal.
- Run and debug your application
- Build it with your compiler
- Run a post compile tool to convert your redistributable release into obfuscation mode
Obfuscation aims
- It make the de-compiling fail difficult and many de-compiler will fail to de-compile the application
- Many de-compilers will refuse to decompile this file at all. To do it.
- If the de-compilers succeed the resulting code will be harder to understand or analyzed
Obfuscation can be done or more of the following
- Name obfuscation
- This will delete the names of all functions, forms, modules and objects and all kinds of signatures from the EXE file.
- The new name will be random and include nonprinting characters and symbols that can't be used in the programing language
- String Encryption
- Control Flow Obfuscation is about modifying the program so that it yields the same result when run, but is different flow to prevent decompiling into a well-structured source code.
- Code Encryption and adding loader of your codes. The loader will decrypt the MSIL as needed.
- Code Virtualization converts your MSIL code into Virtual Op codes that will only be understood by a Virtual machine that Obfuscator adds to your code. Code Virtualization can significantly degrade performance if used unwisely.
- See List of obfuscators for .NET for more info.
- For an of compiled none .Net code (ex. C++) obfuscator see Obfuscator for the x86 assembler
Example of de-compile code after obfuscation
loc_B6FE91: MemVar_F903A0 = &HFF
If (MemVar_F9039E = &HFF) Then
If MemVar_F903A0 Then
loc_B6FFD5: Function_A15FF8()
loc_B6FFDA: GoTo loc_B70001
End If
If Not(Function_A83D7C(1)) Then
loc_B6FFED: Function_ADC870(0)
If arg_8(206) Then
loc_B6FFFA: Function_B07AC8()
End If
loc_B6FFFF: End
End If
loc_B70001:
End If
- Cracker will look in the code and will see the application end code which may indicate test for unlocking
- Cracker try to modify the code by replace End with nop on the address loc_B6FFFF
- One of if statements may be changed to avoid the application end
- De-compiler will generate random name for variables and function because obfuscation put non printing chars in names.
Obfuscation & Unlocking software
- Good obfuscation makes many de-compiler fails to de-compile your code but power de-compiler will de-compile it.
- The de-complied code will be hard to understood and analyze. and may required very hard work to understood who to unlock your application.
- The good obfuscation makes the cost of unlocking your code much more than buying it.
Source code obfuscation
- Many developer call it as unreal obfuscation because it deal with source code not with the compiled code
- Some companies that ship cross-platform software prefer to ship it in the obfuscated source code form, expecting customers to build that software on any platform they wish.
- Some language does not have compiler and your application will shipped in source codes forms such as PHP & Javascript.
- Obfuscator making source code difficult to understand.
Stunnix Obfuscator is an example of Source code obfuscation and it will do the following
- Replacing symbol names with non-meaningful ones, e.g. replacing list_of_customers with zcadaa4fc81
- Replacing numeric constants with expressions, e.g. replacing 232 with (0x14b6+2119-0x1c15)
- Replacing characters in strings with their hex escapes, e.g. turning string "cust" into "\x63\x75\x73\x74"
- Unique! Renaming files and directories with source code, e.g. renaming /lib/context.c into /7a84b51/b4e8c5.c
- Removing or obfuscation of comments
- Removing spaces and tabs in the lines of code
- Joining all lines in your code
- They have separate obfuscator for C++, Javascript, VB Script & Prel.
C++ obfuscated codes
main( argc, char * argv[ ] )
{
int j;
char version[ 80] ;
while ( ( j = getopt_helper( argc, argv, "n:o:vV:",
((char)(0x10b4+390-0x11d2)), ((char)(0xeb+9378-0x2537))) ) != - 1) {
switch ( j) {
case ((char)(0x607+6157-0x1da6)):
name_wide = MYMIN( atoi( optarg) , 0xff) ;
break;
}
PHP Obfuscators
What tools to be used to check the crack ability of may software?
What to do to protect my software
- Build your application as 64 bit application, 64bit application is much harder to crack.
- Encrypt error messages: for example see this link
- Use debugger detection technique: see this Link
- Use Computer ID: It is simple software key useful to identify user computer to be used for give separate license for each computer see: C++ simple software key
- Use Obfuscation which can delete the names of all functions, forms, modules and objects and all kinds of signatures from the EXE file. It will make analyzing the program with this de-compiler difficult and many de-compilers will refuse to decompile this file at all. To do it. see Eazfuscator.NET
- Strong-Naming Your Assemblies: By strong-naming your assembly you ensure the fact that the assembly was not altered since it was built.
- lARP64Pro: It is a 64 bit anti-piracy and anti-cracking program with implemented code compression, it make the de-compiling much difficult.
- Soft Activate: It is tools provide protecting with license key and software activation
- Dongle is not always the wright idea, it maybe increase the crack ability.
- Try to crack your software.
- Search the net for the crack of your software and ask search engine to remove the search result.
- Have the checking logic run at many critical times (not just startup), and using different ways
- Have the checking logic invert the conditional in some checking and direct in another.
- Have the checking in different ways
- Some checks were performed ONLY on a specific day of the week. And would tell them to call support.
- When you detect a license failure, close the application in different ways each time, you could use direct close, application exit or raise an error to crash your application, or even go to un limited looping to make your application not stable
- Finally, we would modify the EXE itself, so at the end of the actual EXE we would store a hash of the file, and check at run time that if there is a modification done to exe file.
- If you have any other idea please set it in the comments, I will modify the article to include it.
Why cracker attack some software and leave another one
- Cracking is not always for money, it may be as challenge or as punishment.
- If you have a contact email to whom cracked your software; Write a message and ask politely, if they can stop cracking your software. They may do so.
- If the software mentioned that it is hard to cracked then the cracker will attacked it, Normally one of the will succeed.
- If you put a very high price or put a hiden fees or ask the users to pay a new license for formatting his hard disk or any bad practice; then your software may be attacked as punishment.
Note:
Please comment any useful data you want me to add it to the article.