Продолжаем решать головоломки: сегодня это 1337ReverseEngineer’s VMAdventures 1 https://crackmes.one/crackme/63bd7f5733c5d43ab4ecf3ad
Задача: узнать верный пароль, на который программа выдаст «Correct key!».
Проверка пароля
С помощью дизассемблера находим строку «Correct key!» и код, что на нее ссылается. Над ним — цикл проверки пароля: eax пробегает по символам, а в edi — длина пароля.


Строка byte_4032E0 содержит непечатные символы: это не сам пароль, а хеш.

При помощи отладчика выясняется, что в esi хранится указатель на строку пароля, затем вызов loc_401170 «портит» символы.
Выполнение байт-кода
Работа функции управляется байт-кодом: цикл перебирает байты строки .rdata:004032D0 и выполняет команды. Функция предусматривает 5 случаев для следующих значений байтов: 0x0, 0x1, 0x2, 0x3, 0x4. За исключением команды 0, которая останавливает выполнение байт-кода, команды 1-4 изменяют строку пароля. Таким образом программа шифрует пароль: чтобы расшифровать, выполним обратные действия в обратном порядке.
Расшифровка пароля
Изучим команды.
0x1 Если внимательно изучать код, увидим, что на блоки размером 64 байта операцией XOR накладывается 16-байтная константа, а для остальных байтов выполняет XOR 54h. Заметим, что длина верного пароля — 32 и XOR по 64-блокам не будет выполняться. Повторное применение XOR,восстанавливает исходное значение: A XOR B XOR B = A.
0x2 Тот же алгоритм, что и у 0x1, но отличается константа: выполняет XOR 24h.
0x3 Выполняет циклический сдвиг влево на 2 бита для каждого символа пароля. Обратная операция — сдвиг вправо.
0x4 Выполняет сложение каждого байта пароля с 0xEB. Обратная операция — вычитание.

Теперь программа сама выдаст секретный пароль:
-
вводим пароль из 32-х символов
-
подадим на вход функции loc_401170 шифр пароля из .rdata:004032E0
-
изменим код loc_401170, чтобы выполнить обратные операции:
-
заменим в case 3 операцию сдвига ROL на ROR
-
заменим в case 4 сложение на вычитание
-
запишем команды байт-кода в обратном порядке
-

Несложно написать и код дешифратора.
#include <bit> #include <vector> #include <iostream> #include <string> using namespace std; using BytesVector = vector<uint8_t>; BytesVector code{0x01, 0x03, 0x04, 0x02, 0x01, 0x03, 0x02, 0x01, 0x02, 0x01, 0x03, 0x02, 0x03, 0x04, 0x02, 0x03}; void xor1(BytesVector& key) { for (auto &c: key) c ^= 0x54; } void xor2(BytesVector& key) { for (auto &c: key) c ^= 0x24; } void rol2(BytesVector& key) { for (auto &c: key) c = rotl(c, 2); } void add(BytesVector& key) { for (auto &c: key) c += 0xEB; } void ror2(BytesVector& key) { for (auto &c: key) c = rotr(c, 2); } void sub(BytesVector& key) { for (auto &c: key) c -= 0xEB; } enum Opcode { XOR1 = 0x1, XOR2, ROL, ADD, ROR, SUB }; void exec(const BytesVector& code, BytesVector& key) { for (auto i: code) { switch(i) { case XOR1: xor1(key); break; case XOR2: xor2(key); break; case ROL: rol2(key); break; case ADD: add(key); break; case ROR: ror2(key); break; case SUB: sub(key); break; } } } BytesVector explode(const string& s) { BytesVector result; for (char c: s) { result.push_back(static_cast<uint8_t>(c)); } return result; } void encrypt(BytesVector& text) { exec(code, text); } void reverseBytecode(BytesVector& code) { for (uint8_t& op: code) { switch(op) { case ROL: op = ROR; break; case ADD: op = SUB; break; case ROR: op = ROL; break; case SUB: op = ADD; break; } } } void decrypt(BytesVector& text) { BytesVector rev{code.rbegin(), code.rend()}; reverseBytecode(rev); exec(rev, text); } int main() { BytesVector magic{0xBD, 0x35, 0xA9, 0xA1, 0xD1, 0xE1, 0xD9, 0x35, 0x31, 0x01, 0x39, 0xD9, 0xAA, 0x95, 0x01, 0xAA, 0xFD, 0xB9, 0x28, 0xD5, 0x7C, 0xD9, 0x1D, 0x95, 0x99, 0xCD, 0xD9, 0xF1, 0xAA, 0xD2, 0xEE, 0xF9}; string password; cout << "Enter password: "s; cin >> password; cout << endl; BytesVector key = explode(password); encrypt(key); cout << "Encrypted: "s; for (auto k: key) { printf("%X ", k); } decrypt(key); cout << "\nDecrypted: "s; for (auto k: key) { printf("%c", k); } decrypt(magic); cout << "\nTOP SECRET: "s; for(auto b: magic) { printf("%c", b); } return 0; }
ссылка на оригинал статьи https://habr.com/ru/post/712290/
Добавить комментарий