Autor


Pluto
  Jak na systémové patche
Vydáno dne:  18.5.2004
Průměrné hodnocení:  
1111.21.21.21.41.41.41.61.61.61.81.81.82222.22.22.22.42.42.42.62.62.62.82.82.83333.23.23.2   3.2 (hodnoceno 88x)
1111.21.21.21.41.41.41.61.61.61.81.81.82222.22.22.22.42.42.42.62.62.62.82.82.83333.23.23.2
 
návod

Výroba systémových patchů je především určena pro zkušenější uživatele. Jaké postupy a co je potřeba se dozvíme z následujícího návodu.

Používání níže uvedených postupů či programů není v souladu se záručními podmínkami výrobce telefonu. Jejich používáním se vystavujete riziku neuznání záruky na přístroj v případě jeho poškození.

Tento článek není vyčerpávajícím popisem programátorských metod ani návodem pro úplné začátečníky. Je pouze lehkým úvodem do poměrně komplikované problematiky tvorby patchů pro telefony Siemens. Zaměříme se zejména na telefony MC60, M55, C60 a S55, které jsou si z hlediska programování dost podobné.

Pokusíme se vytvořit jednoduchý patch, který zobrazí na display telefonu ikonku s textem. Budeme postupovat v jednotlivých krocích které podrobně rozebereme.

Co budeme potřebovat:

 V_Klay     
Stáhnout
 FuBu - Full Backup, neboli zálohu paměti telefonu. Nejlépe vytvořenou vKlayem     
Stáhnout
 WinHex - editor (pro naše účely spíš prohlížeč) obsahu paměti     
Otevřít v novém okně
 Smelter- slouží k získání řady informací o obsahu paměti telefonu     
Stáhnout
 PSPad - vhodný textový editor     
Otevřít v novém okně
 Instruction Set Manual - příručka firmy Infineon, výrobce procesoru C166     
Otevřít v novém okně


Nejprve je dobré mít jasno v tom, jak se vlastně prohánějí data v telefonu. Vše řídí 16ti bitový procesor C166 navržený firmou Infineon. Tento procesor je postavený na RISCové technologii. Z toho plyne, že instrukční sada obsahuje příkazy s pevnou délkou 2 nebo 4 Byte. Telefony obsahují celkem 16 MByte paměti, z toho první 2MB jsou RAM (u S55 4MB). Záloha paměti vytvořená vKlayem data z RAM neobsahuje, proto má pouze 14 MB (12MB u S55). Ostatně, vzhledem k tomu že se pořizuje při 'vypnutém' telefonu, nelze čekat že by se v RAM co zajímavého mohlo při zálohování nacházet. Jelikož je FuBu kratší o zmíněné 2MB (4MB u S55), neodpovídají adresy jednotlivých byte v paměti a ve FuBu. Jsou posunuty o 2MB (4MB u S55), takže např. adresa 600000h ve FuBu je defacto 800000h v telefonu (v případě S55 je to adresa A00000h). Na tento posun budeme občas narážet, ale pokud nebude uvedeno jinak, budeme udávat adresu ve FuBu. S tou pracují i aplikace vKlay a Smelter. Při psaní kódu v assembleru s posunem musíme počítat, pro veškeré adresování je samozřejmě směrodatná fyzická paměť telefonu. Opomenutí posunu je jednou z nejčastějších chyb. Taková chyba se projevují téměř bez výjimky vždy stejně - pádem systému telefonu. To ale nebývá velkým problémem, obvykle stačí patch odstranit, opravit a znovu použít. Telefon se i z častých pádů při ladění vzpamatovává zpravidla bez následků. Pro krátkodobé uchování dat slouží šestnáct šestnáctibitových registrů r0 až r15.

Rozložení obsahu paměti:



