
![]() | Binlex - бинарная каркас Lexer Genetic Cirt Lexer Если Maldevs думают, что их бинар - это FUD, они собираются иметь экзистенциальный кризис. |
Binlex - это инструмент для аналитиков и исследователей вредоносных программ, который извлекает инструкции , основные блоки и функции из бинарных файлов и организует их в структурированную иерархию геномов , хромосом , пары аллелей и генов . ??
Этот иерархический разбил позволяет Binlex анализировать и сравнивать бинарные районы вредоносных программ, обрабатывая их структуру кода, как «отпечатки пальцев ДНК», облегчая обнаружение закономерности, сходства и вариации между образцами.
В отличие от инструментов, основанных на Pure Python , который может быть медленным?, Binlex разработан для скорости, простоты и гибкости. Его интерфейс командной строки помогает аналитикам искать шаблоны в сотнях или тысячах образцов вредоносных программ , экономя время и ресурсы ?
Для разработчиков Binlex предлагает Rust API и привязки Python для создания пользовательских инструментов обнаружения с минимальными ограничениями лицензирования. ?
В рамках борьбы с вредоносными программами Binlex можно использовать - просто скачать двоичные файлы со страницы выпуска. ?
Последняя версия Binlex предоставляет следующие удивительные функции!
| Особенность | Описание |
|---|---|
| Платформы | - окна? - macos? - Linux? |
| Форматы | - PE - Мачо - эльф |
| Архитектуры | - AMD64 - i386 - cil |
| ? Многопоточное | - Отсека с безопасностью. -? Многопоточный инструмент для максимальной эффективности |
| Настраиваемая производительность | Включить/выключить функции, чтобы оптимизировать для вашего варианта использования |
| ? Сжатие строки JSON | Сохранить память с сжатием JSON |
| ? Сходство хэширование | -? Минхаш - Tlsh -? SHA256 |
| ? Символы функции | - Передайте символы функции Binlex в качестве стандартного ввода с помощью BLPDB , BLELFSYM или BLMACHOSIM или вашего собственного инструмента |
| ? ️ Tagging | Тегин для легкой организации |
| Подстановка | Идеально подходит для создания правил Yara, а теперь и в резолюции Nibbles! |
| API | -? Ржавчина API -Битон API |
| ? Функции машинного обучения | - Нормализованные особенности для последовательности -? Функция Scaler Utility -? Фильтрация признаков - Образец пробоотборения ONNX -? Образец классификации |
| Виртуальная визуализация | - Эффективный кеш отображения для виртуальных изображений -? ️ совместимо с ZFS / BTRFS - Ускоряет повторяющиеся задачи и фильтрацию - Скорость освещения ⚡ |
Кэшируя виртуальные изображения, Binlex может работать на лучших скоростях, делая повторные пробежки быстрее и эффективнее.
Чтобы построить бинлекс , вам нужна ржавчина.
Установка - это прямой Foward на Linux и MacOS.
cargo build --release cd src/bindings/python/
virtualenv -p python3 venv/
source venv/bin/activate
pip install maturin[patchelf]
maturin develop
python
>> import binlex Для создания пакетов для различных платформ используйте Makefile .
make zst # Make Arch Linux Package
make deb # Make Debian Package
make wheel # Make Python Wheel Полученные пакеты будут в target/ каталоге.
Установка плагина IDA легко установить, просто убедитесь, что вы установили привязки Python в среде Python для IDA.
Теперь скопируйте каталог для плагина Binlex в свой каталог плагинов.
mkdir -p ~ /.idapro/plugins/
cp -r scripts/plugins/ida/binlex/ ~ /.idapro/plugins/Как только вы откроете IDA, вас следует встретить с помощью приветственного сообщения Binlex .

