Целью данной статьи является показать, как работает простейший EXE Builder на основе бинарного патча.Я решил не добавлять стаб в ресурсы билдера, при желании вы можете сами это сделать.Для примера мы сделаем простейший MessageBox Builder.Данный способ является одним из самых примитивных, однако конечные EXE подлежат крипту.
Минусы данного способа:
Код стаба:
Теперь скомпилируем стаб и откроем его в HEX редакторе.Нам необходимо найти pszCaption и pszMessage заполнить нулями.
Теперь запомним смещение(нам надо будет его сохранить, оно понадобится при создании билдера):
Аналогичные действия проделываем с pszMessage и сохраняем.
Теперь приступим к написанию билдера.
Скомпилируем билдер , скинем ранее подготовленный стаб в папку с билдером и протестируем.
Ну вот собственна и все)
Минусы данного способа:
- Ограничение ввода.
- Невозможность использования конфигов(типа Zeus-овских).
- Вводимые данные не должны содержать пробелов.
Код стаба:
Код:
#include <Windows.h>
//Это заглушки , они нам понадобятся потом...
LPCSTR pszCaption = "HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH";
LPCSTR pszMessage = "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG";
VOID WINAPI Entry(VOID) {
MessageBoxA(NULL, pszMessage, pszCaption, MB_OK);
ExitProcess(EXIT_SUCCESS);
}
Теперь скомпилируем стаб и откроем его в HEX редакторе.Нам необходимо найти pszCaption и pszMessage заполнить нулями.
Теперь запомним смещение(нам надо будет его сохранить, оно понадобится при создании билдера):
Аналогичные действия проделываем с pszMessage и сохраняем.
Теперь приступим к написанию билдера.
Код:
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
SetConsoleTitle("Example EXE Builder.");
//Выделяем память и запрашиваем ввод
LPSTR pszCaption = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
LPSTR pszMessage = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
cout << "Caption: ";
cin >> pszCaption;
cout << "Message: ";
cin >> pszMessage;
if (!pszCaption || !pszMessage)
ExitProcess(EXIT_FAILURE);
DWORD dwWritten = 0;
//Копируем стаб
if (!CopyFile("Stub.exe", "Builded.exe", FALSE))
ExitProcess(EXIT_FAILURE);
//Открываем файл для записи
HANDLE hFile = CreateFileA("Builded.exe", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
ExitProcess(EXIT_FAILURE);
/*
Смещения:
-Caption: 0x610
-Message: 0x678
*/
//Спускаемся по смещениям и записываем данные
SetFilePointer(hFile, 0x610, 0, FILE_BEGIN);
WriteFile(hFile, pszCaption, lstrlen(pszCaption), &dwWritten, NULL);
SetFilePointer(hFile, 0x678, 0, FILE_BEGIN);
WriteFile(hFile, pszMessage, lstrlen(pszMessage), &dwWritten, NULL);
//Закрываем хэндл и осводождаем память.
std::cout << "Result saved as Builded.exe\n";
std::cin.get();
CloseHandle(hFile);
HeapFree(GetProcessHeap(), NULL, pszCaption);
HeapFree(GetProcessHeap(), NULL, pszMessage);
}
Скомпилируем билдер , скинем ранее подготовленный стаб в папку с билдером и протестируем.
Ну вот собственна и все)