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.
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óź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
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 1,2,3..... o, 16 ! Dzielimy na dwa i mamy 8
Pozwolicię, że pokażę screen z IDA. Podzielmy sobie to na poszczególne kolumny.
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"
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'.
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. 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 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.
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 :)