Доброго времени суток, %username%! Сегодня мы отправимся изучать бесчисленные возможности фреймворка для реверсера — radare2. В виде подопытного я взял первую попавшую бомбу, она оказалась с сайта Университета Карнеги Меллон.
md5sum: 1f38d04188a1d08f95d8c302f5361e9f
sha1sum: 31022a4baa524f6275209f7424c616226bc9814b
sha256sum: 8849e033691d51426c0c91a76eeb0c346eddd37e8fdf21cd93acd16669f1b461
О чем вообще речь?
Radare2(aka r2) — опенсорсный кроссплатформенный фреймворк, для исследования бинарных файлов(изначально, к слову, hex-редактор). Главным конкурентом оного является небезызвестная IDA Ильфака, но, увы, для студента она дороговата, а бесплатная версия с x86-64 не дружит. А еще радар вроде как круче.
Бинарная бомба или просто бомба — исполняемый файл для обучения, который получает некое количество строк, и, в случае, если все строки проходят проверки, поздравляет с этим юного аналитика. Это так называемые уровни или фазы, у нас их целых 6.
Еще немного про фреймворк
Radare2, как уже было сказано, именно фреймворк, а не просто дизассемблер. Он включает кучу различных тулз вроде дебаггера, hex-редактора, компилятора, поиска ROP-гаджетов и много чего другого. Для не любителей консоли у него также имеется два сыроватых фронтенда это WebUI(
$ r2 -c "=H" file
) и Bokken.Мануал как обычно есть в man, а также для каждой команды путем добавления после нее "?". Например, «pd?» выдаст описания команд, начинающихся на pd.
Немного ссылок по теме:
- Офф. сайт
- Бесплатная книжка
- Гитхаб
- Блог
- Cheatsheet. UPD: и еще один в пдф
- Migration guide для закоренелых идеров
- IRC-канал на Freenode
Here we go!
Помимо самого исполняемого файла нам любезно предоставили файл с исходными кодами. Однако все, что там есть — инициализация ввода, вызов фаз, и забавные комментарии. Остальные функции вытягиваются из соответствующих хэдеров, которых у нас нет.
/***************************************************************************
* Dr. Evil's Insidious Bomb, Version 1.1
* Copyright 2011, Dr. Evil Incorporated. All rights reserved.
*
* LICENSE:
*
* Dr. Evil Incorporated (the PERPETRATOR) hereby grants you (the
* VICTIM) explicit permission to use this bomb (the BOMB). This is a
* time limited license, which expires on the death of the VICTIM.
* The PERPETRATOR takes no responsibility for damage, frustration,
* insanity, bug-eyes, carpal-tunnel syndrome, loss of sleep, or other
* harm to the VICTIM. Unless the PERPETRATOR wants to take credit,
* that is. The VICTIM may not distribute this bomb source code to
* any enemies of the PERPETRATOR. No VICTIM may debug,
* reverse-engineer, run "strings" on, decompile, decrypt, or use any
* other technique to gain knowledge of and defuse the BOMB. BOMB
* proof clothing may not be worn when handling this program. The
* PERPETRATOR will not apologize for the PERPETRATOR's poor sense of
* humor. This license is null and void where the BOMB is prohibited
* by law.
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "support.h"
#include "phases.h"
/*
* Note to self: Remember to erase this file so my victims will have no
* idea what is going on, and so they will all blow up in a
* spectaculary fiendish explosion. -- Dr. Evil
*/
FILE *infile;
int main(int argc, char *argv[])
{
char *input;
/* Note to self: remember to port this bomb to Windows and put a
* fantastic GUI on it. */
/* When run with no arguments, the bomb reads its input lines
* from standard input. */
if (argc == 1) {
infile = stdin;
}
/* When run with one argument <file>, the bomb reads from <file>
* until EOF, and then switches to standard input. Thus, as you
* defuse each phase, you can add its defusing string to <file> and
* avoid having to retype it. */
else if (argc == 2) {
if (!(infile = fopen(argv[1], "r"))) {
printf("%s: Error: Couldn't open %s\n", argv[0], argv[1]);
exit(8);
}
}
/* You can't call the bomb with more than 1 command line argument. */
else {
printf("Usage: %s [<input_file>]\n", argv[0]);
exit(8);
}
/* Do all sorts of secret stuff that makes the bomb harder to defuse. */
initialize_bomb();
printf("Welcome to my fiendish little bomb. You have 6 phases with\n");
printf("which to blow yourself up. Have a nice day!\n");
/* Hmm... Six phases must be more secure than one phase! */
input = read_line(); /* Get input */
phase_1(input); /* Run the phase */
phase_defused(); /* Drat! They figured it out!
* Let me know how they did it. */
printf("Phase 1 defused. How about the next one?\n");
/* The second phase is harder. No one will ever figure out
* how to defuse this... */
input = read_line();
phase_2(input);
phase_defused();
printf("That's number 2. Keep going!\n");
/* I guess this is too easy so far. Some more complex code will
* confuse people. */
input = read_line();
phase_3(input);
phase_defused();
printf("Halfway there!\n");
/* Oh yeah? Well, how good is your math? Try on this saucy problem! */
input = read_line();
phase_4(input);
phase_defused();
printf("So you got that one. Try this one.\n");
/* Round and 'round in memory we go, where we stop, the bomb blows! */
input = read_line();
phase_5(input);
phase_defused();
printf("Good work! On to the next...\n");
/* This phase will never be used, since no one will get past the
* earlier ones. But just in case, make this one extra hard. */
input = read_line();
phase_6(input);
phase_defused();
/* Wow, they got it! But isn't something... missing? Perhaps
* something they overlooked? Mua ha ha ha ha! */
return 0;
}
После запуска r2 он встречает нас случайной фразой. Затем он ставит текущий указатель на entry-point и ждет команды. Флажок -А при открытии файла сразу же его анализирует.
Тоже самое можно сделать блоком команд начинающихся, на a), к примеру afl — достает из бинарника список функций. ~ — аналог grep-a(фильтра). Поищем у него наши функции.
$ r2 -A bomb
-- In soviet Afghanistan, you debug radare2!
[0x00400c90]> afl~phase
0x00400ee0 28 3 sym.phase_1
0x004015c4 149 8 sym.phase_defused
0x00400efc 71 8 sym.phase_2
0x00400f43 139 8 sym.phase_3
0x0040100c 86 7 sym.phase_4
0x00401062 146 9 sym.phase_5
0x004010f4 272 26 sym.phase_6
0x00401242 81 5 sym.secret_phase
Level 1
Чудесно, все функции из исходника на месте, а заодно еще и нашли секретную фазу. Давайте наконец посмотрим содержимое первого уровня. Сделать это можно, сместив указатель на определенный адрес функции, а затем вывести нужное количество опкодов для дизассемблирования.
[0x00400c90]> s 0x00400ee0 # В данном случае 's' - не обязательно
[0x00400ee0]> pd 8 # дизассемблировать 8 опкодов от текущего смещения
Т.к. вывод r2 из коробки просто прекрасен, то для наглядности ради буду ассемблерные листинги постить в виде картинок.
Обратите внимание, что радар снабдил нас XREF-ами(то откуда может быть передано управление) с мнемониками прыжка. Кроме того, подставил строку по указанному адресу и самое главное — показал в виде ascii-стрелок переходы в блоке.
0000000000400ee0 <phase_1>:
400ee0: 48 83 ec 08 sub rsp,0x8
400ee4: be 00 24 40 00 mov esi,0x402400
400ee9: e8 4a 04 00 00 call 401338 <strings_not_equal>
400eee: 85 c0 test eax,eax
400ef0: 74 05 je 400ef7 <phase_1+0x17>
400ef2: e8 43 05 00 00 call 40143a <explode_bomb>
400ef7: 48 83 c4 08 add rsp,0x8
400efb: c3 ret retq
Даже не вникая, становится ясно, что первая необходимая нам строка — «Border relations with Canada have never been better.». И само собой, при скармливании ее бомбе, она, пускает нас на вторую фазу.
$ ./bomb
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Border relations with Canada have never been better.
Phase 1 defused. How about the next one?
Level 2
Второй вариант вывода дизассемблированной функции — с помощью абсолютной адресации/меток. На примере второй фазы — это будет выглядеть так:
[0x00400ee0]> pdf @ 0x00400efc
либо, если адрес не известен:
[0x00400ee0]> pdf @ sym.phase_2
Конечная цель у нас — не взорвать бомбу, т.е. не делать вызовов call sym.explode_bomb, так что от этого и будем отталкиваться. Следовательно, у нас всегда должны срабатывать оба прыжка je.
Первое, что стоит у нас на пути — вызов call sym.read_six_numbers. Соответственно после этого вызова на верху стека должна быть единица. Посмотрим, что происходит в этой функции.
Раньше r2 разбирал файлы на функции основываясь на опкоде ret, что нередко приводило к выводу нескольких функций(например, при наличии системных вызовов exit()). В подобных случаях, когда радар неправильно определяет функции можно сделать это вручную.
[0x00400ee0]> s 0x0040149e # двигаем указатель на опкод после конца
[0x0040149e]> af+ sym.read_six_numbers `?vi $$-sym.read_six_numbers` rsn # Определение функции rsn, начинающейся с метки sym.read_six_numbers до текущего указателя.
Кстати, в этом примере использовалась другая команда как аргумент первой с помощью парных скобок``.
В самой функции не происходит ничего интересного, она из считанной строки достает 6 чисел и записывает их по порядку в переданный указатель. Затем убеждается, что чисел больше 5.
В Си бы это выглядело примерно так:
void read_six_numbers(char *str, long long *p) {
if (sscanf(str, "%d %d %d %d %d %d", p, p+1, p+2, p+3, p+4, p+5) <= 5)
explode_bomb();
}
Вернемся к нашей функции phase_2. Указатель на массив передается указатель на вершину стека(mov rsi, rsp). Следовательно, первое число в строке должно быть — 1.
Как вы могли заметить там достаточно много переходов. Пользователь IDA скорей всего нажал бы пробел и посмотрел граф переходов. Вы не поверите, но тут они тоже есть. Подобно vim тут есть visual-mode (команда V) и в нем присутствует тот самый граф переходов, тоже по команде V(либо сразу VV). Выход из каждого мода — q
Отображается он прекрасно, с минимум пересечений(по сравнению с прошлыми версиями). Подвигать это чудо можно стрелками, либо vim-like 'hjkl'. Если же вам не нравится расположение блоков их также можно двигать хоткеями Shift+'hjkl'. При этом двигается выбранный блок(синий), выбрать его можно Tab/Shift-Tab.
В первом блоке в rbx записывается указатель на второе число, а в rbp — на конец массива чисел. И управление перекидывается на цикл, в котором попарно сравниваются соседние числа.
mov eax, dword [rbx - 4] ; Положить предыдущее число в eax
add eax, eax ; Удвоить его
cmp dword [rbx], eax ; Сравнить с текущим
je 0x400f25 ; Продолжить цикл, если равны
call sym.explode_bomb ; Взорвать бомбу, если не равны
add rbx, 4 ; Сдвинуть указатель на следующее число
cmp rbx, rbp ; Проверить, в конце ли мы массива
jne 0x400f17 ; Если нет, то вернутся в начало
jmp 0x400f3c ; Завершить цикл
Получается, что нам нужно ввести последовательность степеней двойки от 1 до 32. Отлично, но все-таки проверим, что это то, что нужно.
$ ./bomb
...
Phase 1 defused. How about the next one?
1 2 4 8 16 32
That's number 2. Keep going!
Level 3
Наверно сейчас человек, далекий от ассемблера, в эпилептических припадках пытается попасть по крестику на краю окна. На самом деле бояться тут нечего, просто так выглядит самый обычный switch-case блок.
Числа считываются аналогично предыдущему случаю, только без вызова функции и всего два. Хранятся они в [rsp+8] и [rsp+0xc] соответственно.
Затем идут проверки, что оба числа считаны успешно, а также первый аргумент не больше 7. После чего и происходит тот самый switch переход по адресу 0x402470 со смещением (введенное число)*8.
Не трудно догадаться, что там лежат адреса case-меток. Дабы не быть голословным, посмотрим, что там действительно лежит. Сделать это можно с помощью групп команд px. В данном случае нас интересуют 8-байтные слова(Quad-word).
[0x0040149e]> pxQ 72 @ 0x402470
0x00402470 0x0000000000400f7c sym.phase_3+57
0x00402478 0x0000000000400fb9 sym.phase_3+118
0x00402480 0x0000000000400f83 sym.phase_3+64
0x00402488 0x0000000000400f8a sym.phase_3+71
0x00402490 0x0000000000400f91 sym.phase_3+78
0x00402498 0x0000000000400f98 sym.phase_3+85
0x004024a0 0x0000000000400f9f sym.phase_3+92
0x004024a8 0x0000000000400fa6 sym.phase_3+99
Собственно, что и ожидалось, хотя не совсем последовательно. Дальше идет проверка второго нашего числа с тем магическим, что было записано в eax при свитче. Так как ввод в десятичном основании придется переконвертировать из hex-а. Посчитать можно это с помощью rax2(аналог калькулятора) через вызов шелла, а также напрямую, через встроенный калькулятор(хоткей — ?), не создавая новых программ. А, дабы не жмакать постоянно enter можно группировать команды прям как в баше.
[0x0040149e]> !rax2 0xcf
207
[0x0040149e]> ?vi 0x2c3; ?vi 0x100; ?vi 0x185; ?vi 0xce; ?vi 0x2aa; ?vi 0x147; ?vi 0x137
707
256
389
206
682
327
311
Итого возможные решения будут:
- 0 207
- 1 311
- 2 707
- 3 256
- 4 389
- 5 206
- 6 682
- 7 327
И лишний раз убедимся, на произвольном варианте, что все работает:
$ ./bomb
...
That's number 2. Keep going!
4 389
Halfway there!
Level 4
На этом уровне появляется рекурсия. Помимо встроенных ASCII-графов также есть возможность получить графы в виде файлов для dot утилиты, а затем, например, переконвертить в png.
[0x0040149e]> ag sym.func4 > func4.dot
[0x0040149e]> dot -Tpng -o func4.png func4.dot
Если все это перевести в Си, то будет выглядеть почти не так страшно.
void phase_4(char *str) {
int x, y;
if (sscanf(str, "%d %d", &x, &y) != 2 ||
x > 14 ||
func4(x, 0, 14) ||
y != 0)
explode_bomb();
}
int func4(int x, int y, int z) {
unsigned diff = (z - y)/2;
int p = y + diff;
if (p > x) {
func4(x, y, p-1);
return diff * 2;
} else if (p < x) {
func4(x, p + 1, z);
return diff * 2 + 1;
}
return 0;
}
Самое простое и очевидное решение — функция func4 возвращает 0, когда она не заходит внутрь else-if. Ввод пользователя управляет только x, а p=7 при первом заходе. Соответственно при x=7 функция просто вернет 0, без рекуррентных вызовов. Вторая же переменная строго задана нулем. Убедимся в этом.
$ ./bomb in.tmp
...
Halfway there!
7 0
So you got that one. Try this one.
Level 5
С этим будет сложнее, тут нагромождено очень много кода.
В 0x00401073 записывается канарейка на стек. Подобную информацию о бинарнике можно достать с помощью команды i. К примеру, i~canary вернет в данном случае true.
После этого возвращаемое значение string_length сравнивается с 6 и начинается трудно анализируемый спагетти-код. Разбираться без дебагера с этим долго и сложно, поэтому будет грех им не воспользоваться. Для этого надо открыть файл с флагом дебага либо при запуске:
$ r2 -Ad bomb
либо просто переоткрыв файл:
[0x0040149e]> ood
Адрес указателя при этом автоматически поменяется на первый опкод в entry-point, который уже подгружен в память. Как обычно ставим breakpoints и продолжаем выполнение до них.
[0x7f2960b99d80]> db sym.phase_5 # либо s sym.phase_5; db $$
[0x7f2960b99d80]> dc # продолжить выполнение до 1 брейкпоинта
Дальше есть 2 способа анализа: первый — использовать блок команд d/db, второй — переключиться в Visual-mode. Первый способ не такой наглядный, поэтому остановимся на втором.
Как и раньше переходим Visual-mode, а затем выбираем необходимый debug-layout для отладки хоткеями p/P.
Перемешаться по код можно с помощью n/N — следующая/предыдущая функция; j/k — следующий предыдущий опкод.
И самое интересное: b/F2 — поставить брейкпоинт, s/F7 — шаг в 1 опкод, S/F8 — шаг в 1 опкод не заходя в call, F9 — продолжить до брейкпоинта.
Итого поскармливав дебаггеру несколько строк, не трудно догадаться, что там происходит.
Для каждого символа из нашей строки по модулю 16 берется соответствующий символ из строки
char *s = "maduiersnfotvbyl"
и полученная строка сравнивается «flyers».Собственно наша задача и найти такие символы, индексы которых в str дают искомую строку.
Строку flyers получить можно единственным образом: {s[0x9], s[0xe], s[0xf], s[0x5], s[0x6], s[0x7]}. Думаю, ASCII таблицу в голове хранит не каждый, посему можно снова обратиться к утилите rax2 за помощью. С ключом -s он конвертит из hex в string. Т.к. символы берутся по модулю 16, то для эстетичности можно подобрать печатаемые значения.
$ rax2 -s 49 4e 4f 45 46 47
IONEFG
$ ./bomb
...
So you got that one. Try this one.
IONEFG
Good work! On to the next...
The Last One
Так как статья вышла великовата все фазы я рассматривать не буду. В частности, 6 фазу я опущу, ибо там достаточно много кропотливого вникания без непосредственного участия фреймворка. Пусть это останется домашним заданием самым любознательным.
В секретную фазу попасть не так просто, посему упростим себе жизнь пропатчив бинарник. Открыть файл нам придется заново, выдав права на запись флажком -w, либо переоткрыть с помощью oo+ не выходя из r2.
$ r2 -Aw bomb
-- Did you ever ordered a pizza using radare2?
[0x00400c90]> s 0x00400ec6 # call sym.phase_6
[0x00400ec6]> wa call sym.secret_phase # запись нужных опкодов
[0x00400ec6]> pdf @ sym.secret_phase; pdf @ sym.fun7
Опять появляется рекурсивная функция и на этот раз ее так просто не обойти, ибо без рекурсивных вызовов нужное значение так просто, как было в прошлый раз, не получить. ASCII-граф снова может упростить жизнь.
Анализ дает примерно такой аналог на Си:
void secret_phase() {
long num = strtol(read_line()) - 1;
if (num > 0x3e8 ||
fun7((long*)(0x6030f0), num) != 2)
explode_bomb();
puts("Wow! You've defused the secret stage!");
phase_defused();
}
int fun7(long *array, int num) {
if (array == 0)
return -1;
if (*array <= num) {
if (*array == num)
return 0; // 1
else {
return 2 * fun7(array + 1, num); // 2
}
} else {
return 2 * fun7(array + 2, num) + 1; // 3
}
}
Итого, чтобы получить на выходе fun7 именно двойку, нам надо вначале вызвать ret на 2 строке, затем на 3 и наконец на 1. Остается лишь одна загадка — что хранится по адресу 0x6030f0.
[0x00401204]> px 480 @ 0x6030f0
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x006030f0 2400 0000 0000 0000 1031 6000 0000 0000 $........1`.....
0x00603100 3031 6000 0000 0000 0000 0000 0000 0000 01`.............
0x00603110 0800 0000 0000 0000 9031 6000 0000 0000 .........1`.....
0x00603120 5031 6000 0000 0000 0000 0000 0000 0000 P1`.............
0x00603130 3200 0000 0000 0000 7031 6000 0000 0000 2.......p1`.....
0x00603140 b031 6000 0000 0000 0000 0000 0000 0000 .1`.............
0x00603150 1600 0000 0000 0000 7032 6000 0000 0000 ........p2`.....
0x00603160 3032 6000 0000 0000 0000 0000 0000 0000 02`.............
0x00603170 2d00 0000 0000 0000 d031 6000 0000 0000 -........1`.....
0x00603180 9032 6000 0000 0000 0000 0000 0000 0000 .2`.............
0x00603190 0600 0000 0000 0000 f031 6000 0000 0000 .........1`.....
0x006031a0 5032 6000 0000 0000 0000 0000 0000 0000 P2`.............
0x006031b0 6b00 0000 0000 0000 1032 6000 0000 0000 k........2`.....
0x006031c0 b032 6000 0000 0000 0000 0000 0000 0000 .2`.............
0x006031d0 2800 0000 0000 0000 0000 0000 0000 0000 (...............
0x006031e0 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x006031f0 0100 0000 0000 0000 0000 0000 0000 0000 ................
0x00603200 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00603210 6300 0000 0000 0000 0000 0000 0000 0000 c...............
0x00603220 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00603230 2300 0000 0000 0000 0000 0000 0000 0000 #...............
0x00603240 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00603250 0700 0000 0000 0000 0000 0000 0000 0000 ................
0x00603260 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00603270 1400 0000 0000 0000 0000 0000 0000 0000 ................
0x00603280 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x00603290 2f00 0000 0000 0000 0000 0000 0000 0000 /...............
0x006032a0 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x006032b0 e903 0000 0000 0000 0000 0000 0000 0000 ................
0x006032c0 0000 0000 0000 0000 0000 0000 0000 0000 ................
Тут хранятся 8-байтные переменные блоками по 4. Первая используется для сравнения с нашим числом; второе и третье — указатели на следующие символы для сравнения; четвертое — просто паддинг, не используется.
Теперь можно разложить все условия и найти искомую переменную.
- 2 ret: num < 0x24
- 3 ret: num > 0x08
- 1 ret: num == 0x16
$ ./bombSec in.tmp
...
Good work! On to the next...
22
Wow! You've defused the secret stage!
Congratulations! You've defused the bomb!
Еху, мы сделали это!
Комментарии (26)
tmnhy
08.01.2016 17:24-5Такая мысль крутилась постоянно пока читал «кто все эти люди», т.е. о чём, про что и зачем. Напряг то, что осталось, «о чём и про что» — понял, но вот «зачем» — так и осталось загадкой…
Когда-то, в прошлой жизни, приходилось и инлайн-вставки писать на асме и софтайсом пользоваться. В нынешней, на 2/3 головоломки из TIS-100 прошел, потом надоело. Вроде бы тема должна была меня интересной, но не пошло что-то…
Идея для продолжения: объясните мне про «зачем» ))) Пжлста, заинтересуйте!CodeRush
08.01.2016 17:31+3Чтобы лучше понимать, как все работает на самом деле, во что компилируется switch и почему именно в это. Эти знания помогут потом в отладке сложных проблем, за решением которых понадобиться опуститься до уровня машинного кода и прямого взаимодействия с железом. Если вы думате, что никогда не столкнетесь с такими проблемами — это только потому, что с вашими системами до вас работала куча людей, столкнулась с ними, и сделала все, чтобы вам это было не нужно. Ну и прочтите вот эту статью, станет немного понятнее.
monah_tuk
08.01.2016 18:03+3Зачем? Мне, например, для этого: habrahabr.ru/post/249991, что бы потом обычная разработка стала комфортной. И да, до меня, наконец, дошло, как, примерно, работает вытесняющая многозадачность :)
Кстати, не хватало простых обзорных статей по radare2, приходилось xref стрелочки самому рисовать.dukebarman
09.01.2016 02:47+1Про какой именно функционал Вы бы хотели прочитать в первую очередь? Нам казалось, что простых обзорных хватает :), хотя они и в основной массе на английском языке.
Для тех, кто не «любит» IRC и телеграмм чаты, еще есть форум для общения как русско-, так и англоговорящих пользователей radare2, который в скором времени планируем официально представить после решения организационных моментов, но там уже можно задавать вопросы.monah_tuk
09.01.2016 03:56+1Даже не могу точно сказать. Погуглил, попробовал, почитал, что-то сходу не получилось. Взял классику. Просто времени разобраться не было.
А вот за форум — спасибо.
mark_ablov
08.01.2016 18:47+1Не, не брошу иду ;)
Уже и ids'ов куча написано, и пара плагинов.
Правда поглядел что процессорные модули можно достаточно просто писать для r2, но в принципе и для IDA это не такая уж и проблема.xvilka
08.01.2016 21:38+2radare2 тоже понимает FLIRT сигнатуры от IDA Pro — см. команду `zF [file]` (z?)
farcaller
08.01.2016 19:06А есть что-то почитать на тему анализа «сырых» бинарников? Конкретно такой пример: есть файл, в нем надо взять адрес из
*((unsigned int*)0x4)
, дизассемблировать как функцию, найти XREF'ы, вывести листинг и умереть.
edeldm
09.01.2016 16:14Еще одно средство для реверса — это здорово!
Но!
Как насчет Олечки с бесчисленным морем плагинов для реверса, сокрытия от обнаружения, анализа дампов, стека, построения графов потока управления и др.?
И также бесплатной x64dbg?
В чем существенное отличие от них? Они не менее популярны, чем IDA.
Для отладки часто используется Оля, а IDA незаменима в связке с HexRays декомпилятором.l4l
09.01.2016 16:47+3Что olly, что x64dbg работают только под win32. Мне, к примеру, не очень удобно постоянно поднимать ради этого виртуалку. К тому же одна из главных прелестей радара — все есть из коробки, соответственно ничего искать и ставить не нужно.
xvilka
11.01.2016 18:36Я бы еще добавил, что x64dbg не поддерживает удаленную отладку, как это делает WinDbg, radare2 это поддерживает. Ну и x64dbg парсит PDB символы с использованием интерфейса DIA, так что .EXE файл не открыть на Linux/OS X с подтягиванием символов. У нас — свой парсер символов.
destroy
09.01.2016 19:36В windows версии нету файла r2.exe
destroy
09.01.2016 19:59+1Еще такой баг, в cmd.exe не вставляет текст из буфера, вернее только один символ. Такое чувство что windows версию вообще не тестировали, т.к. это баг очевидный, или авторы предлагают адреса вручную вписывать? :)
dukebarman
09.01.2016 21:15destroy, Вы в какой-то степени правы :) Windows версия находится в стадии тестирования, так как основные ОС это различные представители семейства *NIX, поэтому будем рады любому конструктивному фидбэку (можно в ПМ, можно сразу на github-ссылку проекта в виде багов). Пока что одно из решений не использовать cmd, а к примеру conemu (ответ представителя команды разработчиков twitter.com/Maijin212/status/685879093024440320)
destroy
09.01.2016 21:20+1Так я использую conemu, там видимо какие-то настройки надо выставить…
dukebarman
10.01.2016 02:24Спасибо! Баг подтвердили и отправили в трэкер проекта на github. Скоро поправят.
На счет r2 тоже придумаем что-нибудь
RainM
11.01.2016 13:40+1Пробовал Radare2 несколько лет назад… но определение тела функций по наличию ret убило все желание дальше изучать.
xvilka
Советую попробовать включить юникод командой 'e scr.utf8=true' и True Colour 'e scr.truecolor=true'. И поменять цветовую схему командой 'eco'
l4l
Да уже стоит и похоже с вашей цветовой схемой :)
Просто хотел сам пост написать с радаром из коробки
xvilka
По поводу — 'wa' — есть визуальный режим ассемблера, в том числе и с графовым представлением, и cfg обновляется на лету, в случае необходимости.
xvilka
Да, забыл упомянуть про увеличение места для reflines справа 'e asm.lineswidth'
CodeRush
//@xvilka, где моя Apply structure offset? Еще пару месяцев подожду и пойду хакать её сам. :)
По теме — отличная статья и ссылки, большое спасибо.
xvilka
Каюсь, посыпаю голову пеплом, вот вернусь с новогодних каникул, и займусь.