Русский
Русский
English
Статистика
Реклама

Ломаем зашифрованный диск для собеседования от RedBalloonSecurity. Part 1

А что дальше?

Хабровчане и хабровчушки, эта статья является долгожданным (ага, в пару дней) продолжением моей предыдущей статьи о взломе жесткого диска для собеседования в инфосек компанию RedBalloonSecurity. Любителей поковырять железяки я спешу разочаровать, поскольку все дальнейшие манипуляции с диском будут проводится только на уровне ассемблерного кода и логики. Поэтому, приготовьте чай/кофе или чего покрепче, ведь мы снова лезем в embeded дебри и опять пускаемся в неизвестность.

LEVEL2

Моему счастью не было предела когда я залил пропатченую прошивку на Winbond Flash чип и ядро моего Debian-неттопа распознало еще 1 раздел диска. Здесь будет немного больше информации, чем в предыдущем разделе. Ведь повышая уровень, сложность нашей с вами задачи только увеличивается.

Содержимое раздела:

tkchk@ubuntu:/media/user/LEVEL2$ file *0001-keystone-armv5.patch: unified diff output, ASCII textlevel_2.html:              HTML document, ASCII text, with very long lineslevel2_instructions.txt:   ASCII textlevel_2.lod:               datalevel_3.lod.7z.encrypted:  7-zip archive data, version 0.3
  1. level_2.lod - это новый файл прошивки для диска. Прошиваемся так же, как и в предыдущей статье. Здесь ничего нового.

  2. level_3.lod.7z.encrypted - это файл прошивки для следующего уровня. Судя по его разрешению, файл находится в запароленном 7z архиве. Нам нужно решить текущий уровень чтоб достать пароль от слудующего.

  3. level2_instructions.txt - это, собственно, инструкции что и как делать. Подсказки тоже имеются.

  4. 0001-leystone-armv5.patch - это патч для Keystone Assembler. Keystone это компилятор и набор С-шных библиотек для перевода ассемблерного кода в опкоды для процессора. Об этом чуть позже.

  5. level_2.html - изюминка текущего уровня. Выглядит точ-в-точ как текст, который генерирует IDA Pro при загрузке бинарника.

Для тех, кто не в курсе, IDA Pro это программа для дизассемблирования. Дело в том, что когда мы пишем код на высокоуровневых языках (C, Python и тд) и подвергаем его компиляции, мы переводим наш +- human-readable текст в язык машинного кода. Тоесть, мы опускаем более понятную человеку логику в логику, которая больше понятна машине. Машина не понимает что такое функция, ведь функция, это скорее абстракция в голове у программиста. Процесс дизассемблирования позволяет сделать наоборот - поднять логику из машинного на человекопонятный уровень. Некоторые дизассемблеры позволяют поднять логику даже на C-шный уровень, хоть и не всегда делают это корректно (на самом деле очень даже корректно, но читать такой код порой бывает сложнее чем ассемблер). Если работаем с чем-то мелким, и надо кабанчиком понять что там происходит - этого хватит, но для более высокоточных вещей нужен уровень ассемблера. Это мы и получили в виде level_2.html файла.

