Cracking tutorial

Смартфоны и коммуникаторы Nokia 9500, 9300, 9210 + Nokia 7710 + платформы Symbian Series 60 + смартфоны Symbian UIQ
Закрыто
Аватара пользователя
Gorby
Доктор (4 lvl)
Сообщения: 324
Зарегистрирован: Ср июн 04, 2003 15:03

Cracking tutorial

Сообщение Gorby » Чт май 13, 2004 12:06

Нашел в сети... Неплохой бегиннер-стайл туториал. Смотрим, кому интересно. Попытаюсь приаттачить unmakesis этого же кул хаксора. Но аттачи у меня почему-то битые раньше получались... Не буду аттачить. Вот ссылка: unmakesis.
ÛÛÛÛÛÛÛÛ ÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛ
ÛÛÛ°°°°°ÛÛÛ ÛÛÛ°ÛÛÛ ÛÛÛ°°°°°°°ÛÛÛ
ÛÛ°°°ÛÛ°°°ÛÛ ÛÛ°°°°°ÛÛ ÛÛÛ°°ÛÛÛÛÛ°°ÛÛÛ
ÛÛ°°ÛÛÛÛ°°°ÛÛÛÛ°°°°°°°ÛÛ ÛÛÛ°°ÛÛ ÛÛ°°ÛÛÛ
ÛÛ°°ÛÛ ÛÛ°°°ÛÛÛ°°°°°°°°°ÛÛÛÛ°°ÛÛÛ ÛÛ°°°ÛÛÛ
ÛÛ°°ÛÛ ÛÛ°°°ÛÛÛ°°°°°°°°°ÛÛ ÛÛÛÛÛ ÛÛ°°°ÛÛ
ÛÛ°°ÛÛ ÛÛ°°°ÛÛÛÛ°°°°°°°ÛÛ ÛÛÛ°°ÛÛ
ÛÛÛÛÛÛ ÛÛ°°°ÛÛ ÛÛ°°°°°ÛÛ Û ÛÛ°°°ÛÛ
ÛÛ°°°ÛÛ ÛÛÛÛÛÛÛ Û ÛÛ°°°ÛÛ
ÛÛ°°°ÛÛ ÛÛ°°°°ÛÛ ÛÛÛÛÛ ÛÛ°°°ÛÛ
ÛÛ°°°ÛÛ ÛÛ°°°°°°ÛÛ Û ÛÛ°°°ÛÛ
ÛÛ°°°ÛÛÛÛ°°°°°°°°ÛÛ Û ÛÛ°°°ÛÛ
ÛÛ°°°ÛÛÛ°°°°°°°°°°ÛÛ ÛÛ°°°ÛÛ
ÛÛ°°°ÛÛÛÛ°°°°°°°°ÛÛÛ ÛÛ°°°ÛÛ ÛÛÛ
ÛÛ°°°ÛÛÛÛ°°°°°°°°ÛÛ ÛÛ°°°ÛÛ ÛÛ°ÛÛ
ÛÛ°°°ÛÛ ÛÛ°°°°°°ÛÛ ÛÛÛ°°°ÛÛÛÛÛÛ°ÛÛ
ÛÛ°°°ÛÛ ÛÛÛ°°ÛÛÛ ÛÛ°°°°°°°°°°ÛÛ
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛ

-------------------------------------------------------------------------

eighteen plus two
AchTZehn PLus ZWei

proudly presents

-------------------------------------------------------------------------

Cracking SymbianWare Stacker v2.02

A newbie tutorial by atzplzw

Version 1.2


Tools:
------
IDA Pro v4.04 or higher, I use ver 4.30
Hex Editor, I prefer WinHex


Target:
-------
SymbianWare Stacker v2.02

"Stacker is a fully automatized and reliable compression system for your Nokia 7650.
Stacker doubles the size of your entire drives and works invisible behind the scene.
When you start an application it becomes decompressed in background automatically
and it becomes compressed again when you close it."

