eXTracted INternals

eXTracted INternals
 
ФорумФорум  ЧаВоЧаВо  ПоискПоиск  РегистрацияРегистрация  ПользователиПользователи  ГруппыГруппы  Вход  

Поделиться | 
 

 Дизассемблирование и анализ кода ARM процессоров

Предыдущая тема Следующая тема Перейти вниз 
АвторСообщение
Hex

avatar

Количество сообщений : 397
Возраст : 35
Дата регистрации : 2006-07-12

СообщениеТема: Дизассемблирование и анализ кода ARM процессоров   Пт 25 Авг - 0:29

Начнем с архитектуры ARM. ARM процессоры имеют 18 регистров. 3 из которых можно назвать служебными, т.к. их можно использовать и как любые другие:
PC - указатель на текущую команду. Ничем не отличается от других регистров, в него можно писать обычным mov
LR - Link register, специальный регистр для хранения адреса возврата при вызове процедур. Т.е. в стэк он не сохраняется, а просто ложится в регистр.
SP - типа указатель на стэк, но стэковая передача это последнее, что используется в ARM ассемблере.

У ARM процессоров есть 2 режима ARM и THUMB. ARM - режим, это 32-битный режим, а THUMB - 16 битный. Набор команд в обоих режимах практически одинаковый. Команды THUMB режима имеют длину 2 байта, ARM - 4 байта.
Описание команд thumb и ARM режима можно взять тут: http://www.atmel.com/dyn/resources/prod_documents/doc0673.pdf
Особенно итересно то, что многие команды оперируют сразу с несколькими регистрами. Например:
ADD R3, SP, #4
что соответствует:
R3=SP+4
Или вот например команда сохранения регистров в стэк:
PUSH {R2-R4,R7,LR}
Это не аналог pushad из ассемблера x86. Просто в ARM ассемблере можно вот так запихивать список регистров стэк.

Данные в памяти могут быть как little endian(как у intel), так big endian (как у моторолы). Так что исследуя код стоит определиться с типом данных - это сэкономит вам кучу времени.

Для разработки программ для ARM довольно много компиляторов:
http://heanet.dl.sourceforge.net/sourceforge/gnude/gnude-arm-win.exe гнушный компилер со всеми вытекающими последстивиями.
http://www.goldroad.co.uk/grARM.html - простенький ARM ассемблер.
http://www.arm.com/support/downloads/index.html - официальный набор инструментов для разроботки под ARM. Тут его не возьмешь - только покупать. Ищите в сети Edonkey.
http://www.iar.com/ - альтернативное IDE для ARM. Предлагают триальный 30-дневный вариант.

Особенности ARM ассемблера генерируемого C++ ARM компиляторами
Естественно при анализе кода различных прошивок сталкиваешься не с кодом написаным на чистом ассемблере, а на коде сгенерированом сишным ARM компилятором, и естественно тут есть чему удивиться человеку привыкнувшему к ассемблеру x86.

Вызовы функций
Конвенций вызова (cdecl, stdcall и т.д) нет! Все функции используют конвенцию похожую на борладновский fastcall. Т.е. сначала регистры, а если их не хватает то параметры передаются через стэк.

Например:
Код:

ROM:0001F4E2 MOV R0, SP
ROM:0001F4E4 MOV R2, #6
ROM:0001F4E6 ADD R1, R4, #0
ROM:0001F4E8 BL memcmp

Порядок передачи параметров соответсвует номерам регистров т.е. R0 - первый, R1 - второй, R2 - третий.
То есть для
Код:

int memcmp(
const void *buf1,
const void *buf2,
size_t count
);

buf1 = R0
buf2 = R1
count = R2

Значение возвращаемое функцией передается через R0:
Код:

ROM:0001F4E2 MOV R0, SP
ROM:0001F4E4 MOV R2, #6
ROM:0001F4E6 ADD R1, R4, #0
ROM:0001F4E8 BL memcmp
ROM:0001F4EC CMP R0, #0
ROM:0001F4EE BNE loc_1F4F4

Вызов с передачей через стэк:
Код:

ROM:000BCDEC MOV R2, #0
ROM:000BCDEE STR R2, [SP]
ROM:000BCDF0 MOV R2, #128
ROM:000BCDF2 MOV R3, #128
ROM:000BCDF4 MOV R1, #14
ROM:000BCDF6 MOV R0, #0
ROM:000BCDF8 BL FillBoxColor
То есть R0-R3 содержат координаты, а пятый параметр (цвет) - записывается в стэк.

