Наконец я вошёл в колею, продолжаем.. Итак, мы нашли адрес функции uhActivateVibrator в прошивке U300 - Это 0x205703EA и заменили адрес функции в компиляторе в первой строке, начинающейся с .equ. Аналогично найдём адрес функции GSMStartTimer, перейдём по её адресу: 0x2062F40C в U600 и видим, что у нас есть достаточно большой кусок без адресов и констант до команды BL. Смотрим на код команды BL (FFF766FF), запоминаем его, открываем вкладку Hex, выделяем и копируем в буфер код до FFF766FF, т.е. 10B582B0141C00220092221C. Ищем такой код в прошивке U300 и находим единственный вариант - 0x2057D54C, это и есть адрес функции GSMStartTimer в U300. Это тот самый лёгкий вариант поиска, о котором я говорил, т.е. когда мы имеем большой кусок в начале функции без адресов, BL, констант и др. Заменяем адрес функции GSMStartTimer в компиляторе и получаем уже следующий текст: .equ uhActivateVibrator 0x2029672E
.equ GSMStartTimer 0x2057D54C
0x203F8CDA:
ldr r0,=0x217D0000+1
bx r0
;.hex 1E230818C25E1C23C15E
0x217D0000:
ldr r0,[sp]
cmp r0,#0xAD
blt exit
cmp r0,#0xF4
bgt exit
push {r1-r3}
MOV R0, 1
BL uhActivateVibrator
LDR R2, =stop+1
MOV R1, 15
LDR R0, =0x0000081D
MOV R3, #0x0
BL GSMStartTimer
pop {r1-r3}
exit:
LDR R0, =0x000033E0
mov r4,r2
mov r3,#0x1E
add r0,r1,r0
ldsh r2,[r0,r3]
ldr r3,=0x203F8CE4+1
bx r3
stop:
push {r0,lr}
mov r0,0
BL uhActivateVibrator
pop {r0,pc} leonne молодец, он до этого догадался сам и самостоятельно уже нашёл эот адрес Теперь самое время поговорить об основном принципе написания патчей. Редко бывает, что патч состоит просто из замены какого-то адреса, команды и т.п. Патчи в основном состоят из нескольких или одной пар: место врезки и код врезки. Врезки нужны тогда, когда код основного патча не поместится в том месте, где нужно его выполнение. Ведь если мы напишем свои команды по какому-то адресу, то эти команды затрут стандартные команды. И что же делать, если нам нельзя так делать? Вот здесь используются врезки: мы вставляем по какому-то из адресов переход на свободный участок прошивки, выполняем там какой угодно код и затем возвращаемся обратно на место перехода, чтобы продолжить выполнение стандартного кода прошивки. Как вы наверное уже поняли, место врезки - это адрес, по которому нужно выполнить код и по которому мы вставляется переход на новый участок памяти, а код врезки - это как раз тот код, который выполняется в свободном участке. В нашем случае мы имеем одну такую пару, где 0x203F8CDA - Это адрес места врезки, а 0x217D0000 - это адрес кода врезки. Переход на новый адрес осуществляется парой команд: Причём надо следить, чтобы на месте врезки регистр, через который мы осуществляем переход, не был занят какой-либо информацией. Перейдём в прошивке U600 по адресу врезки: 0x203F8CDA.Мы видим, что по этому адрес находится команда LDR R0, =0x000033E0, т.е. в регистр R0 записывается число 33E0, значит регистр R0 не занят, и мы можем его использовать для перехода. Найдём эквивалент адреса врезки в U300: мы видим, что до команды BL мы имеем внушительный кусок кода, но первая команда у нас содержит число 0x000033E0, а в U300 уже может быть другое число в этом месте, и, соответственно, код этой команды там будет отличаться, поэтому нам нужно перейти на одну команду ниже, кликнув 2 раза по адресу 203F8CDC. Теперь копируеи кусок кода во вкладке Hex до кода команды BL - 141C1E230818C25E1C23C15E281C231C, ищем такой код в U300 И находим единственный вариант - 0x2036AF2A, но не стоит забывать, что в U600 мы сместились на одну команду вниз, поэтому в программе с открытой прошивкой U300 нам нужно переместиться на одну команду вверх от найденного адреса 0x2036AF2A. Для этого кликнем по этому адресу 2 раза в результатах поиска, чтобы перейти по нему, и нажмём стрелку вверх на внешнем скроллбаре (который правее).По аналогии с U600 мы видим, что команда LDR находится по адресу 0x2036AF28, поэтому в код патча в компиляторе мы уже можем менять адрес 0x203F8CDA на 0x2036AF28. Заметим, что бывают например такая ситуация: пусть в U300 по адресу 0x2036AF28 было бы LDR R1, =0x000033E0 вместо LDR R0, =0x000033E0. В этом случае переход на новый адрес нужно делать не через R0, а через регистр R1. В этом случае мы бы поменяли регистр в коде патча с R0 на R1. Теперь возникает вопрос, а как же найти свободный регион в прошивке? Я в своих патчах использую память языковых ресурсов, которые редко используются - это языковые ресурсы начиная с языка Latviesu. При этом я себе составляю что-то вроде карты уже занятых патчами регионов, чтобы патчи не конфликтовали. Рассмотрим, как найти начальный такой адрес. Для начала в окне BinEdit с открытой прошивкой U600 перейдём на вкладку символы, найдём функцию ker_get_name, перейдём по её адресу, кликнув на неё 2 раза, и мы увидим сразу после команды PUSH команду BL kit_get_menu?. Нам самом деле здесь должно быть BL kit_get_name, просто я перепутал название одного символа)) Перейдём на функцию kit_get_menu?, кликнув по ней 2 раза. Здесь мы видим один из редких случае, когда функция начинается не с команды PUSH. Обратите внимание на команду LDR R3, =ker_tab_menu, вот адрес ker_tab_menu нам и нужно найти в U300. Повезло, что в символах, что я выкладывал, уже найдена функция ker_get_name. Переходим по ней, затес по адресу 2061F6B8. Тут есть единственный адрес, который может быть ker_tab_menu (он должен начинаться с 0x20) - Это 0x20F2A618. Заметим, что тут код не так уж похож на U600. Итак, можем добавить в наш символьный файл строку: 0x20F2A618 T ker_tab_menu открыв его при помощи блокнота, чтобы потом уже не искать этот адрес. Перейдём в прошивке U300 по этому адресу и откроем вкладку Hex. Это таблица языковых ресурсов меню телефона. Мы видим тут список таких составляющих: 4 байта - перевёрный в Little Endian адрес и 4 байта - такое же перевёрнутой число. Например, рассмотрим первые 8 байт: 38A9F120 08090000 Тут адрес 0x20F1A938 - это адрес таблицы языковых ресурсов для языка English, а число 0x980 - это количество элементов этой таблицы в Hex. Далее мы видим четыре нуля, а затем опять 8 байт уже для русского языка. И так далее, составляющие таблицы расположены в том порядке, в котором расположены языки в меню выбора языка в телефоне (Меню - Настройки - Телефон - Язык). Итак, нам нужно попасть на таблицу ресурсов для языка Latviesu. Он 4-й в списке, поэтому берём 4-й адрес в таблице - это 0x20F21598 и меняем в коде патча адрес 0x217D0000 на 0x20F21598. Также не забываем менять адрес в команды LDR выше на месте врезки. При портировании следующего патча с использованием свободной памяти я расскажу, как выбрать следующий свободный адрес. Итак, мы уже имееи в результате: .equ uhActivateVibrator 0x2029672E
.equ GSMStartTimer 0x2057D54C
0x203F8CDA:
ldr r0,=0x20F21598+1
bx r0
;.hex 1E230818C25E1C23C15E
0x20F21598:
ldr r0,[sp]
cmp r0,#0xAD
blt exit
cmp r0,#0xF4
bgt exit
push {r1-r3}
MOV R0, 1
BL uhActivateVibrator
LDR R2, =stop+1
MOV R1, 15
LDR R0, =0x0000081D
MOV R3, #0x0
BL GSMStartTimer
pop {r1-r3}
exit:
LDR R0, =0x000033E0
mov r4,r2
mov r3,#0x1E
add r0,r1,r0
ldsh r2,[r0,r3]
ldr r3,=0x203F8CE4+1
bx r3
stop:
push {r0,lr}
mov r0,0
BL uhActivateVibrator
pop {r0,pc}
leonne, как переваришь, отпиши, в следующий раз мы уже закончим портировать этот патч.