
Открытая библиотека команды FLARE для дизассемблирования инструкций Common Intermediate Language (CIL).

dncil — это библиотека дизассемблирования общего промежуточного языка (CIL), написанная на Python, которая поддерживает разбор заголовка, инструкций и обработчиков исключений управляемых методов .NET. Разобранные данные предоставляются через объектно-ориентированный API, что позволяет быстро разрабатывать инструменты анализа CIL с помощью dncil.
Почему Python? Существующие библиотеки, поддерживающие дизассемблирование CIL, такие как dnLib, написаны на C#. Чтобы использовать эти инструменты, необходимо создавать приложения на C#, что требует опыта разработки на C#. Используя dncil, альтернативу на чистом Python, вы:
C# для программного анализа CIL.CIL.CIL с существующими проектами на Python.Пример скрипта print_cil_from_dn_file.py использует dncil вместе с библиотекой анализа .NET dnfile для дизассемблирования управляемых методов, найденных в исполняемом файле .NET. Посмотрим, что он умеет.
Сначала скомпилируем следующий исходный код на C#:
using System;
public class HelloWorld
{
public static void Main(string[] args)
{
Console.WriteLine ("Hello World!");
}
}
В результате компиляции получается исполняемый файл PE, содержащий метаданные .NET, которые сообщают Common Language Runtime (CLR), как выполнять наш код. Мы используем dnfile для разбора этих метаданных, что даёт нам смещение нашего управляемого метода Main. Затем мы используем dncil, чтобы дизассемблировать и отобразить инструкции CIL, хранящиеся по этому адресу.
Посмотрим на это в действии:
$ python scripts/print_cil_from_dn_file.py hello-world.exe
Method: Main
0000 00 nop
0001 72 01 00 00 70 ldstr "Hello World!"
0006 28 04 00 00 0a call System.Console::WriteLine
000B 00 nop
000C 2a ret
Наш метод Main представлен классом CilMethodBody. Этот класс содержит данные, включающие заголовок, инструкции CIL и обработчики исключений заданного управляемого метода. Он также предоставляет различные вспомогательные функции:
> main_method_body.flags
SmallFormat : false
TinyFormat : false
FatFormat : false
TinyFormat1 : true
MoreSects : false
InitLocals : false
CompressedIL : false
> main_method_body.size
14
> hexdump.hexdump(main_method_body.get_bytes())
00000000: 36 00 72 01 00 00 70 28 04 00 00 0A 00 2A 6.r...p(.....*
> hexdump.hexdump(main_method_body.get_header_bytes())
00000000: 36 6
> hexdump.hexdump(main_method_body.get_instruction_bytes())
00000000: 00 72 01 00 00 70 28 04 00 00 0A 00 2A .r...p(.....*
Каждая инструкция CIL, найденная в нашем управляемом методе Main, представлена классом Instruction. Этот класс содержит данные, включающие смещение, мнемонику, опкод и операнд конкретной инструкции CIL. Он также предоставляет различные вспомогательные функции:
> len(main_method_body.instructions)
5
> insn = main_method_body.instructions[1]
> insn.offset
1
> insn.mnemonic
'ldstr'
> insn.operand
token(0x70000001)
> insn.is_ldstr()
True
> insn.size
5
> hexdump.hexdump(insn.get_bytes())
00000000: 72 01 00 00 70 r...p
> hexdump.hexdump(insn.get_opcode_bytes())
00000000: 72 r
> hexdump.hexdump(insn.get_operand_bytes())
00000000: 01 00 00 70 ...p
Чтобы установить dncil, используйте pip для загрузки модуля dncil:
$ pip install dncil
Для запуска примеров обязательно установите dnfile. В качестве альтернативы установите dncil с зависимостями для разработки, как описано в разделе Development ниже.
Смотрите print_cil_from_bytes.py для краткого примера использования dncil для вывода инструкций CIL, найденных в потоке байтов, содержащем управляемый метод .NET.
Если вы хотите изучить и изменить исходный код dncil, вам нужно скачать его с GitHub и установить локально.
Используйте следующую команду для локальной установки dncil с зависимостями для разработки:
$ pip install /local/path/to/src[dev]
Вам понадобятся зависимости dncil для разработки, чтобы запускать тесты и линтинг, как описано ниже.
Используйте следующую команду для запуска тестов:
$ pytest /local/path/to/src/tests
Используйте следующие команды для выявления ошибок форматирования:
$ black -l 120 -c /local/path/to/src
$ isort --profile black --length-sort --line-width 120 -c /local/path/to/src
$ mypy --config-file /local/path/to/src/.github/mypy/mypy.ini /local/path/to/src/dncil/ /local/path/to/src/scripts/ /local/path/to/src/tests/
dncil основан на коде разбора CIL, найденном в dnLib.