Copy Link
Add to Bookmark
Report

451: Data-Trash Generator

eZine's profile picture
Published in 
451
 · 7 Mar 2022

DTRASH v 1.00
Data-Trash Generator

DTRASH is a garbage generator using data. The principle of its operation is such that it receives a list of addresses that can be used, flags, a buffer, etc. as input, and at the output there is a command in the buffer and its length. In total, the engine is capable of generating about 30-40 commands of various opcodes, except for modifications of the same commands like rcl reg,1 and rcl reg,im. In addition to memory accesses, common registers and operands are used.

Main procedure (C call is used here):

DWORD 	Dtrash( VOID* DataTable,		// pointer to addresses 
DWORD DataCnt, // their number
VOID* TrashTable, // table pointer,
// needed by the generator.
VOID* OutBufer, // output buffer
DWORD Flags, // flags
DWORD* Seed, // pointer to seed
DWORD *(RND(DWORD* SEED,DWORD Range)) // pointer to the RNG procedure
);


As an output parameter, the generator returns in EAX the length of the received command.

The list of addresses (addresses) is an array of structures:

	typedef	struct{ 
DWORD getd_dRVA
DWORD getd_cRVA
DWORD getd_cSize
DWORD getd_cdType
} node;


Where the second and third fields are ignored, and only getd_RVA is used, the first contains the RVA of the data and getd_cdType, the size of the data in the second byte and the type of access to them. The list itself can be obtained by analyzing the program's access to data, but it is worth remembering that when generating write commands, you should take into account the size of the data, because not the fact that the data is aligned there, i.e. some value (usually dword) is used instead of bytes and words and all variables on the border of this value, so much so that the program does not "know" about it. But even if they are aligned, then it is not known to which border ;)

The generator uses its table to work. It can be included as data in the code, in other words, include its include, or more universally, use a procedure that unpacks the tables (about 300 bytes) into a buffer:

VOID	trash_init( 
VOID* Ptr // buffer pointer
)


After that, you can pass the address of the buffer to the main procedure and call it.

The following flags are used to set the garbage generation options:

DTF_READ	0000000000000000b	generate read commands 
DTF_WRITE 0000000000000001b generate write commands
DTF_MFLAGS 0000000000000010b use garbage flags?
DTF_EAX 0000000100000000b use AL/AX/EAX
DTF_ECX 0000001000000000b use CL/CX/ECX
DTF_EDX 0000010000000000b use DL/DX/EDX
DTF_EBX 0000100000000000b use BL/BX/EBX
DTF_ESP 0001000000000000b use AH/SP/ESP
DTF_EBP 0010000000000000b use CH/BP/EBP
DTF_ESI 0100000000000000b use DH/SI/ESI
DTF_EDI 1000000000000000b use BH/DI/EDI
DTF_ALL 1111111100000000b use all registers


The used registers also depend on the size of the input data. So with a data size of 1 byte and the DTF_EAX flag turned on, only AL will be used, but when the DTF_ESP flag is turned on, AH will also be generated. The same applies to other single-byte registers.

If the data size is 4 bytes, then it can be accessed as a 1/2/4 byte variable.


original russian version


DTRASH v 1.00
Data-Trash Generator

DTRASH является генератором мусора с использованием данных. Принцип его действия таков, что на вход ему подается список адресов, которые можно использовать, флаги, буфер и др., а на выходе имеется команда в буфере и ее длина. Всего движок способен генерировать около 30-40 команд различных опкодов, если не считать модификаций одних и тех же команд типа rcl reg,1 и rcl reg,im.Помимо обращений к памяти используются общие регистры и операнды.

Главная процедура (тут использован C call):

DWORD 	Dtrash( VOID* DataTable,		// указатель на адреса 
DWORD DataCnt, // их количество
VOID* TrashTable, // указатель на таблицу,
// необходимую генератору.
VOID* OutBufer, // выходной буфер
DWORD Flags, // флаги
DWORD* Seed, // указатель на seed
DWORD *(RND(DWORD* SEED,DWORD Range)) // указатель на процедуру ГСЧ
);


Как выходной параметр генератор возвращает в EAX длину полученной команды.

Список адресов (адреса) представляет собой массив структур:

	typedef	struct{ 
DWORD getd_dRVA
DWORD getd_cRVA
DWORD getd_cSize
DWORD getd_cdType
} node;


Где вторе и третье поля игнорируются, а используются лишь getd_RVA, содержащее RVA данных и getd_cdType- размер данных во втором байте и тип обращения к ним - в первом. Сам список может быть получен путем анализа обращения программы к данным, но стоит помнить, что при генерировании команд на запись следует учесть размер данных т.к. не факт, что там данные выровнены, т.е. используются какая-то величина (чаше dword) вместо байтов и слов и все переменные на границе этой величины, да так, что программа и не "знает" об этом. Но и если выровнены,то неизвестно на какую границу ;)

Генератор использует свою таблицу для работы. Ее можно включать как данные в код, другими словами - включать ее инклудник,либо же,что более универсально, использовать процедуру,которая распакует таблицы (где-то 300 байт) в буфер:

VOID	trash_init( 
VOID* Ptr // указатель на буфер
)


После этого можно передать адрес буфера в главную процедуру и вызвать ее.

Для задания параметров генерирования мусора используются флаги:

DTF_READ	0000000000000000b	генерировать команды на чтение 
DTF_WRITE 0000000000000001b генерировать команды на запись
DTF_MFLAGS 0000000000000010b использовать флаги мусором?
DTF_EAX 0000000100000000b использовать AL/AX/EAX
DTF_ECX 0000001000000000b использовать CL/CX/ECX
DTF_EDX 0000010000000000b использовать DL/DX/EDX
DTF_EBX 0000100000000000b использовать BL/BX/EBX
DTF_ESP 0001000000000000b использовать AH/SP/ESP
DTF_EBP 0010000000000000b использовать CH/BP/EBP
DTF_ESI 0100000000000000b использовать DH/SI/ESI
DTF_EDI 1000000000000000b использовать BH/DI/EDI
DTF_ALL 1111111100000000b использовать все регистры


Использованные регистры зависят и от размера входных данных. Так при размере данных в 1 байт и включенном флаге DTF_EAX будет использоваться лишь AL ,но при включении флага DTF_ESP ,будет еще генерироваться и AH. Тоже касается и остальных однобайтовых регистров.

Если размер данных - 4 байта, то к ним может использоваться обращение как к 1/2/4 байтовой переменной.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT