----------------------------------------------------- ----------------------------------------------------- Ma First Steps in Reversing on the PPC / WinCE OS ----------------------------------------------------- ----------------------------------------------------- Published by +Tsehp May 2002 |
CHAPTER ONE - walking up the path to iPAQia | ||||||||
ok, let's start now! making friends with the PPC OS (formerly known as WindowsCE) is not that difficult if you're already familiar with Win32 cracking. One thing is that different Handheld devices use different processors. That means that, even if they all run the Microsoft PPC Os, they use different opcodes. The most common processors atm are StrongARM, Mips and SH3. So, once again, you'll have to deal with differnt commands and opcodes depending of the type of handheld device you're actually using. This example here focuses on StrongARM processors as I'm using a Compaq iPAQ maself. choosing your weapons ... http://download.microsoft.com/download/wince/Install/3.0/W9X2K/EN-US/EN_WINCE_EMBDVTOOLS30.exe
for the following example you should at least have an idea of the opcodes + commands and know a bit about cracking in general! the example will be a very easy one, so... no fear ;) |
||||||||
CHAPTER TWO- Opening the gates | ||||||||
then follow the XREFs till you find the place where the MessageBoxW finally is called. the place's here: .text:00011704 ; --------------------------------------------------------------------------- .text:00011704 STMFD SP!, {R4-R6,LR} .text:00011708 MOV R4, R3 ; <-- R1 .. R5 a.s.o are registers .text:0001170C BL sub_13578 ; <-- call some sub that checks wheter you're regged or not .text:00011710 CMP R0, #1 ; <-- does R0 equal 1 ? .text:00011714 BNE loc_11744 ; <-- if it doesn't .. jump to some nice place .text:00011718 BL sub_13964 ; <-- did u use that game for more than 14 days?? .text:0001171C CMP R0, #1 ; <-- is 'R0 = 1' true? .text:00011720 BNE loc_11744 ; <-- no? OK, let's play that game .text:00011724 LDR R2, =aError ; ----------------------------------------------------- .text:00011724 ; <-- you're not registered, show the damn .text:00011724 ; MessageBox .text:00011728 MOV R3, #0 ; .text:0001172C LDR R1, =a14DayTrialPeri ; <-- set message .text:00011730 MOV R0, #0 ; <-- set type .text:00011734 BL MessageBoxW ; <-- api call .text:00011738 B loc_11840 ; <-- jump to the place of no return ;) .text:00011738 ; --------------------------------------------------------------------------- .text:0001173C off_1173C DCD a14DayTrialPeri ; DATA XREF: .text:0001172Cr .text:0001173C ; "14-Day Trial Period is over.\nPlease vis"... .text:00011740 off_11740 DCD aError ; DATA XREF: .text:00011724r .text:00011740 ; "Error" .text:00011744 ; --------------------------------------------------------------------------- .text:00011744 the BL on line 1170C calls a sub that finds out wheter you're registered or not. the return value is saved in R0. R0 then is checked for equality with 1. if R0 doesn't equal 1 we are registered and can continue playing the game without getting the stupid nag telling us that our trial time is over. now we could only change the BNE on line 11714 to a BEQ or a B and we could continue playing the game without the nag. but in order to make the game think we're really registered we'll have to examine sub_13578. examining the code in this subroutine shows that every mistake in the serial brings us to the same location ... .text:00013680 MOV R0, #1: .text:00013578 .text:00013578 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ .text:00013578 .text:00013578 .text:00013578 sub_13578 ; CODE XREF: .text:0001170Cp .text:00013578 ; .text:00011B4Cp ... .text:00013578 STMFD SP!, {R4,R5,LR} .text:0001357C SUB SP, SP, #0xE0 .text:00013580 LDR R0, =aRegcode .text:00013584 ADD R1, SP, #0x18 .text:00013588 BL sub_13BCC .text:0001358C ADD R0, SP, #0x18 .text:00013590 BL wcslen .text:00013594 CMP R0, #0xA .text:00013598 BCC loc_13680 ; <-- WRONG KEY .text:0001359C ADD R0, SP, #0x18 .text:000135A0 BL sub_1371C .text:000135A4 MOVS R3, R0 .text:000135A8 BNE loc_13680 ; <-- WRONG KEY .text:000135AC LDRH R3, [SP,#0x26] .text:000135B0 MOV R4, #0 .text:000135B4 LDR R1, =aD .text:000135B8 ADD R2, SP, #0x14 .text:000135BC ADD R0, SP, #0 .text:000135C0 STRH R3, [SP] .text:000135C4 STRH R4, [SP,#2] .text:000135C8 BL swscanf .text:000135CC ADD R2, SP, #4 .text:000135D0 LDRH R3, [SP,#0x1E] .text:000135D4 ADD R0, SP, #0 .text:000135D8 LDR R1, =aD_0 .text:000135DC STRH R3, [SP] .text:000135E0 STRH R4, [SP,#2] .text:000135E4 BL swscanf .text:000135E8 ADD R2, SP, #8 .text:000135EC LDRH R3, [SP,#0x1C] .text:000135F0 ADD R0, SP, #0 .text:000135F4 LDR R1, =aD_1 .text:000135F8 STRH R3, [SP] .text:000135FC STRH R4, [SP,#2] .text:00013600 BL swscanf .text:00013604 ADD R2, SP, #0xC .text:00013608 LDRH R3, [SP,#0x2A] .text:0001360C ADD R0, SP, #0 .text:00013610 LDR R1, =aD_2 .text:00013614 STRH R3, [SP] .text:00013618 STRH R4, [SP,#2] .text:0001361C BL swscanf .text:00013620 ADD R0, SP, #0x18 .text:00013624 BL sub_136A4 .text:00013628 LDRH R3, [SP,#0x2C] .text:0001362C ADD R2, SP, #0x10 .text:00013630 MOV R5, R0 .text:00013634 LDR R1, =aD_3 .text:00013638 STRH R3, [SP,#0x18] .text:0001363C ADD R0, SP, #0x18 .text:00013640 LDRH R3, [SP,#0x2E] .text:00013644 STRH R4, [SP,#0x1C] .text:00013648 STRH R3, [SP,#0x1A] .text:0001364C BL swscanf .text:00013650 LDR R3, [SP,#0x14] .text:00013654 LDR R2, [SP,#0xC] .text:00013658 CMP R3, R2 .text:0001365C BNE loc_13680 ; <-- WRONG KEY .text:00013660 LDR R3, [SP,#4] .text:00013664 LDR R2, [SP,#8] .text:00013668 CMP R2, R3 .text:0001366C BNE loc_13680 .text:00013670 LDR R3, [SP,#0x10] .text:00013674 MOV R0, #0 ; R0 = 0 and you're fully registred .text:00013678 CMP R5, R3 .text:0001367C BEQ loc_13684 ; <-- YAY, your serial is valid! :) .text:00013680 .text:00013680 loc_13680 ; CODE XREF: sub_13578+20j .text:00013680 ; sub_13578+30j ... .text:00013680 MOV R0, #1 ; R0 = 1 and you're not registered! .text:00013684 .text:00013684 loc_13684 ; CODE XREF: sub_13578+104j .text:00013684 ADD SP, SP, #0xE0 .text:00013688 LDMFD SP!, {R4,R5,PC} .text:00013688 ; End of function sub_13578 .text:00013688 the easiest way to make the app think that you're using a correct serial is just to change that single line
why again?? because when the app returns from that subroutine R0 is checked for equality with 1. and as we found out before, if it equals 1, the app knows that it's NOT registered! ;) |
||||||||
CHAPTER THREE - The Bare Knuckle Fight | ||||||||
now it's time for the heXeditor. for me the thing that makes changing the code a bit more difficult than changing the code of a win32 app is that you can't just easily use HIEW's built in assembly-view but that you have to know the opcodes. that's the point where i'm opening ma opcode list ;).
now load 'lines.exe' into your heXeditor and go to Offset 13680.
by the way, arm commands consist of 4 bytes (and btw. each command can be conditional! eg. MOVEQ, MOVNE). now let's see how we gotta change that command: MOV R0, #1 stands for 01
00 A0 E3 so quickly patch the .exe file, save it and upload
it to your PPC. run it and .. TATAA, you're fully registered! ah, ok .. that's it for now. if you're looking
for more texts about wince / ppc cracking check ka0s.net every now and
then and |
||||||||
greetings and thanks to ma mum, iri5, toni, regen, paul, nutty, tommek, the lz0 tribe, COREPDA and all ma friends! | ||||||||
KEN WHOT A MEAN? - heXc
http://www.ka0s.net |