Author:Aodrulez.
Email: f3arm3d3ar@gmail.com
Well..we all know there are thousands of such text
files floating on the Internet.Am not adding sumthin to
the already present chaos.This paper focuses primarily
on approaches that you might find novel or useful in
implementing "Anti-Cracking Protection" in your apps.
Techniques:
1]A Registration-Routine Technique:
Simply bored of seeing the same tricks being used &
abused, I thought of trying a novel approach.What if we tried
this:
Usual Registration Routines:
1]Accept Username/Serial from user/file.
2]Use some math-operators & either....
a] Calculate the serial directly from Username
& then compare with user-input serial.(Dumb)
b] Calculate a Hash from the username as well as serial
using different algo ofcourse & then compare them.
3]Either carry on with the registered status.
4]or Display...a message saying.."Not Registered!"
My way:
1] Accept the username/serial from user/file.
2] Use some algo on both the Username & serial
and based on that, generate "opcodes".
3] Inject these opcodes into the registration routine.
4] If the "opcodes" generated match, then & only then
will the app get registered..else it will crash!!
5] Use SEH so that in case of a crash, the app can be
terminated elegantly.
So Algorithm-Wise this looks like this:
-----------------------------------------------------------------
@app_startup:
1]Implement SEH.
@registration_routine:
1]Accept username/password from the user/file.
2]Use some algo that generates "opcodes" from
the user input data.
3]Inject these opcodes into the successful_registration
routine.
@successful_registration:
(most of the instrucions here are like this:)
push 0
push offset good-boy-text
push offset good-boy-caption
push 0
lea eax,MessageBoxA
db 090h }-------this should be "FF" to make the MessageBoxA
db 0d0h } function work
"call eax" instruction--> FFD0 "byte-sequence"
Depending upon the user input & the algo used,
the 0x90 byte should be changedto/injected-with
0xFF for the app to get registered.
Else, if the user/input is not correct, the further
routine will look malformed & the app will crash.
@SEH_routine:
1] Just when the app crashes, the SEH will be called &
you can make a graceful exit or maybe handle it &
resume execution :) .
----------------------------------------------------------------------
Benefits of this approach:
1] You can simply make the whole Registration routine look
Bogus & generate it on the fly from user-input.
2] Unless the user enters the right Serial/sequence, the registration
routine will always look bogus.So not much can be made from
Disassembly of the routine.
3] The only way to crack this kind of a protection would be to
know the "opcodes" fairly well & know how code execution takes place.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2]Anti-patching.
Well, most (almost all) of the debuggers
of today rely on "0xcc" or rather "int3" for setting up
normal breakpoints.How this thing works is like this:
The moment you place a BreakPoint sumwhere, that
particular OpCode gets replaced by a "0xcc" byte.Now lets
simplify this method's idea.Its like..the actual opcode is
replaced by 0xcc, then the debugger monitors the app's
execution to spot int3 being executed.. if its hit, then
the debugger halts execution at that point & replaces the
0xcc byte with the actual Previous Byte (opcode).
How to defeat it? One way would be to implement a
CRC check.Or you might go on the same idea,develop a small
algo that simply calculates a magic value by going through
your code during runtime & checks it with the actual value
it should have if your app is intact.This approach of writing
your own algorithm is recommended because the standard CRC
library functions if implemented in your app, can be easily
detected by the current tools available.
Second way? Yep another good way would be to write the
important parts of your apps' code dynamically to the required
locations like used in many Virii.Example?...here we go:
A simple app with Username/Serial type registration routine:
-----------------------------------------------------------------
app_startup:
Immediately when your app starts,
1]Do a simple crc-type check on the registration
routine.
2]If intact, copy the actual registration routine
byte-wise-encrypted into the encrypted_code section
of the apps' memory.
3]Simultaneously Nullify or 'NOP' the actual
registration routine.
registration_routine:
1]Decrypte code from encrypted_code into the actual_code
section of your app.
2]Call this newly written routine for the
validation of registration details.
actual_code:
1]Actual registration routine goes here.
encrypted_code:
1]Its more like a buffer to store the encrypted
registration routine.
------------------------------------------------------------------
Benefits of using this technique:
1] The actual registraion routine is always re-written
before being executed.This kills the 0xcc byte placed
by the debugger to cause a break in execution(breakpoint).
2] You can always use a CRC-type of check to verify the
integrity of your registration-routine, so if patched
by "newbie-crackers",you could tackle this by maybe
over-writing from a bakup-copy of your registration
routine from the app's memory or a Dll.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3]Applying Modified Shell-Code Trick.
ShellCodes are nothing but executable machine code to which
if EIP points to..will do something worthwhile :-)..like maybe
spawn a Windows Calc.Shellcodes are many a times crafted for a
particular version of an OS..because of the Library function calls
that have to be made.But with much less pain, similar technique
can be used to cause some more Code-Reversing trouble.Okies... that
was a pathetic introduction to Shellcodes..but its another huge topic
in itself..& this paper only mentions certain aspects of it which
we can use as Anti-Cracking techniques.So what can we use from them?
Lets see another algo:
-----------------------------------------------------------------
@startup:
1]Find the exact version of the OS currently your app is
running on.Lets assume your registration routine uses
MessageBoxA function in it.so in that case,recover the
address of that function from a table already present in
your app...which looks sumwhat like this:
Windows 2000 : MessageBoxA ==0x7AAAAAA;
Windows Xp Sp1: MessageBoxA ==0x7BBBBBB;
Windows Xp Sp2: MessageBoxA ==0x7CCCCCC;
Or else....do sumthin like this:
lea eax,MessageBoxA
mov [api_Addr],eax ----> "api_Addr" is a variable to
hold its address.This eliminates
the need for maintaining a table.
2] Call @Registration_routine(part 1)
@Registration_routine(part 1):
1]Actual registration routine lies in the
"@encrypted_registration_routine(part 2)"
section of your apps' memory.
2]So first you decrypt it right there.
3]Now the Win32 API function calls will
look obsolete..because the addresses differ.
4]Inject the API's Correct memory address from the api_Addr
variable so that its fixed.
5]Call @encrypted_registration_routine(part 2) routine.
@encrypted_registration_routine(part 2):
1]This section contains already encrypted machine code.
2]For example....the actual (un-encrypted) code could look
sumthing like this:
push 0
push offset Text
push offset Caption
push MB_OK
call 0xAAAAAAAA <---- This is the address we have to fix
when called from the previous function
after decryption.
---------------------------------------------------------------------
Benefits of this technique:
1] You don't need to have the actual code...then encrypt it...& then
decrypt it...as in the 2nd technique described in this Paper.
2] If disassembled this code will look fairly weird.
3] Even here, the Breakpoints can be killed as described previously.
Ofcourse these techniques are not Fool-Proof but if
implemented correctly & efficiently can prevent your app
from being cracked by the "Newbie & maybe even Intermediate"
type of a software cracker.One very important thing you must know is:
"Every Piece of code ever written to this day, can be either Reversed or
Patched."
You can only try to make it harder or simply Boring to do so... :P
Hope this Paper was useful..... :)
A very Simple PoC of these techniques might be obtained from here:
http://www.crackmes.de/users/aodrulez/aodrulez_crackme_v1.0/
---------------------------------------------------------------------
Greetz fly out to:
1]Amforked() :My Mentor.
2]LiquidWorm & Jeremy Brown :For being so nice to a noob like me.
3]www.OrchidSeven.com :For givin me this beautiful opportunity.
No comments:
Post a Comment