Используя плагин IDA, у вас есть различные функции, которые предоставляются, чтобы помочь вам с написанием правил Yara и анализу сходства.
Основное меню:
Контекстное меню разборка:
Образец копирования и функция копии шестнадцатеричной функции предназначены для помощи с правилами Yara, а копирование хэшей сходства и сканирование предназначено для охоты на аналогичные данные.
Чтобы сравнить одну базу данных с другой, используйте функцию экспорта для экспорта файла JSON, затем нажмите Compare Functions , которая заполнит таблицу после завершения.
cargo docВы также можете открыть документы.
cargo doc --openВ Binlex иерархия генетических терминов используется для описания и символирования структуры и признаков двоичного кода. Эта терминология отражает отношения между различными абстракциями и их генетическими аналогиями:
Геном : представляет анализируемый каждый объект, такой как функция или блок. Он инкапсулирует всю информацию, включая метаданные, хромосомы и другие атрибуты.
Хромосома : представляет основные шаблоны или последовательности, извлеченные из блока или функции. Хромосома действует как план для выявления ключевых характеристик бинарного файла без адресации памяти, как указано в таких подстановочных знаках ? , где единственный подстановка представляет собой единый ген.
Alllepair : единица в хромосоме, состоящая из двух генов . Пары аллелей - это строительные блоки хромосомы, объединяя гены в значимые пары.
Ген : наименьшая единица генетической информации, представляющая единый кусочек данных (половина байта).
Отношения между этими абстракциями могут быть визуализированы следующим образом:
Genome (function / block)
└── Chromosome (pattern / sequence)
└── AllelePair (two genes / single byte / two nibbles)
└── Gene (single nibble)
{
"type" : " block " ,
"architecture" : " amd64 " ,
"address" : 6442934577 ,
"next" : null ,
"to" : [],
"edges" : 0 ,
"prologue" : false ,
"conditional" : false ,
"chromosome" : {
"pattern" : " 4c8b47??498bc0 " ,
"feature" : [ 4 , 12 , 8 , 11 , 4 , 7 , 4 , 9 , 8 , 11 , 12 , 0 ],
"entropy" : 2.2516291673878226 ,
"sha256" : " 1f227bf409b0d9fbc576e747de70139a48e42edec60a18fe1e6efdacb598f551 " ,
"minhash" : " 09b8b1ad1142924519f601854444c6c904a3063942cda4da445721dd0703f290208f3e32451bf5d52741e381a13f12f9142b5de21828a00b2cf90cf77948aac4138443c60bf77ec31199247042694ebb2e4e14a41369eddc7d9f84351be34bcf61458425383a03a55f80cbad420bb6e638550c15876fd0c6208da7b50816847e62d72b2c13a896f4849aa6a36188be1d4a5333865eab570e3939fab1359cbd16758f36fa290164d0259f83c07333df535b2e38f148298db255ac05612cae04d60bb0dd810a91b80a7df9615381e9dc242969dd052691d044287ac2992f9092fa0a75d970100d48362f62b58f7f1d9ec594babdf52f58180c30f4cfca142e76bf " ,
"tlsh" : null
},
"size" : 7 ,
"bytes" : " 4c8b4708498bc0 " ,
"functions" : {},
"number_of_instructions" : 3 ,
"entropy" : 2.5216406363433186 ,
"sha256" : " 84d4485bfd833565fdf41be46c1a499c859f0a5f04c8c99ea9c34404729fd999 " ,
"minhash" : " 20c995de6a15c8a524fa7e325a6e42b217b636ab03b00812732f877f4739eeee41d7dde92ceac73525e541f9091d8dc928f6425b84a6f44b3f01d17912ec6e8c6f913a760229f685088d2528447e40c768c06d680afe63cb219a1b77a097f679122804dd5a1b9d990aa2579e75f8ef201eeb20d5650da5660efa3a281983a37f28004f9f2a57af8f81728c7d1b02949609c7ad5a30125ff836d8cc3106f2531f306e679a11cabf992556802a3cb2a75a7fe3773e37e3d5ab107a23bf22754aee15a5f41056859b06120f86cb5d39071425855ec90628687741aa0402030d73e04bc60adb0bd2430560442c4309ae258517fc1605438c95485ac4c8621026a1bb " ,
"tlsh" : null ,
"contiguous" : true ,
"attributes" : [
{
"type" : " tag " ,
"value" : " corpus:malware "
},
{
"type" : " tag " ,
"value" : " malware:lummastealer "
},
{
"entropy" : 6.55061550644311 ,
"sha256" : " ec1426109420445df8e9799ac21a4c13364dc12229fb16197e428803bece1140 " ,
"size" : 725696 ,
"tlsh" : " T17AF48C12AF990595E9BBC23DD1974637FAB2B445232047CF426489BD0E1BBE4B73E381 " ,
"type" : " file "
}
]
}Учитывая этот пример генома JSON.
"4c8b47??498bc0""4c" или "8b""4" или "c"Используя Binlex API, можно мутировать эти хромосомы, их пары аллелей и гены для облегчения генетического программирования.
Генетическое программирование в этом контексте может иметь несколько бенфийтов, включая, но не ограничиваясь:
Самый простой способ начать с командной линией, используя инструмент фильтрации JSON, такой как jq .
Следующий командный разборник. sample.dll с 16 потоками, соответствующими признаками являются объекты JSON, по одному на строку и переводятся в jq для фильтрации и украшения.
Чтобы увидеть, какие параметры доступны при использовании командной строки Binlex -h или --help .
A Binary Pattern Lexer
Version: 2.0.0
Usage: binlex [OPTIONS] --input < INPUT >
Options:
-i, --input < INPUT >
-o, --output < OUTPUT >
-a, --architecture < ARCHITECTURE > [amd64, i386, cil]
-c, --config < CONFIG >
-t, --threads < THREADS >
--tags < TAGS >
--minimal
-d, --debug
--enable-instructions
--enable-block-instructions
--disable-hashing
--disable-disassembler-sweep
--disable-heuristics
--enable-mmap-cache
--mmap-directory < MMAP_DIRECTORY >
-h, --help Print help
-V, --version Print version
Author: @c3rb3ru5d3d53cПростой пример использования командной строки приведен ниже.
binlex -i sample.dll --threads 16 | jq Обратите внимание, что Binlex обнаружит формат файла в форте и в настоящее время поддерживает бинаты PE , ELF и MACHO .
После вашего первого выполнения Binlex он будет хранить файл конфигурации в вашем каталоге конфигурации в binlex/binlex.toml .
Этот бинлекс находит каталог конфигурации по умолчанию на основе вашей операционной системы, как указано в таблице ниже для его конфигурации.
| ОС | Переменная среды | Пример пути конфигурации Binlex |
|---|---|---|
| Linux | $XDG_CONFIG_HOME или $HOME/.config | /home/alice/.config/binlex/binlex.toml |
| macOS | $HOME/Library/Application Support | /Users/Alice/Library/Application Support/binlex/binlex.toml |
| Окна | {FOLDERID_RoamingAppData} | C:UsersAliceAppDataRoamingbinlexbinlex.toml |
Имя конфигурации по умолчанию binlex.toml для binlex приведено ниже.
[ general ]
threads = 16
minimal = false
debug = false
[ formats . file . hashing . sha256 ]
enabled = true
[ formats . file . hashing . tlsh ]
enabled = true
minimum_byte_size = 50
threshold = 200
[ formats . file . hashing . minhash ]
enabled = true
number_of_hashes = 64
shingle_size = 4
maximum_byte_size_enabled = false
maximum_byte_size = 50
seed = 0
threshold = 0.75
[ formats . file . heuristics . features ]
enabled = true
[ formats . file . heuristics . entropy ]
enabled = true
[ instructions ]
enabled = false
[ instructions . hashing . sha256 ]
enabled = true
[ instructions . hashing . tlsh ]
enabled = true
minimum_byte_size = 50
threshold = 200
[ instructions . hashing . minhash ]
enabled = true
number_of_hashes = 64
shingle_size = 4
maximum_byte_size_enabled = false
maximum_byte_size = 50
seed = 0
threshold = 0.75
[ instructions . heuristics . features ]
enabled = true
[ instructions . heuristics . entropy ]
enabled = true
[ blocks ]
enabled = true
[ blocks . instructions ]
enabled = false
[ blocks . hashing . sha256 ]
enabled = true
[ blocks . hashing . tlsh ]
enabled = true
minimum_byte_size = 50
threshold = 200
[ blocks . hashing . minhash ]
enabled = true
number_of_hashes = 64
shingle_size = 4
maximum_byte_size_enabled = false
maximum_byte_size = 50
seed = 0
threshold = 0.75
[ blocks . heuristics . features ]
enabled = true
[ blocks . heuristics . entropy ]
enabled = true
[ functions ]
enabled = true
[ functions . blocks ]
enabled = true
[ functions . hashing . sha256 ]
enabled = true
[ functions . hashing . tlsh ]
enabled = true
minimum_byte_size = 50
threshold = 200
[ functions . hashing . minhash ]
enabled = true
number_of_hashes = 64
shingle_size = 4
maximum_byte_size_enabled = false
maximum_byte_size = 50
seed = 0
threshold = 0.75
[ functions . heuristics . features ]
enabled = true
[ functions . heuristics . entropy ]
enabled = true
[ chromosomes . hashing . sha256 ]
enabled = true
[ chromosomes . hashing . tlsh ]
enabled = true
minimum_byte_size = 50
threshold = 200
[ chromosomes . hashing . minhash ]
enabled = true
number_of_hashes = 64
shingle_size = 4
maximum_byte_size_enabled = false
maximum_byte_size = 50
seed = 0
threshold = 0.75
[ chromosomes . heuristics . features ]
enabled = true
[ chromosomes . heuristics . entropy ]
enabled = true
[ chromosomes . homologues ]
enabled = true
maximum = 4
[ mmap ]
directory = " /tmp/binlex "
[ mmap . cache ]
enabled = false
[ disassembler . sweep ]
enabled = trueЕсли параметров командной строки недостаточно, файл конфигурации обеспечивает наиболее детальное управление всеми параметрами.
Если вы хотите переопределить файл конфигурации по умолчанию и указать другой файл конфигурации, используйте параметр командной строки.
binlex -c config.toml -i sample.dllКогда вы запускаете Binlex , он использует файл конфигурации и переопределяет любые настройки, когда используется соответствующий параметр командной строки.
Вот общий рабочий процесс, начинающий с соблюдения правил Yara, где мы получаем 10 уникальных шестнадцатеричных струн Yara с подстановкой из данной выборки.
binlex -i sample.dll --threads 16 | jq -r ' select(.size >= 16 and .size <= 32 and .chromosome.pattern != null) | .chromosome.pattern ' | sort | uniq | head -10
016b ?? 8b4b ?? 8bc74c6bd858433b4c0b2c0f83c5 ??????
01835404 ???? c6836a0400 ???? 837e04 ??
03c04c8d05 ???????? 4863c8420fb60401460fb64401018942 ?? 85c074 ??
03c38bf0488d140033c9ff15 ???????? 488bd84885c075 ??
03c6488d55 ?? 41ffc58945a ? 41b804000000418bcce8b8fd01 ?? eb ??
03c6488d55 ?? 41ffc58945a ? 41b804000000418bcce8e3fb01 ?? eb ??
03f7488d05 ???????? 4883c310483bd87c ??
03fb4c8bc6498bd7498bcc448d0c7d04000000e89409 ???? 8bd84885f6
03fe448bc6488bd3418bcee8d8e501 ?? 85ed
03fe897c24 ?? 397c24 ?? 0f867301 ???? Чтобы сделать это на шаг вперед, вы можете пропустить его через инструмент blyara , чтобы сделать быструю подпись Yara.
binlex -i sample.dll --threads 16 | jq -r ' select(.size >= 16 and .size <= 32 and .chromosome.pattern != null) | .chromosome.pattern ' | sort | uniq | head -10 | blyara -n example
rule example {
strings:
$trait_0 = {016b ?? 8b4b ?? 8bc74c6bd858433b4c0b2c0f83c5 ?????? }
$trait_1 = {01835404 ???? c6836a0400 ???? 837e04 ?? }
$trait_2 = {03c04c8d05 ???????? 4863c8420fb60401460fb64401018942 ?? 85c074 ?? }
$trait_3 = {03c38bf0488d140033c9ff15 ???????? 488bd84885c075 ?? }
$trait_4 = {03c6488d55 ?? 41ffc58945a ? 41b804000000418bcce8b8fd01 ?? eb ?? }
$trait_5 = {03c6488d55 ?? 41ffc58945a ? 41b804000000418bcce8e3fb01 ?? eb ?? }
$trait_6 = {03f7488d05 ???????? 4883c310483bd87c ?? }
$trait_7 = {03fb4c8bc6498bd7498bcc448d0c7d04000000e89409 ???? 8bd84885f6}
$trait_8 = {03fe448bc6488bd3418bcee8d8e501 ?? 85ed}
$trait_9 = {03fe897c24 ?? 397c24 ?? 0f867301 ???? }
condition:
1 of them Для еще лучших результатов, если вы экспортировали геномы , используя плагин Binlex IDA или другими средствами, вы можете фильтровать для начала префиксов функции, таких как mw:: , для malware , что довольно распространено.
cat dump.json | jq -r ' select(.type == "function" and .size > 32 and (.attributes[] | .type == "symbol" and (.name | startswith("mw::")))) | .blocks[] | select(.size > 32) | .chromosome.pattern ' | blyara -n example Чтобы использовать Binlex с Ghidra, используйте сценарий blghidra/blghidra.py в каталоге сценариев.
Использовать имена функций и виртуальные адреса из ваших проектов Ghidra и предоставить им Binlex , используйте сценарий analyzeHeadless в вашем каталоге установки Ghidra .
./analyzeHeadless
< project-directory >
< project-name >
-process sample.dll
-noanalysis
-postscript blghidra.py 2> /dev/null | grep -P " ^{ " type " | binlex -i sample.dll Обратите внимание, что analyzeHeadless Prints Prints Mescests в stdout и другие выводы журнала в stderr , который бесполезно взаимодействует с другими утилитами командной строки.
Таким образом, для сбора вывода сценария он должен быть отфильтрован с помощью 2>/dev/null | grep -P "^{"type" .
Чтобы использовать мощность обнаружения функций ризина и именования функций в Binlex , запустите rizin в вашем проекте, используя aflj , чтобы перечислить функции в формате JSON.
Затем приведите этот выход для blrizin , который анализирует rizin json в формате binlex undesdand.
Кроме того, вы можете объединить это с другими инструментами, такими как blpdb , чтобы разобрать символы PDB, чтобы получить адреса функции и имена.
Затем вы можете сделать любой анализ, так как вы обычно используете jq , в этом примере мы подсчитываем функции, обработанные Binlex , чтобы увидеть, обнаружим ли мы их больше.
rizin -c ' aaa;aflj; ' -q sample.dll |
blrizin |
blpdb -i sample.pdb |
binlex -i sample.dll |
jq ' select(.type == "function") | .address ' | wc -l Примечание . В это время blrizin также совместимый с выходом из radare2 с использованием blrizin .
Если вы хотите сделать какое -то машинное обучение, вы можете получить функции, представляющие Nibbles без адресации памяти от Binlex, как это.
binlex -i sample.dll --threads 16 | jq -r -c ' select(.size >= 16 and .size <= 32 and .signature.feature != null)| .signature.feature ' | head -10
[4,9,8,11,12,0,4,1,11,9,0,3,0,0,1,15,0,0,4,5,3,3,12,0,8,5,13,2,4,8,8,11,13,0,4,1,0,15,9,5,12,0,4,8,15,15,2,5]
[4,4,8,11,5,1,4,5,3,3,12,0,3,3,12,0,4,8,8,3,12,1,3,0,4,1,0,15,10,3,12,2]
[4,8,8,3,14,12,4,12,8,11,12,10,4,4,8,9,4,4,2,4,11,2,0,1,4,4,0,15,11,7,12,1,8,10,12,10,14,8,5,11,4,8,8,3,12,4,12,3]
[4,8,8,3,14,12,4,4,8,9,4,4,2,4,4,12,8,11,12,10,4,4,0,15,11,7,12,1,11,2,0,1,3,3,12,9,14,8,0,11,4,8,8,3,12,4,12,3]
[4,0,5,3,4,8,8,3,14,12,15,15,1,5,8,11,12,8,8,11,13,8,15,15,1,5,8,11,12,3,4,8,8,3,12,4,5,11,12,3]
[11,9,2,0,0,3,15,14,7,15,4,8,8,11,8,11,0,4,2,5,4,8,0,15,10,15,12,1,4,8,12,1,14,8,1,8,12,3]
[8,11,0,12,2,5,11,8,2,0,0,3,15,14,7,15,4,8,12,1,14,1,2,0,4,8,8,11,4,8,12,1,14,0,0,8,4,8,15,7,14,1,4,8,8,11,12,2,12,3]
[4,8,8,11,0,5,4,8,8,5,12,0,7,5,12,3,4,8,15,15,2,5]
[4,8,8,11,0,13,3,3,12,0,3,8,8,1,11,0,0,8,0,15,9,5,12,0,12,3]
[4,8,8,11,0,5,4,8,8,5,12,0,7,5,12,3,4,8,15,15,2,5] Если вы хотите усовершенствовать это для своей модели машинного обучения, нормализуя их от 0 до 1 значений поплавок Binlex, вы покрыли вас инструментом blscaler .
binlex -i sample.dll --threads 16 | jq -r -c ' select(.size >= 16 and .size <= 32 and .signature.feature != null) ' | blscaler --threads 16 | jq -c -r ' .signature.feature ' | head -1
[0.26666666666666666,0.6,0.5333333333333333,0.7333333333333333,0.8,0.0,0.26666666666666666,0.06666666666666667,0.7333333333333333,0.6,0.0,0.2,0.0,0.0,0.06666666666666667,1.0,0.0,0.0,0.26666666666666666,0.3333333333333333,0.2,0.2,0.8,0.0,0.5333333333333333,0.3333333333333333,0.8666666666666667,0.13333333333333333,0.26666666666666666,0.5333333333333333,0.5333333333333333,0.7333333333333333,0.8666666666666667,0.0,0.26666666666666666,0.06666666666666667,0.0,1.0,0.6,0.3333333333333333,0.8,0.0,0.26666666666666666,0.5333333333333333,1.0,1.0,0.13333333333333333,0.3333333333333333]Использовать мощную особенность выполнения перемещения, чтобы уменьшить использование памяти, но все же бенифит от виртуальных изображений.
# Install BTRFS
sudo pacman -S btrfs-progs compsize
# Enable the Kernel Module on Boot
echo " btrfs " | sudo tee /etc/modules-load.d/btrfs.conf
# Reboot
reboot
# Create Virtual Image Cache Storage Pool
dd if=/dev/zero of=btrfs.img bs=1M count=2048
# Make it BTRFS
mkfs.btrfs btrfs.img
# Make a Cache Directory in /tmp/
mkdir -p /tmp/binlex/
# Mount the Cache (Multiple Compression Options Available)
sudo mount -o compress=lzo btrfs.img /tmp/binlex/
# Run Binlex
binlex -i sample.dll --threads 16 --enable-file-mapping --file-mapping-directory /tmp/binlex/ --enable-file-mapping-cache
sudo compsize ec1426109420445df8e9799ac21a4c13364dc12229fb16197e428803bece1140
# Virtual Image 6GB vs Stored Size of 192MB
# Processed 1 file, 49156 regular extents (49156 refs), 0 inline.
# Type Perc Disk Usage Uncompressed Referenced
# TOTAL 3% 192M 6.0G 6.0G
# none 100% 384K 384K 384K
# lzo 3% 192M 6.0G 6.0G Это может настроить это на диск, или если /tmp/ каталог отображается с RAM.
При картировании с RAM мы используем преимущества виртуального разборки изображений, но без дополнительного штрафа RAM, где повторяющиеся задачи почти удваиваются в скорости обработки.
Поскольку btrfs абстрагирует доступ к отображенному файлу в ядре, мы можем получить к нему доступ, как и любой сопоставленный файл, но с преимуществом сжатия.
Чтобы сохранить время, если вы выберете эту опцию, сделайте монтаж пула btrfs на загрузке и установите набор файлов конфигурации Binlex , чтобы предпочитать виртуальное кэширование изображения в каталоге монтированного пула. Этот подход гарантирует, что вам не нужно полагаться на параметры командной строки каждый раз.
Филофсия проекта Binlex ориентирована на безопасность, простоту, скорость и расширяемость.
Частично это предоставляет разработчикам API, чтобы написать свою собственную логику обнаружения и охоты.
В настоящее время Binlex обеспечивает как Rust, так и Python.
Ржавчина, создавая API, легко начать
use std :: process ;
use binlex :: Config ;
use binlex :: formats :: PE ;
use binlex :: disassemblers :: capstone :: Disassembler ;
use binlex :: controlflow :: Graph ;
// Get Default Configuration
let mut config = Config ( ) ;
// Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16 ;
// Read PE File
let pe = PE . new ( "./sample.dll" , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// To check if DotNet PE use pe.is_dotnet()
// Get Memory Mapped File
let mapped_file = pe . image ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 )
} ) ;
// Get Mapped File Virtual Image
let image = mapped_file
. mmap ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Disassembler
let disassembler = Disassembler ( pe . architecture ( ) , & image , pe . executable_virtual_address_ranges ( ) , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Control Flow Graph
let cfg = Graph ( pe . architecture ( ) , config ) ;
// Disassemble Control Flow
disassembler . disassemble_controlflow ( pe . entrypoint_virtual_addresses ( ) , & mut cfg ) ; use std :: process ;
use binlex :: Config ;
use binlex :: formats :: PE ;
use binlex :: disassemblers :: custom :: cil :: Disassembler ;
use binlex :: controlflow :: Graph ;
// Get Default Configuration
let mut config = Config ( ) ;
// Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16 ;
// Read PE File
let pe = PE . new ( "./sample.exe" , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// To check if DotNet PE use pe.is_dotnet()
// Get Memory Mapped File
let mapped_file = pe . image ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 )
} ) ;
// Get Mapped File Virtual Image
let image = mapped_file
. mmap ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Disassembler
let disassembler = Disassembler ( pe . architecture ( ) , & image , pe . dotnet_metadata_token_virtual_addresses ( ) , pe . dotnet_executable_virtual_address_ranges ( ) , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Control Flow Graph
let cfg = Graph ( pe . architecture ( ) , config ) ;
// Disassemble Control Flow
disassembler . disassemble_controlflow ( pe . dotnet_entrypoint_virtual_addresses ( ) , & mut cfg ) ; use std :: process ;
use binlex :: Config ;
use binlex :: formats :: ELF ;
use binlex :: disassemblers :: custom :: cil :: Disassembler ;
use binlex :: controlflow :: Graph ;
// Get Default Configuration
let mut config = Config ( ) ;
// Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16 ;
// Read PE File
let elf = ELF . new ( "./sample.exe" , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Get Memory Mapped File
let mapped_file = elf . image ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 )
} ) ;
// Get Mapped File Virtual Image
let image = mapped_file
. mmap ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Disassembler
let disassembler = Disassembler ( elf . architecture ( ) , & image , elf . executable_virtual_address_ranges ( ) , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Control Flow Graph
let cfg = Graph ( elf . architecture ( ) , config ) ;
// Disassemble Control Flow
disassembler . disassemble_controlflow ( elf . entrypoint_virtual_addresses ( ) , & mut cfg ) ; use std :: process ;
use binlex :: Config ;
use binlex :: formats :: MACHO ;
use binlex :: disassemblers :: custom :: cil :: Disassembler ;
use binlex :: controlflow :: Graph ;
// Get Default Configuration
let mut config = Config ( ) ;
// Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16 ;
// Read PE File
let macho = MACHO . new ( "./sample.app" , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Iterate the MACHO Fat Binary Slices
for index in macho . number_of_slices ( ) {
// Get Memory Mapped File
let mapped_file = macho . image ( index )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 )
} ) ;
// Get Mapped File Virtual Image
let image = mapped_file
. mmap ( )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Disassembler
let disassembler = Disassembler ( macho . architecture ( index ) , & image , macho . executable_virtual_address_ranges ( index ) , config )
. unwrap_or_else ( |error| {
eprintln ! ( "{}" , error ) ;
process :: exit ( 1 ) ;
} ) ;
// Create Control Flow Graph
let cfg = Graph ( macho . architecture ( index ) , config ) ;
// Disassemble Control Flow
disassembler . disassemble_controlflow ( macho . entrypoints ( index ) , & mut cfg ) ;
} use binlex :: controlflow :: Instruction ;
use binlex :: controlflow :: Block ;
use binlex :: controlflow :: Function ;
for address in cfg . instructions . valid_addresses ( ) {
// Read Instruction from Control Flow
instruction = Instruction ( address , & cfg ) ;
// Print Instruction from Control Flow
instruction . print ( ) ;
}
for address in cfg . blocks . valid_addresses ( ) {
// Read Block from Control Flow
block = Block ( address , & cfg ) ;
// Print Block from Control Flow
block . print ( ) ;
}
for address in cfg . functions . valid_addresses ( ) {
// Read Function from Control Flow
function = Function ( address , & cfg ) ;
// Print Function from Control Flow
function . print ( ) ;
}Binlex Python API теперь предназначен для абстрагирования Disasssembler и графика Controlflow.
Чтобы разобрать изображение с отображением памяти PE, используйте следующие примеры.
В examples/python/ Directory.
from binlex . formats import PE
from binlex . disassemblers . capstone import Disassembler
from binlex . controlflow import Graph
from binlex import Config
# Get Default Configuration
config = Config ()
# Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16
# Open the PE File
pe = PE ( './sample.exe' , config )
# To check if a DotNet PE use ps.is_dotnet()
# Get the Memory Mapped File
mapped_file = pe . image ()
# Get the Memory Map
image = mapped_file . as_memoryview ()
# Create Disassembler on Mapped PE Image and PE Architecture
disassembler = Disassembler ( pe . architecture (), image , pe . executable_virtual_address_ranges (), config )
# Create the Controlflow Graph
cfg = Graph ( pe . architecture (), config )
# Disassemble the PE Image Entrypoints Recursively
disassembler . disassemble_controlflow ( pe . entrypoint_virtual_addresses (), cfg ) from binlex . formats import PE
from binlex . disassemblers . custom . cil import Disassembler
from binlex . controlflow import Graph
from binlex import Config
# Get Default Configuration
config = Config ()
# Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16
# Open the PE File
pe = PE ( './sample.exe' , config )
# To check if a DotNet PE use ps.is_dotnet()
# Get the Memory Mapped File
mapped_file = pe . image ()
# Get the Memory Map
image = mapped_file . as_memoryview ()
# Create Disassembler on Mapped PE Image and PE Architecture
disassembler = Disassembler ( pe . architecture (), image , pe . dotnet_metadata_token_virtual_addresses (), pe . dotnet_executable_virtual_address_ranges (), config )
# Create the Controlflow Graph
cfg = Graph ( pe . architecture (), config )
# Disassemble the PE Image Entrypoints Recursively
disassembler . disassemble_controlflow ( pe . dotnet_entrypoint_virtual_addresses (), cfg ) from binlex . formats import ELF
from binlex . disassemblers . capstone import Disassembler
from binlex . controlflow import Graph
from binlex import Config
# Get Default Configuration
config = Config ()
# Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16
# Open the ELF File
elf = ELF ( './sample.so' , config )
# Get the Memory Mapped File
mapped_file = pe . image ()
# Get the Memory Map
image = mapped_file . as_memoryview ()
# Create Disassembler on Mapped ELF Image and ELF Architecture
disassembler = Disassembler ( elf . architecture (), image , elf . executable_virtual_address_ranges (), config )
# Create the Controlflow Graph
cfg = Graph ( elf . architecture (), config )
# Disassemble the PE Image Entrypoints Recursively
disassembler . disassemble_controlflow ( elf . entrypoint_virtual_addresses (), cfg ) from binlex . formats import MACHO
from binlex . disassemblers . capstone import Disassembler
from binlex . controlflow import Graph
from binlex import Config
# Get Default Configuration
config = Config ()
# Use 16 Threads for Multi-Threaded Operations
config . general . threads = 16
# Open the ELF File
macho = MACHO ( './sample.app' , config )
# MachO Fat Binary Can Support Multiple Architectures
for index in macho . number_of_slices ():
# Get the Memory Mapped File
mapped_file = macho . image ( index )
# Get the Memory Map
image = mapped_file . as_memoryview ()
# Create Disassembler on Mapped MACHO Image and MACHO Architecture
disassembler = Disassembler ( macho . architecture ( index ), image , macho . executable_virtual_address_ranges ( index ), config )
# Create the Controlflow Graph
cfg = Graph ( macho . architecture ( index ), config )
# Disassemble the MACHO Image Entrypoints Recursively
disassembler . disassemble_controlflow ( macho . entrypoints ( index ), cfg )Иногда, возможно, это, чтобы разобрать сгенерированный график Controlflow.
В этом случае вы можете использовать следующую технику.
from binlex . controlflow import Instruction
from binlex . controlflow import Block
from binlex . controlflow import Function
# Iterate Valid Instructions
for address in cfg . instructions . valid_addresses ():
# Read Instruction from Control Flow
instruction = Instruction ( address , cfg )
# Print Instruction from Control Flow
instruction . print ()
# Iterate Valid Blocks
for address in cfg . blocks . valid_addresses ():
# Read Block from Control Flow
block = Block ( address , cfg )
# Print Block from Control Flow
block . print ()
# Iterate Valid Functions
for address in cfg . functions . valid_addresses ():
# Read Function from Control Flow
function = Function ( address , cfg )
# Print Function from Control Flow
function . print ()Вместо анализа вы можете получить доступ к инструкциям, блокам и функциям более напрямую.
for instruction in cfg . instructions ():
instruction . print ()
for block in cfg . blocks ():
block . print ()
for function in cfg . functions ():
function . print ()Также возможно итерацию от функций до блоков, до инструкций, до пар аллелей, до генов.
Это представляет собой переход от абстракции высшего уровня к самой низкой абстракции.
for function in cfg . functions ():
for block in function . blocks ():
for instruction in block . instructions ():
for allelepair in instruction . chromosome (). allelepairs ():
for gene in allelepair . genes ():
print ( gene )Одним из самых мощных инструментов, которые вы можете использовать в Binlex, является сравнение функций, блоков и инструкций с использованием хэширования сходства.
Для выполнения этих сравнений так же просто, как и называть метод compare .
for lhs in lhs_cfg . functions ():
for rhs in rhs_cfg . functions ():
similarity = lhs . compare ( rhs )
similarity . print ()
for lhs in lhs_cfg . blocks ():
for rhs in rhs_cfg . blocks ():
similarity = lhs . compare ( rhs )
similarity . print ()
for lhs in lhs_cfg . instructions ():
for rhs in rhs_cfg . instructions ():
similarity = lhs . compare ( rhs )
similarity . print ()Любые поддерживаемые алгоритмы хеширования сходства будут рассчитаны, если они включены в вашу конфигурацию.
Хотя это может быть сложным, Binlex поддерживает анализ сходства по неосвязным функциям, используя свой собственный алгоритм, чтобы найти лучшие совпадения сходства.
По крайней мере, 75% или более данных, не связанной с непрерывной функцией, должны быть хранения, чтобы получить хэш сходства.
Каждая инструкция, блок и функция или геном имеют связанную хромосому, к которой можно получить доступ через API.
Вы можете следовать этим абстракциям до пар аллелей и их соответствующих генов.
# Iterate Block Chromosome
chromosome = block . chromosome ()
for allelepair in chromosome . allelepairs ():
for gene in allelepair . genes ()
gene . print ()
# Iterate Block Chromosome
chromosome = function . chromosome ()
for allelepair in chromosome . allelepairs ():
for gene in allelepair . genes ()
gene . print ()
# Iterate Block Chromosome
chromosome = function . chromosome ()
for allelepair in chromosome . allelepairs ():
for gene in allelepair . genes ()
gene . print ()Если вы хотите выполнить задачи генетического программирования, вы также можете мутировать хромосомы, аллелеперы и гены, и они отслеживают свое собственное количество мутаций.
chromosome = block . chromosome ()
chromosome . mutate ( 'deadbe?f' )
chromosome . number_of_mutations ()
chromosome . print ()
for allelepair in chromosome . allelepairs ():
allelepair . mutate ( 'dead' )
allelepair . number_of_mutations ()
allelepair . print ()
for gene in allelepair . genes ():
gene . mutate ( 'd' )
gene . number_of_mutations ()
gene . print ()Это облегчает мутации с генетическими алгоритмами, с которыми вы можете использовать для ваших использования.
Если вы используете Binlex в публикации в журнале или модель искусственного интеллекта с открытым исходным кодом, используйте следующую цитату.
@misc { binlex ,
author = { c3rb3ru5d3d53c } ,
title = { binlex: A Binary Genetic Trait Lexer Framework } ,
year = { 2024 } ,
note = { Available at url{https://github.com/c3rb3ru5d3d53c/binlex-rs} }
}Если использование Binlex предназначено для корпоративных, личных целей или для создания выходов, которые не являются моделями ИИ с открытым исходным кодом, цитирование не требуется.
Например, если вы используете Binlex для создания правил Yara, цитирования не требуется.
Это гарантирует, что Binlex остается актуальным, но также обеспечивает разрешающее корпоративное и личное использование.