Telefony mají pasivní display disponující rozlišením 101x80 pixelů s 12ti bitovou barevnou hloubkou (S55 8mi bitovou), což odpovídá 4096ti možným barvám (256ti u S55). Telefon pracuje s obrázky 1, 2, 8 a 16ti bitovými a před zobrazením je konvertuje na patřičnou barevnou hloubku. U 8mi bitových obrázků (tj. 256 barev) se používá standardní Siemens barevná paleta.
Obrázky se ukládají v paměti na vyhrazené místo (MC60 - od adresy 204000h, C60 - od adresy 700000h, atd., viz. obrázek rozložení obsahu paměti). Zároveň existuje PIT, tj. Picture Index Table, neboli tabulka s odkazy na jednotlivé obrázky a s informací o velikosti, počtu barev, komprimaci a místě uložení obrázku. PIT je poměrně důležitá tabulka (u MC60 je od adresy 23C000h, u C60 od 75A974h, atd.), rutiny v systému se totiž neodkazují přímo na obrázky, ale přistupují k nim na základě dat právě v PIT. Což má obrovskou výhodu spočívající v tom, že obrázky můžeme modifikovat nejen obsahově, ale můžeme měnit i jejich velikost, barevnou hloubku nebo umístění v paměti a systém s nimi dál nerušeně dělá 'jako by byly jeho vlastní'.

Pro účely našeho patchu si vytvoříme obrázek, který zapíšeme do paměti telefonu namísto jiného nepoužívaného. Náš obrázek bude dvoubarevný, o rozměrech 48x9 pixelů. Správný programátor tvoří obrázek tak, že si jej načrtne na čtverečkový papír a následně z hlavy vypočítá jednotlivé bajty. Papír se potom musí válet nejméně půl roku na stole vedle monitoru spolu s velkým množstvím dalších podobných pokladů :-)


Pro dvoubarevný obrázek si vystačíme s každým byte pro osm pixelů obrázku. Velikost obrázku bude (48*9)/8 = 54 Byte.
Musíme tedy ve Smelteru najít nějaký nepoužívaný obrázek který má velikost 54 bytů nebo větší. U MC60 se nabízí např. obrázek s ID 179 velikosti 68byte (nějaká pruhovaná kočka na kolečkách), který jsem nikdy na display telefonu neviděl a předpokládám že ani neuvidím. Stejný obrázek má v C60 ID 198, v M55 ID 261 a v S55 ID 226. Pracovně mu pro zjednodušení říkejme obrázek 179. Obrázek 179 tedy použijeme pro naše účely - předěláme ho na náš nápis SIEMENSMANIA.



Výpočtem ze čtverečkovaného papíru jsme získali následující data reprezentující dvoubarevný (tedy pouze černá/bílá) orámovaný nápis SIEMENSMANIA:

FF FF FF FF FF FF
80 00 00 00 00 01
BA EA EA E5 25 49
A2 8E 8A 87 55 55
BA CE CE E7 57 55
8A 8A 8E 25 77 5D
BA EA EA E5 55 55
80 00 00 00 00 01
FF FF FF FF FF FF

Tato data seskupíme po 16ti:

FFFFFFFFFFFF800000000001BAEAEAE5
2549A28E8A875555BACECEE757558A8A
8E25775DBAEAEAE55555800000000001
FFFFFFFFFFFF

Ze Smelteru zjistíme, že data původního obrázku v MC60 začínají na adrese 222C96h (sloupec Offset). V C60 je to adresa 737CAAh, M55 27BF7Eh a v S55 adresa 04FF72h. Otevřeme si FuBu WinHexem a najdeme zmíněnou adresu (u registrované verze WinHexu stačí ve Smelteru dvojkliknout na řádku reprezentující obrázek a WinHex otevře FuBu automaticky + data obrázku označí).



Z WinHexu zkopírujeme 54 hexa hodnot původního obrázku (označíme a stiskneme CTRL+SHIFT+C). Data srovnáme v editoru opět po 16ti před našich 56 hodnot. Před každou řádku navíc přidáme adresu začátku, postupně zvyšovanou pro každý řádek po 16ti (resp. po 010h).
Výsledek by měl vypadat takto:

