|
SOFTWrapper: wrapping galore
An encryptionless wrapper is a protectionless
protection
|
Programmers
|
2-10-98
|
by
HalVar+
|
|
|
Courtesy of Fravia's page of
reverse engineering
|
|
fra_00E5 980213 Halvar+ 1100 PC XX
|
Very interesting essay... as HalVar+ writes: "A funny thing about reversing: While you're at it, it all looks
new and interesting,and after you're done, you're often surprised how
trivial the actual crack you considered interesting 5 minutes ago is..." it is true, in a sense,
yet real knowledge is like that: ad astra per aspera. Enjoy this essay: you may learn
something about code relocation as well reading it...
|
|
|
Feudalism: It's your count that
votes
| |
Rating
|
(x)Beginner (x)Intermediate ( )Advanced (
)Expert
|
|
A little essay on how to execute only the parts of a wrapper we like;
only
those which are necessary to run the main program. Plus some ideas on
how a
"generic" crack for all programs protected with this wrapper could be
created.
Interesting for newbies, experienced +crackers will hardly find anything
new.
SOFTWrapper -- an easy to bypass wrapper
An encryptionless wrapper is like a protectionless protection
Written by
HalVar+
A trend you could see for a while (and which still hasn't completely
disappeared) are the so-called "plugin-protections", like RSAGNT32.DLL
and the like. Some of the IMO most stupid ideas ever were the so-called
"Wrappers" which basically wrap a finished executable with a "protection
envelope". I will crack a very antiquated example of these wrappers to
demonstrate how to bypass the parts of the wrapper we do not like while
executing the parts we need to execute.
SoftICE 3.01
TASM (optional)
Do an ftp-search on WRAPEVAL.ZIP (175.157 bytes) :-)
No history, no future, no wonder :-)
In recent times we've seen a drastical increase in so called "Plug&Play"
protections which vary greatly in strenght. Some are fairly strong, but
many
of them (especially the earlier ones) are nothing but junk to take money
from the already cracker-newbie-battered shareware authors.
The probably weakest version of these "P&P"-protections are those which
do
not even require the programmer to integrate them into their program
source,
but which take an executable and "wrap" it instead.
The target we're examining here is itself an evaluation version, but so
sadly
crippled and even in it's full version useless. It is not good for
anything,
and the readme.txt points out that it was released in 96 and never used.
No
wonder if you look at what it does, but for a first study it can help
pull
some things together.
This wrapper will add a time/date check to an existing file. While I am
sure
it would be trivial to crack the time check or the registration routine,
I am
sick and tired of the same stupid Registry-Keys or RegKey-checks. I want
to
completely bypass everything I do not need and as quickly as possible
transfer
the control back to the wrapped program.
Since this wrapper is attaching it's functions to an existing file which
are
then to be executed before the main program is, it acts in certain ways
like
a virus. So what do those AV-people do again to figure out how a virus
works ?
They create tiny bait files to be infected and examine them
afterwards.
For this purpose I dug my first Win32-ASM-File out. Well, I think
everybody
has one or two like these lying around, but I'll give you the short
source
nonetheless :
----------------------------------cut here------------------------------------
; HalVars 1st Win32 Program, a bait file to be wrapped
.386P
Locals
Jumps
.Model Flat, StdCall
Extrn ExitProcess:PROC
Extrn MessageBoxA:PROC
.data
title_box1 db 'HalVar`s Bait', 0
Box_textSTART db ' Now you can choose : :-)',0
Box_textYES db 'You pushed the YES Button !',0
Box_textNO db 'You pushed the NO Button !',0
Box_textEXIT db 'Do you want to repeat the whole crap ??',0
.Code
Main:
beginhere:
xor bx, bx
mov bx, 0004h
push bx
push offset title_box1
push offset Box_textSTART
push 0
call MessageBoxA
cmp ax, 6
je Yes_Box
mov bx, 10h
push bx
push OFFSET title_box1
push OFFSET Box_textNO
push 0
call MessageBoxA
jmp EndIt
Yes_Box:
mov bx,10h
push bx
push OFFSET title_box1
push OFFSET Box_textYES
push 0
call MessageBoxA
EndIt:
mov bx, 0004h
push bx
push OFFSET title_box1
push OFFSET Box_textEXIT
push 0
call MessageBoxA
cmp ax, 6
je beginhere
push LARGE-1
call ExitProcess
End Main
---------------------------------cut here-------------------------------------
Quit laughing already ;-)
The advantage of using a tiny bait file like this is that you know your
code 100%ly, and that you'll definitely recognize anything that is not
part
of the original program. Lateron, you should test your findings on a
bigger
target, but right now, this one is enough.
Allright, the code is self-explanatory. Compile it, then make a copy
of it before you wrap it. Load the unwrapped bait into the SICE-Loader,
go
through the whole thing once to know what's going on.
Enter some small explanatory strings for the MessageBoxes
created by the wrapper and run the wrapped bait
file, and you'll be prompted with a MessageBox which asks you something
like
"Not expired yet. You want to register now?", and YES/NO-buttons.
Now, since we don't want to crack the registration mechanism, click on
NO, and
there you are:
Our bait file. Quit it and load it again, this time
in the SICE
loader.
The loader will go into SICE at the first instruction of your program.
Funnily enough, the program does not start at 00401000 any more, but at
00407000
with the following instructions:
:00407000 call 00407005 ; Hey, it's the old trick to find the
:00407005 pop ebp ; delta-offset again :-)
:00407006 mov eax, ebp
:00407008 sub eax, 00006005 ; eax now contains 00401000, the original
:0040700D push eax ; program starting point, while bp contains
:0040700E sub ebp, 00000005 ; 00407000, the starting point of the wrapper
Well, old tricks never die: The mysterious (?) call is necessary to know
the
address of the wrappers' variables, the so-called "delta-offset". This
is a big
name for something so easy: If you write a program which is intended to
append
itself to another program, it can't reference to it's own variables in
the
standard way:
lea ax, OFFSET title_box1
will not work, since the offset will be compiled to an absolute address.
Naturally,
these addresses change when the program is appended, so the above
snippet would have to
look like this in order to work in an appended program (assuming bp
contains the delta offset):
lea ax, [bp+OFFSET title_box1]
For more questions concerning the delta offset, consult your local virus
site.
I could hardly believe it: There, at 00401000, the original program
entry point,
lay my own program unencoded, not even XORed :-) This truly IS a weak
wrapper.
When I looked at this, I, full of youthfull enthusiasm and naivity,
thought
"This is too easy !" and made the following change:
:0040700D jmp eax ; JMP to the beginning of the unwrapped program
And rubbing my hands in glee, I was surprised to see my computer
splatter in slo-mo
and full color, giving me first a few GPFs and then a stack fault.
So I rebooted, got myself a cup of good tea and looked again. I did the
same change,
this time not exiting, but tracing into my own program.
And what did I have to see ?
:00401009 push 00402000 ; Points to the "HalVar's Bait"-String
:0040100E push 0040200E ; Points to the "Now you can choose"-String
:00401013 push 00000000
:00401015 call 0040107A ; But hey, isn't this supposed to be [MessageBoxA]
; instead ?
The fact that the call references to an address instead of the function
it
is supposed to call to tells us that the imports haven't yet been loaded
for
this particular program. So I we'll have to step to our program a bit
longer
before we can jump back to our own code.
So we fire our program up another time and step through the code until
we
reach a thoroughly interesting code snippet at
:00407076 add dword ptr [esi+02], eax ; eax contains 00400000
:00407079 add esi, 00000006 ; si points to a jumptable
:0040707C loop 00407076 ; which starts at 00407A0D
The above snippet adds eax to the jumptable's locations, thus
"importing" the
most basic funtions which will lateron allow the wrapper
to import further API-calls or dlls.
After it is finished, the jumptable looks like this:
:00407A0D jmp dword ptr [Kernel32!GetSystemTime]
:00407A13 jmp dword ptr [Kernel32!LoadLibraryA]
:00407A19 jmp dword ptr [Kernel32!GetProcAddress]
:00407A1F jmp dword ptr [Kernel32!FreeLibrary]
:00407A25 jmp dword ptr [Kernel32!ExitProcess]
:00407A2B jmp dword ptr [Kernel32!GetModuleFileNameA]
:00407A31 jmp dword ptr [Kernel32!GetModuleFileHandleA]
:00407A37 jmp dword ptr [Kernel32!GetVolumeInformation]
:00407A3D jmp dword ptr [Kernel32!CreateFileA]
:00407A43 jmp dword ptr [Kernel32!WriteFile]
:00407A49 jmp dword ptr [Kernel32!CloseHandle]
:00407A4F jmp dword ptr [Kernel32!WinExec]
Well, this does look like a smorgasboard to everyone who wants to import
more functions,
but it does little more. None of these table entries include
[MessageBoxA], which
means that the imports the bait files need are located elsewhere.
When we trace into the next instruction, we encounter a call to a
function located
at 00407083; and there it is, finally : The importation of all functions
needed by
our BaitFile, as well as the usual crap the protection imports to check
for expirations etc...
Now, for stability's sake, these functions should better be unloaded
before our
original program is run, therefore we bpx on 00407A1F. We end up (after
'p ret'ing our way back to our
code) in the function which unloads all unneeded functions, located at
004079CE.
Finally, we got everything together to crack this crud.
We change the code to the following:
:0040707e call 00407889 ; Import all functions
:00407083 call 004079CE ; Unload all unneeded functions
:00407083 pop eax
:00407083 jmp eax
Voila, the crack is done.
A generic crack could be prepared easily for this, just search for the
bytesequence
"E8000000005D8BC5" (which is the beginning of the wrapped part). From
there on
you can calculate the offset for the bytes to patch. You would have to
change the call, though
to something that respects the delta offset, the address to call would
be (bp+09ce).
This whole protection is incredibly easy to bypass, since it doesn't
encrypt the
wrapped program in any way. But one of the nice things about
programmers: They tend
to put things like en/decryption into nice functions, much like the
function we
called at 004079CE.
If there had been an decryption, you could've usually called it in a
similar way
we unloaded all unneeded functions.
This is in fact a pretty powerful way to bypass big parts of a
protection: Figure
out what the functions are doing and call only the parts you're actually
using.
This does not hold true for any strong wrappers which decrypt only if
the right
serial is entered, but as long as the wrapper leaves you time to
evaluate it, cracking
should be a rather trivial task.
HalVar, February 1998
Well, apparently the programmers of this small prog read a few basic virus
tutorials and had a few ideas, but while they were at reading these tutes
they could've dug out a few clever ways how to conceal what they're doing
and how to avoid being debugged like this.
The one thing I learned (and give as advice to every beginner): Get
yourself a few virus tutorials and learn how to program some DOS-Assembly,
then learn how to program some simple Win32-Stuff in Assembler.
This helped me a lot, and without it I wouldn't have written this
textfile :-)
I'd like to thank/greet the following people:
Kneefalls go to: Mammon, Quine, Stone, NatzGul, Fravia, ORC, Razzia,
DataPimp, Yoshi, the whole UCF as well as PhrozenCrew
and Revolt...and everyone I forgot
Greets go to: Tin, blorght, bulll, all others in #C4N, Alia, Gnoof, iSa :-)
I wont even bother explaining you
that Fravia's ob duh paragraph doesn't apply to this program, since
we're just reversing our own program ....
You are deep inside Fravia's page of reverse engineering,
choose your way out:
Back to progcor
homepage
links
search_forms
+ORC
students' essays
academy database
reality cracking
how to search
javascript wars
tools
anonymity academy
cocktails
antismut CGI-scripts
mail_Fravia
Is reverse engineering
legal?