Здравствуйте дорогие форумчане, это будет вводная статья в ассемблер, а именно FASM.
Почему именно FASM, а не например MASM, NASM, TASM?
По моему личному мнению FASM является более удобным чем остальные: FASM подходит под маленькие приложения, MASM для создания драйверов под Windows, а NASM как конкурент GAS в Linux.
Надеюсь вы получили ответ на этот вопрос, теперь - что такое DIE, и как он работает?
Спойлер: Информация про DIE
Detect It Easy (DiE) — это мощный инструмент для определения типа файлов, популярный среди аналитиков вредоносного ПО, экспертов в области кибербезопасности и реверс-инженеров по всему миру. Поддерживая как основанный на сигнатурах, так и эвристический анализ, DiE обеспечивает эффективную проверку файлов на широком диапазоне платформ, включая Windows, Linux и MacOS. Его адаптируемая, управляемая скриптами архитектура обнаружения делает его одним из самых универсальных инструментов в этой области с обширным списком поддерживаемых образов ОС.
Но, как же он работает? - Зайдя в папку db - PE - Можно увидеть большое количество обфускаторов/протекторов и прочего мусора но сейчас нас интересует пакер UPX
Спойлер: Нахождение UPX
// Detect It Easy: detection rule file
// Authors: ajax, adoxa, DosX
meta("packer", "UPX");
function isPatchedUPX() {
var isDetected = 0,
nNumberOfFunctions = PE.getNumberOfImportThunks(0);
if (nNumberOfFunctions > 1 && nNumberOfFunctions < 7) {
if (PE.getSizeOfCode() && PE.getSizeOfUninitializedData() && PE.section.length > 2 && PE.section.FileSize == 0) {
var funcCounter = 0;
if (PE.getImportFunctionName(0, 0) == "LoadLibraryA") {
funcCounter++;
}
if (PE.getImportFunctionName(0, 1) == "GetProcAddress") {
funcCounter++;
}
if (nNumberOfFunctions == 4) {
if (PE.getImportFunctionName(0, 2) == "VirtualProtect") {
funcCounter++;
}
if (PE.getImportFunctionName(0, 3) == "ExitProcess") {
funcCounter++;
}
}
if (nNumberOfFunctions >= 3 && funcCounter < 4) {
if (PE.getImportFunctionName(0, 2) == "ExitProcess") {
funcCounter++;
} else if (PE.isDll()) {
if (PE.getImportFunctionName(0, 2) == "VirtualProtect") {
funcCounter++;
}
}
}
if (nNumberOfFunctions == 6) {
if (PE.getImportFunctionName(0, 2) == "VirtualProtect") {
funcCounter++;
}
if (PE.getImportFunctionName(0, 3) == "VirtualAlloc") {
funcCounter++;
}
if (PE.getImportFunctionName(0, 4) == "VirtualFree") {
funcCounter++;
}
if (PE.getImportFunctionName(0, 5) == "ExitProcess") {
funcCounter++;
}
}
if (funcCounter == 2 && nNumberOfFunctions == 2 ||
funcCounter == 3 && nNumberOfFunctions >= 3 ||
funcCounter == 4 && nNumberOfFunctions == 4 ||
funcCounter == 6 && nNumberOfFunctions == 6) {
isDetected = true;
}
if (isDetected) {
if (PE.getAddressOfEntryPoint() == 0x00001018) {
// (Win)Upack
isDetected = false;
}
}
}
}
return isDetected;
}
function getUPXOptions(nOffset) {
var nMethod = PE.readByte(nOffset + 2),
nLevel = PE.readByte(nOffset + 3),
sCompression = "";
switch (nMethod) // From http://sourceforge.net/p/upx/code/ci/default/tree/src/conf.h
{
case 2: case 3:
case 4: case 5:
case 6: case 7:
case 8: case 9:
case 10: sCompression = "NRV"; break;
case 14: sCompression = "LZMA"; break;
case 15: sCompression = "zlib"; break;
}
if (sCompression) {
sOptions = sOptions.append(sCompression);
if (nLevel == 8) {
sOptions = sOptions.append("best");
} else {
sOptions = sOptions.append("brute");
}
}
}
function getUPXVersion() {
var nOffset1 = PE.findString(0, 1024, "$Id: UPX "),
nOffset2 = PE.findString(0, 1024, "UPX!");
if (nOffset2 != -1) {
getUPXOptions(nOffset2 + 4);
}
if (nOffset1 != -1) {
sVersion = PE.getString(nOffset1 + 9, 4);
}
if (!sVersion && nOffset2 != -1) {
sVersion = PE.getString(nOffset2 - 5, 4);
}
if (sVersion) {
if (+sVersion.toString() != sVersion) {
if (PE.is64()) {
sVersion = "3.91+";
} else {
sVersion = "0.89+";
}
sOptions = "modified";
}
}
}
function detect() {
if (PE.isNet()) return; // Doesn't support .NET
if (!PE.is64()) {
if (PE.compareEP("60BE........8DBE........57", PE.compareEP("807C") ? 27 : 0)) {
bDetected = true;
} else if (PE.compareEP("60e8000000005883e8..508db8........578db0........83cd..31db9090909001db75")) {
sVersion = "0.70";
bDetected = true;
}
} else {
if (PE.compareEP("53565755488D35........488DBE........57", PE.compareEP("4889") ? 24 : 0)) {
bDetected = true;
}
}
getUPXVersion();
if (sVersion) {
bDetected = true;
}
if (!bDetected) {
bDetected = isPatchedUPX();
} else {
if (!sVersion) {
if (PE.is64()) {
sVersion = "3.91+"; // UPX 3.91 was the first version with a PE+ support.
}
sOptions = "modified";
} else if (!PE.isSectionNamePresent("UPX0")) {
sOptions = sOptions.append("modified");
}
}
return result();
}Теперь как мы имеем информацию про то как определяется UPX, мы можем написать на FASM "Спуфер".
Ниже приведу код программы которая вызывает в MessageBox текст SkeetLIMB
 подробнее вы можете узнать в оффициальной документации WinApi
