Palmtops cracking (HP100/200lx)

by Frog's Print

(10 December 1997, slightly edited by fravia+)
Courtesy of fravia's page of reverse engineering
Well, Frog's Print brings us all in the palmtop realm, and demonstrates brilliantly how relatively easy it is (once he has explained it :-) to crack software that is not even supposed to run on your PCs... nothing is impossible for the wizards of assembly and of DOS interrupt cracking!
Therefore the most amusing (and amazing) teaching from this very nice essay is: WindowsCE (Gates' dream: porting his pathetically slow and overbloated operating system inside every domestic appliance) will be defeated (I mean, turned to our, not his, advantage) through simple assembly... QED (quod erat demonstrandum :-)

- A (LATE) TUTORIAL FOR THE HP 100/200lx -
(ex: QuickStar Fax Pro V1.10 for HP)

by Frog's Print -: )

You probably know (or at least have heard about) those small computers that fit in the palm of your hand and in your pocket: Hewlett Packard HP 95/100/200LX.
Though other companies (i.e. Psion...) have released such products as well, we will only discuss here Hewlett Packard Palmtops just because they are 100% DOS compatible (Psion are not).

So, first, a little bit of history:
In 1991, HP announced the 95lx (code name "Jaguar").
LCD screen, MDA (Monochrome Display Adapter) displaying 16 rows x 40 columns (240 x 128 pixels), MS-DOS v3.22, with 512Kb or 1Mb RAM, including a File Manager, Lotus (v2.2), a note editor, a diary, calculator...., a PCMCIA slot for PC Cards (type I and II v1.0).
The product was great but soon, its specs got unadapted to its users due to PC's evolution.

During May 1993, they released the 100lx (code name "Couguar").
It was the most amazing Palmtop ever created:
LCD screen, CGA (Color Graphic Adapter) displaying 25 rows x 80 columns (640 x 200 pixels), MS-DOS v5.0, 1Mb or 2Mb RAM, a ROM full of miscellaneous apps, and utilities, including a File Manager closed to Norton Commander, Lotus (v2.4), Lotus ccMAIL, word processor, database, macro, IR communications, financial and programmer calculator, a PCMCIA slot for PC Cards (type I and II v2.0) for RAM, Flash or Fax/Modem...or any other kind of communications,
IR and serial ports, full printing capabilities...

A year later (1994) came the 200lx.
It was similar to the 100lx except that the Graphic interface was re-designed and looked far much better, the ROM was increased to 2Mb, the RAM from 1 to 2 and, lately, to 4Mb and a version of Pocket Quicken added.

The 100 and the 200lx were so succesful, that a huge amount of hardware products (floppy drive, fax, printers, wireless communications stuffs, GPS, BareCode, etc...) were created for them as well as an amazing quantity of professional softwares (medical, electronic cicuit analysys, radiation detection, Internet browsers...), newspapers (HP Palmtop Paper), www-ftp sites and a nice forum on Compu$erve (HPHand).

And, of course, a lot of succes (as well as the released, at that time, of 80Mb PCMCIA flash memory cards!) means... a LOT of beautiful sharewares with passwords, '.key' files, nagscreens... to feed our cracker's appetite! At least mine, because I owned those 3 palmtops (and still got my 200lx 4Mb baby) and spent nights and days to crack them using A86/D86 (from Eric Isaacson, latest version available at and DIS86 (from James R. Van Zandt, latest version available via FTPSearch ).
It was a real pleasure because, in the Palmtops world, it's a place where you can meet some of the most amazing shareware (and most of the time freeware) ASM and C programmers you'll ever see. I really mean it!

A lot of people still own and use those Palmtops today (I saw 2 weeks ago an engineer working with Lotus 123 on his 200LX  in the street )but, due to the apparition of Window$ CE, there shouldn't be any more products or softwares developed for them using the good old DOS 5.0.
Hewlett Packard released the HP 360, a 8 Mb RAM / 10 Mb ROM 60Mhz Windows CE based computer ( with all Micro$oft craps: Excel, Words, Internet Explorer...) and announced and 16 Mb RAM, 16 colors new serie 300 for 1998.
There are already a couple of Windows CE Internet sites, and, of course, quite a lot of Sharewares available.
But right before we start to crack Windows CE (I will soon take care of that..) let's see and study how the "old" HP100/200lx works:

On your PC, you boot, then can stay under DOS to run any DOS .exe or .com files, or launch your graphic interface (Window$) by typing "WIN" at the prompt and then, run programs adapted to (and only to) this interface (Window$ crappy sharewares...). You can even open DOS shells from it to run DOS softwares.

The HP100/200lx works exactly the same:
It boots, loads Then you can stay under DOS or launch the graphic interface (called System Manager) by typing "100" on the 100lx, or "200" on the 200lx (you can even type "$ysmgr" as well, but you really must have time to waste to do so), and you can open a DOS shell (only one at a time) while the System Manager is running.

For this reason, there a 2 different kinds of executable files that can run on the Palmtop:

1/ DOS exe/com files:
They must run with DOS v5.00, and require a CGA video board.

2/ System Manager compliant applications:
These files have a .exm extension for "EXecute in Memory" (there were few .xip - eXecute In Place - files as well for programs located on PCMCIA cards :- ).
I will not write a lot about them, though it is very interesting to program Exm files. When running, such files have access to the same set of services that are used by the built-in applications. This enables the program to share a non-preemptive multitasking environment with the built-in applications so that the user can conveniently switch between tasks.
They must be programmed in C and ASM only to create a special .exe file that will be transformed, later, into a Exm. The most important part is that Hewlett Packard developpers are really smart guys: they provided independant programers with a lot of infos they needed (and some tools) to help them to develop Exm programs. They gave a great support (even much more than what they were supposed to) to anyone interested with that. Just think about Micro$oft, which only support is to tell you that if you're having problem with their programs, it is not because they have bugs but because you may not be smart enough to use them well....

There are no real reasons to crack Exm files because most of them are commercial programs. 99% of sharewares are Exe or Com files. The main reason is that a Exm file has a lot of limitations. For instance, it doesn't accept command line arguments (like "Myfile.exm Mydata.dat" or "Myfile.exm /B -1"). Another limitation is that you cannot highlight one of them in the File Manager and launch it by pressing <Enter> because they must be added to the Program Manager, then assiociated to an Icon. It will be launched by clicking on this icon ( you could only crack it using a Dead Listing approach). And, finally, the Program Manager has a limitation about the total amount of Exm files it can handle.

So, HP100/200lx sharewares are Exe/Com files that look like ordinary Exe/Com files. You could think you could crack a program written for the 100/200lx with SoftICE on your PC and then transfer it back to your Palmtop. But you can't. They could ONLY run on the Palmtop for the following reasons:
The Ms-Dos version has been enhanced to fit the Palmtop specifications. Quite a lot of new interrupts and functions have been added and/or modified. Here is a quick list of them:
(I added at the end of this essay a list of HP's interrupts)

INT 15h:
Display control status, power off timeout, display contrast, buzzer, serial interface, system time, installation check, power and battery, announciators.
INT 16h (ah=10h/11h):
Special function/Menu keys.
INT 1Ah:
INT 2Fh:
Key200 and Pushkeys installation check
INT 5Fh (Graphics Primitives):
Video mode, fill mask, graphic info, logical origin, clip region, drawing line, rectangle..., move pen, set color, replacement rules, line type, get pixel, get image, put image, write text, get/set font pointer.....
INT 60h:
System Manager
INT 63h:
Memory map...

A program written for the HP100/200lx will extensively use, at least, the functions of the INT 5Fh (graphics primitives) to set the video mode, write text and to draw its interface.
That why it will not run on a PC as DOS doesn't recognise this INT 5Fh (as well as all others above mentioned interrupts or functions).

Here is now, how works a Exe/Com program for the Palmtop 100/200lx:

Check_If_HP100_200   : mov ax,    4DD4h         ; Are we running
                       int        15h           ; on a HP palmtop?
                       cmp bx,    4850h         ; 0x4850='HP'.
                       jne        Exit          ; No, Exit. 
                       cmp cx,    0102h         ; Is it a HP95lx or 100/200lx?
                       jne        Exit          ; No, it is a 95lx, so Exit otherwise.
Initialize_HP_Graph  : mov ax,    0006h         ; Set HP graph mode
                       int        5Fh           ; to 640x200 CGA.
                       mov ax,    0A08h         ; Set replacement rule
                       int        5Fh           ; to 'Text'.
                       mov ah,    09h           ; Set pen color
                       mov al,    01h           ; to black.
                       int        5Fh
My_nice_Program      : ...                      ; Put your stuff here.
Restore              : mov ax,    0003h         ; Restore HP DOS
                       int        5Fh...        ; text mode.
Exit                 : mov ah,    4Ch           ; Have a nice day.
                       int        21h

The graph mode and replacement rule could be set differently as there are different options available but these ones are the most usual.

Now, let's crack!
Of course, it is not possible to use SoftICE or any other similar debuggers/tracers like TR196 on a Palmtop (except Borland Turbo Debugger).
And I said above that you are not supposed to be able to run a Exe/Com file written for the HP100/200lx on your PC in order to crack it with SoftICE.
But this is pure theory, not reality...
I will show you how to do it anyway, even on your new P266MMX with SoftICE 3.22.

For this, we will crack QuickStar FAX Pro V1.10 HP written by Anthony "I am a proud member of the Association of Shareware Professionals" Mai. It is available at
This is a good, fast program for sending, receiving and viewing faxes on a HP100/200 lx.

Run it on your Palmtop (or just assume you get one -: ) and analyse it. The program's graphic interface (CGA 640x200) is definitely designed for, and only for, the HP100/200lx. It looks something like this:
Filename: FILE_ID.DIZ                       FaxNumber:_____________
C:\FAX                                      SubDir:
FILE_ID.DIZ                                |.. 
QFREC.EXE                                  |[-A-] 
QFAX.EXE                                   |[-B-] 
QFAX.CFG                                   |[-C-] 
....                                       |[-D-] 
FType: TXT - FAX       CFont: 16 - 24         Pause: Yes - No     Send     Quit
The program picks up the first file (here, File_id.diz) in your current directory (C:\Fax).
You can select another one with the UP and Down arrow keys. By pressing <Tab> or <Enter>, the cursor is moved to "FaxNumber" where you have to type the fax number. Pressing <Tab> or <Enter> again, will move the cursor to "FType" (TXT or FAX), then to "CFont" (choose fonts), then to "Pause" (prompt before sending) and then to "Send". Pressing the <Enter> key will leave the graphic interface and return to the Dos text mode. Then, you'll get the following message:

    The unique serial Number of this software is:
    What's your registration license number?_

You have to type your license number + <Enter> to send your fax. If it is wrong, the program will ask you to press a specific key (at random) before processing.
 Transfer Qfaxe.exe on your PC and run it. You'll see:

    This program only runs on a HP palmtop computer
    Ask the author for a parallel version for regular PCs

Usually, as described above, to check if a program is running on a HP palmtop you must call Int 15h function 4DD4h. The return values are:

    bx=4850h if it is a HP Palmtop (0x48="H" & 0x50="P")
    cx=model (0101h=HP95lx & 0102h=HP100/200lx)

Other values returned (dh, dl) concern the Bios and language versions.

Just put a BPINT on Int 15h:

    :BPINT 15 IF ax==0x4DD4

(note: SoftICE will break on Int 15h but will NOT on other HP's special interrupts (i.e. int 5Fh...) -: ).

Run again QFax and'll get nothing!
So, how the hell does it know it is not running on a HP?

To find out what is going on, with SoftICE put a BPINT on Int21/ah=4Ch (exit program interrupt) and, in the meantime check the stack:

    :BPINT 21 If AH==4C DO "Stack"

Run again QFax and you'll get:

    xxxx:5A5F    mov     ax, [bp+arg_0]
    xxxx:5A62    mov     ah, 4Ch
    xxxx:5A64    int     21h             ; Quit with exit code

    Owner Is QFAX at xxxx:11E1 [?]       ; <= the caller
    =>Owner Is QFAX at xxxx:5A64 [?]
Check at xxxx:11E1 to see why the program doesn't want to run: 
    :U 11E1

    xxxx:11B7    mov    ax, 1000h       ; ???
    xxxx:11BA    xor    bx, bx          ; ???
    xxxx:11BC    xor    dx, dx          ; ???
    xxxx:11BE    mov    cx, 0A0Bh       ; ???
    xxxx:11C1    int    5Fh             ; ???
    xxxx:11C3    mov    [5528],ax
    xxxx:11C6    cmp    w,[5528],008
    xxxx:11CB    jz     11E5            ; Jmp to Good_Guy...
    xxxx:11E1    call   59dc            ; Otherwise, exit.
This is what I call "another_nice_stupid_little_trick_from_a_hopeless_protectionist".
We can see just above our JZ a call to Int 5Fh with:
Function 10h of Int 5Fh is used to get the Palmtop font pointer:
    Int 5Fh
    ah = 10h
    cx = font size
            0808h  8x8  small  (80x25 text)
            0A0Bh 11x10 medium (64x18 text)
            100Ch 12x16 large  (40x16 text)
            dx:ax -> pointer to font or 0000h:fontID# if built-in font
           (ax=4 for small fonts, 2 for large fonts and 8 for medium fonts)

The program stores AX value in [5528] and just compares it to what it was expecting to get: 8.
If it is different, it is not a HP palmtop.

Get rid of the JZ and make it JMP for ever.

It is clear that the call to Get_Font_Pointer is only used here as a protection trick, because after a call to this function, you MUST call immediately the Set_Current_Font function (ah=11h) otherwise it is absolutely useless and will never work (see list of Int at the bottom of this essay -: ). Note as well, that the program doesn't check if it is running on a HP95lx. This means that if you ran it on a 95lx, the program would tell you that it is not a HP Palmtop, though is is!

What's going to happen now if we run the program on our PC? Will it crash?
No, it won't. In fact you'll get a blank screen as your computer will not recognise HP graphics interrupts but it will still work because the Palmtop needs Int 16h functions 00h/01h/02h for its keyboard like any other PC (except for one special key: the "Menu" key (ASCII code #200) , used to display pull down menus -function 10h- but we do not need it here.).

We know that when we run QFax it will first pick up the first file in your current directory, so just press <ENTER> and you should reach the Fax Number input field. Type any number and then, press 4 times the <ENTER> or <TAB> key. Though you still don't see anything on your screen, your cursor should be positioned on "Send". If you pressed <ENTER>, the program would get back to the DOS text mode and this part would be displayed on your screen!
But before, as we know that it will wait for us to type in our serial number, with SoftIce put another BPINT on Int 21h function 0Ah (return the buffer filled with user input including CR):

    BPINT 21 IF ah==0x0A

And press <ENTER> ("Send"). SoftICE breaks. Press <F11> and you'll see the message asking for your password. Type anything you want and press <ENTER>. S-Ice pops here:

    xxxx:A32855              mov    [05528],ax     ; Store our password
    xxxx:4E92: FF362655      push   w,[05526]
    xxxx:4E96: E8370B        call   59D0           ; Calculate correct_password
    xxxx:4E99: 5B            pop    bx
    xxx4x:E9A: 3B062855      cmp    ax,[05528]     ; Compare both
    xxxx:4E9E: 7525          jne    4EC5           ; Bad_Guy jump
    xxxx:4EA0: C70680550100  mov    w,[05580],0001 ; Good_Guy flag.

No explanations needed.... except the fact that the program stores our password into [5528] which is the memory location where it has previously stored the return value of AX for the Get_Font_Pointer routine we cracked above.
If you crack this part, the program will automatically create a REG.DAT file with the following line:

   License Number: xxxx This program is registered.

And now you can use a registered soft to send beautiful faxes with a 200g / 7oz computer from anywhere in the World.

 Here is now a list of the HP Palmtop's interrupts that will give return codes that could be used to check it the program is running on a 100/200lx or not:

INT 15h

    AL = subfunction
         00h set contrast
    BL = new contrast (00h-0Fh, 0Fh is darkest, 10h-FFh are same as 0Fh)
         other get current contrast
    Return: AL = contrast (00h-0Fh, 0Fh is darkest)

    Return: BX = 4850h ("HP") if HP 95LX/100LX/200LX
            CX = model   (0101h HP 95LX  - 0102h HP 100LX/200LX )

    Return: AX = battery level
            (multiply the returned value with 1Bh and add 622h to get millivolts)

    Return: AX = battery level
            (multiply the returned value with 1Bh and add 622h to get millivolts)

    AX = 6002h  GET POWER INFO
    Return: AL = power settings (see below)
            Bitfields for power settings:
            Bit(s)  Description
            0-1    unused ???
            2      card battery status low (OK if bit clear)
            3      battery charging off (disabled if bits 3-5 clear)
            4      battery charging slow
            5      battery charging fast
            6      power adaptor active
            7      battery type NiCad (alkaline if bit clear)


    Return: ES:DI -> buffer (behind code)
    Range:  AH=C0h to AH=FFh, selected by scanning for signature with AL=AEh

    ES:DI -> graphics info record
    Return: DX:AX -> filled graphics info record (for return to high-level langs)
            Format of HP Palmtops graphics info record:
            Offset  Size    Description
            00h    BYTE    current video mode
            01h    BYTE    default video mode
            02h    WORD    display width in pixels
            04h    WORD    display height in pixels
            06h    WORD    current pen column
            08h    WORD    current pen row
            0Ah    WORD    current line type
            0Ch    WORD    current replacement rule
            0Eh    WORD    current pen color
            10h    WORD    current leftmost column of clip region
            12h    WORD    current rightmost column of clip region
            14h    WORD    current topmost row of clip region
            16h    WORD    current bottommost row of clip region
            18h    WORD    current column of logical origin
            1Ah    WORD    current row of logical origin
            1Ch  8 BYTEs   current fill mask

    AH = 0Ch    GET PIXEL
    DX,CX = row,column of pixel to read
    Return: AX = pixel color


    AH = 10h    GET FONT POINTER
    CX = font size of desired font
         0808h  8x8  small  (80x25 text)
         0A0Bh 11x10 medium (64x18 text)
         100Ch 12x16 large  (40x16 text)
    Return: DX:AX -> ptr to font or 0000h:fontID# if built-in font


    AH = 11h    SET CURRENT FONT
    ES:DI -> ptr to font or 0000h:fontID# for built-in font
            (this function should be called immediately after AH=10h with the
            pointer supplied by that call )

Hope this will help the HP100/200lx nostalgic users...

Frog's Print  December 1997 (c) FootSteps All rights reversed

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

redhomepage redlinks redanonymity +ORC redstudents' essays redacademy database
redtools redcocktails redjavascripts redantismut CGI-scripts redsearch_forms redmail_fravia
redIs reverse engineering legal?