222C96: 0000001F01F8001F0664001F0D64001F FFFFFFFFFFFF800000000001BAEAEAE5
222CA6: 1D6800DF2C67FF5F6F66665F6E66665F 2549A28E8A875555BACECEE757558A8A
222CB6: 7A66669F027E7C9F0162629F0141411F 8E25775DBAEAEAE55555800000000001
222CC6: 00C9C91F0041 FFFFFFFFFFFF
Zároveň najdeme WinHexem PIT záznam obrázku, který je podle Smelteru na adrese 23C598h (MC60).



Původní obrázek měl rozměry 27x17 (01Bh x 011h). Náš má velikost 48x9 (030h x 09h). Upravíme proto tabulku PIT následujícím způsobem:

23C598: 1B11 3009

Získané části dáme dohromady, okomentujeme a máme grafickou část patche, která změní obrázek číslo 179.

; **** verze MC60 ****
; *** Obrazek 179 ***
; Picture Index Table (PIT)
23C598: 1B11 3009

; Picture Data
222C96: 0000001F01F8001F0664001F0D64001F FFFFFFFFFFFF800000000001BAEAEAE5
222CA6: 1D6800DF2C67FF5F6F66665F6E66665F 2549A28E8A875555BACECEE757558A8A
222CB6: 7A66669F027E7C9F0162629F0141411F 8E25775DBAEAEAE55555800000000001
222CC6: 00C9C91F0041 FFFFFFFFFFFF

Vytvoříme si kopii FuBu a vKlayem do ni zapíšeme náš patch. Kopii FuBu potom otevřeme Smelterem a na místě obrázku 179 by jsme měli najít náš nápis SIEMENSMANIA. Pokud by telefon obrázek pruhované kočky používal, nyní by byla nahrazena naším nápisem a telefon by s tím neměl žádnou potíž.

Nastal čas pro nalezení vhodného místa v paměti telefonu, kam umístíme systémovou část patchu. Volná místa se poznají podle souvislého bloku nul nebo FFh. Takových míst je v telefonu poměrně dost, takže je z čeho vybírat. Musíme dát pozor, aby jsme patch neumístili do části vyhrazené pro souborová data nebo na místo které používá některý jiný patch. Souborová data a EEPROM začínají u MC60 od adresy B00000h (viz. mapa paměti). Pokud by jsme umístili patch za tuto adresu, mohlo by snadno dojít ke kolizi se soubory na virtuálních discích telefonu nebo s jinými daty. Stejně tak pokud by jsme použili místo které používá jiný patch, způsobíme, že jej později nepůjde vKlayem zapsat bez toho aby jsme přepsali náš patch. Ale vzhledem k tomu, že nemůžeme predikovat, jaké adresy použijí ostatní tvůrci patchů v budoucnu, jsou možnosti nalezení ideálního místa poněkud omezené. Riziko, že vznikne kolize s jiným patchem je tady vždy. V takovém případě si potom uživatel bude muset zvolit jestli chce použít náš skvělý, nebo cizí, mnohem horší, patch :)

Při průzkumu FuBu WinHexem vidíme, že pěkné volné místo obsahující blok bytů 0FFh v M60 je například na adrese 477132h. Není známý žádný existující patch který by je používal, takže si zde vyhradíme několik desítek bajtů pro sebe. Systémová část našeho patchu tedy bude začínat na adrese 477132h (vKlay), resp. fyzicky v telefonu na adrese 677132h.

Nyní nastává slavnostní okamžik - začneme psát kód samotného patche. Předtím si však ještě ujasněme co od něj očekáváme. Patch musí vzít obrázek číslo 179, umístit jej na display do stanovených souřadnic a vrátit řízení systému telefonu. To je vše co od něj nyní budeme chtít.
Systém telefonu obsahuje nepřeberné množství subrutin s rozličnými funkcemi. Voláním těchto rutin si můžeme výrazně usnadnit práci. Problém ale spočívá v tom, že nevíme kde jaké rutiny jsou, jaká vyžadují vstupní data a eventuelně taky co vlastně dělají. Pro tvorbu patchů jsou přitom tyto informace velmi důležité. Cest, jak se dostat alespoň k některým z nich je několik. Asi nejefektivnější je nahlédnout do dokumentace k systému telefonu. Bohužel tuto možnost mají pravděpodobně pouze programátoři od Siemense. Další relativně bezbolestnou možností je disassemblovat již existující patche, které by mohly obsahovat funkcionalitu jež nás zajímá. Takto se jde dostat k velkému množství informací, které po nocích lovili v telefonu ostatní patcheři. Snadno tak najdeme adresy a vstupní parametry rutin pro pípnutí, zavibrování, zobrazování čehokoliv, vyvolání info okýnek, atd. Další metodou jak ke kýženým informacím přijít je, zařadit se po bok ostatních patcherů badatelů a začít v disassembleru louskat různé části paměti telefonu. Je to dřina s nejistým výsledkem, ale zato s možností najít něco zcela nového, dosud neopatchovaného :)