Количество операндов можно определить только аналитически т.е. приходится анализировать вызов функции и ее пролог. Частично получить информацию о количестве аргументов исходя из того какие регистры в начале функции сохраняются в стэк. Например в THUMB режиме процессор оперирует регистрами R0-R7 и служебными. Т.е. увидев функцию начинающуюся с
Код:

ROM:00059ADA getTextBounds
ROM:00059ADA PUSH {R4-R7,LR}

можно предположить что она получает аргументы через r0,r1,r2,r3 и SP. Далее уже по вызову:
Код:

ROM:0005924E ADD R0, SP, #0x14
ROM:00059250 ADD R1, SP, #0x6C
ROM:00059252 ADD R2, SP, #0x68
ROM:00059254 ADD R3, SP, #0x64
ROM:00059256 BL getTextBounds
Видим что используются только R0-R3. То есть передается 4 параметра.

Переходы
Переходы aka jumps как обычно бывают условные и безусловные. Сами переходы могут быть как относительные так и регистровыми. Причем регистровые часто используются для переключения между THUMB/ARM режимом. Безусловные короткие переходы реализуются как команда B (branch). А длинные через регистровый переход BX (Branch with exchange). Вызовы функций делаются через BL (Branch with link), т.е. переход с сохранением адреса возврата в LR. Еще можно менять адрес выполнения записывая в регистр PC:
ADD PC, #0x64
Но компиляторы Си так себя обычно не ведут. Запись в PC они используют только в ветвлениях.

Ветвления
Они же switch. Реализуются весьма оригинально:
Код:

ROM:0027806E CMP R2, #0x4D ; 'M'
ROM:00278070 BCS loc_27807A
ROM:00278072 ADR R3, word_27807C
ROM:00278074 ADD R3, R3, R2
ROM:00278076 LDRH R3, [R3,R2]
ROM:00278078 ADD PC, R3
ROM:0027807A
ROM:0027807A loc_27807A
ROM:0027807A B loc_278766
ROM:0027807C word_27807C DCW 0xAA, 0xBE, 0xC6, 0x180, 0x186; 0
ROM:0027807C DCW 0x190, 0x1A0, 0x1A8, 0x1DE, 0x1E4; 5
ROM:0027807C DCW 0x1B0, 0x212, 0x276, 0x1FE, 0x294; 10
Сначала идет проверка номера case. Он должен быть меньше 0x4D. Если номер case выше идет переход на default case, т.е. на loc_27807A.
Далее берется адрес таблицы переходов word_27807C. В этой таблице лежат не адреса переходов а смещения! А дальше по индексу case извлекается нужное смещение и прибавляется к PC. То есть для case 0 произойдет переход к адресу
0x278078(текущее значение PC) +0xAA(смещение из таблицы) + 0x4(!!!) = 0x278126.
Приходится прибавлять 4 изза особености ARM процессоров: когда происходит операция с регистром PC - результат будет на 4 больше, как пишут в документации: "to ensure it is word aligned".

Доступ к памяти
В Thumb режиме процессор может обращатся к памяти в пределах +/- 256 байт. Поэтому доступ к памяти происходит не напрямую, а через регистровую загрузку. Т.е. нельзя напрямую обратиться к адресу 0x974170, но можно через регистр. Например:
Код:

ROM:00277FF6 LDR R0, =unk_974170
ROM:00277FF8 LDR R0, [R0]

Получили значение по адресу 0x974170. Но и это еще не все! Сам адрес переменной (0x974170) хранится тут же рядом в пределах 256 байт:
Код:

ROM:00278044 off_278044 DCD unk_974170
То есть опкод команды LDR на самом деле содержит смещение операнда для команды LDR относительно текущего адреса.

Еще есть хитрая особеность оптимизации. Если какой-то адрес в можно получить относительно другого уже использованного в текущей функции, то его получают через арифметические операции или косвеный доступ. Это означает, что если функция к примеру хочет использовать одну переменную по адресу 0x100000, а другую по адресу 0x100150. То компилятор может сделать доступ как через два отдельных адреса, так и через такой код:
Код:

