Перейти к содержанию
Old Phone Forum

dаs

Администраторы ROOT
  • Постов

    2 828
  • Зарегистрирован

  • Посещение

  • Победитель дней

    1

Сообщения, опубликованные dаs

  1. leonne,

    Перед тем, как портировать Missed Call, нужно:

    1) Портировать патч трассировки и научиться им пользоваться.

    2) Портировать патч ATComm и слить дамп оперативки.

     

    Это нам всё равно в будущем пригодится, поэтому будем делать это сейчас. Начнём с патча Trace. Вот его код для U600XEGG2:

     

    .equ GSMsprintf 0x2062ECF8
    .equ TB 0x300DCDF8
    .equ ATSendReplyByEG 0x204B733E
    .equ GSMstrlen 0x2062D270
    .equ GSMstrcpy 0x2062D260
    .equ GSMstrcat 0x2062D1FC
    .equ p_GSMMalloc 0x040000B8
    .equ p_GSMFree 0x040000BC
    
    
        0x217D0EC0:
         myTrace:
            push {r0-r7,lr}
    	sub sp,8
    
    		;Добавим к маске адрес вызова:
    			;Выделим память:
    			bl GSMstrlen
    			add r0,4
    			ldr r1,=p_GSMMalloc
    			ldr r1,[r1]
    			bl call_by_R1
    			mov r6,r0			
    
    		adr r1,="%X: "	;Это для вывода LR (адреса вызова)
    		bl GSMstrcpy
    
    		mov r0,r6
    		ldr r1,[sp+8]
    		bl GSMstrcat
    
    		;Подготовим строку:
    		ldr r0,=TB
    		mov r1,r6
    		ldr r2,[sp+40]	;r2=LR
    		ldr r3,[sp+12]	;r3=R1
    		ldr r4,[sp+16]	;r4=R2
    		str r4,[sp]		;[sp]=R2
    		ldr r4,[sp+20]	;r4=R3
    		str r4,[sp+4]	;[sp+4]=R3
    		bl GSMsprintf
    
    		;Выведем в порт:
    		mov r1,0
    		ldr r0,=TB
    		bl ATSendReplyByEG
    
    			;Освободим память:
    			ldr r1,=p_GSMFree
    			ldr r1,[r1]
    			mov r0,r6
    			bl call_by_R1
    
    	add sp,8
    	pop {r0-r7,pc}
    	.data
    
    call_by_R1:
    	bx r1

     

    Открываем 2 прошивки, создаём новое окно компилятора в U300XEGJ1, вставляем туда этот код и начинаем портировать.

     

    Для начала надо портировать функции, что в .equ. Итак, поехали (не забываем добавлять функции в символы):

     

    1) .equ GSMsprintf 0x2062ECF8

    Функцию найдём по коду 0FB400B58DB010A90C910190104802900F990C9A01A8 - получаем 0x205891A4

     

    2) .equ TB 0x300DCDF8

    Этот адрес уже есть в Сиимволах - 0x300D3A20

     

    3) .equ ATSendReplyByEG 0x204B733E

    Эту функцию находим по коду 30B5FFB0FFB083B0051C0C1C - получаем 0x20556D2A

     

    4) .equ GSMstrlen 0x2062D270

    Эту функцию находим по коду 002800D17047002100E0013102780130002A (несмотря на то, что в этом коде присутствуют команды с адресами, по нему находятся такие типовые функции, как работа со строками, числами и т.д.). Получаем 0x2057CA18

     

    5) .equ GSMstrcpy 0x2062D260

    Тут можно заметить, что эта функция лежит выше предыдущей функции GSMstrlen на 0x10 (16 в десятичной). Поэтому переходим по адресу функции GSMstrlen в U300 (0x2057CA18) и удостоверимся, так ли это здесь. Для этого внизу по середине, где выбрано число 4, выберем из раскрывающегося списка 16 и нажмём "-" слева. Тем самым мы сместимся на 16 байт вверх в прошивке (эту функция вообще очень удобная для перемещения по прошивке). Теперь перейдём по адресу функции GSMstrcpy в U600 (0x2062D260) и визуально сравним, как выглядит код прошивок U600 и U300 в этом месте. Видим, что одинаково, значит в U300 функция GSMstrcpy тоже на 0x10 выше от функции GSMstrlen, .т.е. лежит по адресу 0x2057CA08

     

    6) .equ GSMstrcat 0x2062D1FC

    Эту функцию найдём по коду 021C1378101C002B03D001321378002BFBD10B78013113700132002BF9D1704710B40 (такой длинный для того, чтобы отсечь другие варианты). Повторяюсь, что для других функцию такой метод поиска вряд ли пройдёт. Получаем 0x2057C9A4

     

    7) .equ p_GSMMalloc 0x040000B8

    Этот адрес не похож на другие адреса в оперативной памяти. Это адрес в какой-то специально области, где хранятся различные адреса (как правило, адреса различных функций). В этом случае по этом указателю хранится адрес функции выделения динамической памяти. Сейчас я расскажу, как искать такие адреса (собственно, также ищутся и другие обычные адреса в оперативной памяти).

    Открываем окно с прошивкой U600? вставляем в поле поиска 040000B8 (адрес без 0x). Теперь нажмём на панели выше строки поиска красную букву А с лупой (ссылки на адрес). Программа найдёт места, где используется этот адрес. Открываем плюсик рядом с Ссылки на данные, переходим кликом по первому адресу (201B247C). Теперь надо выбрать блок кода без адресов, пригодный для поиска. Как видим, подходит довольно большой блок с 201B2486 до 201B249E. Переходим по адресу 201B2486, копируем на вкладке Hex блок 0021017010BC08BC1847704730B583B0041C0125AD02281C и находим его в U300. Получили 0x201B2162. В прошивке U600 теперь поднимемся выше до тех пор, пока не увидим p_GSMMalloc, и затем постепенно поднимаемся вверх в прошивке U300, пока не увидим команду, где использовался адрес p_GSMMalloc в U600 (в нашем случае это LDR R1..). Итак, мы видим, что в U300 адрес такой же - 0x040000B8.

     

    :ab: .equ p_GSMFree 0x040000BC

    Это адрес функции освобождения динамической памяти. Тут ищем аналогично предыдущему. Поиском блока 70BC08BC184710B5011CB4203A4A48438018A82212588A42 мы находим, что и этот адрес остаётся таким же.

     

    Итак, основная работа сделана. Далее нам осталось изменить адрес размещения кода (0x217D0EC0), т.к. в самом коде изменять ничего не надо (здесь нету врезок).

    Код нам нужно разместить по "свободному" адресу, поэтому опять прибегнем к памяти из под языковых ресурсов. Итак, предыдущий патч (MainMenuVib) мы расположили по адресу 0x20F0CFB8. Откроем s3 файл этого патча при помощи блокнота и увидим, что код патча занимает регион с 0x20F0CFB8 по 0x20F0D018. На случай модификации патча MainMenuVib оставим ещё место про запас после адреса 0x20F0D018, и этот патч можно расположить где-то по адресу 0x20F0D500. Теперь в символы нужно добавить функцию MyTrace по адресу 0x20F0D500, т.к. в будущем она нам пригодится.

     

    Вот окончательный код патча:

     

    .equ GSMsprintf 0x205891A4
    .equ TB 0x300D3A20
    .equ ATSendReplyByEG 0x20556D2A
    .equ GSMstrlen 0x2057CA18
    .equ GSMstrcpy 0x2057CA08
    .equ GSMstrcat 0x2057C9A4
    .equ p_GSMMalloc 0x040000B8
    .equ p_GSMFree 0x040000BC
    
    
        0x20F0D500:
         myTrace:
            push {r0-r7,lr}
    	sub sp,8
    
    		;??????? ? ????? ????? ??????:
    			;??????? ??????:
    			bl GSMstrlen
    			add r0,4
    			ldr r1,=p_GSMMalloc
    			ldr r1,[r1]
    			bl call_by_R1
    			mov r6,r0			
    
    		adr r1,="%X: "	;??? ??? ?????? LR (?????? ??????)
    		bl GSMstrcpy
    
    		mov r0,r6
    		ldr r1,[sp+8]
    		bl GSMstrcat
    
    		;?????????? ??????:
    		ldr r0,=TB
    		mov r1,r6
    		ldr r2,[sp+40]	;r2=LR
    		ldr r3,[sp+12]	;r3=R1
    		ldr r4,[sp+16]	;r4=R2
    		str r4,[sp]		;[sp]=R2
    		ldr r4,[sp+20]	;r4=R3
    		str r4,[sp+4]	;[sp+4]=R3
    		bl GSMsprintf
    
    		;??????? ? ????:
    		mov r1,0
    		ldr r0,=TB
    		bl ATSendReplyByEG
    
    			;????????? ??????:
    			ldr r1,=p_GSMFree
    			ldr r1,[r1]
    			mov r0,r6
    			bl call_by_R1
    
    	add sp,8
    	pop {r0-r7,pc}
    	.data
    
    call_by_R1:
    	bx r1

     

    leonne, отпишись, как разберёшься, тогда продолжим.

    • Like 7
  2. leonne,

    Я сам немного запутался, где у меня ker_tab_menu, а где ker_tab_mesg, но здесь это не важно - нам без разницы, чью память использовать - память строк меню или память строк сообщений.

     

    При портировании патча нужно понимать, для чего предназначена каждая строка кода и что она делает, поэтому пройдёмся по строкам кода патча (врезки) и посмотрим, что нам нужно изменять, а что нет:

     

    Смысл патча таков: мы делаем врезку в том месте, которое выполняется при прорисовке картинки (в функцию вывода картинки на экран) и проверяем, если это иконка меню, то делаем краткую вибру.

     

    ldr r0,[sp] - в R0 загружаем значение по адресу sp, где хранится номер картинки, которая рисуется в данным момент.

    cmp r0,#0xAD - сравниваем номер картинки с 0xAD, где 0xAD - это номер первой в таблице иконки меню в программе read_pict. Напомню, что на предыдущей странице мы нашли, что номера картинок-иконок меню в U300 - это номера с 0x8B по 0xD2. Соответственно, номер первой картинки - 0x8B, поэтому заменяем 0xAD на 0x8B.

    blt exit - если номер рисуемой картинки меньше номера первой (результат предыдущего сравнения), то просто выходим.

    cmp r0,#0xF4 - сравниваем с номером последней картинки. Здесь 0xF4 соответственно меняем на 0xD2.

    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}

     

    Смысл здесь в том, что сначала вызывается функция uhActivateVibrator с параметром в R0 1, что включает вибрацию. Затем при помощи функции GSMStartTimer телефон ждёт столько тактов, сколько мы передадим в R1 (в нашем случае 15, соответственно, увеличивая это значение, можно увеличивать длину вибры), и после этого вызывает функцию, адрес котором передаётся в R2 (в нашем это адрес метки stop, где вибра останавливается). Вот так и получается короткая вибра. Перед вызовом функции таймера в R0 передаётся число - это что-то вроде ID таймера, вот это число для каждой прошивки своё. Здесь этот ID (да и вообще способ генерации вибры) я взял из функции входа в бесшумный режим, которая называется EnterSilentMode. Поэтому, чтобы найти, что передавать в R0 для U300, нам нужно найти функцию EnterSilentMode.

     

    Переходим в U600 на вкладку Символы, находим строку с EnterSilentMode, переходим на эту функцию двойным кликом. Здесь нам нужно выбрать оптимальный кусок кода для поиска. Мне попался на глаза кусок с адреса 0x205BBF14 до 0x205BBF1C. Поэтому переходим на адрес 205BBF14 двойным кликом по нему, запоминаем код команды по адресу 205BBF1C (3C49), переходим на вкладку Hex и копируем кусок кода до 3C49 (0068042188430430).

    В окне BinEdit с прошивкой U300 пытаемся найти этот код. Как видим, получается 2 варианта. Чтобы выбрать правильный, я поступаю так: перехожу назад на прошивку U600, ищу этот код и смотрю результаты. Здесь тоже 2 варианта, но правильный - первый по порядку (тот адрес, с которого мы как раз копировали этот код), поэтому в U300 смело считаем правильным первый по порядку вариант - т.е. адрес 0x205189A8. Но это ещё не адрес функции, переходим по адресу, открываем вкладку Код, поднимаемся вверх крайним скроллбаром до команды PUSH и видим, что адрес функции EnterSilentMode в U300 - это 0x2051899C. Смело можем добавить эту функцию в sym-файл.

     

    В окне с U600 возьмите мышкой внутренный скроллбар и тащите его медленно, пока не увидите вызов функции GSMStartTimer. Убедитесь, что ID я дествительно взял отсюда, и теперь найдите этот вызов в U300. Как мы видим, 0x0000081D нам нужно заменить на 0x0000081E.

     

    Теперь остался последний шаг - возврат из врезки, т.е. то, что идёт после метки exit. Во-первых, разместив переход на свободный участок в U600 по адресу 0x203F8CDA, мы затёрли стандартные команды, которые должны были выполниться. Если просто вернуться на том место, откуда был переход, то телефон будет зависать. Теперь здесь нам нужно восстановить те команды, которые мы затёрли.

    Код команд перехода вида:

     0x203F8CDA:
    ldr r0,=0x20F21598+1
    bx r0

    может занимать 8 или 10 байт. Это зависит от адреса, по которому располагается переход (в нашем случае 0x203F8CDA). Если этот адрес кратен 4, то код займёт 8 байт, иначе 10. Чтобы проверить кратность адреса 4-м, копируем в буфер адрес без 0x (в нашем случае 203F8CDA), открываем стандартный калькулятор, выбираем Вид - Инженерный, выбираем Hex и сочетанием Ctrl + V вставляем адрес в поле калькулятора. Затем переходим на Dec и делим число на 4. Если получается целое число, без 5-ти десятых, значит этот адрес кратен 4-м, иначе нет. В нашем случае получилось число 135258934.5, значит наш адрес не кратен 4-м и код перехода займёт 10 байт.

    Знать, сколько байт займёт переход, важно для того, чтобы знать, сколько команд нужно востановить с места перехода. Перейдём в прошивке U600 по адресу, с которого был переход (0x203F8CDA). Для этого ниже вкладов Hex и Код поставим галочку справа от слова Адрес, вставим в поле 203F8CDA и нажмём Enter. А теперь посмотрите на команды, которые идут в коде патча после метки exit. Это повторение 5-ти команд из места перехода (т.к. одна команда (кроме команд BL и некоторых других) занимает 2 байта.

    Поэтому теперь перейдём по адресу, с которого мы делаем переход в U300 ( 0x2036AF28). Кстати в предыдущем посте в окончательном варианте кода я забыл поменять адрес места врезки с 0x203F8CDA на 0x2036AF28.

    Итак, нетрудно заметить, что 5 команд по этим адресам не отличаются друг от друга, поэтому мы можем их оставить такими же. Внимание, если бы в U600 у нас адрес был бы кратен 4-м, то это совсем не значит, что в U300 это тоже так. Если оставить это без внимания, мы можем затереть лишнюю команду и всё пойдёт на перекосяк. Поэтому, в U300 нам следовало бы проверить, кратен ли адрес 4-м, и если нет, то добавить ещё одну команду в дублирование затёртых команд и адрес возврата сместить на 2 вниз (читаем далее).

     

    И последнее, что нам осталось - это вернуться обратно. Это осуществляется переходом:

     ldr r3,=0x203F8CE4+1
    bx r3

     

    Смотрим на прошивку U600 и видим, что возврат осуществляется на команду MOV R3, #0x1C, причём через регистр R3. Это не просто так, тут тоже нужно следить за тем, чтобы адрес перехода не затёр регистр с важной информацией, которая далее будет использоваться. Т.к. по адресу возврата в R3 записывается число 0x1C, то мы смело можем возвращаться через него. Теперь откроем прошивку U300 и видим, что команда MOV R3, #0x1C расположена по адресу 0x2036AF32, поэтому в коде патча меняем 203F8CE4 на 2036AF32.

     

    Небольшой бонус: посмотрите на место перехода в прошивке U600, открыв окно с ней. Видите BL ker_PutPackedBitmap? А теперь откройте окно с прошивкой U300, на аналогичном месте стоит команда BL off_2040C820. Это означает, что адрес функции ker_PutPackedBitmap в U300 - 0x2040C820, можем записать это в sym. И вообще в процессе портирования патчей нужно замечать такие моменты и добавлять функции в sym-файл, чтобы потом ей вдруг не пришлось портировать отдельно.

     

    Итак, вот окончательный код патча:

     

    .equ uhActivateVibrator 0x2029672E
    .equ GSMStartTimer 0x2057D54C
    
     0x203F8CDA:
       ldr r0,=0x20F21598+1
       bx r0
       ;.hex 1E230818C25E1C23C15E
    
     0x20F21598:
       ldr r0,[sp]
       cmp r0,#0x8B
       blt exit
       cmp r0,#0xF4
       bgt exit
       push {r1-r3}
       MOV	R0, 1	
       BL	uhActivateVibrator	
       LDR	R2, =stop+1	
       MOV	R1, 15	
       LDR	R0, =0x0000081E	
       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,=0x2036AF32+1
       bx r3
     stop:
       push {r0,lr}
       mov r0,0
       BL	uhActivateVibrator
       pop {r0,pc}

     

    leonne, компилируй и проверяй :ak: Если всё будет нормально, выбирай следующий патч.

     

    Об отмене: в исходниках патчей обычно принято оставлять по комментариями данные отмены. При компилировании в sre компилятор не делает отмены автоматически, поэтому приходится делать её вручную. Данные отмены в нашем случае - это ;.hex 1E230818C25E1C23C15E

    ; - это знак комментария, т.е. текст далее в этой строке не будет учтён при компиляции.

    .hex - это команда вставки блока кода без изменений.

     

    1E230818C25E1C23C15E - это по идее 10 байт кода, которые затирает переход, с места врезки в U600 (но здесь это не так, я забыл поменять данные отмены, когда делал 1.1 версию патча). Этот кусок кода нужно заменить на 10 байт кода из прошивки U300 с адреса врезки (0x2036AF28) - это F848141C1E230818C25E.

     

    Чтобы создать патч отмены, создаём новый проект компилятора (как новый патч), вставляем туда:

     

     0x2036AF28:
     .hex F848141C1E230818C25E

    и компилируем.

    Данные по адресу 0x20F21598 восстанавливать не обязательно, т.к. тут мы затёрли всего лишь текстовые ресурсы.

    • Like 7
  3. Прошивка: E570XEGD1

    Патч: BluetoothInShadow

     

    Теперь во время передачи файла по Bluetooth по нажатию кнопки C передача свернётся в фон и телефон перейдёт в

    главное меню. Сообщения об окончании передачи не будет, но по окончании передачи перестанет мигать значок Bluetooth.

    BluetoothInShadow.rar

    • Like 6
×
×
  • Создать...