Pro začátek doporučuji spokojit se s dolováním informací z exitujících patchů. Takto můžeme objevit velmi oblíbenou rutinu které říkejme třeba ShowIcon. Tato rutina vyzvedne podle ID obrázek přes PIT, v případě potřeby jej dekomprimuje, barevně upraví pro 4096 barev (u S55 pro 256) a umístí na display do definovaných souřadnic. Tuto rutinu používá téměř každý patch který něco zobrazuje, není tedy ani těžké vystopovat, že vstupní parametry jsou ID obrázku v registru r14, X-ová souřadnice na display v registru r12 a Y-ová v registru r13. Souřadnice [0, 0] jsou v levém horním rohu displeje. ShowIcon je tedy přesně to co potřebujeme. S jejím pomocí se vyhneme dost náročnému zápisu přímo do VideoRAM telefonu. U MC60 FW10 se ShowIcon nachází fyzicky na adrese 2DE676h (resp. 0DE676h ve FuBu). Na firmware upozorňuji proto, že adresy rutin můžou (a s dost velkou pravděpodobností také budou) u každé verze firmware jiné. To je důvod, proč pro různé verze není možné použít tytéž patche bez úprav.

Pojďme na assembler. V příručce Instruction Set Manual jsou výborně popsány všechny instrukce procesoru C166 včetně jejich hexa kódu. Instrukční sada procesoru je poměrně jednoduchá, má omezenou množinu instrukcí pevné délky a pro ty kdo se někdy zabývali programováním neRISCovýc procesorů je přímo radost s C166 pracovat.
Pro naše účely si vystačíme s instrukcemi CALLS addr - zavolá subrutinu na dané adrese, MOV op1, op2 - přiřadí do operandu č. 1 hodnotu operandu 2. RETS - ukončení subrutiny, návrat a přechod na instrukci následující po instrukci kterou byla tato rutina volána.

Náš patch bude vypadat takto:

DA2D76E6 CALLS 2DE676 ; zavoláme ShowIcon
E6FC1A00 MOV r12, #001A ; umístění obrázku, osa X = 26 (01Ah)
E0CD MOV r13, #C ; umístění obrázku, osa Y = 12 (0Ch)
E6FEB300 MOV r14, #00B3 ; ID obrázku = 179 (0B3h)
DA2D76E6 CALLS 2DE676 ; zavoláme ShowIcon
DB00 RETS ; konec subrutiny, návrat

První řádek volá subrutinu ShowIcon. Důvod proč začínáme právě touto instrukcí si nechejme na později. Souvisí s voláním naší subrutiny, ke kterému se ještě dostaneme.
Na druhé řádce je první vstupní parametr - X-ová pozice obrázku na display, předaná rutině ShowIcon prostřednictvím registru r12. Kód instrukce MOV pro přiřazení 16ti bitové hodnoty registru je E6. Označení registru je F následované číslem registru. Pro r12 je to tedy FC. Vyšší a nižší byte přiřazované hodnoty jsou přehozeny. Proto je hexa kód celé instrukce E6FC1A00.
Třetí řádek funguje stejně jako řádek 2, jen s tím rozdílem, že hodnota kterou registru přiřazujeme je vyjádřitelná 4mi bity a proto můžeme použít kratší zápis instrukce MOV - identifikace instrukce E0 a hodnota C přiřazena registru r13, neboli C. Výsledkem je E0CD.
Čtvrtý řádek obsahuje ID obrázku, zápis je identický s instrukcí MOV na druhém řádku.
Pátý řádek - voláme subrutinu ShowIcon, která zajistí zobrazení obrázku č. 179. Kód instrukce CALLS je DA, 2D označuje segment v paměti, poslední dva byty potom nižší a vyšší byte adresy (pozor, stejně jako u všech 16ti bitových čísel přehozeno!). Výsledkem je tedy kód DA2D76E6.
Poslední řádka obsahuje pouze instrukci pro ukončení subrutiny a návrat.

