©IGNITUS (Allsiemens-Berlic)
2007 Портирование патчей
Понадобятся:
1)Прога IDA: http://forum.allsiemens.com/viewtopic.php?t=7022
Настраиваем IDA: идём в папку с IDA\cfg ,ищем файлик "idagui.cfg" В нём есть строка "PatchByte" раскоментировываем её, прописываем в ней кнопку, например i , можно и другую, которая не занята, получится:
"PatchByte" = "i"
ещё ищем DISPLAY_PATCH_SUBMENU (в самом начале файла) и пишем "yes":
DISPLAY_PATCH_SUBMENU = YES // Display the Edit,Patch submenu
2)Любой HEX-редактор, например WinHex
3)Bin Edit - компилятор, дизасемблер, дебаггер, можно использовать вместо IDA, ищем через поиск или на аллсименсе, на мотофане, где душе угодно
3)Чистые фуллфлэши телов: с которого портируем и на который портируем (Тут описано на примере портирования с S65 sw58 на CX70 sw56).
4)Мозги и руки (желательно прямые)
Сначала не плохо былобы понять как устроен проц, ну и немного ознакомится с Assembler`ом
Проц:
Он обрабатывает, то что лежит во флеше, т.е. ASM код
В проце самое главное регистры, их в ARM 18:
R1-R15-обычные регистры и 3 специальных:
PC-указатель на текущую комманду
LR-здесь хранятся адреса возврата при вызове процедур
SP-указатель на стёк (что это такое расскажу чуть позже)
Теперь расскажу о командах ASM:
ARM процессор имеет 2 режима комманд ARM и Thumb:
Thumb-16-битный, длина комманд 2 байта, для перехода в IDA жмём ALT+G, ставим T, и пишем 1
ARM-32-битный, длина комманд 4 байта, для перехода в IDA жмём ALT+G, ставим T, и пишем 0
IDA часто их путает между собой, и ещё путает их с данными, поэтому лучше пользоватся скриптами, у меня он есть только для моторолловского Big Endian\ARMB, нам не подойдёт, ссылка в конце статьи там должны быть.
Сами команды ничем не отличаются
И вот комманды:
Матем.действия
ADD R1, #230 ; сложение R1 = R1+230
ADD R2, R1, #50 ; сложение R2 = R1+50
SUB ; То же самое что сложение, только вычитание
MUL ;умножение; деление я не нашёл, вродебы оно осуществляется функцией dwMODdw
MOV R0, #100 ; комманда копирования R0 = 100
LDR R7, #0xA0000000; комманда, похожая на MOV, запихивает адреса в регистры
BX R7 ;продолжение LDR, переходит по адресу в регистре
DCD 0xA0000000 ;данные для LDR
Такая конструкция используется в библиотеке функций, если у адреса на конце 0, значит функция в ARM, если 1 - Thumb.
B {адрес} ; переход на адрес
BL {адрес} ; переход на адрес и как я понял сохраняет в LR адрес возврата
BLX {адрес} ; вродебы тот же BX, но с адресом возврата
CMP R0, #1 ; сравнение регистра с числом
BEQ {адрес} ; переход, если равно
BNE {дрес} ; переход, если не равно
BCS {адрес} ; переход, если больше, ещё есть если меньше, но я его не знаю
NOP ;ничего не делающая комманда, занимает пространство и время
Стёковые операции:
Надо понять стёк: это такая штука, как магазин автомата, запихнули регистр, потом ещё один,
потом ещё, и тот, который вошёл последним выйдет первым.
PUSH R0 ; положит R0 в стёк, так же можно запихивать несколько регистров:
PUSH {R0-R4, LR}; запихивает с R0 по R4 и LR
POP R3 ; вытаскивает из стёка в R3
POP {R0-R4, SP} ; вытаскивает в R0, R1, R2, R3, R4 и LR
Данные записываются с помощью
db - 1 байт
dw - 2 байта - 1 слово
dd - 4 байта - 2 слова
dq - 8 байт - 4 слова
dt - 10 байт,
например:
{Имя переменной} db 'Text',0
Ну теперь можно начать портирование
Вот патч от S65 sw58
Code
;x65 - Дата внизу (на главном экране) "Ср, 11 Май" v8
;(c) avkiev
;(!) MasterPatch
0C37BFC: 041C081C111C1A1C 004DA847,0xA0FC1001 ; S65v58
#pragma enable old_equal_ff
0FC1000: 0FB50425002F2ED11E48FFF7F9FD2AD0
0FC1010: 6C461434301D011C0831FEF7F1FF301D
0FC1020: FEF7F2FF0D3000F023F89523A1780029
0FC1030: 00D1A370E3702C237078002800D19523
0FC1040: 2371202363712372717A0A20FEF7E8FF
0FC1050: 3030A0713031E171307A093400F008F8
0FC1060: 002302930C2510BC87BC0B1C7F193847
0FC1070: 00B5FFF759FBC019211CFEF7DDFF00BD
0FC1080: 0xB1C2D3E4,0x0000AB01,0000000000000000,"\
{patch=BottomDate ver=8 cp=avkiev id=AB01 mem=20}\
{1 cb ShowComma v=1}\
",00
#pragma disable old_equal_ff
1.Открываем портируемый патч
2.Открываем в HEX-редакторе фулфлеш тела на который портируем
3.Открываем в IDA фулфлеш тела с которого будем портировать (портируемый патч в нём не должен быть установлен). Открытие фулфлеша подробно описано на ВсеСименсе или можно прочитать в конце этой инструкции.
4.Идём в IDA Options->General и ставим в Number of opcode bytes "4"
5.Смотрим в патче на энтрипоинт (тот что в начале патча) там написано:
0C37BFC: 041C081C111C1A1C 004DA847,0xA0FC1001 (Если в патче есть ",0x", то адрес после него переворачивается по 1 байту)
нам нужно A0C37BFC, идём по этому адресу в IDA, жмём ALT+G и ставим 1, т.к. Thumb и нажимаем C, появится такое:
Code
ROM:A0C37BFC 04 1C ADD R4, R0, #0
ROM:A0C37BFE 08 1C ADD R0, R1, #0
ROM:A0C37C00 11 1C ADD R1, R2, #0
ROM:A0C37C02 1A 1C ADD R2, R3, #0
ROM:A0C37C04 0B 1C ADD R3, R1, #0
ROM:A0C37C06 69 46 MOV R1, SP
ROM:A0C37C08 CC F7 16 EC BLX sub_A0C04438
ROM:A0C37C0C 00 23 MOV R3, #0
ROM:A0C37C0E 01 22 MOV R2, #1
ROM:A0C37C10 20 1C ADD R0, R4, #0
ROM:A0C37C12 69 46 MOV R1, SP
ROM:A0C37C14 D0 F0 F6 EE BLX sub_A0D08A04
ROM:A0C37C18 9E BD POP {R1-R4,R7,PC}
6.Теперь открываем HEX-редактор и ищем байты 041C081C111C1A1C0B1C6946, предварительно поставив галочку "Use as wildcard: 3F", комманды начинающиеся с B (если есть) заменяем на 3F, вот нашли адрес B9167C, если найдено несколько адресов, то нужно расширить поиск, т.е. добавлять дальше 3F3F3F3F потом 00230122 и так пока не найдём. Для проверки открываем фуллфлеш от CX70 и идём по адресу A0B9167C там видим почти такой-же кусок кода.
Code
ROM:A0B9167C 04 1C ADD R4, R0, #0
ROM:A0B9167E 08 1C ADD R0, R1, #0
ROM:A0B91680 11 1C ADD R1, R2, #0
ROM:A0B91682 1A 1C ADD R2, R3, #0
ROM:A0B91684 0B 1C ADD R3, R1, #0
ROM:A0B91686 69 46 MOV R1, SP
ROM:A0B91688 BF F0 82 E8 BLX sub_A0C50790
ROM:A0B9168C 00 23 MOV R3, #0
ROM:A0B9168E 01 22 MOV R2, #1
ROM:A0B91690 20 1C ADD R0, R4, #0
ROM:A0B91692 69 46 MOV R1, SP
ROM:A0B91694 A9 F5 EC EA BLX sub_A093AC70
ROM:A0B91698 9E BD POP {R1-R4,R7,PC}
Вот тут видно,что 8 и 12 строчка изменились-это команды Bxx 7.Теперь вставляем адрес в патч
Получаем
Code
0B9167C: 041C081C111C1A1C 004DA847,0xA0FC1001
#pragma enable old_equal_ff
0FC1000: 0FB50425002F2ED11E48FFF7F9FD2AD0
0FC1010: 6C461434301D011C0831FEF7F1FF301D
0FC1020: FEF7F2FF0D3000F023F89523A1780029
0FC1030: 00D1A370E3702C237078002800D19523
0FC1040: 2371202363712372717A0A20FEF7E8FF
0FC1050: 3030A0713031E171307A093400F008F8
0FC1060: 002302930C2510BC87BC0B1C7F193847
0FC1070: 00B5FFF759FBC019211CFEF7DDFF00BD
0FC1080: 0xB1C2D3E4,0x0000AB01,0000000000000000,"\
{patch=BottomDate ver=8 cp=avkiev id=AB01 mem=20}\
{1 cb ShowComma v=1}\
",00
#pragma disable old_equal_ff
Теперь это патч для CX70sw56 Устанавливаем и проверяем.
З.Ы. Адрес врезки т.е 0B9167C должен быть кратен 4.
В теле патча ничего менять не надо, если он юзает библиотеку функций, но если нет или если надо перетащить на другой адрес, то надо менять ссылки на внешние функции, дальше идёт патч, в нём описано.
Для примера ещё покажу Change_Imei c S65sw58 на CX70sw56:
Code
;S65v58
;Замена отображаемого IMEI
;Change Display of IMEI
;(c) Bennie
;(p) KiRiK
;Version:
;PatchID: 826
;Details:
http://patches.kibab.com/patches/details.php5?id=826 1330E70: 98B5041C0821474A96F006EE454A684601 00B50249D9F65EED00BDC046800E33A120
1330E81: 3A012196F000EE00AB1878E073002020 "MyNameIsABCDEF\0" ; maximum 15 ASCII chars
Открываем в ИДА фулл S65 без патча, идём A1330E70, там жмём ALT+G, выбираем Т, пишем 1, т.к Thumb, жмём C, видим
Code
ROM:A1330E70 CODE16
ROM:A1330E70 98 B5 PUSH {R3,R4,R7,LR}
ROM:A1330E72 04 1C ADD R4, R0, #0
ROM:A1330E74 08 21 MOV R1, #8
ROM:A1330E76 47 4A LDR R2, =0xA86CEFDD
ROM:A1330E78 96 F0 06 EE BLX sub_A13C7A88
ROM:A1330E7C 45 4A LDR R2, =0xA86CEFDD
ROM:A1330E7E 68 46 MOV R0, SP
ROM:A1330E80 01 3A SUB R2, #1
ROM:A1330E82 01 21 MOV R1, #1
ROM:A1330E84 96 F0 00 EE BLX sub_A13C7A88
ROM:A1330E88 00 AB ADD R3, SP, #0
ROM:A1330E8A 18 78 LDRB R0, [R3]
ROM:A1330E8C E0 73 STRB R0, [R4,#0xF]
ROM:A1330E8E 00 20 MOV R0, #0
ROM:A1330E90 20 74 STRB R0, [R4,#0x10]
ROM:A1330E92 20 20 MOV R0, #0x20
ROM:A1330E94 20 70 STRB R0, [R4]
ROM:A1330E96 20 1C ADD R0, R4, #0
ROM:A1330E98 98 BD POP {R3,R4,R7,PC}
Составляем паттерн 98B5041C0821, ищем WinHexом в своём фулле, я нашёл по адресу 125B158, теперь идём в фулле, на который портируем в IDA на A125B158, жмём ALT+G, пишем 1, жмём C, ура нашли.
Code
ROM:A125B158 98 B5 PUSH {R3,R4,R7,LR}
ROM:A125B15A 04 1C ADD R4, R0, #0
ROM:A125B15C 08 21 MOV R1, #8
ROM:A125B15E 47 4A LDR R2, =0xA86CD32D
ROM:A125B160 BC F0 FA EE BLX sub_A1317F58
ROM:A125B164 45 4A LDR R2, =0xA86CD32D
ROM:A125B166 68 46 MOV R0, SP
ROM:A125B168 01 3A SUB R2, #1
ROM:A125B16A 01 21 MOV R1, #1
ROM:A125B16C BC F0 F4 EE BLX sub_A1317F58
ROM:A125B170 00 AB ADD R3, SP, #0
ROM:A125B172 18 78 LDRB R0, [R3]
ROM:A125B174 E0 73 STRB R0, [R4,#0xF]
ROM:A125B176 00 20 MOV R0, #0
ROM:A125B178 20 74 STRB R0, [R4,#0x10]
ROM:A125B17A 20 20 MOV R0, #0x20
ROM:A125B17C 20 70 STRB R0, [R4]
ROM:A125B17E 20 1C ADD R0, R4, #0
ROM:A125B180 98 BD POP {R3,R4,R7,PC}
жмём i на A1330E70 в S65, вписываем наш патч через пробел 00 B5 02 49 D9 F6 5E ED 00 BD C0 46 80 0E 33 A1, потом идём на A1330E81, жмём i, пишем "MyNameIsABCDEF\0", жмём C на A1330E70
Code
ROM:A1330E70 00 B5 PUSH {LR}
ROM:A1330E72 02 49 LDR R1, =unk_A1330E80
ROM:A1330E74 D9 F6 5E ED BLX sub_A120A934
ROM:A1330E78 00 BD POP {PC}
ROM:A1330E7A ;
-------------------------------------------------------------------------
ROM:A1330E7A C0 46 NOP
ROM:A1330E7A ;
-------------------------------------------------------------------------
ROM:A1330E7C 80 0E 33 A1 off_A1330E7C DCD unk_A1330E80 ; DATA XREF: ROM:A1330E72r
ROM:A1330E80 01 unk_A1330E80 DCB 1 ; DATA XREF:
ROM:off_A1330E7Co
тут в R1 ложится наше имеи, оно лежит по A1330E80, дальше вызов функции 120A934, кликаем 2
раза по sub_A120A934, тут ARM, у меня IDA поняла всё правильно, если этого не произошло жмём ALT+G, T, пишем 0
Code
ROM:A120A934 00 C0 9F E5 LDR R12, =(sub_A166AE00+1)
ROM:A120A938 1C FF 2F E1 BX R12
ROM:A120A938 ; ------------------------------------------------------------
---------------------------------------------------------------------------
R OM:A120A93C 01 AE 66 A1 off_A120A93C DCD sub_A166AE00+1 ; DATA XREF: sub_A120A934r
видим переход на A166AE00+1 (+1 значит Thumb), кликаем 2раза на нём, там составляем паттерн 021C031C0B439B0770B4, ищем, я нашёл в 16EF458, идём на него в фулле на кот. портируем, переходим в Thumb, жмём С, смотрим-тут тоже самое. Теперь непомешает полностью дизасмить фулл, для этого можно использовать скрипт (ссылка в самом конце статьи), очищаем в фулле FFS,EEFULL,EELITE,LP для этого жмём D в Смелтере, и где стоит надпись из выше перечисленных блоков, жмем пр.кн.мыши->очистить блок, сохраняем, откр. в IDA, жмём File->IDC script..выбираем файл...->дальше, возможно надо будет ввести нач. и конеч. адрес, точно незнаю, пользовался таким только в мотороле->ждём, вобщем слева от ROM:A16EF458 зелёным цветом должны появится адреса, исп. его, там будет и тот, который ищем мы, идём поочерёдно по ним, там должно быть:
ROM:AXXXXXXX sub_A120A934 ; CODE XREF: sub_A!!!!!!!p - вот это нам надо найти
ROM:AXXXXXXX: LDR R12, =(sub_A1??????+1)
ROM:AXXXXXXX+4: BX R12
ROM:AXXXXXXX+8: off_AXXXXXXX+8 DCD sub_A1??????+1 ; DATA XREF: sub_AXXXXXXXr
...А пока можно заниматься своими делами.
Ура у меня ида нашла!
Code
ROM:A16EF458
ROM:A16EF458 sub_A16EF458 ; CODE XREF:
sub_A002B520+118p
ROM:A16EF458 ; sub_A08A59F0+4j ...
ROM:A16EF458 02 1C ADD R2, R0, #0
ROM:A16EF45A 03 1C ADD R3, R0, #0
ROM:A16EF45C 0B 43 ORR R3, R1
A08A59F0 - вот это мы и искали, сюда должна идти ссылка из патча
Теперь, когда нашли осталось только собрать патч:
Нужно поменять A120A934 на A08A59F0, это можно сделать идой, но я не знаю как
, поэтому делаю BinEdit`om, там заходим в ARM компилятор, слева написано "Файлы" -> пр.кн.мыши -> новый, !!!вверху кнопки ARM и BIG ENDIAN не должны быть нажаты!!!, теперь вписываем в NONAME.ASM:
0xA125B15C: BLX 0xA08A59F0
Жмём на верху Начать компиляцию
АААА!!Не компилируется! Адресация выходит за пределы действия BLX, т.е он компилируется, но не умещается, ещё придётся впихнуть переход, я не гарантирую, что патч будет работать...Пока оставлю как есть, думаю, основную мысль я передал, потом ещё допеределаю. Переход будет по адресу 125B17A, т.к. там остался старый код и он особо ни чего не делает...
Пишем в компилятор:
Code
0xA125B15C: BLX 0xA125B17A+1 ;+1 т.к Thumb
0xA125B17A: LDR R7,=0xA08A59F0 ;на конце 0 т.к ARM, или можно сразу на A16EF458+1 (+1 Thumb)
BX R7
DCD 0xA08A59F0
Получаем в окне "результат":
A125B15C: 00F00EE.
A125B17A: 004F3847F0598AA0 ;копируем в патч без A
A125B158-адрес тела патча, его нашли самым первым (в патч записываем без буквы A).
125B169-продолжение патча: адрес тела патча + 17байт.
98B5041C0821474ABCF0FAEE454A684601 и 3A0121BCF0F4EE00AB1878E073002020-старые данные, смотрим в фулле на кот. порт. тамгде.адрес тела патча.
Меняем старый BLX D9F65EED на новый 00F00EE8 и адрес данных с ИМЕИ (ссылка на байт 20 т.е имеи, 68B125A1, переворачиваем по 1 байту = 0xA125B168.)
00B5024900F00EE800BDC04668B125A120-новые данные
"MyNameIsABCDEF\0"-само имеи.
125B17A-адрес перехода.
Собираем патч
Code
;Конечный результат порта
125B158: 98B5041C0821474ABCF0FAEE454A684601 00B5024900F00EE800BDC04668B125A120
125B169: 3A0121BCF0F4EE00AB1878E073002020 "MyNameIsABCDEF\0",0
125B17A: 20202070201C98BD 004F3847F0598AA0
Патч с гемороем, поэтому чуть позже перепишу нормально, а так вродебы всё, тела у меня нет, отписывайтесь о работоспособности!
Или если не попрёт можете сами попробывать переписать, щас обясню как:
Смотрим откуда вызывается патч, там должна быть комманда Bxx, меняем ссылку на место где есть FF, теперь в BinEdite пишем: patch equ 0xAXXXXXXX; адрес куда перенесли патч !ОБЯЗАТЕЛЬНО надо ввести
patch: PUSH {LR}
LDR R1, patch+20
LDR R7, =0xA08A59F0
BX R7 ;переход на несчастный A08A59F0 или можно сразу на
A16EF458+1
DCD 0xA08A59F0
POP {PC}
NOP
DCD patch+20 ;ссылка на данные; начало патча+20 в DEC = 14 в HEX
как добавить ИМЕИ сразу в компиляторе я пока не знаю, поэтому добавляем в патч
получаем:
#pragma enable old_equal_ff
0FC1000: 00B50349004F3847F0598AA000BDC0461410FCA0 ;я ставил вместо Даты в виде "Ср, 11 Май"
0FC1014: 01,"MyNameIsABCDEF\0" ;ставим по предыдуший адрес+14 в hex
#pragma disable old_equal_ff
и всё, судя по дизасму это более дееспособная версия, чем придыдущая, должна заработать
-------------------------------------------------------------------------------------------
Шорткаты:
В патчах типа Меню пуск, Говорящий телейон используется запуск по шорткатам, ну в них ничего сложного нет, ищем сам шорткат в фулфлеше он выглядит так:
<название_шортката(15байт)>00<Адрес вызываемой функции>00000000<номер строки из ленга(4байта)>0000<номер строки из ленга(4байта)>0000FF7F0000FF7F и т.д, например будильник(CX70sw56):
Code
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
009435B0 45 4C 53 45 ELSE
009435C0 5F 41 4C 41 52 4D 43 4C 4F 43 4B 00 87 F9 8E A0 _ALARMCLOCK.‡uZ
009435D0 00 00 00 00 20 03 00 00 8F 01 00 00 FF 7F 00 00 .... ...?...y..
009435E0 FF 7F 00 00 2F 05 00 00 FF 7F 00 00 FF 7F 00 00 y../...y..y..
Заменяем адрес вызываемой функции на тот который требуется, и, если надо - заменяем сообщения из лэнгпака, для этого открываем фулл и нажимаем на "L", сморим номер строки в графе HEX, переварачиваем по байту и вписываем новое значение (т.к.сейчас не имею Сименса, то точно не помню, какое из двух сообщений выводится в меню выбора шортката, а какое при его вызове). Строки в лэнге можно добавлять, возможно, не успел протестить - окрываем фулл в смелтере, нажимаем на "L", "Cохранить весь лэнгпак", открываем сохранённый файл в блокноте или другом текстовом редакторе, и добавляем такое в конце:
Code
String $<Предыдущий номер+1(hex)>, "<9B>Свой<95> <9B>текст"
Не нужные языки можно удалить, сохраняем файл и жмём в Смелтере "Загрузить весь ленгпак" и "Сохранить область лэнгпака", заливаем полученный файл в тел по адресу E0000, получившееся значение <Предыдущий номер+1> переварачиваем по байту, и, что с ним делать дальше - написано выше, как собрать патч, я думаю, догадаетесь сами!
ВСЁ!
------------------------------------------------------------------------------------------
Открытие фулфлеша в IDA
Открываем IDA
Жмём Open и выбираем фулл
Выбираем тип процессора ARM710a и жмём Set потом OK.
Убираем галку в RAM
Ставим галку в ROM
Прописываем ROM start adress: 0xA0000000
Прописываем Loading adress: 0xA0000000
Жмём OK
Ждём
Жмём OK
Жмём OK
Если начнётся поиск строк (generate list of string) жмем CANCEL
Теперь надо добавить оперативку, я всегда без неё обходился, но может пригодится, читать сдесь:
http://forum.allsiemens.com/viewtopic.php?t=7162&page=0
Тут же есть скрипты для IDA в самом конце, пост от Papuas`а
Всё- фулл открыт
------------------------------------------------------------------------------------------
IGNITUS ©
v1.0-7.07.07 портирование энтрипоинта
v2.0-3.08.07 портирование ссылок на внешние функции + кое-что изменил
v3.0-23.08.07 чё то я пишу про перенос тела на другой адрес уже месяц и всё никак не напишу, так что вот написал про шорткаты
v4.0-2.10.07 исправил пример патча, просто я тогда ASM плохо знал, написал про ASM, чтоб моих ошибок не повторяли + описал порт патча Замена отображаемого IMEI + мелкие доработки Исходники патчей. Взято с Siemens-club.org. Могут кому-то пригодится...