LDR R0, =0x100000
ADD R0, #0xFF
ADD R0, #0x51
LDR R0, [R0]
В x86 такое можно было бы трактовать как обращение к подструктуре в переделах другой структуры. А тут это обычная оптимизация. Зачем это надо? Для того чтобы минимизировать доступ к памяти. Т.е. арифметика работает быстрее загрузки данных. Да и вообще весь код ARM ассемблера изобилует разными регистровыми вычислениями, для того их и сделали аж 16 штук (в режиме thumb), чтобы как можно реже обращаться к памяти и стэку. Изза этого стэковые переменные встречаются только в очень больших функциях. Работа со стэком ничем не отличается от x86.

Переход между режимами ARM и THUMB:
Переход в THUMB делается через вызов BX, операндом которой является регистр с выставленым в 1 битом состояния.
Переход в ARM делается через вызов BX, операндом которой является регистр с выставленым в 0 битом состояния.

Процессорный модуль IDA довольно примитивен и очень часто в попытке анализа таких переключений, большое количество THUMB кода превращает в ARM и наоборот. Вручную переключить режим кода можно нажав ALT-G и в поле Value ввести 0 для ARM режима, и 1 - для THUMB.
Вернуться к началу Перейти вниз
Посмотреть профиль
wl



Количество сообщений : 127
Дата регистрации : 2007-02-15

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Ср 12 Дек - 9:07

Hex, а что можно сделать с функцией __ARM_switch8?
после неё идут относительные смещения по байту на каждый case, как-то бы автоматизировать добавление XREF, да и вообще, не всегда получается офрмить всё в функцию, что не удобно
Вернуться к началу Перейти вниз
Посмотреть профиль
wl



Количество сообщений : 127
Дата регистрации : 2007-02-15

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Ср 6 Фев - 17:31

свой пост отредактировал(вопрос более соответствующий теме), а тема не поднялась Sad
Вернуться к началу Перейти вниз
Посмотреть профиль
Hex

avatar

Количество сообщений : 397
Возраст : 35
Дата регистрации : 2006-07-12

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Чт 7 Фев - 1:36

wl пишет:
Hex, а что можно сделать с функцией __ARM_switch8?
после неё идут относительные смещения по байту на каждый case, как-то бы автоматизировать добавление XREF, да и вообще, не всегда получается офрмить всё в функцию, что не удобно
Можно добавить в загрузчик анализ __ARM_switch8.
Вернуться к началу Перейти вниз
Посмотреть профиль
wl



Количество сообщений : 127
Дата регистрации : 2007-02-15

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Чт 7 Фев - 14:28

наверное не стоит, всё равно это не поможет оформить в виде процедуры. проще скрипт написать наверное
Вернуться к началу Перейти вниз
Посмотреть профиль
wl



Количество сообщений : 127
Дата регистрации : 2007-02-15

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Пт 22 Фев - 7:50

Hex, что ты об этом думаешь?
http://j2me.ucoz.ru/forum/3-59-1

и еще о том, что если руками загрузить app-файл от s60v2 (поправив естественно импорты, и всякую сопутствующую шелуху, типа путей), то можно старые игры запустить на s60v3 - единственное неудобство, если игры не станут тянуться
Вернуться к началу Перейти вниз
Посмотреть профиль
Hex

avatar

Количество сообщений : 397
Возраст : 35
Дата регистрации : 2006-07-12

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Пт 22 Фев - 8:45

wl пишет:
Hex, что ты об этом думаешь?
http://j2me.ucoz.ru/forum/3-59-1

и еще о том, что если руками загрузить app-файл от s60v2 (поправив естественно импорты, и всякую сопутствующую шелуху, типа путей), то можно старые игры запустить на s60v3 - единственное неудобство, если игры не станут тянуться
Я за загрузку вручную. Это заодно может стать началом для проекта запуска Symbian приложений под WinCE Smile
Вернуться к началу Перейти вниз
Посмотреть профиль
wl



Количество сообщений : 127
Дата регистрации : 2007-02-15

СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   Пт 22 Фев - 9:30

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




СообщениеТема: Re: Дизассемблирование и анализ кода ARM процессоров   

Вернуться к началу Перейти вниз
 
Дизассемблирование и анализ кода ARM процессоров
Предыдущая тема Следующая тема Вернуться к началу 
Страница 1 из 1

Права доступа к этому форуму:Вы не можете отвечать на сообщения
eXTracted INternals :: Cтатьи :: Mobile and Embedded-
Перейти: