Доброго времени суток, читатели Codeby!
Будем честными. В большинстве случаев ревёрсеры используют IDA в качестве дизассемблера. Но что насчёт других дизассемблеров? Можно ли через терминальные отладчики отлаживать программы без проблем? Например, через radere2. В этой статье мы попытаемся ответить на этот вопрос. Также мы узнаем какая необходимая информация нужна для комфортного использования radare2. Всё рассматривать не будем, так как статья станет одеялом
Powerful_Crackme
Для обучения возьмём
Ссылка скрыта от гостей
. Откроем его в radare2.Проанализируем файл в radare2 через
aaa
. Это нужно для полного анализа программы. Мы будем использовать эту команду почти во всех случаях. Если нужно проанализировать что-то конкретное, можно обратиться к справке в radare2 (a?
). Теперь перейдём к функции main, используя команду s main
.В IDA очень часто нужна информация из вкладки
View
. В radare2 тоже есть свои аналоги.Важные вкладки из View | Команды radare2 |
---|---|
Exports | iE |
Imports | ii |
Names | is |
Functions | afl или afll |
Strings | iz или izz (Все строки) |
Segments | iS |
Signatures | iT. Также можно использовать zg (генерация) z (просмотр) |
Type Libraries | il (Информация о библиотеках) |
Structure | ts |
Если вам нужен Hexdump, то используйте
px
или px количество символов
для вывода.
Графика!
В radare2 есть два основных способа получения информации.- Через команды radare2.
- Через визуальный режим.
Ссылка скрыта от гостей
, интернета или из графического режима. Да и статья станет слишком большой, поэтому я не буду писать о командах.Поэтому, мы будем рассматривать графический режим. Начнём с графов.
В IDA для активации режима графов нужно нажать пробел. В radare2 это делается через
VV
. В режиме графов можно перемещаться через hjkl
или стрелочками. Можно использовать режим курсора (c
) для редактирования частей графа. Переключение между блоками графа осуществляется через TAB
или введением названия блока графа (od
, ol
и т.д.).Если мы находимся в режиме курсора, то в левом верхнем углу это будет отображено.
Для выхода нужно нажать
q
. Эта клавиша работает везде одинаково.Переходим к другим частям визуального режима. Нажав
V
, мы попадаем в Hexdump. С помощью TAB
мы можем менять информацию, выводимую на экране. Нажав Vp
, мы попадаем в Hexdump, дизассемблированный код или в вывод другой команды. Сама команда отображается наверху.Нажав
v
, мы попадаем в V?
).Чтобы переключаться между окнами, нажимайте
TAB
. Чтобы переключаться между окнами и верхней панелью, нажимайте m
. Можно переключаться между вкладками иоткрывать их. Самое главное - это наличие игры 2048!
В окнах можно менять вывод команд. Нажимаем правую кнопку мыши и выбираем нужное. Можно задать свои команды через
e
. Далее нужно будет ввести новую команду.Мы можем переходить к разным функциям через браузер функций (
_
). Если браузер функций вам не нужен, то перемещаться между функциями можно в самом окне с дизассемблированным кодом. Клавиша n
для перехода к следующей функции и N
для перехода к предыдущей. Для перехода к конкретному адресу используйте g
, а затем введите адрес или функцию. Если хочется поменять окна местами, то можно использовать p
или P
.Если вы замечали надпись
Tab
, то поздравляю вас! Вы можете создавать/удалять новые вкладки через t
. На значения из этих вкладок можно смотреть в увеличенном режиме, нажав Enter
.Вводить команды radare2 можно через
:cmd
. Через )
мы можем вывести дополнительную информацию на экран. O
позволяет нам представлять код в дизассемблированном виде и в виде псевдо-кода си. А o
даёт возможность переключаться между hexdump'ом, esil и другими режимами. Ну и самое важное - R
Оно меняет тему radare2 на рандомную.Если вы хотите посмотреть ссылки (
refs
) или перекрёстные ссылки (xrefs
), то нажимайте x
. Далее выбирайте то, что вам нужно, нажимая X
или x
. Самое главное - это не перепутать с клавишей X
. Она закрывает окно.c
) мы можем менять значения байтов, нажимая i
. Для записи изменений нужно указать флаг -w
и -e bin.cache=true
в командной строке, так как все изменения записываются в кеш. Через команду A
мы можем вставлять произвольные ассемблерные инструкции вместо самой верхней инструкции. Мы можем посмотреть все изменения в программе через wc
. Удалить конкретное изменение можно через wc- address
. Также можно убирать изменения с какого-либо адреса по какой-либо через wc- from to
. Ну или можно удалить все изменения через wcr
. Их можно будет применить через wci
или wc+ addr
.b
мы можем просматривать и редактировать множество значений. Например: искать ROP-гаджеты, редактировать биты, смотреть импорты и т.д.Часто приходится оставлять комментарии для себя в коде. В визуальном режиме это делается через
;
. Комментарий будет добавлен к самой верхней инструкции.Теперь перейдём в меню анализа и просмотра самой полезной информации. Нажмём
Vv
. Здесь мы можем просматривать xrefs (перекрёстные ссылки в самой программе), refs (ссылки в программе), переменные, определения и многое другое. Также мы можем не только просматривать их, но и редактировать! Почти всегда нужно менять какие-либо переменные в коде для удобства чтения.Перейдём к отладке программы. В визуальном режиме точка останова ставиться через
F2
на самой верхней инструкции. Начать выполнение программы до точки останова через F9
. Выполнить шаг с заходом в функцию через F7
, а без захода в функцию через F8
.Главная проблема отладки в визуальном режиме - это отсутствие вывода и ввода. Есть несколько способов решить это.
Первый - это выполнять функции вывода и ввода через команды radare2.
Второй - ввод данных через второе окно терминала.
Самые полезные команды для первого способа.
do
- Заново открыть программу для отладкиdb address
- Установить точку останова по указанному адресуds
- Выполнить инструкцию, заходя в функцию call
dss
- Выполнить инструкцию, не заходя в функцию call
dc
- Начать выполнение программы до точки останова. Если точек останова нет, то выполнять программу до самого конца.Остальные команды можно узнать из справки
d?
.Как выводить и вводить данные через второй терминал?
Создадим простой скрипт rarun2, где укажем ввод и вывод:- Откроем новый терминал.
- Запустим команду
tty
и скопируем вывод. Введём командуsleep 999999999
. - Вставим значение после символа
=
.
Код:
#!/usr/bin/env rarun2
stdin=/dev/pts/3
stdout=/dev/pts/3
Теперь сохраняем этот скрипт в файл. Например, pty3. Вводим команду
r2 -e dbg.profile=pty3 -d PowerFul_Crackme
для запуска программы в radare2.Весь визуальный режим можно сравнить с главным окном в IDA. Давайте перейдём к решению самого crackme.
Решение crackme.
Код функцииmain
в radare2:В radare2 не указывается в квадратных скобках к какому регистру, что прибавляется. Эта информация указывается в начале функции!
IDA:
C-подобный:
.text:0000558FBDF1F248 lea rax, [rbp+inp_str]
radare2:
C-подобный:
0x560ba5a7f248 488d45de lea rax, [var_22h]
Фрагмент из начала функции main:
C-подобный:
; var int64_t var_22h @ rbp-0x22
Проанализируем дизассемблированный код этого crackme.
C-подобный:
```clike[/FONT]
[FONT=verdana]; DATA XREF from entry0 @ 0x560ba5a7f08d
┌ 274: int main (int argc, char **argv, char **envp);
│ ; var int64_t var_2dh @ rbp-0x2d
│ ; var int64_t var_23h @ rbp-0x23
│ ; var int64_t var_22h @ rbp-0x22
│ ; var int64_t var_18h @ rbp-0x18
│ ; var int64_t var_17h @ rbp-0x17
│ ; var int64_t var_fh @ rbp-0xf
│ ; var int64_t var_dh @ rbp-0xd
│ ; var int64_t var_ch @ rbp-0xc
│ ; var int64_t var_8h @ rbp-0x8
│ ; var int64_t var_4h @ rbp-0x4
│ 0x560ba5a7f155 55 push rbp \\ Пролог функции
│ 0x560ba5a7f156 4889e5 mov rbp, rsp \\
│ 0x560ba5a7f159 4883ec30 sub rsp, 0x30
│ 0x560ba5a7f15d 48b862706661. movabs rax, 0x626f676a61667062 ; 'bpfajgob' | Перемещаем 'bpfajgob' в rax
│ 0x560ba5a7f167 488945e9 mov qword [var_17h], rax | Перемещаем значение rax (строка выше) в память var_17
│ 0x560ba5a7f16b 66c745f16977 mov word [var_fh], 0x7769 ; 'iw' | Добавляем 'iw' в конец строки 'bpfajgob'
│ 0x560ba5a7f171 c645f300 mov byte [var_dh], 0
│ 0x560ba5a7f175 488d3d8c0e00. lea rdi, str.The_magic_string:_ ; 0x560ba5a80008 ; "The magic string: " \\ В rdi лежит адрес строки
│ 0x560ba5a7f17c b800000000 mov eax, 0
│ 0x560ba5a7f181 e8bafeffff call sym.imp.printf ; int printf(const char *format) \\ printf("The magic string: ");
\\ strcpy(or_str, "bpfajgobiw");
\\ printf("The magic string: ");
│ 0x560ba5a7f186 c745fc000000. mov dword [var_4h], 0 \\ Здесь начнётся цикл for. var_4 - счётчик.
│ ┌─< 0x560ba5a7f18d eb24 jmp 0x560ba5a7f1b3 \\ Переходим по адресу 0x560ba5a7f1b3
│ ┌──> 0x560ba5a7f18f 488d55de lea rdx, [var_22h] \\ В rdx лежит адрес значения var_22 (введённая строка)
│ ╎│ 0x560ba5a7f193 8b45fc mov eax, dword [var_4h] \\ В eax значение var_4
│ ╎│ 0x560ba5a7f196 4898 cdqe \\ Выполняет преобразование dword в qword в rax
│ ╎│ 0x560ba5a7f198 4801d0 add rax, rdx \\ Добавляем к rax значение rdx. Таким образом мы записываем символы друг за другом, не перезаписывая ничего лишнего
│ ╎│ 0x560ba5a7f19b 4889c6 mov rsi, rax \\ В rsi лежит значение rax
│ ╎│ 0x560ba5a7f19e 488d3d760e00. lea rdi, [0x560ba5a8001b] ; " %c" \\ В rdi адрес форматной строки для считывания символов
│ ╎│ 0x560ba5a7f1a5 b800000000 mov eax, 0
│ ╎│ 0x560ba5a7f1aa e8a1feffff call sym.imp.__isoc99_scanf ; int scanf(const char *format) \\
│ ╎│ 0x560ba5a7f1af 8345fc01 add dword [var_4h], 1
│ ╎│ ; CODE XREF from main @ 0x560ba5a7f18d
│ ╎└─> 0x560ba5a7f1b3 837dfc09 cmp dword [var_4h], 9 \\ Сравниваем "Счётчик" со значением 9
│ └──< 0x560ba5a7f1b7 7ed6 jle 0x560ba5a7f18f \\ Переходим в тело цикла, если "счётчик" >= 9[/FONT]
[FONT=verdana]\\ for ( i = 0; i <= 9; ++i )
\\ scanf(" %c", inp_str[i]);[/FONT]
[FONT=verdana]│ 0x560ba5a7f1b9 c745f8000000. mov dword [var_8h], 0 \\ "Счётчик"=0
│ ┌─< 0x560ba5a7f1c0 eb3a jmp 0x560ba5a7f1fc
│ ┌──> 0x560ba5a7f1c2 837df806 cmp dword [var_8h], 6 \\ Сравниваем "счётчик" с 6.
│ ┌───< 0x560ba5a7f1c6 7f19 jg 0x560ba5a7f1e1 \\ Если "счётчик" больше 6, то переходим к адресу 0x560ba5a7f1e1.
│ │╎│ 0x560ba5a7f1c8 8b45f8 mov eax, dword [var_8h] \\ Перемещаем значение из "счётчика" (var_8h) в eax.
│ │╎│ 0x560ba5a7f1cb 8d4803 lea ecx, [rax + 3] \\ Переносим адрес значения из rax+3 в ecx.
│ │╎│ 0x560ba5a7f1ce 8b45f8 mov eax, dword [var_8h] \\ Переносим значение из "счётчика" в eax.
│ │╎│ 0x560ba5a7f1d1 4898 cdqe \\ Выполняет преобразование dword в qword в rax.
│ │╎│ 0x560ba5a7f1d3 0fb65405de movzx edx, byte [rbp + rax - 0x22] В edx лежит байт из введённой строки[eax] (var_22).
│ │╎│ 0x560ba5a7f1d8 4863c1 movsxd rax, ecx \\ Переносим значение, полученное в инструкции по адресу 0x560ba5a7f1cb в rax.
│ │╎│ 0x560ba5a7f1db 885405d3 mov byte [rbp + rax - 0x2d], dl \\ Переносим символ в финальную строку.
│ ┌────< 0x560ba5a7f1df eb17 jmp 0x560ba5a7f1f8 \\ Переходим к 0x560ba5a7f1f8
│ │└───> 0x560ba5a7f1e1 8b45f8 mov eax, dword [var_8h] \\ "Счётчик" > 6. Перемещаем значение из "счётчика" (var_8h) в eax.
│ │ ╎│ 0x560ba5a7f1e4 8d48f9 lea ecx, [rax - 7] \\ Переносим адрес значения из rax-7 в ecx.
│ │ ╎│ 0x560ba5a7f1e7 8b45f8 mov eax, dword [var_8h] Перемещаем значение из "счётчика" (var_8h) в eax.
│ │ ╎│ 0x560ba5a7f1ea 4898 cdqe \\ Выполняет преобразование dword в qword в rax.
│ │ ╎│ 0x560ba5a7f1ec 0fb65405de movzx edx, byte [rbp + rax - 0x22] В edx лежит байт из введённой строки[eax] (var_22).
│ │ ╎│ 0x560ba5a7f1f1 4863c1 movsxd rax, ecx \\ Переносим значение, полученное в инструкции по адресу 0x560ba5a7f1e4 в rax.
│ │ ╎│ 0x560ba5a7f1f4 885405d3 mov byte [rbp + rax - 0x2d], dl \\ Переносим символ в финальную строку.
│ │ ╎│ ; CODE XREF from main @ 0x560ba5a7f1df
│ └────> 0x560ba5a7f1f8 8345f801 add dword [var_8h], 1 \\ "Счётчик" = "Счётчик" + 1
│ ╎│ ; CODE XREF from main @ 0x560ba5a7f1c0
│ ╎└─> 0x560ba5a7f1fc 837df809 cmp dword [var_8h], 9 \\ Сравниваем "счётчик" с 9.
│ └──< 0x560ba5a7f200 7ec0 jle 0x560ba5a7f1c2 \\ Если меньше или равно 9, то переходим в тело цикла.
\\for (i = 0; i <= 9; ++i ) {
\\ if ( i > 6 )
\\ j = i - 7;
\\ else
\\ j = i + 3;
\\ f_str[j] = inp_str[i];
}
│ 0x560ba5a7f202 c645e800 mov byte [var_18h], 0 |
│ 0x560ba5a7f206 c645dd00 mov byte [var_23h], 0 | Отделяем строки друг от друга через 0x00.
│ 0x560ba5a7f20a c745f4000000. mov dword [var_ch], 0 \\ "Счётчик" = 0
│ ┌─< 0x560ba5a7f211 eb2f jmp 0x560ba5a7f242 \\ Переходим к 0x560ba5a7f242
│ ┌──> 0x560ba5a7f213 8b45f4 mov eax, dword [var_ch] \\ В eax будет значение "счётчика"
│ ╎│ 0x560ba5a7f216 4898 cdqe \\ Выполняет преобразование dword в qword в rax.
│ ╎│ 0x560ba5a7f218 0fb65405d3 movzx edx, byte [rbp + rax - 0x2d] \\ Перемещаем в edx код символа из финальной строки[eax].
│ ╎│ 0x560ba5a7f21d 8b45f4 mov eax, dword [var_ch] \\ В eax будет значение "счётчика"
│ ╎│ 0x560ba5a7f220 4898 cdqe \\ Выполняет преобразование dword в qword в rax.
│ ╎│ 0x560ba5a7f222 0fb64405e9 movzx eax, byte [rbp + rax - 0x17] \\ Перемещаем в eax код символа из оригинальной строки[eax].
│ ╎│ 0x560ba5a7f227 38c2 cmp dl, al \\ Сравниваем символ из финальной строки с символом из оригинальной строки
│ ┌───< 0x560ba5a7f229 7413 je 0x560ba5a7f23e \\ Если символы равны, то переходим к 0x560ba5a7f23e
│ │╎│ 0x560ba5a7f22b 488d3ded0d00. lea rdi, str.Sorry__wrong_input_:_ ; 0x560ba5a8001f ; "Sorry, wrong input :(" \\ Символы не равны. Переносим адрес строки str.Sorry__wrong_input_ в rdi
│ │╎│ 0x560ba5a7f232 e8f9fdffff call sym.imp.puts ; int puts(const char *s) \\ puts("Sorry, wrong input :(");
│ │╎│ 0x560ba5a7f237 b800000000 mov eax, 0 \\ Переносим в eax 0 (Код выхода)
│ ┌────< 0x560ba5a7f23c eb27 jmp 0x560ba5a7f265 \\ Переходим к концу функции main
│ │└───> 0x560ba5a7f23e 8345f401 add dword [var_ch], 1 \\ "Счётчик" = "Счётчик" + 1
│ │ ╎│ ; CODE XREF from main @ 0x560ba5a7f211
│ │ ╎└─> 0x560ba5a7f242 837df409 cmp dword [var_ch], 9 \\ Сравниваем "счётчик" с 9
│ │ └──< 0x560ba5a7f246 7ecb jle 0x560ba5a7f213 \\ Если счётчик меньше или равен 9, то переходим к 0x560ba5a7f213
│ │ 0x560ba5a7f248 488d45de lea rax, [var_22h] \\ Переносим в rax адрес начала финальной строки
│ │ 0x560ba5a7f24c 4889c6 mov rsi, rax \\ Переносим адрес в rsi
│ │ 0x560ba5a7f24f 488d3de20d00. lea rdi, str.Congratulations__correct_flag__nThe_flag_is:_WatadCTF_s_n ; 0x560ba5a80038 ; "Congratulations, correct flag!\nThe flag is: WatadC
TF{%s}\n" \\ Переносим в rdi адрес str.Congratulations__correct_flag__nThe_flag_is
│ │ 0x560ba5a7f256 b800000000 mov eax, 0
│ │ 0x560ba5a7f25b e8e0fdffff call sym.imp.printf ; int printf(const char *format) \\ printf("Congratulations, correct flag!\nThe flag is: WatadCTF{%s}\n", inp_str);
│ │ 0x560ba5a7f260 b800000000 mov eax, 0 \\ Переносим в eax 0 (Код выхода)
│ │ ; CODE XREF from main @ 0x560ba5a7f23c
│ └────> 0x560ba5a7f265 c9 leave \\ Копирует содержимое RBP в RSP
└ 0x560ba5a7f266 c3 ret \\ Возвращаемся в функцию из RSP
\\ for (i = 0; i <=9; i++) {
\\ if ( f_str[i] != or_str[i] ) {
\\ puts("Sorry, wrong input :(");
return 0;
\\ }
\\ else
\\ printf("Congratulations, correct flag!\nThe flag is: WatadCTF{%s}\n", inp_str);
\\ return 0;
\\}
Ассемблерный код можно перевести в код на си.
C:
#include <stdio.h>
#include <string.h>[/FONT]
[FONT=verdana]char or_str[11] = ""; //
char inp_str[11] = ""; // 11 символ - 0x00. Он означает конец строки.
char f_str[11] = ""; //
int i = 0;
int j = 0;[/FONT]
[FONT=verdana]int main() {[/FONT]
[FONT=verdana] strcpy(or_str, "bpfajgobiw");
printf("The magic string: ");
for ( i = 0; i <= 9; ++i )
scanf(" %c", &inp_str[i]);
for (i = 0; i <= 9; ++i ) {
if ( i > 6 )
j = i - 7;
else
j = i + 3;
f_str[j] = inp_str[i];
}
for (i = 0; i <=9; i++) {
if ( f_str[i] != or_str[i] ) {
puts("Sorry, wrong input :(");
return 0;
}
}
printf("Congratulations, correct flag!\nThe flag is: WatadCTF{%s}\n", inp_str);
return 0;
}
Эту программу можно скомпилировать в
PowerFul_Crackme_my
через команду gcc PowerFul_Crackme_my.c -o PowerFul_Crackme_my
Объяснение на русском языке.
В программе задумана строка bpfajgobiw. Пользователь вводит строку длиной 10 символов. Программа переносит последние три символа в начало строки. Таким образом создаётся финальная строка. Затем, финальная строка сравнивается со строкой bpfajgobiw. Если строки равны, выводитсяCongratulations, correct flag!...
. Если строки не равны, то выводится Sorry, wrong input :(
Написанный выше текст можно проверить этим кодом:
C:
#include <stdio.h>
#include <string.h>[/FONT]
[FONT=verdana]char or_str[11] = "";
char inp_str[11] = "";
char f_str[11] = "";
int i = 0;
int j = 0;[/FONT]
[FONT=verdana]int main() {[/FONT]
[FONT=verdana] strcpy(or_str, "bpfajgobiw");
printf("The magic string: ");
for ( i = 0; i <= 9; ++i )
scanf(" %c", &inp_str[i]);
for (i = 0; i <= 9; ++i ) {
if ( i > 6 )
j = i - 7;
else
j = i + 3;
f_str[j] = inp_str[i];
}
printf("f_str = %s\n", f_str);[/FONT]
[FONT=verdana] for (i = 0; i <=9; i++) {
if ( f_str[i] != or_str[i] ) {
puts("Sorry, wrong input :(");
return 0;
}
}
printf("Congratulations, correct flag!\nThe flag is: WatadCTF{%s}\n", inp_str);
return 0;
}
Или через radare2
Правильный ответ - ajgobiwbpf
Расширение и дополнительные утилиты из radare2.
Дополнительные утилиты.
- rabin2. Эта утилита выводит нам информацию:
- О файле:
rabin2 -I PowerFul_Crackme
- О секциях:
rabin2 -S PowerFul_Crackme
- О заголовках:
rabin2 -H PowerFul_Crackme
- и многом другом...
Ссылка скрыта от гостей
- О файле:
- radiff2. Через него можно сравнивать два бинарных файла.
radiff2 PowerFul_Crackme PowerFul_Crackme_my
. radiff2 покажет различия в файлах.
Ссылка скрыта от гостей - rasm2. Это консольный ассемблер и дизассемблер, и он очень полезен! Сначала нам нужно определиться с архитектурой. Все архитектуры можно посмотреть через
rasm2 -L
. Возьмём архитектуру x86, а размер регистров (-b
) установим в 64. Получится архитектура x86-64.
rasm2 -a x86 -b 64 "push eax"
= 0x50rasm2 -a x86 -b 64 -d 50
= push raxrasm2 -w "push" -a x86 -b 64
- для получения информации об инструкции push.
Ссылка скрыта от гостей
- rafind2. Эта утилита помогает искать информацию в файлах. Например, строку flagв
PowerFul_Crackme_my
.
rafind2 -s "flag" ./PowerFul_Crackme_my
= 0x2051 или 0x205b.-
Ссылка скрыта от гостей
- rahash2. Эта утилита вычисляет хеш программы, кодирует/декодирует данные в base64 и некоторые функции шифрования.
ПРЕДУПРЕЖДЕНИЕ - Не пытайтесь использовать rahash2 для большого файла, поскольку он сначала пытается загрузить весь файл в память.
Для просмотра всех хеш-функций используйте флаг-L
.
rahash2 -a md5 ./PowerFul_Crackme_my
- узнать md5-хеш дляPowerFul_Crackme_my
.rahash2 -a all ./PowerFul_Crackme_my
- узнать все доступные хеш-функции дляPowerFul_Crackme_my
.-
Ссылка скрыта от гостей
- rarun2. Эта утилита позволяет запускать программу с различными параметрами среды, аргументами, правами и директориями. Вспомните скрипт, который написали ранее...
Код:
#!/usr/bin/env rarun2
stdin=/dev/pts/3
stdout=/dev/pts/3
-
Ссылка скрыта от гостей
Radare2 также можно расширять, как и IDA. Через свои скрипты или чужие. Раздел с расширением функций рассматривается бегло, так как для того же Cutter можно написать целую статью.
Декомпилятор.
Мы рассмотрели только малую часть возможностей radare2, которая поставляется "из коробки". Так эти возможности тоже можно расширить! Например, через пакетный менеджер r2pm.В radare2 нет встроенного декомпилятора, но
pdc
может выдать псевдо-код. Через r2pm можно установить декомпилятор от Ghidra. Зайдите в radare2 и напишите:
Bash:
r2pm update
r2pm -ci r2ghidra
Дальше переходите в функцию
main
и вводите pdg
.pdga
тоже может пригодиться.pdg?
показывает справку про r2ghidra.Прокаченный псевдо-код.
Когда декомпилятор от Ghidra не помогает иpdc
выдаёт что-то странное, можете попробовать использовать r2dec (GitHub - wargio/r2dec-js: radare2 plugin - converts asm to pseudo-C code.). Это переводчик с языка ассемблера на псевдо-C.
Bash:
r2pm init
r2pm install r2dec
Дальше переходите в функцию
main
и вводите pdd
.pdd?
показывает справку про r2dec.Cutter
Ссылка скрыта от гостей
- это бесплатное приложение с открытым исходным кодом для реверс-инженеринга, основанное на Rizin.
Ссылка скрыта от гостей
- фреймворк для реверс-инженеринга (форк radare2), созданный и поддерживающийся частью основной команды radare2.Cutter можно запустить на Linux, Windows и MacOs. Для Linux она поставляется в AppImage. Загрузите файл и назначьте ему права на исполнение (
chmod +x Cutter-v2.0.4-x64.Linux.AppImage
), а затем запускайте (./Cutter-v2.0.4-x64.Linux.AppImage
).В Cutter есть русский язык, возможности radare2 и встроенный декомпилятор от Ghidra.
❄❄❄ Снег! ❄❄❄
Так как уже зима и скоро Новый Год, то посмотрите на снежок в radare2
Предлагаю сделать небольшое задание. Попробуйте найти команду, которая вызывает его и отправьте её мне в личные сообщения на форуме вместе со скриншотом. Никнеймы первых 10 человек будут находиться в табличке. Удачи ^_^
Вывод.
Radare2 является хорошим инструментом для реверс-инжиниринга со множеством функций, но чтобы его освоить, нужно постараться. Особенно радует цена radare2, а точнее её отсутствие + open source. Не забывайте, что цена IDA PRO более 170 000 рублей!
Также не следует забывать о расширяемости radare2! Для него написано множество дополнений. Итог: использовать radare2 можно.
Спасибо за то, что прочитали эту статью до конца!
Последнее редактирование: