Reverse Engineering for Beginners

(avery) #1

CHAPTER 78. DONGLES CHAPTER 78. DONGLES


seg000:00118708
seg000:00118708 must_jump: # CODE XREF: check2+78j
seg000:00118708 7F A3 EB 78 mr %r3, %r29
seg000:0011870C 48 00 00 31 bl check3
seg000:00118710 60 00 00 00 nop
seg000:00118714 54 60 06 3F clrlwi. %r0, %r3, 24
seg000:00118718 41 82 FF AC beq skip
seg000:0011871C 38 60 00 01 li %r3, 1
seg000:00118720
seg000:00118720 exit: # CODE XREF: check2+30j
seg000:00118720 # check2+80j
seg000:00118720 80 01 00 58 lwz %r0, 0x50+arg_8(%sp)
seg000:00118724 38 21 00 50 addi %sp, %sp, 0x50
seg000:00118728 83 E1 FF FC lwz %r31, var_4(%sp)
seg000:0011872C 7C 08 03 A6 mtlr %r0
seg000:00118730 83 C1 FF F8 lwz %r30, var_8(%sp)
seg000:00118734 83 A1 FF F4 lwz %r29, var_C(%sp)
seg000:00118738 4E 80 00 20 blr
seg000:00118738 # End of function check2


We are lucky again: some function names are left in the executable (debug symbols section? Hard to say while we are
not very familiar with the file format, maybe it is some kind of PE exports? (68.2.7 on page 674)), like.RBEFINDNEXT()
and.RBEFINDFIRST(). Eventually these functions call other functions with names like.GetNextDeviceViaUSB(),
.USBSendPKT(), so these are clearly dealing with an USB device.


There is even a function named.GetNextEve3Device()—sounds familiar, there was a Sentinel Eve3 dongle for ADB
port (present on Macs) in 1990s.


Let’s first take a look on how the r3 register is set before return, while ignoring everything else. We know that a “good” r3
value has to be non-zero, zero r3 leads the execution flow to the message box with an error message.


There are twoli %r3, 1instructions present in the function and oneli %r3, 0(Load Immediate, i.e., loading a value
into a register). The first instruction is at0x001186B0—and frankly speaking, it’s hard to say what it means.


What we see next is, however, easier to understand:.RBEFINDFIRST()is called: if it fails, 0 is written into r3 and we jump
toexit, otherwise another function is called (check3())—if it fails too, .RBEFINDNEXT()is called, probably in order to
look for another USB device.


N.B.:clrlwi. %r0, %r3, 16it is analogical to what we already saw, but it clears 16 bits, i.e.,.RBEFINDFIRST()
probably returns a 16-bit value.


B(stands forbranch) unconditional jump.


BEQis the inverse instruction ofBNE.


Let’s seecheck3():


seg000:0011873C check3: # CODE XREF: check2+88p
seg000:0011873C
seg000:0011873C .set var_18, -0x18
seg000:0011873C .set var_C, -0xC
seg000:0011873C .set var_8, -8
seg000:0011873C .set var_4, -4
seg000:0011873C .set arg_8, 8
seg000:0011873C
seg000:0011873C 93 E1 FF FC stw %r31, var_4(%sp)
seg000:00118740 7C 08 02 A6 mflr %r0
seg000:00118744 38 A0 00 00 li %r5, 0
seg000:00118748 93 C1 FF F8 stw %r30, var_8(%sp)
seg000:0011874C 83 C2 95 A8 lwz %r30, off_1485E8 # dword_24B704
seg000:00118750 .using dword_24B704, %r30
seg000:00118750 93 A1 FF F4 stw %r29, var_C(%sp)
seg000:00118754 3B A3 00 00 addi %r29, %r3, 0
seg000:00118758 38 60 00 00 li %r3, 0
seg000:0011875C 90 01 00 08 stw %r0, arg_8(%sp)
seg000:00118760 94 21 FF B0 stwu %sp, -0x50(%sp)
seg000:00118764 80 DE 00 00 lwz %r6, dword_24B704
seg000:00118768 38 81 00 38 addi %r4, %sp, 0x50+var_18
seg000:0011876C 48 00 C0 5D bl .RBEREAD
seg000:00118770 60 00 00 00 nop
seg000:00118774 54 60 04 3F clrlwi. %r0, %r3, 16
seg000:00118778 41 82 00 0C beq loc_118784
seg000:0011877C 38 60 00 00 li %r3, 0

Free download pdf