Copied from www.symbianware.com (slidely edited)


Recommended:
------------
A little knowledge in ARM assembler... (www.arm.com)
If not, at least you have to know how to use IDA and a Hex Editor and how to transfer
files between the PC and the Nokia 7650.


Warning:
--------
This is my first tutorial and also english is not my native language. I hope that
you will understand what is meant and shit on the grammar...

Also this is not a tutorial for beginners in computing. I'll not explain where to
get the tools nor will I answer any questions regarding this by email. Any other
questions are welcome!!
Also if you don't know what assembler is STOP now!!!!


Introduction:
-------------
I have choosen SymbianWare Stacker because it's really easy to understand and to
crack. In my opinion all SymbianWare progs are easy to crack. You may find it
difficult in the beginning, but it isn't.

Also (till now, all) SymbianWare progs are compiled with full ARM instructions set
and not in ARM Thumb mode.



Here we go:
-----------
First, of course, run the app. Look at the nag screen. Test all things.
After that...

Open stacker.app in the Hex Editor and look through the wired numbers and ascii
letters. In the first line at offset 0x10 you will find "EPOC" which means that
this is an EPOC file for use with the Symbian OS.

Scroll down and you will find some Unicode strings between offset 0x76C0 and
0x7FA0.

What do we read here?? Isn't it the text from the About Box and other Messages?
Yes, it is.

Now we take a closer look at offset 0x7F18:

00007F18 U.n.r.e.g.i.s.t.e.r.e.d.!. .T.r.i.a.l. .i.s. .o.v.e.r....... ....... .d.
00007F60 a.y.s. .l.e.f.t. .t.o. .e.x.p.i.r.e.....U.n.r.e.g.i.s.t.e.r.e.d.


Woohh! We found the text of the nag box when the app is started. Write this offset
down and go fast to IDA...


Open stacker.app. It suggests that it is a EPOC file as we already found out.
Mark Load resources. And press OK! Now you will be informed that the ARM processor
has two instruction sets but this is irrelevant for now.

Now IDA presents you the disassembled ARM instruction code. You may also turn on
Options/General/Auto Comments for better understanding of the code...
For those of you who are not familiar with IDA it is important to know that in the
status line at the bottom the offset is displayed. (tooltip: Current position in
the input file, means offset)

Now scroll all the way down until you will find the offset we wrote down. IDA
displays this mess:

.text:10007E9C dword_0_10007E9C DCD 0x6E0055, 0x650072, 0x690067, 0x740073,
.text:10007E9C 0x720065, 0x640065 ; DATA XREF: .text:10005830
.text:10007E9C DCD 0x200021, 0x720054, 0x610069, 0x20006C, 0x730069,
.text:10007E9C DCD 0x6F0020, 0x650076, 0x2E0072, 0
.text:10007ED8 dword_0_10007ED8 DCD 0xA0020, 0 ; DATA XREF: .text:100058A4


Now just right click on a number, choose Undefine and your mind will be cleared up:


.text:10007E9C unk_0_10007E9C DCB 0x55 ; U ; DATA XREF: .text:10005830o
.text:10007E9D DCB 0 ;
.text:10007E9E DCB 0x6E ; n
.text:10007E9F DCB 0 ;
.text:10007EA0 DCB 0x72 ; r
.text:10007EA1 DCB 0 ;
.text:10007EA2 DCB 0x65 ; e
.text:10007EA3 DCB 0 ;
.text:10007EA4 DCB 0x67 ; g
.text:10007EA5 DCB 0 ;
.text:10007EA6 DCB 0x69 ; i
.text:10007EA7 DCB 0 ;
.text:10007EA8 DCB 0x73 ; s
.text:10007EA9 DCB 0 ;
.text:10007EAA DCB 0x74 ; t
.text:10007EAB DCB 0 ;
.text:10007EAC DCB 0x65 ; e
.text:10007EAD DCB 0 ;
.text:10007EAE DCB 0x72 ; r
.text:10007EAF DCB 0 ;
.text:10007EB0 DCB 0x65 ; e
.text:10007EB1 DCB 0 ;
.text:10007EB2 DCB 0x64 ; d
.text:10007EB3 DCB 0 ;
.text:10007EB4 DCB 0x21 ; !
.text:10007EB5 DCB 0 ;
...............................................(shortend)