Mohli by jsme se na tomto místě samozřejmě rozšoupnout a s použitím několika dalších instrukcí zařídit aby se nápis zobrazoval jenom při zamknuté klávesnici, při vybité baterce, nebo třeba při ztrátě signálu - to by byla obzvláštní lahůdka, vzpomeňme že po zavolání patche máme v registru r14 číslo obrázku který se má zobrazit coby reprezentant aktuální síly signálu na display. Pro naše účely však plně postačí i jednoduchý kód který nebude dohromady nic velkého dělat - ve vylepšování můžeme ostatně pokračovat jakmile patch uchodíme ve stávající jednoduché podobě.

Po použití adresy začátku kódu a původních hodnot v paměti tedy můžeme přerovnáním sestavit další část patche:

477132: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF DA2D76E6E6FC1A00E0CDE6FEB300DA2D
477142: FFFFFFFF 76E6DB00

Teď nám ještě zbývá zajistit volání naší rutiny. K tomu vyžijeme malého triku. Telefon je plný instrukcí pro volání rozmanitých subrutin. Existuje pochopitelně také několik volání rutiny ShowIcon, kterou telefon používá, stejně jako my, k zobrazení ikonek na display. Pokusíme se najít místa kde tato volání telefon provádí, jedno z nich si vybereme a změníme je na volání naší rutiny. Telefon tedy nebude volat ShowIcon jako dosud, ale náš patch. Aby o volání ShowIcon a tedy o plánované zobrazení ikony nepřišel, jako první instrukci v našem patchi ShowIcon zavoláme. Tím se realizuje zobrazení ikony ale návrat ze ShowIcon není zpět do systému ale do našeho patche. Do systému vrátíme běh programu až instrukcí RETS. Mezitím může proběhnout celý kód patche.
Jak tedy najít místo, kde systém volá ShowIcon? Ve WinHexu použijeme funkci Find Hex Values, které zadáme hledat všechny funkce CALLS ShowIcon, neboli 'DA2D76E6' (MC60). Najde jich postupně řekněme zhruba tak deset. Některé zajišťují zobrazení ikony baterky, signálu, systémových ikonek v levém dolním rohu displeje (příchozí SMS, MMS, zmeškaný hovor, budík, atd.), ikonku GPRS, klíče, zvonku,... Pro naše účely si nyní zvolíme třeba ikonku signálu. Pokud bude na display zobrazen signál, budeme chtít aby byl zobrazen také naším patchem obrázek 179. Které z nalezených volání ShowIcon je tedy to pravé? Můžeme na věc jít několika způsoby. Složitější, ale spolehlivá metoda je vKlayem v telefonu postupně u jednotlivých nalezených volání přepsat 'DA2D76E6' kódem 'CC00CC00'. CC00 je šestnáctibitová instrukce NOP, která nechá proběhnout procesor bez jakékoliv akce. Pokud nahradíme CALLS ShowIcon dvěma instrukcemi NOP, procesor tímto místem proběhne aniž by ShowIcon zavolal. Dostaneme tak vizuální efekt - něco se na display nezobrazí. Pokud se nezobrazí ikona signálu která se před naší úpravou normálně zobrazovala, máme místo které hledáme. Tato metoda pokus-omyl je ale poměrně zdlouhavá a můžeme při ní snadno omylem něco přehlédnout. Často bývá snazší omrknout okolí instrukcí CALLS ShowIcon. Stejně jako my v našem patchi před jejím voláním nastavujeme vstupní parametry, dělá totéž i systém. Není proto velkým překvapením, když několik bytů před CALLS vidíme v hexa instrukci E6xxxxxx nebo E0xx. Z nich si můžeme vyčíst ID obrázku nebo souřadnici a podle toho udělat závěr jestli jde o volání které nás zajímá, nebo jestli 'jsme jinde'. Toto hledání je poněkud nezáživné, ale do budoucna nás můžou zajímat všechna tato volání, takže není od věci analyzovat co které vlastně dělá, i když je teď právě nepotřebujeme.
Je jen otázkou času (spíše krátkého), kdy objevíme volání na adrese 0DE900h (MC60 FW10). O několik byte dřív je sekvence E0 0C E0 0D - neboli nastavení os X i Y na 0 (E0 0C = MOV r12, 0; E0 0D = MOV r13, 0). V pozici 0, 0 je na display právě ukazatel signálu. Nabízí se otázka co by se asi stalo, kdyby jsme tyto vstupní parametry změnili. Ano, jak asi tušíte, přepíšeme-li např. E00D na E0AD, posuneme na telefonu ukazatel signálu o deset pixelů dolů.

