/--------------------------------/
/
Как написать билдер на VC++/
/--------------------------------/
Очень часто спрашивают на форумах вопрос: "Как написать именно билдер а не конфигуратор?". Если у тебя есть этот же вопрос то читай статью.
Немного теории
----------------------
Главное очень часто народ путает понятия конфигуратор и билдер, а для некоторых это вообще одно и тоже.
Рассмотрю на примере.
Конфигуратор:
Вот есть есть например сокс бот. Вы зашли в папку с ботом и там 2 файла например socks.dat и build.exe. В readme написано запустить build.exe и настроить бота как вам нужно. Как же это происходит? Очень просто. В build.exe мы задаём параметры и потом делаем сокс бота, после этого у нас в папке появляется сконфигурированный нами bot.exe.
Что делает build.exe:
-Открывает файл socks.dat(это уже исполняемый файл просто ему поменяли расширение вручную на dat)
-Читает его содержимое в буфер
-Ищет в буфере определённые строки и заменяет их на введённые нами
-Создаёт навый файл для записи с расширением exe
-Записывает туда из буфера уже сконфигурированного нами бота
Билдер:
Теперь. У вас есть сокс бот. Вы зашли в папку с сокс ботом и там один builder.exe. Вы его запускаете и вводите нужные вам параметры,затем в папке после сборки появляется из неоткуда в папке с билдером уже готовый файл bot.exe который можно пользовать в своих целях. Как это получилось если нету фалйа который можно изменить так как изложено в примере выше? Этому то и посвещена статья.
От теории к практике
----------------------------
Билдер работает почти так же как и конфигуратор но бот лежит не в папке а в самом билдере в расурсах. У PE файла есть несколько секций, а это секция кода, секция данных, секция ресурсов и т.д. Вот как раз билдер то и хранит в секции ресурсов бота.
Алгоритм сборки бота такой:
-Извлекает из секции ресурсов файл в память
-Из памяти записывает в обозначенный файл
-Открывает файл на запись
-Устанавливает указатель по определённому адресу где хранится нужный нам параметр
-Заменяет его и если нужно ещё чтото заменить то ставит указатель на другой параметр и тоже заменяет его
-Проверяет успешно ли создан файл на диске
На первый взгляд страшно это всё звучит, секция ресурсов и всякие указатели. Дальше я всё подробно и просто опишу, приведу исходники, напишу MessageBox билдер и вы увидите что ничего сложного нет а это даже проще чем написать конфигуратор =)
Процесс написания MessageBox билдера
----------------------------------------------
Для того чтобы написать MessageBox билдер нам нужен WinHex,файл который вызывает MessageBox,ну и VC++
Сначала пишем файл с MessageBox который будем помещать в ресурсы билдера.
Создаём новый win32 проект в VC++ и вставляем туда код:
Код:
#include <windows.h> //Здесь подключаем нужные нам заголовочные файлы
#pragma optimize( "gsy", on )
#pragma comment( linker, "/ENTRY:WinMain" )
#pragma comment( linker, "/MERGE:.rdata=.data" )
#pragma comment( linker, "/MERGE:.text=.data" )
#pragma comment( linker, "/SECTION:.text,EWR" )
#pragma comment( linker, "/SUBSYSTEM:WINDOWS" )
#pragma comment( linker, "/INCREMENTAL:NO" )
#define MESSAGE "1_____________________________" //Сообщение MessageBox
#define TITLE "2_____________________________" //Заголовок MessageBox
typedef int (WINAPI* MB) (HWND,LPCTSTR,LPCTSTR,UINT);
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
MB fMessageBox; //Обозначаем переменную
HMODULE user32_dll = LoadLibraryA("user32.dll");//Подгружаем библиотеку
if (user32_dll)
{
fMessageBox = (MB)GetProcAddress(user32_dll,"MessageBoxA");//Получаем адрес функции MessageBox и присваиваем переменной fMessageBox
}
fMessageBox(0, MESSAGE, TITLE, MB_OK|MB_SETFOREGROUND);//Вызываем MessageBox
FreeLibrary(user32_dll);//Освобождаем библиотеку
return 0;
}
Я вызывал MessageBox получая адрес функции. MESSAGE и TITLE сожержат максимум 30 символов и в билдере мы сможем вводить от 1 до 30 символов.
Теперь нужно изменить пару опций в проекте.
Отключаю манифест:
Project Property->Linking->Manifest File->Generating Manifest->NO
Далее выбираю:
Project Property->General Configuration->Character Set->Use Multi-byte Character Set это ставлю чтобы не писать (LPCTSTR)"test" а просто "test" в функции
Рантайм библиотеки:
Project Property->Configuration properties->c/c++->code generation->runtime library->MT
Теперь можно скомпилировать из запустить. Если чтото не запускается или не компилируется ищи ошибку у себя.
Открываем в WinHex файл который мы только что получили. Ищем 1_____________________________, это текст нашего сообщения. Можно заменить это сообщения используя WinHex и поиграться с приложением, но нам нужен адрес, а точнее смещение от начала файла.Колонка смещений или offset расположена слева, там написано чтото вроде 0x0000200 и т.д. Ставим курсор точно на 1 и смотрим смещение(offset).Для того чтобы не отсчитывать числа от начала чтроки да ещё и не переводить в hex смотрите смещение по текущему положению курсора,оно нааписано внизу =) Запешите значение. У меня оно равно 24C, а для записи в исходник 0x000024C, затем
ищем 2_____________________________, ставим курсор на 2 и записываем смещение. У меня оно равно 26C, а для записи в исходник 0x000026C. Теперь когда известны смещения и всё что нам нужно *** создания билдера есть то можно приступить к сборке.
Создаём новый проект
MFC Application. Открываем
Solution Explorer и ищем там
Resource Files. Нажимаем правой кнопкой на файл с расширением .rc и выбираем
View code. Для того чтобы добавить файл в ресурсы то нам нужно добавить его туда прописав в файле ресурсов.
Синтаксис такой:
имя_ресурса тип "файл"
Так как у нас не иконка какаято и не картинка для которых есть определённые типы, а exe файл то мы обозначаем тип ресурсов как RCDATA
File RCDATA "file.exe"
Берём наш exe файл с MessageBox,переименовываем в file.exe и кидаем в папку с проектом где лежат исходники.Теперь заходим в
Solutin Explorer и нажимаем правой кнопкой на файле .rc затем
Compile. После компилируем проект и наш файл должен добавиться в ресурсы билдера и быть уже в нём. Проверить это можно поискав просто строки 2_____ или 1_____ если есть то значит exe добавлен.
Открываем ещё раз
Solutin Explorer и нажимаем правой кнопкой на файл с расширением .rc, выбираем
open with, затем выбираем
Resource Editor и кидаем на форму 2-а EditBox, 2-а label и одну кнопку. После нам нужно создать обработчик события нажатия кнопки по которому будет извлекаться из ресурсов файл и делаться билд.
Нажимаем правой кнопкой на button который лежит на форме и выбираем
Add Event Handler...
Далее выбираем BN_CLICKED и нажимаем OK, теперь вставляем код:
Код:
HRSRC hRes = 0; //Это переменная
HGLOBAL hData = 0;
char *zero = "\0";
LPVOID pData;
DWORD szDw,dwSize,Written;
CString message,title; //Переменные для сообщения и заголовка
GetDlgItemText(IDC_EDIT1,message); //Получаем из EditBox1 текст и сохраняем в перепенную message
GetDlgItemText(IDC_EDIT2,title);//Получаем из EditBox2 текст и сохраняем в перепенную title
if((lstrlen(title)==0 || lstrlen(message)==0)) //Проверка на заполнение EditBox-ов
{
AfxMessageBox("Заполните все поля");
return;
}
if((lstrlen(title)>30 || lstrlen(message)>30)) /*Проверка длины введённого сообщения так как мы не можем записать больше 30 символов в сообщение или заголовок во избежании казусов необходимо сделать проверку*/
{
AfxMessageBox("Слишком длинная строка. Введите меньше 30 символов");
return;
}
HMODULE hModule=GetModuleHandle(NULL);/*Получаем дескриптор модуля. Так как будем искать в себе то должны передать функции параметр NULL*/
if(hModule==NULL)
{
AfxMessageBox("Ошибка определения модуля");
return;//Обработка ошибки
}
hRes = FindResource(hModule, "File", RT_RCDATA); /*Ищем в ресурсах наш файл по имени ресурса. Так как мы не присвоили ему ID то имя ресурса пишем в "". Так как тип был RCDATA то и тут тоже указываем RCDATA.*/
// Если ресурс не найден, то выходим
if(hRes == NULL)
{
AfxMessageBox("Ресурс не найден");
return;//Обработка ошибки
}
// Получаем размер ресурса для того, чтобы сохранить его в файл
dwSize = SizeofResource(hModule,hRes);
// Если не смогли получить размер, то выходим
if(dwSize == NULL)
{
AfxMessageBox("Размер ресурса не получен");
return;//Обработка ошибки
}
hData = LoadResource(hModule, hRes);//Пытаемся загрузить ресурс
// Если не смогли загрузить, то выходим
if(hData == NULL)
{
AfxMessageBox("Не могу загрузить ресурс");
return;//Обработка ошибки
}
pData = LockResource(hData);//Задерфиваем ресурс в памяти
// Если не удалось зафиксировать ресурс, то выходим
if(pData == NULL)
{
AfxMessageBox("Не могу зафиксировать ресурс в памяти");
return;//Обработка ошибки
}
HANDLE File = CreateFile("file.exe",GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_ALWAYS,0,0); /* Создаём файл для записи куда запишем извлечённый ресурс. Так как у нас exe файл то и запишем его в exe*/
// Если не удалось создать файл, то выходим
if(File == INVALID_HANDLE_VALUE)
{
AfxMessageBox("Не могу создать файл для записи");
return;//Обработка ошибки
// Освобождаем исполняемый файл
}
// Записываем весь ресурс в файл
if(WriteFile(File,pData,dwSize,&Written,0)==NULL)
{
// Освобождаем исполняемый файл
FreeLibrary(hModule);
// Закрываем хендл файла
CloseHandle(File);
}
HANDLE hFile = CreateFile("file.exe",GENERIC_WRITE,FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0); //Открываем уже извлечённый из ресурсов файл который лежит у нас на диске в папке с билдером
if (hFile!=INVALID_HANDLE_VALUE)
{
SetFilePointer(hFile,0x000024C,NULL,0); //Ставим указатель в файле на значение которое мы получили когда искали смещение
WriteFile(hFile,title,lstrlen(title),&szDw,NULL);//Записываем
WriteFile(hFile,zero,1,&szDw,NULL);/*Так как сообщение может быть меньше 30 а остальные символы нам не нужны то запишем в файл символ конца строки. Теперь у нас будет отображаться только введённый нами текст без лишних символов. Попрбуйте не поставить и посмотрите что получится*/
SetFilePointer(hFile,0x000026C,NULL,0);//Теперь переходим ко второму найденному ранее смещению
WriteFile(hFile,message,lstrlen(message),&szDw,NULL); //Записываем
WriteFile(hFile,zero,1,&szDw,NULL);//Ставим разделитель
CloseHandle(hFile); //Закрываем дескриптор файла
AfxMessageBox("Builded OK!"); //Оповещаем что удачно создали файл
}
Теперь можно компилировать и пользовать MessageBox билдер.
Заключение
------------------
Я думаю теперь общий смсл понятен и теперь вы сможите делать билдеры для любых пинчей и других каких-нибудь лоадеров или ботов. Ведь найдя смещение пожно легко записать в файл всё что нужно. Всё зависит от билда и задай я сообщение в 5 симоволов в фале MessageBox мы бы больше 5-и в билдере и не записали, нет ну записали конечно же но файл бы просто не запустился.
Bulder: http://ifolder.ru/3594356
Source: http://ifolder.ru/3594695
WinHex: http://wasm.ru/baixado.php?mode=tool&id=24
Article by: perdimonokl aka 4nob1oz, TGBR.ORG, 2007