The Unicode string we saw in the Hex Editor, right? Now we want to know when the
string is used in the code. So right click on "DATA XREF: .text:10005830o",
choose Jump to cross reference and click OK. You will land here:

.text:10005830 off_0_10005830 DCD loc_0_10007E9C ; DATA XREF: .text:1000580Cr


Do it again, right click on "DATA XREF: .text:1000580Cr", choose Jump to cross
reference and click OK. Finally you arrive in the code:

.text:1000580C LDR R1, =dword_0_10007E9C ; Load from Memory


LDR is the instruction to load the string from memory. This string is displayed
afterwards. But we don't want to see it because it's so annoying.
So we scroll a little bit up and look at the code. What did it before?


.text:100057BC BL sub_0_1000538C ; Branch with Link
.text:100057C0 CMP R0, #0 ; Set cond. codes on Op1 - Op2
.text:100057C4 BNE loc_0_100058B0 ; Branch <<<<<<<
.text:100057C8 MOV R0, R4 ; Rd = Op2
.text:100057CC BL loc_0_100054C4 ; Branch with Link
.text:100057D0 SUBS R7, R0, #0 ; Rd = Op1 - Op2
.text:100057D4 BEQ loc_0_10005834 ; Branch <<<<<<<
.text:100057D8 BL loc_0_10006168 ; Branch with Link
.text:100057DC LDR R1, =0x5BED5021 ; Load from Memory
.text:100057E0 LDR R2, =0x5BED5020 ; Load from Memory
.text:100057E4 BL loc_0_100064A8 ; Branch with Link
.text:100057E8 MOV R0, R4 ; Rd = Op2
.text:100057EC BL loc_0_10005230 ; Branch with Link
.text:100057F0 MOV R0, R4 ; Rd = Op2
.text:100057F4 BL sub_0_1000538C ; Branch with Link
.text:100057F8 CMP R0, #0 ; Set cond. codes on Op1 - Op2
.text:100057FC BNE loc_0_100058B4 ; Branch <<<<<<<
.text:10005800 BL loc_0_10006168 ; Branch with Link
.text:10005804 MOV R4, R0 ; Rd = Op2
.text:10005808 ADD R0, SP, #0x20 ; Rd = Op1 + Op2
.text:1000580C LDR R1, =dword_0_10007E9C ; Load from Memory <--- Stupid String
.text:10005810 BL loc_0_10005B48 ; Branch with Link


As you see from the code snip there are three conditional branches to avoid that
the string is loaded. I marked them with <<<<<<<. For me it seems that the prog is
testing if we registered it and if not it loads the string "unregistered".

Now we are on the move: It is clear that we have to examine the BL's before the
branches. Why? I'll explain the code:


.text:100057BC BL sub_0_1000538C ; Branch with Link