Nyní můžeme napsat další řádek patche, který změní na adrese 0DE900h volání ShowIcon na volání začátku patche:

0DE900: DA2D76E6 DA673271

Tím máme pohromadě vše co pro fungování patche potřebujeme. Můžeme tedy sestavit jeho finální podobu:



A jak o celé bude vypadat na display? Pokud se vše podařilo, po nainstalování patche a zapnutí telefonu uvidíme přibližně toto:



Přestože je celý postup popsaný podle firmware 10 pro MC60, neměl by být velký problém aplikovat poznatky na jiné verze firmware nebo na jiné telefony. Obecné postupy se můžou a nemusí lišit, v závislosti na fantazii a schopnostech patchera. Každý si najde svoje metody a cestičky vedoucí, nebo někdy bohužel taky nevedoucí k cíli.

Souhrn významných bodů z článku, potřebných pro vytvoření variace patche pro další telefony a jiné verze FW:

MC60 FW10:
ID kočky: 179
adresa záznamu v PIT: 23C598h
adresa obrázku v paměti: 222C96h
vhodné místo v paměti pro umístění patche: 477132h
adresa rutiny ShowIcon: 0DE676h
volání ShowIcon systémem pro zobrazení ikony signálu: 0DE900h

MC60 FW7:
ID kočky: 179
adresa záznamu v PIT: 23C598h
adresa obrázku v paměti: 222C96h
vhodné místo v paměti pro umístění patche: 47731Ch
adresa rutiny ShowIcon: 0DE1EAh
volání ShowIcon systémem pro zobrazení ikony signálu: 0DE474h

C60 FW14:
ID kočky: 198
adresa záznamu v PIT: 75AFA4h
adresa obrázku v paměti: 737CAAh
vhodné místo v paměti pro umístění patche: 442000h
adresa rutiny ShowIcon: 2C09D2h
volání ShowIcon systémem pro zobrazení ikony signálu: 2C0BBAh

M55 FW11:
ID kočky: 261
adresa záznamu v PIT: 308828h
adresa obrázku v paměti: 27BF7Eh
vhodné místo v paměti pro umístění patche: 48F000h
adresa rutiny ShowIcon: 0DD2B2h
volání ShowIcon systémem pro zobrazení ikony signálu: 0DD530Ch

S55 FW20:
ID kočky: 226
adresa záznamu v PIT: 0CC710h
adresa obrázku v paměti: 04FF72h
vhodné místo v paměti pro umístění patche: 21E300h
adresa rutiny ShowIcon: 32C316h
volání ShowIcon systémem pro zobrazení ikony signálu: 32C5BAh

Nikdo nesmí bez souhlasu autorů kopírovat grafiku, texty ani cokoliv jiného z těchto stránek. Veškeré informace uveřejněné na těchto stránkách jsou určené pouze pro vzdělávací účely a nesmí být použity pro komerční využití nebo v rozporu se zákony. Autoři nenesou zodpovědnost za nevhodné použití dat z těchto stránek.
   ©2003-2004 Radim Zeman | ©2004 Roman Gregor