Jump to content


Photo

Tworzenie skryptów ASM


  • Please log in to reply
No replies to this topic

#1 OFFLINE   mc_kibel

mc_kibel

    Proud Member of Sony.yt Community

  • User
  • 26 posts
    • Time Online: 1h 1m

Posted 28 October 2011 - 21:13

Jest to kontynuacja tematu "Otwieranie maina w IDA" - druga część poradnika dotyczącego zaawansowanego portowania patchy.

1. Mając otwarty main, dla którego istnieje patch, musimy go wgrać we właśnie ten firmware w programie IDA - używając skryptów IDC (kierunek: FAQ w dziale developerskim). Osobiście maina spatchuję patchem "Show MegaBass image when Bass EQ is selected", przeznaczonym dla K770i R8BA024. Nie pamiętam już, czy pisałem o tym wcześniej, czy nie - ale jeśli nie pisałem, to zaopatrzcie się w main K770i R8BA024 i K770i R8BC004 oraz ściągnijcie patch z załącznika - przećwiczcie najpierw na tym samym przykładzie, co ja.

2.
  • Rozpakowujemy archiwum IDC
  • W IDA klikamy File > IDC File.
  • Wybieramy plik ApplyPatch.idc.
  • W nowym oknie wybieramy plik patcha dla otwartego softa.
  • Wyskoczy okienko, w którym klikamy YES.
    - Jeśli wyskoczy więcej okienek, oznacza to mismatch. Przerywamy operację, klikając NO.
Ok, jeśli mismatch nie wyskoczył, to main mamy spatchowany :)

3. No więc musimy stworzyć skrypt ASM naszego patcha. Jeśli już mamy dzielić patche na jakieś rodzaje, to są dwa: z bazą i bez. Patche z bazą rozpoznajemy po +xxxxxxxx (gdzie zamiast x są dowolne liczby) występującym zaraz po komentarzach w patchu (lub gdy ich nie ma na samym początku). Nasz patch z załącznika posiada bazę - przez co mamy minimalnie więcej roboty - ale ten przykład jest wybrany specjalnie :P Później z patchami bez bazy poradzicie sobie bez problemu.

4. Otwieramy nasz patch z załącznika. Pierwszy offset to F2E578, a baza patcha +44140000. Więc: Menu start > wszystkie programy > akcesoria > kalkulator > widok > naukowy > zaznaczamy kropkę przy HEX.
Teraz kopiujemy pierwszy offset, dodajemy do niego bazę patcha. Otrzymujemy: 4506E578.
* gdy patch nie ma bazy, to nic nie dodajemy - po prostu kopiujemy offset i tyle :P

5. W IDA klikamy "G" i wklejamy otrzymane "4506E578". Teraz wciskamy ALT+G, a w polu VALUE (gdzie domyślnie mamy ROM) wpisujemy 1 po czym klikamy enter.

6. No i naciskamy "C"...

7. Widzimy
ROM:4506E578 00 49 LDR  R1, off_4506E57C
ROM:4506E57A 08 47 BX   R1
ROM:4506E57A	 ; ---------------------------------------------------------------------------
ROM:4506E57C 65 94 D1 45 off_4506E57C DCD loc_45D19464+1		; DATA XREF: ROM:4506E578r


8. Trzeba będzie więc wpisać to w ASM. Ok, teraz krótka i tania lekcja podrywu o tajemniczej nazwie "Po czym poznać ile tego 'czegoś' trzeba wpisać w plik ASM?" Krótko mówiąc...
Początek patcha:
+44140000
F2E578: F1B5041C051C1430 004908476594D145

Interesują nas tylko nowe wartości, czyli: 004908476594D145 (jeśli nie wiesz skąd to wziąłem, to cofnij się stronkę wcześniej i zerknij w temacik 'Struktura pliku VKP'). Dobra, liczymy ile to znaków :bigyellowgrin: 1,2,3..... o, 16 ! Dzielimy na dwa i mamy 8 :bigyellowgrin:
Pozwolicię, że pokażę screen z IDA. Podzielmy sobie to na poszczególne kolumny.

