8.5. DONGLES
Yes, this is PowerPC code.
The CPU is a very typical 32-bitRISCof 1990s era.
Each instruction occupies 4 bytes (just as in MIPS and ARM) and the names somewhat resemble MIPS
instruction names.
check1()is a function name we’ll give to it later.BLisBranch Linkinstruction, e.g., intended for calling
subroutines.
The crucial point is theBNEinstruction which jumps if the dongle protection check passes or not if an error
occurs: then the address of the text string gets loaded into the r3 register for the subsequent passing into
a message box routine.
From the [Steve Zucker, SunSoft and Kari Karhi, IBM,SYSTEM V APPLICATION BINARY INTERFACE: PowerPC
Processor Supplement, (1995)]^10 we will found out that the r3 register is used for return values (and r4, in
case of 64-bit values).
Another yet unknown instruction isCLRLWI. From [PowerPC(tm) Microprocessor Family: The Programming
Environments for 32-Bit Microprocessors, (2000)]^11 we’ll learn that this instruction does both clearing and
loading. In our case, it clears the 24 high bits from the value in r3 and puts them in r0, so it is analogical
toMOVZXin x86 (1.17.1 on page 202), but it also sets the flags, soBNEcan check them afterwards.
Let’s take a look into thecheck1()function:
seg000:00101B40 check1: # CODE XREF: seg000:00063E7Cp
seg000:00101B40 # sub_64070+160p ...
seg000:00101B40
seg000:00101B40 .set arg_8, 8
seg000:00101B40
seg000:00101B40 7C 08 02 A6 mflr %r0
seg000:00101B44 90 01 00 08 stw %r0, arg_8(%sp)
seg000:00101B48 94 21 FF C0 stwu %sp, -0x40(%sp)
seg000:00101B4C 48 01 6B 39 bl check2
seg000:00101B50 60 00 00 00 nop
seg000:00101B54 80 01 00 48 lwz %r0, 0x40+arg_8(%sp)
seg000:00101B58 38 21 00 40 addi %sp, %sp, 0x40
seg000:00101B5C 7C 08 03 A6 mtlr %r0
seg000:00101B60 4E 80 00 20 blr
seg000:00101B60 # End of function check1
As you can see inIDA, that function is called from many places in the program, but only the r3 register’s
value is checked after each call.
All this function does is to call the other function, so it is athunk function: there are function prologue and
epilogue, but the r3 register is not touched, socheckl()returns whatcheck2()returns.
BLR^12 looks like the return from the function, but sinceIDAdoes the function layout, we probably do not
need to care about this.
Since it is a typicalRISC, it seems that subroutines are called using alink register, just like in ARM.
Thecheck2()function is more complex:
seg000:00118684 check2: # CODE XREF: check1+Cp
seg000:00118684
seg000:00118684 .set var_18, -0x18
seg000:00118684 .set var_C, -0xC
seg000:00118684 .set var_8, -8
seg000:00118684 .set var_4, -4
seg000:00118684 .set arg_8, 8
seg000:00118684
seg000:00118684 93 E1 FF FC stw %r31, var_4(%sp)
seg000:00118688 7C 08 02 A6 mflr %r0
seg000:0011868C 83 E2 95 A8 lwz %r31, off_1485E8 # dword_24B704
seg000:00118690 .using dword_24B704, %r31
seg000:00118690 93 C1 FF F8 stw %r30, var_8(%sp)
seg000:00118694 93 A1 FF F4 stw %r29, var_C(%sp)
seg000:00118698 7C 7D 1B 78 mr %r29, %r3
seg000:0011869C 90 01 00 08 stw %r0, arg_8(%sp)
(^10) Also available ashttp://yurichev.com/mirrors/PowerPC/elfspec_ppc.pdf
(^11) Also available ashttp://yurichev.com/mirrors/PowerPC/6xx_pem.pdf
(^12) (PowerPC) Branch to Link Register