A branch (call) to another function. (BL's always return back to the next instruction)
Also they may give results in one or more of the registers back.

.text:100057C0 CMP R0, #0 ; Set cond. codes on Op1 - Op2

The register R0 is compared with 0 (null).

.text:100057C4 BNE loc_0_100058B0 ; Branch if not equal

If R0 is not 0 the branch is taken, if R0 is 0 nothing happens.



So we have to ensure that the result from the functions call (BL) is not 0. Then the
branch is taken and we have a registered prog.

If you are with me you will now have a good question! Which of the three branches with
the BL's before the string we will exam?
In reality you will have to exam all three and look at the code. But I will just
explain the first, because that's the right one...

OK. Let's start with the one at .text:100057C4! Right click on BL sub_0_1000538C,
choose jump immediate and you will see that:



.text:1000538C ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:1000538C
.text:1000538C sub_0_1000538C ; CODE XREF: sub_0_100003F8+480p
.text:1000538C ; sub_0_100050CC+188p ...
.text:1000538C STMFD SP!, {R4,LR} ; Store Block to Memory
.text:10005390 SUB SP, SP, #8 ; Rd = Op1 - Op2
.text:10005394 MOV R4, R0 ; Rd = Op2
.text:10005398 LDR R3, [R4,#0xF8] ; Load from Memory
.text:1000539C CMP R3, #0 ; Set cond. codes on Op1 - Op2
.text:100053A0 BEQ loc_0_100053C4 ; Branch
.text:100053A4 MOV R0, SP ; Rd = Op2
.text:100053A8 LDR R1, =dword_0_10007D64 ; Load from Memory
.text:100053AC BL loc_0_10005B48 ; Branch with Link
.text:100053B0 MOV R0, R4 ; Rd = Op2
.text:100053B4 MOV R1, SP ; Rd = Op2
.text:100053B8 BL loc_0_10005C48 ; Branch with Link
.text:100053BC CMP R0, #0 ; Set cond. codes on Op1 - Op2
.text:100053C0 BNE loc_0_100053D0 ; Branch
.text:100053C4
.text:100053C4 loc_0_100053C4 ; CODE XREF: sub_0_1000538C+14j
.text:100053C4 MOV R0, #0 ; Rd = Op2
.text:100053C8 B loc_0_100053EC ; Branch
.text:100053C8 ; ---------------------------------------------------------------------------
.text:100053CC off_0_100053CC DCD dword_0_10007D64 ; DATA XREF: sub_0_1000538C+1Cr
.text:100053D0 ; ---------------------------------------------------------------------------
.text:100053D0
.text:100053D0 loc_0_100053D0 ; CODE XREF: sub_0_1000538C+34j
.text:100053D0 MOV R0, R4 ; Rd = Op2
.text:100053D4 MOV R1, R4 ; Rd = Op2
.text:100053D8 BL sub_0_100050CC ; Branch with Link
.text:100053DC LDR R3, [R4,#0xF8] ; Load from Memory
.text:100053E0 CMP R0, R3 ; Set cond. codes on Op1 - Op2
.text:100053E4 MOVNE R0, #0 ; Rd = Op2
.text:100053E8 MOVEQ R0, #1 ; Rd = Op2
.text:100053EC
.text:100053EC loc_0_100053EC ; CODE XREF: sub_0_1000538C+3Cj
.text:100053EC ADD SP, SP, #8 ; Rd = Op1 + Op2
.text:100053F0 LDMFD SP!, {R4,LR} ; Load Block from Memory
.text:100053F4 BX LR ; Branch to/from Thumb mode


This is our function. Here it is decided if the prog is registered or not. Also there
are several Code XREFs in the first line which means that this function can be or is
called more than once.

Now remember: 0 is not registered, not equal 0 is registered. So lets see when another
number then 0 is put in register R0. Found it?

.text:100053E8 MOVEQ R0, #1 ; move if equal

If the cmp instruction before this move is equal a 1 is put in R0.


But we have also two instructions where 0 is put in R0.

.text:100053C4 MOV R0, #0 ; move
.text:100053E4 MOVNE R0, #0 ; move if not equal


What should we do? When you look at the code flow you'll also notice that there are two
way's to get to the end. One is over this location

.text:100053C4 loc_0_100053C4 ; CODE XREF: sub_0_1000538C+14j


the other over this

.text:100053D0 loc_0_100053D0 ; CODE XREF: sub_0_1000538C+34j


It is decided on runtime which way to get. One is always taken!! The other not!! And we
can't decide what the prog does here. So let's make up our mind and think, think, think!

We need a strait way to the end and also there has to be a 1 in register R0. Let's do it
this way:

Change

.text:100053A0 BEQ loc_0_100053C4 ; Branch if equal

to

.text:100053A0 B loc_0_100053C4 ; Branch always

so that this branch is always taken. And change

.text:100053C4 MOV R0, #0 ; R0 = 0

to

.text:100053C4 MOV R0, #1 ; R0 = 1

so that 1 is moved into register R0!


The flow of our code would now be

.text:1000538C ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:1000538C
.text:1000538C
.text:1000538C sub_0_1000538C ; CODE XREF: sub_0_100003F8+480p
.text:1000538C ; sub_0_100050C8+18Cp ...
.text:1000538C STMFD SP!, {R4,LR} ;
.text:10005390 SUB SP, SP, #8 ;
.text:10005394 MOV R4, R0 ;
.text:10005398 LDR R3, [R4,#0xF8] ;
.text:1000539C CMP R3, #0 ;
.text:100053A0 B loc_0_100053C4 ; Branch always <<<<<<< Changed
.text:100053A4 ; ---------------------------------------------------------------------------
.text:100053A4 MOV R0, SP ; .............All
.text:100053A8 LDR R1, =dword_0_10007D64 ; .......these
.text:100053AC BL loc_0_10005B48 ; .............instructions
.text:100053B0 MOV R0, R4 ; .............are
.text:100053B4 MOV R1, SP ; .............never
.text:100053B8 BL loc_0_10005C48 ; .............executed!!!
.text:100053BC CMP R0, #0 ; .............
.text:100053C0 BNE loc_0_100053D0 ; .............
.text:100053C4
.text:100053C4 loc_0_100053C4 ; CODE XREF: sub_0_1000538C+14j
.text:100053C4 MOV R0, #1 ; move R0 = 1 <<<<<<<< Changed
.text:100053C8 B loc_0_100053EC ;
.text:100053C8 ; ---------------------------------------------------------------------------
.text:100053CC off_0_100053CC DCD dword_0_10007D64 ; DATA XREF: sub_0_1000538C+1Cr
.text:100053D0 ; ---------------------------------------------------------------------------
.text:100053D0
.text:100053D0 loc_0_100053D0 ; CODE XREF: sub_0_1000538C+34j
.text:100053D0 MOV R0, R4 ; .............
.text:100053D4 MOV R1, R4 ; .............
.text:100053D8 BL loc_0_100050CC ; .............These
.text:100053DC LDR R3, [R4,#0xF8] ; .............also!
.text:100053E0 CMP R0, R3 ; .............
.text:100053E4 MOVNE R0, #0 ; .............
.text:100053E8 MOVEQ R0, #1 ; .............
.text:100053EC
.text:100053EC loc_0_100053EC ; CODE XREF: sub_0_1000538C+3Cj
.text:100053EC ADD SP, SP, #8 ;
.text:100053F0 LDMFD SP!, {R4,LR} ;
.text:100053F4 BX LR ; back



We are nearly finished to crack this one! We have decided what to change. Now write the
offsets from the two instructions down.
The first one (branch) is at 0x541C, the second (move) is at 0x5440.

Go to the Hex Editor and look at the first offset:

0000541C 07 00 00 0A ã.... <<< this is the branch if equal instruction

change 0A to EA

0000541C 07 00 00 EA ã...ê <<< this means branch always


The second instruction we have to change is at

00005440 00 00 A0 E3 .. ã <<< move R0, 0

change first 00 to 01

00005440 01 00 A0 E3 .. ã <<< move R0, 1


YeaaHH! We got it!!!!!
Send the file to your phone and you have a registered Stacker!!!


Conclusion:
-----------
Not as easy as you and I thought?? I'm really surprised how long this tut has become.
And I feel a little bit uncertain. Did you understand all things? All clear?

Hope so! Please msg me if not!

Believe me, this was one of the easiest targets you'll find in your career..

Enjoy your work and search for the next target!!!


regards
atzplzw

http://www.ka0s.net

Закрыто

Вернуться в «Symbian Series 90, Series 80, Series 60, Symbian UIQ»