push text - Это заголовок окна (caption)
push text - Это сам текст окна
push 0 - Дескриптор родительского окна 0 означает то что его нет, т.е без родителя
call [MessageBoxA] - Вызываем функции MessageBox с user32.dll.
стек в Windows API идёт в обратном порядке (сначала последний аргумент, потом первый).
push 0 - успешное завершение программы, выход
call [ExitProcess] - Вызывает функцию ExitProcess из kernel32.dll
text db 'SkeetLIMB',0 Это значение того что передавалось выше
section '.idata' import data readable writeable - Одна из секций которая хранит внешние DLL.
library kernel32,'kernel32.dll',\
user32,'user32.dll'
import kernel32,\
ExitProcess,'ExitProcess' - Указываем функции которые будем использовать в этих DLL
import user32,\
MessageBoxA,'MessageBoxA'
[/CODE]
Это показательный и легкий код чтоб новички понимали что такое вообще фасм, ниже приведу литературу + источники которую я советую если вы хотите развиваться в этом языке.
Спойлер: Материалы
Видео -
С кодом и что такое FASM мы разобрались, теперь пишем то что я и обещал "Спуфинг DIE" сейчас я приведу и обьясню код который вызывает эти сигнатуры
![](https://forum.LIMB.cc/attachments/3607/?hash=a6647d082bf60d6d8b78d304ceb
format PE GUI on 'stub.com' - Объясню почему я импорчу не GUI 4.0 как в преведущем коде, а stub.com. Вот код stub.com
org 100h
ret
Простая заглушка, а импорчу я ее потому-что DIE теряет сигнатуру FASM при "on файл.com" это называется DOS-заглушка.
entry start
include 'win32a.inc'
section 'LIMB' code readable executable
start:
push user32_name
call [LoadLibraryA]
test eax, eax
jz exit_prog
push msgbox_name
push eax
call [GetProcAddress]
test eax, eax
jz exit_prog
push 0
push text
push text
push 0
call eax
exit_prog:
push 0
call [ExitProcess]
text db 'LIMBSkeet',0
user32_name db 'user32.dll',0
msgbox_name db 'MessageBoxA',0
section 'UPX0' code readable executable - Секция которая используется в оригинальном UPX
nop
section 'UPX1' code readable executable - Секция которая используется в оригинальном UPX
nop
section 'Skeet' import data readable writeable
library kernel32,'kernel32.dll'
import kernel32,\
LoadLibraryA,'LoadLibraryA',\
GetProcAddress,'GetProcAddress',\
VirtualProtect,'VirtualProtect',\
ExitProcess,'ExitProcess'
[/CODE]
И все, сканируя этот файл в DIE мы получаем сигнатуру которая находится на скрин чуть повыше.
На этом статья закончена, если вам понравилось и вы хотите чтоб я сделал вторую статью то напишете об этом в коментариях, и если понравится то я выпущу вторую статью как с файла покрытым UPX, сбить сигнатуру в DIE
LIMB