tkchk@ubuntu:/media/user/LEVEL2$ cat level2_instructions.txt Congratulations... you have made it to the other sideBack when I was an intern, I designed this key generation function. My boss hated it.I hate my boss.1. Invoke the function with command R<User_Input>2. Find the key you must!!!!!level2.html provides disassembly of a memory snapshot of the key generator function.To help... guide... you in this adventure, you'll find a patchfile for the keystoneassembler to force the correct architecture.Also, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASCII
0001-keystone-armv5.patch
tkchk@ubuntu-mac:/media/tkchk/LEVEL2$ cat 0001-keystone-armv5.patch From 5532e7ccbc6c794545530eb725bed548cbc1ac3e Mon Sep 17 00:00:00 2001From: mysteriousmysteries <mysteriousmysteries@redballoonsecurity.com>Date: Wed, 15 Feb 2017 09:23:31 -0800Subject: [PATCH] armv5 support--- llvm/keystone/ks.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)diff --git a/llvm/keystone/ks.cpp b/llvm/keystone/ks.cppindex d1819f0..8c66f19 100644--- a/llvm/keystone/ks.cpp+++ b/llvm/keystone/ks.cpp@@ -250,7 +250,7 @@ ks_err ks_open(ks_arch arch, int mode, ks_engine **result)      if (arch < KS_ARCH_MAX) {         ks = new (std::nothrow) ks_struct(arch, mode, KS_ERR_OK, KS_OPT_SYNTAX_INTEL);-        +         if (!ks) {             // memory insufficient             return KS_ERR_NOMEM;@@ -294,7 +294,7 @@ ks_err ks_open(ks_arch arch, int mode, ks_engine **result)                         TripleName = "armv7";                         break;                     case KS_MODE_LITTLE_ENDIAN | KS_MODE_THUMB:-                        TripleName = "thumbv7";+                        TripleName = "armv5te";                         break;                 } @@ -566,7 +566,7 @@ int ks_asm(ks_engine *ks,     Streamer = ks->TheTarget->createMCObjectStreamer(             Triple(ks->TripleName), Ctx, *ks->MAB, OS, CE, *ks->STI, ks->MCOptions.MCRelaxAll,             /*DWARFMustBeAtTheEnd*/ false);-            +     if (!Streamer) {         // memory insufficient         delete CE;@@ -594,7 +594,7 @@ int ks_asm(ks_engine *ks,         return KS_ERR_NOMEM;     }     MCTargetAsmParser *TAP = ks->TheTarget->createMCAsmParser(*ks->STI, *Parser, *ks->MCII, ks->MCOptions);-    if (!TAP) { +    if (!TAP) {         // memory insufficient         delete Parser;         delete Streamer;-- 1.9.1
level_2.html
ROM:00332D00ROM:00332D00 ; Segment type: Pure codeROM:00332D00                 AREA ROM, CODE, READWRITE, ALIGN=0ROM:00332D00                 ; ORG 0x332D00ROM:00332D00                 CODE16ROM:00332D00ROM:00332D00 ; =============== S U B R O U T I N E =======================================ROM:00332D00ROM:00332D00 ; prototype: generate_key(key_part_num, integrity_validate_table, key_table)ROM:00332D00 ; Function called when serial console input is 'R'. Generates key parts in R0-R3.ROM:00332D00 ; The next level to reach, the key parts to print you must!ROM:00332D00ROM:00332D00 generate_keyROM:00332D00ROM:00332D00 var_28          = -0x28ROM:00332D00ROM:00332D00                 PUSH            {R4-R7,LR}ROM:00332D02                 SUB             SP, SP, #0x10ROM:00332D04                 MOVS            R7, R1ROM:00332D06                 MOVS            R4, R2ROM:00332D08                 MOVS            R5, R0ROM:00332D0A                 LDR             R1, =0x6213600 ; "R"...ROM:00332D0C                 LDRB            R0, [R1,#1]ROM:00332D0E                 CMP             R0, #0x31ROM:00332D10                 BNE             loc_332D1AROM:00332D12                 ADDS            R0, R1, #2ROM:00332D14                 BLX             ahex2byteROM:00332D18                 LDR             R1, =0x6213600ROM:00332D1AROM:00332D1A loc_332D1A                              ; CODE XREF: generate_key+10jROM:00332D1A                 MOV             R2, SPROM:00332D1CROM:00332D1C loc_332D1C                              ; CODE XREF: generate_key+28jROM:00332D1C                 LDRB            R6, [R1]ROM:00332D1E                 ADDS            R1, R1, #1ROM:00332D20                 CMP             R6, #0xDROM:00332D22                 BEQ             loc_332D2AROM:00332D24                 STRB            R6, [R2]ROM:00332D26                 ADDS            R2, R2, #1ROM:00332D28                 B               loc_332D1CROM:00332D2A ; ---------------------------------------------------------------------------ROM:00332D2AROM:00332D2A loc_332D2A                              ; CODE XREF: generate_key+22jROM:00332D2A                 SUBS            R5, #0x49ROM:00332D2C                 CMP             R5, #9ROM:00332D2E                 BGT             loc_332DD8ROM:00332D30                 LSLS            R5, R5, #1ROM:00332D32                 ADDS            R5, R5, #6ROM:00332D34                 MOV             R0, PCROM:00332D36                 ADDS            R5, R0, R5ROM:00332D38                 LDRH            R0, [R5]ROM:00332D3A                 ADDS            R0, R0, R5ROM:00332D3C                 BX              R0ROM:00332D3C ; ---------------------------------------------------------------------------ROM:00332D3E                 DCW 0x15ROM:00332D40                 DCW 0xA6ROM:00332D42                 DCW 0xA4ROM:00332D44                 DCW 0xA2ROM:00332D46                 DCW 0xA0ROM:00332D48                 DCW 0x9EROM:00332D4A                 DCW 0x2EROM:00332D4C                 DCW 0x50ROM:00332D4E                 DCW 0x98ROM:00332D50                 DCW 0xCROM:00332D52 ; ---------------------------------------------------------------------------ROM:00332D52ROM:00332D52 key_part1ROM:00332D52                 LDR             R0, [R4]ROM:00332D54                 MOVS            R6, #1ROM:00332D56                 STR             R6, [R7]ROM:00332D58                 BLX             loc_332DECROM:00332D5C                 CODE32ROM:00332D5CROM:00332D5C key_part2ROM:00332D5C                 LDR             R6, [R7]ROM:00332D60                 CMP             R6, #1ROM:00332D64                 LDREQ           R1, [R4,#4]ROM:00332D68                 EOREQ           R1, R1, R0ROM:00332D6C                 MOVEQ           R6, #1ROM:00332D70                 STREQ           R6, [R7,#4]ROM:00332D74                 B               loc_332DECROM:00332D78 ; ---------------------------------------------------------------------------ROM:00332D78ROM:00332D78 key_part3ROM:00332D78                 LDR             R6, [R7]ROM:00332D7C                 CMP             R6, #1ROM:00332D80                 LDREQ           R6, [R7,#4]ROM:00332D84                 CMPEQ           R6, #1ROM:00332D88                 LDREQ           R2, [R4,#8]ROM:00332D8C                 EOREQ           R2, R2, R1ROM:00332D90                 MOVEQ           R6, #1ROM:00332D94                 STREQ           R6, [R7,#8]ROM:00332D98                 B               loc_332DECROM:00332D9C ; ---------------------------------------------------------------------------ROM:00332D9CROM:00332D9C key_part4ROM:00332D9C                 LDR             R6, [R7]ROM:00332DA0                 CMP             R6, #1ROM:00332DA4                 LDREQ           R6, [R7,#4]ROM:00332DA8                 CMPEQ           R6, #1ROM:00332DAC                 LDREQ           R6, [R7,#8]ROM:00332DB0                 CMPEQ           R6, #1ROM:00332DB4                 LDREQ           R3, [R4,#0xC]ROM:00332DB8                 EOREQ           R3, R3, R2ROM:00332DBC                 MOVEQ           R6, #1ROM:00332DC0                 STREQ           R6, [R7,#8]ROM:00332DC4                 LDR             R4, =0x35A036 ; "Key Generated: %s%s%s%s"ROM:00332DC8                 BLX             loc_332DDCROM:00332DCC                 MOV             R1, SPROM:00332DD0                 LDR             R4, =0x35A05C ; "SP: %x"ROM:00332DD4                 BLX             loc_332DDCROM:00332DD8                 CODE16ROM:00332DD8ROM:00332DD8 loc_332DD8                              ; CODE XREF: generate_key+2EjROM:00332DD8                 LDR             R4, =0x35A020 ; "key not generated"ROM:00332DDA                 NOPROM:00332DDCROM:00332DDC loc_332DDC                              ; CODE XREF: generate_key+C8pROM:00332DDC                                         ; generate_key+D4pROM:00332DDC                 SUB             SP, SP, #4ROM:00332DDE                 STR             R0, [SP,#0x28+var_28]ROM:00332DE0                 MOVS            R0, R4ROM:00332DE2                 LDR             R4, =0x68B08DROM:00332DE4                 BLX             R4ROM:00332DE6                 ADD             SP, SP, #4ROM:00332DE8                 BLX             loc_332DECROM:00332DE8 ; End of function generate_keyROM:00332DE8ROM:00332DEC                 CODE32ROM:00332DECROM:00332DEC loc_332DEC                              ; CODE XREF: generate_key+58pROM:00332DEC                                         ; generate_key+74j ...ROM:00332DEC                 ADD             SP, SP, #0x20ROM:00332DF0                 LDR             LR, [SP],#4ROM:00332DF4                 BX              LRROM:00332DF8ROM:00332DF8 ; =============== S U B R O U T I N E =======================================ROM:00332DF8ROM:00332DF8ROM:00332DF8 ahex2byte                               ; CODE XREF: generate_key+14pROM:00332DF8                 STMFD           SP!, {R4-R6,LR}ROM:00332DFC                 MOV             R4, R0ROM:00332E00                 MOV             R6, R0ROM:00332E04ROM:00332E04 loc_332E04                              ; CODE XREF: ahex2byte+6CjROM:00332E04                 LDRB            R0, [R4]ROM:00332E08                 CMP             R0, #0xDROM:00332E0C                 BEQ             loc_332E68ROM:00332E10                 BL              sub_332E70ROM:00332E14                 CMN             R0, #1ROM:00332E18                 BNE             loc_332E2CROM:00332E1C                 LDRB            R0, [R4]ROM:00332E20                 BL              sub_332E98ROM:00332E24                 CMN             R0, #1ROM:00332E28                 BEQ             locret_332E6CROM:00332E2CROM:00332E2C loc_332E2C                              ; CODE XREF: ahex2byte+20jROM:00332E2C                 MOV             R5, R0ROM:00332E30                 LDRB            R0, [R4,#1]ROM:00332E34                 BL              sub_332E70ROM:00332E38                 CMN             R0, #1ROM:00332E3C                 BNE             loc_332E50ROM:00332E40                 LDRB            R0, [R4,#1]ROM:00332E44                 BL              sub_332E98ROM:00332E48                 CMN             R0, #1ROM:00332E4C                 BEQ             locret_332E6CROM:00332E50ROM:00332E50 loc_332E50                              ; CODE XREF: ahex2byte+44jROM:00332E50                 MOV             R5, R5,LSL#4ROM:00332E54                 ADD             R0, R5, R0ROM:00332E58                 STRB            R0, [R6]ROM:00332E5C                 ADD             R4, R4, #2ROM:00332E60                 ADD             R6, R6, #1ROM:00332E64                 B               loc_332E04ROM:00332E68 ; ---------------------------------------------------------------------------ROM:00332E68ROM:00332E68 loc_332E68                              ; CODE XREF: ahex2byte+14jROM:00332E68                 STRB            R0, [R6]ROM:00332E6CROM:00332E6C locret_332E6C                           ; CODE XREF: ahex2byte+30jROM:00332E6C                                         ; ahex2byte+54jROM:00332E6C                 LDMFD           SP!, {R4-R6,PC}ROM:00332E6C ; End of function ahex2byteROM:00332E6CROM:00332E70ROM:00332E70 ; =============== S U B R O U T I N E =======================================ROM:00332E70ROM:00332E70ROM:00332E70 sub_332E70                              ; CODE XREF: ahex2byte+18pROM:00332E70                                         ; ahex2byte+3CpROM:00332E70                 CMP             R0, #0xDROM:00332E74                 BEQ             loc_332E90ROM:00332E78                 CMP             R0, #0x30ROM:00332E7C                 BLT             loc_332E90ROM:00332E80                 CMP             R0, #0x39ROM:00332E84                 BGT             loc_332E90ROM:00332E88                 SUB             R0, R0, #0x30ROM:00332E8C                 B               locret_332E94ROM:00332E90 ; ---------------------------------------------------------------------------ROM:00332E90ROM:00332E90 loc_332E90                              ; CODE XREF: sub_332E70+4jROM:00332E90                                         ; sub_332E70+Cj ...ROM:00332E90                 MVN             R0, #0ROM:00332E94ROM:00332E94 locret_332E94                           ; CODE XREF: sub_332E70+1CjROM:00332E94                 BX              LRROM:00332E94 ; End of function sub_332E70ROM:00332E94ROM:00332E98ROM:00332E98 ; =============== S U B R O U T I N E =======================================ROM:00332E98ROM:00332E98ROM:00332E98 sub_332E98                              ; CODE XREF: ahex2byte+28pROM:00332E98                                         ; ahex2byte+4CpROM:00332E98                 CMP             R0, #0x41ROM:00332E9C                 BLT             loc_332EB4ROM:00332EA0                 CMP             R0, #0x46ROM:00332EA4                 BGT             loc_332EB4ROM:00332EA8                 SUB             R0, R0, #0x41ROM:00332EAC                 ADD             R0, R0, #0xAROM:00332EB0                 B               locret_332EB8ROM:00332EB4 ; ---------------------------------------------------------------------------ROM:00332EB4ROM:00332EB4 loc_332EB4                              ; CODE XREF: sub_332E98+4jROM:00332EB4                                         ; sub_332E98+CjROM:00332EB4                 MVN             R0, #0ROM:00332EB8ROM:00332EB8 locret_332EB8                           ; CODE XREF: sub_332E98+18jROM:00332EB8                 BX              LRROM:00332EB8 ; End of function sub_332E98ROM:00332EB8ROM:00332EB8 ; ---------------------------------------------------------------------------ROM:00332EBC dword_332EBC    DCD 0x6213600           ; DATA XREF: generate_key+ArROM:00332EC0 dword_332EC0    DCD 0x6213600           ; DATA XREF: generate_key+18rROM:00332EC4 dword_332EC4    DCD 0x35A036            ; DATA XREF: generate_key+C4rROM:00332EC8 dword_332EC8    DCD 0x35A05C            ; DATA XREF: generate_key+D0rROM:00332ECC dword_332ECC    DCD 0x35A020            ; DATA XREF: generate_key:loc_332DD8rROM:00332ED0 off_332ED0      DCD 0x68B08D            ; DATA XREF: generate_key+E2rROM:00332ED4                 DCB 0, 0, 0, 0ROM:00332ED4 ; ROM           endsROM:00332ED4ROM:00332ED4                 END

Серьезно? ASM?

Дабы сделать эту статью более понятной широкому кругу лиц, наверное стоит дать понять что же это за дамп из IDA Pro. Опишем все до мелочей :)

В этом code-box приведены первые 20 строк из level_2.html файла:

01. ROM:00332D0002. ROM:00332D00 ; Segment type: Pure code03. ROM:00332D00                 AREA ROM, CODE, READWRITE, ALIGN=004. ROM:00332D00                 ; ORG 0x332D0005. ROM:00332D00                 CODE1606. ROM:00332D0007. ROM:00332D00 ; =============== S U B R O U T I N E =======================================08. ROM:00332D0009. ROM:00332D00 ; prototype: generate_key(key_part_num, integrity_validate_table, key_table)10. ROM:00332D00 ; Function called when serial console input is 'R'. Generates key parts in R0-R3.11. ROM:00332D00 ; The next level to reach, the key parts to print you must!12. ROM:00332D0013. ROM:00332D00 generate_key14. ROM:00332D0015. ROM:00332D00 var_28          = -0x2816. ROM:00332D0017. ROM:00332D00                 PUSH            {R4-R7,LR}18. ROM:00332D02                 SUB             SP, SP, #0x1019. ROM:00332D04                 MOVS            R7, R120. ROM:00332D06                 MOVS            R4, R2...

Колонка слева с ROM:XXXXXXXX - это адреса памяти. При загрузке бинарника в IDA Pro, мы должны препроверить, правильно ли IDA Pro поняла для какой архитектуры (ARM, x86, MIPS и тд. Их, ну прям очень большое количество) собран наш бинарник (в большинстве случаев, автоопределение работает очень хорошо, но если мы вгружаем не бинарник, а целый дамп памяти - некоторые вещи могут распознатся некорректно), считываем файл байт за байтом, и эта левая колонка автоинкрементируется каждый раз когда IDA Pro понимает что это за кусок данных. Данные в бинарнике могут быть поняты одним из следующих образов:

  • Данные. Самый низкий уровень понимания логики. Это когда кусок данных не представляет собой ничего конкретного. В дампе отображается как DCD, DCW, DCB - doubleword, word, byte соответственно (эти типы данных могут быть разных размеров на разных системах. Здесь советую погуглить и почитать. Сам это не сильно шарю). На такие штуки обычно есть ссылки из других участков кода. Назначение может быть самое разное. Далее будет понятно.

  • Код. Это когда кусок данных представляет собой 1 атомарную единицу операции (записать данные из регистра в память, сравнить числа и тд).

  • Строка. Это когда IDA Pro натыкается на массив данных которые лежат в ASCII диапазоне. От 0x20 до 0x7E (ASCII стандарт также описывает числа ниже 0x20, но они не имеют "текстового" смысла). Вполне возможно, что диапазон расширяется и на другие кодировки, но это вне контекста данной статьи.

  • Подпроцедура (Subroutine). Это самый высокий уровень понимания ассемблерной логики - когда IDA Pro видит функцию. Дальше мы видим то же самое, как если бы видели код. Но понимание того, что это не просто код, а функция дает невероятный скачок в осознании происходящего.

На 5й строке мы видим надпись CODE16. Это очень важно, поскольку этот дамп снят с кода для ARM процессоров (IC от LSI, который есть на плате от жесткого диска построен именно на этой архитектуре). У ARM процессоров есть 2 режима работы - ARM и Thumb.

  • В режиме ARM у нас есть доступ, наверное, ко всем ассемблерным операциям, но такие инструкции занимают 4 байта

  • В режиме Thumb мы немножко ограничены, но такие инструкции занимают 2 байта.

Причины по которым были созданы эти 2 режима мне неизвестны (знатоки в комментариях очень даже приветствуются), но могу сказать следующее.

  • В режиме ARM мы, скорее всего, будем исполнять желаемую логику быстрее. Как минимум потому что у нас есть доступ к инструкциям типа CMPEQ, которая выполнит операцию сравнения чисел только в том случае, когда результат предыдущго сравнения был успешным. Получается, что в этом режиме мы можем отдать логику if-else на железо. И сделать 2 операции (проверка предыдущего результата и выполнение новой операции) за 1 цикл процессора. Но и размер инструкций будет больше, а значит нужно использовать больше памяти.

  • В режиме Thumb мы не можем использовать подобное, но размер инструкций будет в 2 раза меньше, а значит затраты памяти будут ниже.

  • Еще стоит сказать, что архитектура ARM (не путать с режимом) прекрасна тем, что размер инструкций у них фиксирован (2 или 4 байта), чего нельзя сказать об x86

В общем, вот это CODE16 значит что в этом моменте процессор находится в Thumb режиме. И, как мы видим дальше, адреса памяти инкрементируются по 2 (конечно, там, где есть инструкция).

На строках 9-11 мы видим нарошно оставленные комментарии. Они говорят нам, что этот код исполняется тогда, когда мы вводим в серийник диска букву R и что-то после нее. Также, мы видим, что суть задачи - зарулить исполнение код таким образом, чтоб диск отдал нам части ключей. Совмещая эти ключи, мы получаем пароль от level_3.lod.7z.encrypted.

Строка 13 являет собой адрес, на который есть отсылки в коде. Дело в том, что программы на ассемблере не исполняются линейно. Инструкции типа B, BL, BX, BLX переводят исполнение кода по новому адресу. И когда IDA Pro видит такие инструкции, она автоматически дает имя этому адресу. В нашем случае, ребята из RedBalloonSecurity переименовали этот адрес в generate_key. Переименовывать позиции в коде, на который есть ссылки является прекрасным способом оставить для себя заметку о том, что делает определенный кусок кода.

На строке 15 мы видим переменную. Надеюсь, все помнят об области видимости в С? Реализация этого механизма на уровне ассемблера очень хитрая. Здесь используется структура данных типа стек.

мае, вот к чему stack в stackoverflow

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

У ARM процессоров 15 регистров. Для большинства, можно писать код и использовать их как хочешь (хотя внутри компилятора все же есть определенные правила о том, какой регистр для чего использовать). Они имеют имена вида R0, R1 ... R15. Последние имеют специальное назначение:

  • SP (R13) - Stack Pointer. В этом регистре хранится адрес вершины стека

  • BP (R7 в Thumb, R11 в ARM) - Base Pointer. Здесь находится адрес начала стека

  • LR (R14) - Link Register. Если у бренч (B) инструкции есть приставка L, это значит, что адрес в PC нужно записать в LR (там есть определенная специфика, которую я не совсем понимаю. К этому адресу в LR должно добавлятся +2 байта для Thumb, или +4 байта для ARM. Но, это не точно). Потом это используется для возврата на предыдущее место в коде, например через BX LR. По сути, это аналог подхода, когда мы сохраняем адрес возврата на стек, но здесь используем регистр. Из преисуществ - он быстрее и часть програмной логики падает на CPU без хождения по памяти. Недостаток - регистр всего один, и предыдущие адреса возврата все же прийдется складывать на стек.

  • PC (R15) - Program Counter. Здесь находится адрес инструкции, которую процессор выполняет в данный момент. Писать сюда напрямую, кажись, нельзя. Но этот регистр полезен если мы хотим сделать прыжок на другой адрес. Даже если мы работаем с 16-битной архитектурой, мы, ну никак не можем сказать процессору прыгнуть на 16-битный адрес имея 2 байта на 1 инструкцию. Большинство инструкций для прыжка используют именно сдвиг от того, что находится в PC.

  • CSPR - Current State Process Register. Это специфический регистр. К нему нельзя обратится целиком, как и записать сюда что-то. Данные внутри этого регистра формируются автоматически на основе того, какие инструкции выполняет процессор. Он разбит на сегменты, и хранит в себе информацию о текущем состоянии процессора. К примеру, если мы делаем инструкцию CMP (сравнить числа), результат сравнения (0 или 1) пишется в один из битов этого регистра. А в дальнейшем это используется для условных операций.

Стек это определенное место в памяти, где хранятся значения локальных переменных, аргументы функций, адреса возвратов, а также предыдущее значение BP. Стек логически разбит на сегменты (stack frames). Каждый сегмент принадлежит какой-то определенной функции. И, когда мы вызываем из одной функции другую, мы по сути, сдвигаем адреса BP & SP чуть ниже(!) в памяти. Но перед тем как создавать новый сегмент на стеке, мы должны знать адрес, куда должен вернутся PC после завершения функции - он сохраняется на стеке (Return Address) перед вызовом функции. Также, чтоб при возврате, сегмент стека стал того же размера что и был, мы сохраняем предыдущее значение BP (Saved %ebp) на этот же стек. Выглядит все это дело примерно так (%ebp = BP, %esp = SP):

В предыдущем абзаце я сказал, что при создании нового сегмента стека, адреса BP & SP смещаются ниже. Дело в том, что "так сложилось исторически". Стек это FIFO конструкция, которая меняется в процессе исполнения программы. И компилятор не знает какого размера он может быть. То же самое касается кучи (heap) - памяти, которую мы запрашиваем у системы через семейство вызовов malloc (glibc). При выделении памяти в куче, ее адреса растут вверх, а вот когда растет стек, его адреса растут вниз. Стоит оговорится, что мы работаем с embeded устройством. Понятия кучи здесь, может и не быть (опять же, прошу экспертов меня поправить).

У ARM процессоров есть специальные семейство инструкций, которые работают со стеком: PUSH, POP, STMFD, LDMFD (уверен, есть еще, но для наших делишек этого хватит).

  • PUSH кладет то, что в аргументе на стек, и увеличивает стек (на самом деле уменьшает адрес)

  • POP снимает со стека данные и кладет в то, что в аргументе (зачастую регистр, но может быть и адрес памяти) и уменьшает стек (на самом деле увеличивает адрес)

  • STMFD, LDMFD делают то же самое, но туда можно запихнуть несколько регистров, и снять со стека несколько значений в рамках одной инструкции. И, кажись, указать, стоит ли подстраивать SP в зависимости от количества впихнутых регистров. Опять же, прелести ARM архитектуры!

Готовы? Ныряем!

Для того, чтоб что-то правильно сломать, нужно это правильно понять. Начнем с первого куска.

...13. ROM:00332D00 generate_key14. ROM:00332D0015. ROM:00332D00 var_28          = -0x2816. ROM:00332D0017. ROM:00332D00                 PUSH            {R4-R7,LR}18. ROM:00332D02                 SUB             SP, SP, #0x1019. ROM:00332D04                 MOVS            R7, R120. ROM:00332D06                 MOVS            R4, R221. ROM:00332D08                 MOVS            R5, R022. ROM:00332D0A                 LDR             R1, =0x6213600 ; "R"...23. ROM:00332D0C                 LDRB            R0, [R1,#1]24. ROM:00332D0E                 CMP             R0, #0x3125. ROM:00332D10                 BNE             loc_332D1A26. ROM:00332D12                 ADDS            R0, R1, #227. ROM:00332D14                 BLX             ahex2byte...

Строка 17-21. Первая инструкция, это PUSH. Она сохраняет на стек переменные из регистров R4-R7 и LR на стек, тоесть сохраняет предыдущий stack frame. Потом, отнимаем 16 байт от SP (увеличиваем стек). Копируем из регистров R0-R2 аргументы, которые были переданы в функцию generate_key в их "рабочие" места. Как видим, в прототипе было 3 аргумента. Регистров столко же. В предыдущем разделе я говорил, что аргументы падают на стек - это правда только в том случае, когда аргументов больше, чем 3 (или 4, уже не помню).

Процедура в предыдущем абзаце называется Function Prologue. Тоесть, не происходит ничего, что касается программной логики, но выполняется подготовка стека и регистров. Мне кажется, именно по подобным шаблонам IDA Pro отличает код от подпроцедур.

Строка 22-23. Грузим адрес, который будет указывать на то, что мы вводим в консольник диска в R1. Инструкция

LDRB R0, [R1,#1]

берет то, что лежит в R1, добавляет единицу, лезет в память по этому адресу (если значение в квадратных скобках, сначала надо интерпретировать эти данные как адрес), берет 1 байт и сохраняет его в R0.

Строка 24-25. Идет сравнение 2го вводимого символа с 0x31. В ASCII 0x31 это "1". Если мы ввели после буквы R единичку, выполнение кода не пойдет на loc_332D1A. Позже разберем что это за место.

Строка 26-27. Добавляем к адресу наших вводимых данных двойку и сохраняем в R0. По сути, мы смещаем адрес на 2 байта вперед. Тоесть, теперь он указывает на первый символ после R1 - "R1_" (на underscore). Далее, нас ждет безусловный прыжок на функцию ahex2byte. Но, это не просто прыжок. BLX, кроме прыжка, делает еще 2 замечательные вещи - сохраняет текущий адрес PC в LR, и переключает нас в ARM режим! внутри функции ahex2byte у нас теперь 4 байта на инструкцию. Помним, что R0 является первым аргументом при вызове функции.

Дабы подитожить, вот то, как пердыдущий кусок выглядел бы в С-шном виде. Этот код не правильный. Он чисто для наглядности:

void main () {  char *input = "R10000";  if (input[1] == "1") {    &input = &input + 2;    ahex2byte(&input);  }  else {    goto: loc_332D1A;  }}  

ахекс2байт

138. ROM:00332DF8 ; =============== S U B R O U T I N E =======================================139. ROM:00332DF8140. ROM:00332DF8141. ROM:00332DF8 ahex2byte                               ; CODE XREF: generate_key+14p142. ROM:00332DF8                 STMFD           SP!, {R4-R6,LR}143. ROM:00332DFC                 MOV             R4, R0144. ROM:00332E00                 MOV             R6, R0145. ROM:00332E04146. ROM:00332E04 loc_332E04                              ; CODE XREF: ahex2byte+6Cj147. ROM:00332E04                 LDRB            R0, [R4]148. ROM:00332E08                 CMP             R0, #0xD149. ROM:00332E0C                 BEQ             loc_332E68150. ROM:00332E10                 BL              sub_332E70151. ROM:00332E14                 CMN             R0, #1152. ROM:00332E18                 BNE             loc_332E2C153. ROM:00332E1C                 LDRB            R0, [R4]154. ROM:00332E20                 BL              sub_332E98155. ROM:00332E24                 CMN             R0, #1156. ROM:00332E28                 BEQ             locret_332E6C157. ROM:00332E2C158. ROM:00332E2C loc_332E2C                              ; CODE XREF: ahex2byte+20j159. ROM:00332E2C                 MOV             R5, R0160. ROM:00332E30                 LDRB            R0, [R4,#1]161. ROM:00332E34                 BL              sub_332E70162. ROM:00332E38                 CMN             R0, #1163. ROM:00332E3C                 BNE             loc_332E50164. ROM:00332E40                 LDRB            R0, [R4,#1]165. ROM:00332E44                 BL              sub_332E98166. ROM:00332E48                 CMN             R0, #1167. ROM:00332E4C                 BEQ             locret_332E6C168. ROM:00332E50169. ROM:00332E50 loc_332E50                              ; CODE XREF: ahex2byte+44j170. ROM:00332E50                 MOV             R5, R5,LSL#4171. ROM:00332E54                 ADD             R0, R5, R0172. ROM:00332E58                 STRB            R0, [R6]173. ROM:00332E5C                 ADD             R4, R4, #2174. ROM:00332E60                 ADD             R6, R6, #1175. ROM:00332E64                 B               loc_332E04176. ROM:00332E68 ; ---------------------------------------------------------------------------177. ROM:00332E68178. ROM:00332E68 loc_332E68                              ; CODE XREF: ahex2byte+14j179. ROM:00332E68                 STRB            R0, [R6]180. ROM:00332E6C181. ROM:00332E6C locret_332E6C                           ; CODE XREF: ahex2byte+30j182. ROM:00332E6C                                         ; ahex2byte+54j183. ROM:00332E6C                 LDMFD           SP!, {R4-R6,PC}184. ROM:00332E6C ; End of function ahex2byte185. ROM:00332E6C186. ROM:00332E70187. ROM:00332E70 ; =============== S U B R O U T I N E =======================================188. ROM:00332E70189. ROM:00332E70190. ROM:00332E70 sub_332E70                              ; CODE XREF: ahex2byte+18p191. ROM:00332E70                                         ; ahex2byte+3Cp192. ROM:00332E70                 CMP             R0, #0xD193. ROM:00332E74                 BEQ             loc_332E90194. ROM:00332E78                 CMP             R0, #0x30195. ROM:00332E7C                 BLT             loc_332E90196. ROM:00332E80                 CMP             R0, #0x39197. ROM:00332E84                 BGT             loc_332E90198. ROM:00332E88                 SUB             R0, R0, #0x30199. ROM:00332E8C                 B               locret_332E94200. ROM:00332E90 ; ---------------------------------------------------------------------------201. ROM:00332E90202. ROM:00332E90 loc_332E90                              ; CODE XREF: sub_332E70+4j203. ROM:00332E90                                         ; sub_332E70+Cj ...204. ROM:00332E90                 MVN             R0, #0205. ROM:00332E94206. ROM:00332E94 locret_332E94                           ; CODE XREF: sub_332E70+1Cj207. ROM:00332E94                 BX              LR208. ROM:00332E94 ; End of function sub_332E70209. ROM:00332E94210. ROM:00332E98211. ROM:00332E98 ; =============== S U B R O U T I N E =======================================212. ROM:00332E98213. ROM:00332E98214. ROM:00332E98 sub_332E98                              ; CODE XREF: ahex2byte+28p215. ROM:00332E98                                         ; ahex2byte+4Cp216. ROM:00332E98                 CMP             R0, #0x41217. ROM:00332E9C                 BLT             loc_332EB4218. ROM:00332EA0                 CMP             R0, #0x46219. ROM:00332EA4                 BGT             loc_332EB4220. ROM:00332EA8                 SUB             R0, R0, #0x41221. ROM:00332EAC                 ADD             R0, R0, #0xA222. ROM:00332EB0                 B               locret_332EB8223. ROM:00332EB4 ; ---------------------------------------------------------------------------224. ROM:00332EB4225. ROM:00332EB4 loc_332EB4                              ; CODE XREF: sub_332E98+4j226. ROM:00332EB4                                         ; sub_332E98+Cj227. ROM:00332EB4                 MVN             R0, #0228. ROM:00332EB8229. ROM:00332EB8 locret_332EB8                           ; CODE XREF: sub_332E98+18j230. ROM:00332EB8                 BX              LR231. ROM:00332EB8 ; End of function sub_332E98

Строка

Источник: habr.com
К списку статей
Опубликовано: 29.03.2021 00:13:50
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Информационная безопасность

Assembler

Реверс-инжиниринг

Хранение данных

Ctf

Red balloon security

Соискатель

Работа

Шифр

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru