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).
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.
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 http://www.eji.com/a86)
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!
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 Command.com. 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:
PCMCIA
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 http://www.qfax.com.
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-] |[-E-] | |  | 
| FType: TXT - FAX CFont: 16 - 24 Pause: Yes - No Send Quit | 
    The unique serial Number
of this software is:
    R.3001369
    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 ...you'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
    :Stack
    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:
    ax=1000h
    bx=0
    cx=0A0Bh
    dx=0
 
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)
    Return:
           
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
    AH = 47h  GET/SET DISPLAY CONTRAST
    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)
 
    AX = 4DD4h  INSTALLATION CHECK
    Return: BX = 4850h ("HP") if HP 95LX/100LX/200LX
           
CX = model   (0101h HP 95LX  - 0102h HP
100LX/200LX )
 
    AX = 6000h  GET MAIN BATTERY LEVEL
    Return: AX = battery level
           
(multiply the returned value with 1Bh and add 622h to get millivolts)
 
    AX = 6001h  GET BACKUP BATTERY LEVEL
    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)
 
INT 2Fh
 
    AX = C0AFh   PUSHKEYS
- INTERNAL - GET BUFFER ADDRESS
    Return: ES:DI -> buffer (behind code)
    Range:  AH=C0h to AH=FFh, selected by scanning
for signature with AL=AEh
 
 
 
INT 5Fh
GRAPHICS PRIMITIVES
    AH = 02h   GET CURRENT
GRAPHICS INFO
    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 )
 
  
Frog's Print December 1997 (c) FootSteps All rights reversed