12:01 a.m. 20/06/00          -= Palm Reversing tutorial by Latigo =- 

Published by Tsehp, June 2000.



Hey! This time im writting a little tutorial on Palm Rerversing / cracking. The palm enviroment is something that has catched my attention and is not willing to release it :).

Its like a new world to be explored, and that is what attratcts me. Besides, palms rox!.


Target = Bugme! 2.74.2 (included in this zip)


Toolz  = prc2bin,pildis,hiew (prc2bin and pildis can get found in Darrin Massena's ASDK http://www.massena.com/darrin/pilot/index.html)


Goal   = Get a serial for this program.



                              -=      *      =-


Install the program in your palm or in the Emulator (if you don't know what im talking about im sorry). The first thing to identify is some string of any kind that will allow us to make the initial search. So run bugme, go to the menu, click on 'options' and then on 'Register BugMe!'. Just enter some garbage as a serial and there we have it :) .. 'the code you entered was not your..' that's enough!.

This string is inside an Alert resource. So what we have to do now is to extract all the alert resources from Bugme.prc and see what is the name of the resource that holds this string.

We are going to do this with 'prc2bin'. So 'prc2bin' bugme!.prc and boom; there we got tons of resources. But we need the Alert resources (taltxxx.bin).

Let's look inside each alert resource looking for the 'bad serial' string. ..tsk tsk tsk Talt05dc.bin is the culprit!!!!!!!!!!!!. Ok ok so far we know that the name of the alert resource that gets called when we input an erroneous serial is 05dc ...so whats!?!?!

Don't despair my little friend. This is all we need to make it to the end, this is the iceberg's tip :D.


When the name of an alert resource is pushed into the stack, a dollar sign ($) is appended to the beginning of the Alert ID. So in our case we'd have to search for $5dc. Time for disassembling.

'pildis bugme!.prc' will give us some very nice DragonBall disassembly.

View it with hiew and search for the string '$5dc' and if you are a good boy, you'll land here:


00001696        426dff94            L125        CLR.W   -108(A5)

0000169a        3f3c05dc                        MOVE.W  #1500!$5dc,-(A7) <----- yepeey!

0000169e        4e4f                            TRAP    #15

000016a0        a192                            DC.W    sysTrapFrmAlert


In 169a an Alert ID is being pushed into the stack. Remember that the A7 register is the stack. So there is a move instruction and a decrement of a7. This means that something is being pushed.


Then in 16a0 we see sysTrapFrmAlert; FrmAlert is the API that displays Alert Resources, and its only parameter is an Alert Resource ID. So it seems that this is what we've been looking for.

Yes, there are other instances of $5dc if you keep on looking for. But NONE of them are followed by a sysTrapFrmAlert which means that this is THE spot.

Now we have to reverse our way up. Got to unravel the little mistery of who/what/why we end up in this place..so lets go on.


See the L125 at 1696? thats a LABEL. A label which is referencing some spot during the execution of a program. If you are a coder you know what im talking about. So now we got to look for where that label is called. Follow me.

Searching upwards in the dead listing i find this:


00001684        4a6dff94            L124        TST.W   -108(A5)

00001688        670c                            BEQ     L125


TST.W -108(a5) means 'Check if some Global variable is 0. If it is(BEQ), then JUMP to L125'

BEQ = 'Branch if EQual' which is the same as JZ.

This leads us to know that there is a global variable (reg flag) that controls the state of the program in terms of 'unregistered/registered'. Good :)

Another upwards search starts revealing what would be the core of the registration routine..


sysTrapStrCompare at 1662 tells us that there is some string comparison going on..


but i keep going upwards..


and at 15da i find sysTrapFldGetTextPtr whose function is to return a pointer to some string from a text Field (edit box). And here i stay, because i _feel_ this is the right spot. (i can feel the code even though im not an HCUker..hehe, j/k).

Unroll your sleeves, hang up the phone, because we're going to start working from this point down!.



00015da       DC.W    sysTrapFldGetTextPtr      ; get pointer to string

00015dc       ADDQ.W  #4,A7             ; correct stack

00015de       MOVE.L  A0,-(A7)              ; push the recently returned pointer

00015e0       PEA     -30(A6)                  ; push some buffer

00015e4       TRAP    #15             ; call API

00015e6       DC.W    sysTrapStrCopy          ; copy pointer to buffer

00015e8       ADDQ.W  #8,A7             ; Correct Stack

00015ea       CLR.W   -108(A5)                 ; Clear reg flag

00015ee       PEA     -30(A6)                  ; push buffer

00015f2       TRAP    #15

00015f4       DC.W    sysTrapStrLen           ; get length

00015f6       ADDQ.W  #4,A7             ; correct stack

00015f8       SUBQ.W  #6,D0             ; sub ??

00015fa       BNE     L122

00015fc       CMPI.B  #101!$65,-30(A6)            ; is the first char of the buffer an 'e'?

0001602       BNE     L121                  ; no, jump

0001604       CMPI.B  #117!$75,-29(A6)            ; is the second char of the buffer an 'u'?

000160a       BNE     L121                  ; no, jump 

000160c       CMPI.B  #114!$72,-28(A6)            ; is the third char of the buffer an 'r'?

0001612       BNE     L121                  ; no, jump

0001614       CMPI.B  #111!$6f,-27(A6)            ; is the fourth char of the buffer an 'o'?

000161a       BNE     L121                  ; no, jump

000161c       CMPI.B  #112!$70,-26(A6)            ; is the fifth char of the buffer an 'p'?

0001622       BNE     L121                  ; no, jump

0001624       CMPI.B  #97!$61,-25(A6)            ; is the sixth char of the buffer an 'a'?

000162a       BNE     L121                  ; no, jump

000162c       MOVE.W  #1,-108(A5)           ; everything's ok, regflag = 1

0001632       L121    TST.W   -108(A5)           ; flag emtpy?

0001636       BEQ     L122                  ; yes, jmp to bad boy


Woooooooha are you seeing this?? this LAME programmer harcoded the serial!!!!!


He simply checks each and every letter of the inserted string against 'europa' :P.

Man you could have gone a little bit further couldnt ya?


Let's dissect one line in case you still don't get it.


00015fc       CMPI.B  #101!$65,-30(A6)            ; is first char of buffer an 'e'?


First of all, you must know that -30(a6) is a local variable. Why local? simply this '(a6)' indicates us that this variable is local. If instead of a6 it was a5 then that would mean that the variable is global.

'CMPI' = CoMPare Inmediate

'.B' is specifying the size of the operands to be compared. In this case is a BYTE.

#101!$65 is one of the operands. Its either 101 decimal or 65 Hexadecimal.


So all together is:

'Compare if the byte at -30(a6) is 101(dec) which is the same as 65 Hex.

And the x86 version of this instruction would be something like:

'CMP BYTE PTR LocalVariable,101'


Of course,the registration routines goes on, checking that your string is just 'europa' and not other thing. But its not worth the examination. We know there is only ONE serial,and we got it :).


That's all! piece of cake.

Hope you liked the tutorial and/or learned something.

Any mail,comment,criticism,request send them to -> latigo@ciudad.com.ar

Yet more exciting palm coding and cracking tutorials at -> www.latigo.cjb.net