Posted Image
No więc... jest 8 wartości (czyli tyle, ile sobie policzyliśmy, że jest w patchu) ? Odpowiem za was - jest :) Gdy IDA do kodu skonwertuje mniej (Offsety skonwertowane do kodu są bordowe, czarne lub szare, nieskonwertowane - żółte. To ważne! ) to schodzimy na następny żółty adres i znowu wciskamy "C". Gdy skonwertuje do kodu więcej - nie przejmujemy się i wpisujemy tylko tyle ile potrzeba. U mnie skonwertowała dokładnie tyle, ile nam było potrzebne.

9. Dobra, od tych pięciu minut które wykonujecie punkt ósmy nie zmieniło się nic (no, może wiecie trochę więcej :) ) - w IDA dalej widzimy to co w punkcie siódmym. Trzeba więc wpisać to do pliku ASM:
  • Otwieramy notatnik
  • Na samym początku wpisujemy: include "x.inc"
i w końcu jedziemy z tym skryptem :P
Po dodaniu bazy do pierwszego offseta (punkt 4) otrzymaliśmy ten adres: 4506E578. Trzeba więc zdefiniować go w pliku.
  • Pod include "x.inc" wpisujemy: hook1 equ 0x4506E578
  • hook1 jest tutaj nazwą (której będziemy używać dalej), equ znaczy tyle co 'jest równe', a 0x4506E578 to nasz otrzymany adres, poprzedzony kombinacją '0x'.
Teraz, w adresie 'hook1' będziemy wpisywać instrukcje z trzeciej kolumny na screenie, czyli poniżej hook1 equ.... dodajemy:
org hook1
LDR	R1, off_4506E57C
BX	 R1
off_4506E57C	DCD loc_45D19464+1


org hook1 oznacza, że instrukcje występują właśnie pod adresem zdefiniowanym jako 'hook1'. Cała reszta niżej to instrukcje.
Widzimy tam jakieś off_ , jakieś loc_ , które już pewnie zdążyło was zmylić - to, że występują tam cyferki, nic nie znaczy. 'Adresy' (a właściwie nie adresy, bardziej ciągi znaków) poprzedzone takimi rzeczami jak loc_ , sub_ , locret_ , off_ , dword_ , pełnią rolę TYLKO I WYŁĄCZNIE NAZW!. Nie portujemy ich - to są nazwy, które będą używane później w skrypcie.

10. To samo robimy z drugim offsetem - dam wam pole do popisu i nie będę tłumaczył jeszcze raz tego samego co w punkcie 9. Powiem tylko, że nowy adres należy zdefiniować zaraz pod hook1 equ 0x.... , jako np. hook2.

11. Tak więc powiem rzeczy oczywiste, które wynikły w punkcie dziesiątym. :bigyellowgrin: Otrzymaliśmy adres '4507F0EE', który zdefiniowaliśmy w ten sposób: hook2 equ 0x4507F0EE i do ASM dodaliśmy:
org hook2
LDR	R2, off_4507F0F4
BX	 R2
DCB 0xFF
DCB 0xFF
off_4507F0F4	DCD loc_45D194AC+1


Nasz ASM wygląda tak:
include "x.inc"
hook1 equ 0x4506E578
hook2 equ 0x4507F0EE
org hook1
LDR	R1, off_4506E57C
BX	 R1
off_4506E57C	DCD loc_45D19464+1
org hook2
LDR	R2, off_4507F0F4
BX	 R2
DCB 0xFF
DCB 0xFF
off_4507F0F4	DCD loc_45D194AC+1



