Доброго времени суток, %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.

Немного ссылок по теме:

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-стрелок переходы в блоке.
Для сравнения вывод с objdump
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
На выводе будет вот такой милый ASCII граф


Отображается он прекрасно, с минимум пересечений(по сравнению с прошлыми версиями). Подвигать это чудо можно стрелками, либо 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


sym.phase_4


sym.func4


На этом уровне появляется рекурсия. Помимо встроенных 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

secret_phase


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.
480 байт
[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)


  1. xvilka
    08.01.2016 17:10
    +3

    Советую попробовать включить юникод командой 'e scr.utf8=true' и True Colour 'e scr.truecolor=true'. И поменять цветовую схему командой 'eco'


    1. l4l
      08.01.2016 17:15
      +3

      Да уже стоит и похоже с вашей цветовой схемой :)
      Просто хотел сам пост написать с радаром из коробки


      1. xvilka
        08.01.2016 17:17

        По поводу — 'wa' — есть визуальный режим ассемблера, в том числе и с графовым представлением, и cfg обновляется на лету, в случае необходимости.


    1. xvilka
      08.01.2016 17:15

      Да, забыл упомянуть про увеличение места для reflines справа 'e asm.lineswidth'


    1. CodeRush
      08.01.2016 17:19

      //@xvilka, где моя Apply structure offset? Еще пару месяцев подожду и пойду хакать её сам. :)
      По теме — отличная статья и ссылки, большое спасибо.


      1. xvilka
        08.01.2016 21:39
        +3

        Каюсь, посыпаю голову пеплом, вот вернусь с новогодних каникул, и займусь.


  1. tmnhy
    08.01.2016 17:24
    -5

    Такая мысль крутилась постоянно пока читал «кто все эти люди», т.е. о чём, про что и зачем. Напряг то, что осталось, «о чём и про что» — понял, но вот «зачем» — так и осталось загадкой…

    Когда-то, в прошлой жизни, приходилось и инлайн-вставки писать на асме и софтайсом пользоваться. В нынешней, на 2/3 головоломки из TIS-100 прошел, потом надоело. Вроде бы тема должна была меня интересной, но не пошло что-то…

    Идея для продолжения: объясните мне про «зачем» ))) Пжлста, заинтересуйте!


    1. CodeRush
      08.01.2016 17:31
      +3

      Чтобы лучше понимать, как все работает на самом деле, во что компилируется switch и почему именно в это. Эти знания помогут потом в отладке сложных проблем, за решением которых понадобиться опуститься до уровня машинного кода и прямого взаимодействия с железом. Если вы думате, что никогда не столкнетесь с такими проблемами — это только потому, что с вашими системами до вас работала куча людей, столкнулась с ними, и сделала все, чтобы вам это было не нужно. Ну и прочтите вот эту статью, станет немного понятнее.


    1. monah_tuk
      08.01.2016 18:03
      +3

      Зачем? Мне, например, для этого: habrahabr.ru/post/249991, что бы потом обычная разработка стала комфортной. И да, до меня, наконец, дошло, как, примерно, работает вытесняющая многозадачность :)

      Кстати, не хватало простых обзорных статей по radare2, приходилось xref стрелочки самому рисовать.


      1. dukebarman
        09.01.2016 02:47
        +1

        Про какой именно функционал Вы бы хотели прочитать в первую очередь? Нам казалось, что простых обзорных хватает :), хотя они и в основной массе на английском языке.

        Для тех, кто не «любит» IRC и телеграмм чаты, еще есть форум для общения как русско-, так и англоговорящих пользователей radare2, который в скором времени планируем официально представить после решения организационных моментов, но там уже можно задавать вопросы.


        1. monah_tuk
          09.01.2016 03:56
          +1

          Даже не могу точно сказать. Погуглил, попробовал, почитал, что-то сходу не получилось. Взял классику. Просто времени разобраться не было.

          А вот за форум — спасибо.


  1. SadhooKlay
    08.01.2016 18:17
    +2

    Это просто прекрасно


  1. mark_ablov
    08.01.2016 18:47
    +1

    Не, не брошу иду ;)
    Уже и ids'ов куча написано, и пара плагинов.
    Правда поглядел что процессорные модули можно достаточно просто писать для r2, но в принципе и для IDA это не такая уж и проблема.


    1. xvilka
      08.01.2016 21:38
      +2

      radare2 тоже понимает FLIRT сигнатуры от IDA Pro — см. команду `zF [file]` (z?)


  1. farcaller
    08.01.2016 19:06

    А есть что-то почитать на тему анализа «сырых» бинарников? Конкретно такой пример: есть файл, в нем надо взять адрес из *((unsigned int*)0x4), дизассемблировать как функцию, найти XREF'ы, вывести листинг и умереть.


  1. edeldm
    09.01.2016 16:14

    Еще одно средство для реверса — это здорово!
    Но!
    Как насчет Олечки с бесчисленным морем плагинов для реверса, сокрытия от обнаружения, анализа дампов, стека, построения графов потока управления и др.?
    И также бесплатной x64dbg?

    В чем существенное отличие от них? Они не менее популярны, чем IDA.

    Для отладки часто используется Оля, а IDA незаменима в связке с HexRays декомпилятором.


    1. l4l
      09.01.2016 16:47
      +3

      Что olly, что x64dbg работают только под win32. Мне, к примеру, не очень удобно постоянно поднимать ради этого виртуалку. К тому же одна из главных прелестей радара — все есть из коробки, соответственно ничего искать и ставить не нужно.


    1. xvilka
      11.01.2016 18:36

      Я бы еще добавил, что x64dbg не поддерживает удаленную отладку, как это делает WinDbg, radare2 это поддерживает. Ну и x64dbg парсит PDB символы с использованием интерфейса DIA, так что .EXE файл не открыть на Linux/OS X с подтягиванием символов. У нас — свой парсер символов.


  1. destroy
    09.01.2016 19:36

    В windows версии нету файла r2.exe


    1. destroy
      09.01.2016 19:59
      +1

      Еще такой баг, в cmd.exe не вставляет текст из буфера, вернее только один символ. Такое чувство что windows версию вообще не тестировали, т.к. это баг очевидный, или авторы предлагают адреса вручную вписывать? :)


      1. dukebarman
        09.01.2016 21:15

        destroy, Вы в какой-то степени правы :) Windows версия находится в стадии тестирования, так как основные ОС это различные представители семейства *NIX, поэтому будем рады любому конструктивному фидбэку (можно в ПМ, можно сразу на github-ссылку проекта в виде багов). Пока что одно из решений не использовать cmd, а к примеру conemu (ответ представителя команды разработчиков twitter.com/Maijin212/status/685879093024440320)


        1. destroy
          09.01.2016 21:20
          +1

          Так я использую conemu, там видимо какие-то настройки надо выставить…


          1. dukebarman
            10.01.2016 02:24

            Спасибо! Баг подтвердили и отправили в трэкер проекта на github. Скоро поправят.

            На счет r2 тоже придумаем что-нибудь


    1. l4l
      09.01.2016 20:08
      +1

      r2 — мягкая ссылка на radare2: r2.exe = radare2.exe


  1. REU
    09.01.2016 21:28
    -10

    Да радар говно, юзайте иду. )


  1. RainM
    11.01.2016 13:40
    +1

    Пробовал Radare2 несколько лет назад… но определение тела функций по наличию ret убило все желание дальше изучать.