Reverse Engineering a Linux/X Target
Don't call us, we'll call you...
Not Assigned
20 July 1998
by +ReZiDeNt
Courtesy of Reverser's page of reverse engineering
slightly edited
by reverser+
+ReZiDeNt's essays are always welcome! And this one should be of great interest for all the (growing mass) of Linux lovers. For all other readers: listen to me:
You have surely a Linux system on some CD-ROM cover you bought, have a look. Install Linux and fly! If you'r just lazy, think it over! The moment you have installed Linux on your PC you will for the FIRST TIME IN YOUR LIFE (since old Dos forgotten memories) experience the r aw power of your machine! Ahh! The windows chains fall clattering on the floor! Free, free at last!
There is a crack, a crack in everything That's how the light gets in
( )Beginner (x)Intermediate (x)Advanced ( )Expert

A journey into the realm of Linux - if you're interested in Linux (and more specifically X) targets, this might be of some benefit to you.

Reverse Engineering a Linux/X Target
Don't call us, we'll call you...

Written by +ReZiDeNt


Before I begin I want to make it clear that this essay has not been
written to supply lamers with a serial number - if that's what you're
after then you can leave the class now, you won't have much joy here. I
also don't want to see people releasing serial numbers/keygens/patches for
this application based on the contents of this essay - if you do, you will
be regarded as a lamer by +all.

The object of this exercise is to shed a little light on how to reverse
engineer Linux (and more specifically in this case, X-Windows) programs.
It isn't all that often that you come accross a Linux program that isn't
free - the vast majority of Linux applications are freely redistributable
and come with complete source code (indeed, you are sometimes required to
compile the application yourself), making reversing them a touch
pointless. However, here is an essay dealing with reversing an X
application. The target is MXaudio, a GUI MP3 player for X-Windows.
MXaudio comes bundled with Xaudio, which is a commandline MP3 player, both
of are apparently built using the Xaudio SDK. I will use version 1.0b for
this exercise, it is available from:

I don't know what the latest version is, but the protection has probably
not changed much (if any), knowing what +we do about protectionists.

This MP3 player has all the usual features, such as playing files from the
Internet, support for playlists, a nice digital display etc. It also seems
to have some support for a radio interface, but all that is beside the
point. I should perhaps mention that there are plenty of *free* MP3
players for Linux/X around, so I'm a little surprised that this one is for
sale (although the terms seem to indicate that you can evaluate it
indefinitely, unless you are a commercial or goverment entity), even if it
is only $10. In any case all this is irrelevant, since we are only going
to see how this thing works before discarding (or registering) it.

Tools required

DDD (Data Display Debugger)

dasm by SiuL+Hacky (thank you!)

IDA (optional)

A good (quick) text editor - I use joe and vi in console mode, and NEdit in X (unfortunately NEdit can't handle massive files though)

Target's URL/FTP

Xaudio for Linux

Program History

I have absolutely no idea :-)

Let's start!

When you run mxaudio a nagscreen pops up. The nagscreen has a button
saying "Enter License Key", which when pushed, calls up a little dialog
box prompting us to enter our key. The dialog box has three buttons,
labeled "OK", "Cancel" and "Clear". If we enter a few random alphanumeric
characters and push "OK" we are informed that the license key we entered
is invalid and we are given the choice of entering it again.

So let's make a dead listing - I personally don't like the AT&T asm
format, but that is how objdump (used by the excellent dasm Perl script by
SiuL+Hacky) does things, so that's what I'm using. I suggest you do as I
did, and also make a dead listing in IDA (which may apparently be run from
dosemu - can anyone confirm?). That way you can look to IDA when you're
having a hard time getting your head around the AT&T syntax and you need a
dose of the old familiar format :-)

Searching (case insensitive) inside our dead listing for "enter license
key", we find the first occurence, and it turns out to be quite

Possible reference to string:
"Enter Key:"

0806ada6 pushl  $0x819daf7

Possible reference to string:
"Enter License Key"

0806adab pushl  $0x819db02
0806adb0 pushl  %esi
0806adb1 pushl  %ebx
0806adb2 call   0807c35c      ; this call seems interesting...
0806adb7 addl   $0x28,%esp
0806adba jmp    0806adbd

Let's look at the function at 0807c35c. It turns out that this function is
really quite long, and since I don't like showing huge lumps of
disassembled code, I'll instead first explain a little about how X-Windows
works (or rather, how I believe it works :-)), so please bear with me.

In Micro$haft Windoze programming everything (e.g. buttons, labels,
textboxes and so on) is a "window". In X-Windows these are, it seems,
instead called "widgets". Each widget has a user-defined "callback"
function (a pointer to a function) associated with it that is called by
the windowing system whenever certain events occur to that widget (e.g. if
the widget is a button, whenever the button is pushed). This system is
different to the Micro$haft Windoze system in which you must intercept
each event and then find out which window (e.g. widget) is affected. I'm
not entirely certain as to whether all X programs use this system, as I'm
not an X progammer - can anybody enlighten me about this?