Czyli już jakoś zaczyna wyglądać ;) Adresy podmieniające oryginalne funkcje w mainie mamy porobione, teraz trzeba zająć się 'patchbody', czyli adresami wykorzystującymi wolne miejsca. W tym patchu zaczynają się one w trzecim offsecie. Bierzemy go, dodajemy do niego bazę i otrzymujemy 45D19464. Definiujemy ten adres jako patchbody, czyli: patchbody equ 0x45D19464.

12. W IDA klikamy "G" i wklejamy adres patchbody (powtórzę się: 45D19464). Jeśli widzimy, że offsety nie są skonwertowane do kodu, wciskamy C. Zjeżdżamy niżej. Jeśli obok któregoś ROMu (i romów niżej) są wartości różne od zera (np. F0 B5 itd) i widzimy, że są one nieskonwertowane do kodu, to klikamy C, znowu. Zjeżdżamy znowu niżej i jeśli znowu zobaczymy jakieś różne wartości przy ROMach nieskonwertowane do kodu, naciskamy C. I tak do momentu, gdy żółte ROMy pod ostatnim ROMem skonwertowanym do kodu, będą miały obok siebie same zera (to tak na przyszłość tylko - akurat w tym patchu od razu skonwertowało mi całe patchbody, więc "C" nacisnąłem tylko na początku adresu 'patchbody').

13. W szczęśliwym punkcie trzynastym jeszcze raz wciskamy "G" i wklepujemy adres zdefiniowany jako 'patchbody'.
Od samego początku zaznaczamy myszką obszar patchbody: od 45D19464 do ostatniego romu skonwertowanego do kodu (w tym przypadku jest taki pod adresem: 45D194C8).

14. Wciskamy ALT+F10 i sobie gdzieś zapisujemy ten plik :P Otwieramy go, ściągamy program 'ASM Cleaner' z załącznika. Odpalamy go, wklejamy tam całą zawartość pliku asm i wciskamy cleanup. Zaznaczamy wszystko z programu, kopiujemy i wklejamy w plik, który zapisała IDA. Usuwamy jednak linijkę 'include "x.inc"' na początku - gdyż mamy ją w naszym skrypcie. Zapisujemy plik.

15. Powracamy do naszego pliku (przez 'naszego' mam na myśli ten, do którego wpisywaliśmy kod ręcznie). Dodajemy tam org patchbody i wklejamy pod to całą zawartość pliku, który oczyścił nam ASM Cleaner.
Zaczyna się tak:
org patchbody
loc_45D19464		  
					  
PUSH {R0,R4-R7,LR}
ADD R4, R0, 0
ADD R5, R4, 0


po loc_xxxxxxxx musimy dać dwukropek. Ale dodajemy je TYLKO WTEDY, gdy ten loc_xxxxxxxx (lub sub_xxxxxxxx lub locret_xxxxxxxx) są wyrównane skrajnie do lewej strony. Nie robimy tego z adresami off_xxxxxxxx ani dword_xxxxxxxx.

16. Jednak przy linijkach zaczynających się od off_xxxxxxxx mamy zawsze coś w tym stylu:
off_xxxxxxxx dw loc_yyyyyyyy+1

Gdy te linijki występują pod adresem 'patchbody', to tutaj akurat musimy zamienić te loc_ na 0x, w efekcie mamy:
off_xxxxxxxx dw 0x........+1

17. Przeglądając skrypt od 'patchbody' w dół, widzimy więc kilka takich miejsc, zacznijmy od tego:
off_45D19494 dw loc_4506E588+1

i według tego co napisałem otrzymujemy:
off_45D19494 dw 0x4506E588+1

Polecam zaznaczyć te 0x4506E588 i wyciąć. Po wycięciu od razu w tym miejscu piszemy np. branch1, dzięki czemu mamy:
off_45D19494 dw branch1+1

Adres, który wycięliśmy, jest teraz w schowku, przesuwamy więc na początek naszego pliku ASM i przed hook1 dajemy:
branch1 equ 0x4506E588

