Создайте базу данных с кодом операции

#python #c #reverse-engineering

#python #c #обратный инжиниринг

Вопрос:

Я стал больше интересоваться обращением двоичных файлов с тех пор, как АНБ выпустило Ghidra, в котором есть встроенная функция, которая создает псевдокод C из дизассемблирования двоичного файла.

У меня была идея создать базу данных с кодом операции с соответствующей сборкой и кодом C. Я хочу написать инструмент, который может выводить двоичный файл, такой как readelf и objdump, извлекать символы и функции из исходного файла C и объединять все это

Итак, чтобы сделать это более понятным, давайте рассмотрим один пример.

Мы загружаем vim-исходный код в систему Ubuntu. Мы компилируем ее с помощью ./configure и ./make. Когда двоичный файл готов, мы запускаем наш инструмент, извлекаем коды операций символов, создаем из кода ассемблерный код, извлекаем функцию и тело функции из .c-файла, объединяем все это и записываем в базу данных.

Итак, база данных должна содержать следующий материал:

исходный код c-функции, подобный

 int main()
{ 
  return 0; 
}
  

Ассемблер может выглядеть как:

 push rbp
mov rbp, rsp
...
ret
  

и раздел с кодом операции, подобный:

 55 48 89 e5 89 7d ec 89 75 ...
  

Итак, мой вопрос… Имеет ли смысл каталогизировать эти данные, чтобы использовать это, возможно, в качестве плагина в дизассемблере? Идея заключалась в том, что плагин может отправлять коды операций в веб-сервис и получать возможные исходные коды c обратно. Таким образом, декомпилятор может использовать это, чтобы удалить псевдокод и заменить его примерами реального кода.

Я знаю, что это не так просто, потому что у нас разные компиляторы, архитектуры, версии, порядковые номера и так далее. Но в целом, с большой базой данных, содержащей коды операций для каждой архитектуры / версии / компилятора, должно быть возможно упростить обратное проектирование неизвестных двоичных файлов.

Я собрал код для этого вчера, но я не уверен, будет ли это полезно для расширения дизассемблеров.

Чтобы получить представление об этом, вот пример небольшого calc-инструмента, который я написал на c, и выходные данные моего инструмента еще:

 |==================================================================|
| Adress             | Function                       | Size       |
|====================|================================|============|
| 0x0000000000000679 | add                            | 33         |
|==================================================================|
| OPCode                                                           |
|==================================================================|
| 55 48 89 e5 89 7d ec 89 75 e8 c7 45 fc 00 00 00 00 8b 55 ec 8b   |
| 45 e8 01 d0 89 45 fc 8b 45 fc 5d c3                              |
|==================================================================|
| Assembler                                                        |
|==================================================================|
| 0x1000  : push        rbp                                |
| 0x1001  : mov         rbp, rsp                           |
| 0x1004  : mov         dword ptr [rbp - 0x14], edi        |
| 0x1007  : mov         dword ptr [rbp - 0x18], esi        |
| 0x100a  : mov         dword ptr [rbp - 4], 0             |
| 0x1011  : mov         edx, dword ptr [rbp - 0x14]        |
| 0x1014  : mov         eax, dword ptr [rbp - 0x18]        |
| 0x1017  : add         eax, edx                           |
| 0x1019  : mov         dword ptr [rbp - 4], eax           |
| 0x101c  : mov         eax, dword ptr [rbp - 4]           |
| 0x101f  : pop         rbp                                |
| 0x1020  : ret                                            |
|==================================================================|
| Source                                                           |
|==================================================================|
| int add(int a, int b)                                            |
| {                                                                |
|   int c = 0;                                                      |
|   c = a   b;                                                      |
|   return c;                                                       |
| }                                                                |
|                                                                  |
|==================================================================|
  

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

1. Не уверен, в чем здесь вопрос. Несколько человек / компаний выпустили дизассемблеры с разной степенью успеха. Если вы хотите быть следующим, кто попробует это, дерзайте.

2. Отличная проблема.Но: сложно. Пожалуйста, продолжайте. (вы уже исследовали самоизменяющийся код?)

3. Нет, я этого еще не делал. Есть ли у вас какие-либо примеры кода для этого, чтобы я мог с этим работать?

Ответ №1:

Такие базы данных с кодом операции уже реализованы в различных компиляторах, которые компилируются в машинный код.

Например, LLVM имеет такие базы данных в виде файлов языка TableGen. Внутренние дизассемблеры в основном автоматически генерируются на основе этих описаний. Взгляните, например, на серверную часть Sparc.

Такие проекты, как Capstone Disassembler, используют LLVM для дизассемблирования кода для различных процессоров.