For more information on X-Windows programming I suggest you either get a
hold of a book on X programming (if you can find one) or visit the GTK
website ( where you can download the GTK libraries
(GIMP Toolkit, one of many APIs for X programming) together with a pretty
good tutorial on using it. The tutorial should help to give you an idea
about how things work in X...alternatively there are other tutorials on
the Internet covering programming with Motif etc.

Since the validation of the license key must be done after pushing the
"OK" button, finding the callback function for this button would certainly
be a good place to start. Browsing through the function (at 0807c35c) we
see quite a few calls to "XtAddCallback" - how interesting. Looking a
little further our Geiger counter begins to click as we see the below

0807c3df pushl  $0x807c52d    ; address of the callback function

Possible reference to string:

0807c3e4 pushl  $0x81b4c49
0807c3e9 pushl  %esi

Reference to function : XtAddCallback

0807c3ea call   0804fdf0      ; associate the function with the OK button

So now we have the address of the callback function that is called when
the OK button is pushed. Let's take a look at it:

0807c52d pushl  %ebp
0807c52e xorl   %eax,%eax
0807c530 movl   %esp,%ebp
0807c532 subl   $0x8,%esp
0807c535 pushl  %ebx
0807c536 movl   %eax,0xfffffff8(%ebp)
0807c539 movl   0x8(%ebp),%edx
0807c53c movl   0xc(%ebp),%ebx
0807c53f pushl  %eax
0807c540 leal   0xfffffffc(%ebp),%eax
0807c543 pushl  %eax

Possible reference to string:

0807c544 pushl  $0x81b524c
0807c549 pushl  %edx

Reference to function : XtVaGetValues

0807c54a call   0804f3c0      ; get the contents of the text box
0807c54f pushl  %eax
0807c550 leal   0xfffffff8(%ebp),%eax
0807c553 pushl  %eax

Possible reference to string:

0807c554 pushl  $0x81b2afb
0807c559 movl   0xfffffffc(%ebp),%eax
0807c55c pushl  %eax
0807c55d call   08151ad0      ; this call is uninteresting for us...
0807c562 addl   $0x20,%esp
0807c565 movl   0xfffffffc(%ebp),%eax
0807c568 pushl  %eax
0807c569 pushl  %eax
0807c56a call   0810d930      ; as is this one
0807c56f addl   $0x8,%esp
0807c572 movl   0x4(%ebx),%ecx
0807c575 testl  %ecx,%ecx
0807c577 je     0807c58a
0807c579 movl   0xfffffff8(%ebp),%edx
0807c57c testl  %edx,%edx
0807c57e je     0807c58a
0807c580 movl   0xc(%ebx),%eax
0807c583 pushl  %eax
0807c584 pushl  %edx
0807c585 call   *%ecx         ; hmm...this looks promising!
0807c587 addl   $0x8,%esp

Referenced from jump at 0807c577 ; 0807c57e ;

0807c58a pushl  %eax
0807c58b movl   0xfffffff8(%ebp),%eax
0807c58e pushl  %eax

Reference to function : XtFree

0807c58f call   0804f580
0807c594 pushl  %eax
0807c595 pushl  %ebx

Reference to function : __builtin_delete

0807c596 call   08178540
0807c59b movl   0xfffffff4(%ebp),%ebx
0807c59e movl   %ebp,%esp
0807c5a0 popl   %ebp
0807c5a1 ret

Well well, looks as though we're going to have to have to pull out our
debugger and try a little of the "live" approach to find out the value of
ecx in the call at line 0807c585. This is where DDD comes in handy. DDD is
not a bad debugger, (although the latest version 3.x which I'm using is
pretty unstable, you might want to stick with 2.x) and a big thank you
goes to SiuL+Hacky for making me (and +others) aware of it.

So fire up DDD and load mxaudio (File -> Open Program). Now set a
breakpoint at line 0807c585 (make sure you're in the command window of

	(gdb) break *0x0807c585

For those new to DDD, don't type in the "(gdb)", that's the debugger
prompt. Now type "run" and mxaudio will load. When the nagscreen is
displayed push the "Enter License Key" button and enter some random
numbers/letters before pushing "OK". DDD will now snap and you can
disassemble the current line by typing the following commmand:

	(gdb) x/i $eip

You might want to close the source window (View -> Source Window) and
instead open the machine code window (View -> Machine Code Window). Make
sure you have the option to display machine code set (Source -> Display
Machine Code) as well.

OK, so now we are at line 0807c585 and we can now see the value of ecx and
thus determine the location of the function that is about to be called.
Select "Status -> Registers" from the DDD menu or type "info registers" -
you will see that the value of ecx is 0x806af1e, so we can now look up the
function in our dead listing:

0806af1e pushl  %ebp
0806af1f movl   %esp,%ebp
0806af21 subl   $0x30,%esp
0806af24 pushl  %edi
0806af25 leal   0xffffffd0(%ebp),%eax
0806af28 pushl  %esi
0806af29 pushl  %ebx
0806af2a movl   0x8(%ebp),%edi
0806af2d pushl  %eax
0806af2e pushl  %edi
0806af2f call   08090c7f  ; this is the one! The license validation call
0806af34 movl   %eax,%esi
0806af36 movl   $0x1,0x8203c68
0806af40 addl   $0x8,%esp
0806af43 testl  %esi,%esi
0806af45 jne    0806af75

Looking at the call to 08090c7f at line 0806af2f, our Geiger counter goes
beserk and we immediately "feel" we are in the right place - there is a
call to strlen and instructions comparing registers to 0x2D (the '-'
character, present in all too many serial numbers). This function is
obviously the license key validation routine (it is called from two
places, the function we came from and one other location, 0805f4e7. If you
check out the other caller you will see a call to fopen and fgets just
before this validation routine is called, so it is obviously reading the
license key from the license file on startup, if it is present).

As I said before I do not like huge dumps of disassembled code and the
purpose of this essay is not to provide you with a ready-made crack, but
rather to illustrate an approach. Therefore I will only show excerpts of
the license key validation routine, and will leave it as an excercise to
the reader to investigate more thoroughly.

Referenced from call at 0805f4e7 ; 0806af2f ;
Reference to function : strlen

08090cb5 call   08050a30
08090cba addl   $0x8,%esp
08090cbd movl   %eax,%eax
08090cbf cmpl   $0x1e,%eax           ; is the code > 30 chars?
08090cc2 je     08090cce             ; carry on if so
08090cc4 movl   $0xfffffffe,%eax
08090cc9 jmp    080911ea             ; else beggar off
08090d0f addl   $0x4,%eax
08090d12 cmpb   $0x2d,(%eax)          ; is the 5th char a '-'?
08090d15 je     08090d21              ; carry on if it is
08090d17 movl   $0xfffffffb,%eax
08090d1c jmp    080911ea              ; else beggar off
08090d49 pushl  %eax                  ; a character from the license key
08090d4a call   08090bbc              ; is passed to this hex to int
08090d4f addl   $0x8,%esp             ; conversion routine, called
08090d52 movl   %eax,0xffffffc4(%ebp) ; repeatedly throughout this
.                                     ; validation process
08090d9a addl   $0xd,%eax
08090d9d cmpb   $0x2d,(%eax)         ; is the 14th char a '-'?
08090da0 je     08090dac             ; go on if it is
08090da2 movl   $0xfffffffb,%eax
08090da7 jmp    080911ea             ; else beggar off
08090ec0 movl   0xc(%ebp),%eax       ; load value of the 19th - 22nd
08090ec3 movw   0x28(%eax),%dx       ; chars into dx
08090ec7 cmpw   %dx,0xfffffffe(%ebp) ; are they what they should be?
08090ecb je     08090ed7             ; carry on if so
08090ecd movl   $0xfffffffd,%eax
08090ed2 jmp    080911ea             ; else beggar off

The above check compares the value of the 19th to 22nd chars of the
license key to a generated number (this number depends on the earlier
characters in the license key). If the numbers match the validation
routine will continue. Since we already know that the license key is 30
characters longs and has a hypen ('-') as the 5th and 14th characters, we
can set a breakpoint at 08091004 and enter a license key such as:


We can then run up to the check above where it can been seen that the
value of dx is 1212. To see the value that it should be, use the following

	(gdb) x/w 0xfffffffe+$ebp

The last 4 digits of the value printed are the ones that should be at the
19th to 22nd position in the license key - in this case the value is 31e7,
so we can modify the license key like so:


Now the validation routine will continue over the previous check until it
reaches the below (final) check:

08091001 movl   0x2c(%eax),%edx       ; load 23rd to 30th chars into edx
08091004 cmpl   %edx,0xfffffff8(%ebp) ; are they correct?
08091007 je     08091013              ; you're registered!
08091009 movl   $0xfffffffc,%eax
0809100e jmp    080911ea              ; else beggar off
The following command will then show the last 8 characters which should be
at the 23rd to 30th position in the code, giving a valid license key which
will register the program:

	(gdb) x/w 0xfffffff8+$ebp
No, I'm *not* going to tell you what those characters are, that's not the
object of this exercise - instead I recommend you try it for yourself and
see just how much fun reversing Linux is (then of course you should either
delete this app or register it).

I think (or at least hope) that this essay should provide anyone who wants
to delve further into reversing an X application with a starting point,
and perhaps show how one can locate the code associated with a specific
"widget", which is often a good place to start.

Before the bell rings I have one final assignment, your homework: get
Linux and install it on your computer. Use it, and enjoy it. Then convert
someone else to it, and install it on their computer, and get them to
convert someone else...and so on. Linux is great OS, and will easily do
what you want (this entire essay has been constructed with Linux -
completely M$ free!) and more.

Good Hunting,

July 1998

Greetz go to: reverser+ (keep up the good work!), SiuL+Hacky (great Linux essays!),
Hackmore+Readrite, Mammon, The+Intern and the rest of the Visual Assembler
team, and last (but in no way least) +ORC!

Final Notes
Get Linux NOW! 

Ob Duh
I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

You are deep inside reverser's page of reverse engineering, choose your way out:

redhomepage redlinks redsearch_forms red+ORC redstudents' essays redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_reverser
redIs reverse engineering legal?