вторник, 27 июля 2021 г.

Reverse Engineering шпаргалка.

 Сразу скажу, тут я нуб! Это шпаргалка для меня (как я решил задачу). Ну может кому ещё будет полезна. Данные черпал из Reverse Engineering for Beginners (berkeley.edu)

Вводная:

    По работе нужно было исправить логику 3rdparty библиотек, которые предоставил заказчик с хидерами и сборками как static lib в дебажном и релизном варианте. Так как были дебажные версии то решил, что RE будет не сложным. Так и получилось.

Шпаргалка:

1. Получаем asm листнинг библиотеки через утилиту dumpbin, которая идёт в составе Visual Studio.

2. В asm листинге ищем функцию, которую надо "расшифровать" простым поиском по тексту.

3. Для анманглинга имён функций используем утилиту undname из состава Visual Studio.

4. Читаем и пишем свой вариант функции (допустим на С++).

5. Пишем тест на расшифрованную логику.

6. Прогоняем через тест свою функцию и функцию из препарируемой библиотеке.


Детали.


Дело было в винде и я использовал Notepad++. Сделал вертикальный разрез. Справа был чистый asm-листинг - слева был "рабочий" файл, в котором я писал комментарии при расшифровке.


На картинке мои комментарии зелёным.
В процессе расшифровки в комментариях переменные обычно называл так, что бы по asm листингу было проще отследить. Например на скриншоте  по адресу [ebp-24h] находится адрес std::vector< uint8_t >. В комментариях я так и назвал переменную - ebp_24. Все переменные ebp-X - это локальные переменные функции.  ebp-0h - это адрес нашей функции, в которой мы "находимся". Если функция возвращает значение, то выше 0 в стеке лежит (в случае x86) адрес возвращаемой переменной. Дальше ( ebp+X ) лежат входные параметры функции. Указатели (в этом случае) занимают 8 байт, простые значения (uint8_t, uint32_t) - 4 байта или больше (double, int64_t - 8 байт). Про остальные не скажу, но это легко вычисляется при анализе.

Затем написал функцию и к ней написал тест.

На скриншоте слева код теста, а справа код, который я "родил" в процессе расшифровки. Тест пассится, но с кодом надо ещё разобраться (непонятные магические цифры - надо поглядеть предметную область и понять зачем, может в исходном коде ошибка). AfdxPack::GetIpPack - это препарируемая функция, а AfdxPack2::GetIpPack - это то, что я "родил". Как всегда, тест сильно снижает вероятность ошибки при дешифровке.


Комментариев нет:

Отправить комментарий