18. To samo robimy z następnymi takimi miejscami. Mamy tam off_xxxxxxxx dw sub_...... oraz ~dw unk_ - w każdym przypadku robimy tak samo - zamieniamy tutaj te ciągi znakami 0x i kopiujemy je, definiując na początku.

19. Jest też taki fragment, trochę niżej niż w połowie patchbody:
dword_45D194A8 dw 0xED14

Wiemy, że patch ma wyświetlić obrazek w jednym miejscu - w korektorze, przy ustawieniu "basy". 0xED14 to kod hex ikonki w mainie (o tym później). Zamienimy więc tutaj 0xED14 na icon1, definiując te icon1 na początku.

20. Dwadzieścia króciutkich punktów zaawansowanego, ale krótkiego patcha, zawierającego chyba wszystkie przykłady, z jakimi spotkacie się przy portowaniu trudniejszych patchy.
Należy jeszcze usunąć patcha z software w IDA:
  • W IDA klikamy File > IDC File.
  • Wybieramy plik UndoPatch.idc.
  • W nowym oknie wybieramy plik patcha, którego wgrywaliśmy.
  • Wyskoczy okienko, w którym klikamy YES.
Gotowy skrypt ASM dla K770 R8BA024 dla patcha "Show mega bass image when Bass EQ is selected" wygląda tak:
include "x.inc"
branch1 equ 0x4506E588
branch2 equ 0x45490F5C
branch3 equ 0x45BFD14C
branch4 equ 0x4507F0F8
hook1 equ 0x4506E578
hook2 equ 0x4507F0EE
icon1 equ 0xED14
patchbody equ 0x45D19464
org hook1
LDR	R1, off_4506E57C
BX	 R1
off_4506E57C	DCD loc_45D19464+1
org hook2
LDR	R2, off_4507F0F4
BX	 R2
DCB 0xFF
DCB 0xFF
off_4507F0F4	DCD loc_45D194AC+1
org patchbody
loc_45D19464:  
					  
PUSH {R0,R4-R7,LR}
ADD R4, R0, 0
ADD R5, R4, 0
ADD R5, 0xB4
ADD R7, R2, 0
ADD R0, 0x14
LDR R3, dword_45D194C4
LDRB R1, [R3]
CMP R1, 1
LDR R1, [R0,4]
PUSH {R1}
LDR R3, [R0]
BNE loc_45D19490
LDR R2, dword_45D194A8
MOV R0, 0x18
LDRSH R1, [R5,R0]
MOV R0, 0x14
LDRSH R0, [R5,R0]
BL sub_45D19498
ADD SP, SP, 4
POP {R3-R7,PC}

loc_45D19490:		  
LDR R3, off_45D19494
BX R3
off_45D19494 dw branch1+1


sub_45D19498:		  
PUSH {R3}
LDR R3, off_45D194A4
MOV R12, R3
POP {R3}
BX R12

align 4
off_45D194A4 dw branch2+1
dword_45D194A8 dw icon1

loc_45D194AC:		  
					  
LDR R2, off_45D194C0
LDR R4, dword_45D194C4
STRB R3, [R4]
MOV R4, 5
MUL R3, R4
LDRSB R3, [R2,R3]
STRB R3, [R1]
LDR R3, off_45D194C8
BX R3
align 4
off_45D194C0 dw branch3
dword_45D194C4 dw 0x200A68B0
					  
off_45D194C8 dw branch4+1



ASM mamy zrobiony - pora na portowanie adresów - przejdźmy do trzeciej części poradnika.

3. Portowanie adresów w ASM

Attached Files


Edited by not found, 11 April 2012 - 19:23.
Poprawiłem emotikonki, bo ich nie wyświetlało i dodałem odnośnik do kolejnej części :)

  • 2
Sony Ericsson X8 || GingerDX v017 Android 2.3.7 || Sense Theme


0 user(s) are reading this topic