Ну, окей.
Качаем, например, с целью ознакомления триалку Visual Studio 2008, ставим (дело долгое, часа этак два, запускаем).
Почему восьмая? Потому что, например, неко-торые хэдеры сделаны под студию (gcc-based IDE типа кодблокса раньше чуть давились), а дллки из-под двенадцатой студии что-то с собой тянут и на некоторых машинах не идут.
Хотя хз, короч.
Запускаем.
Файл => Создать => Проект. Да, у меня богомерзкая локализованная.
Окей. Запускается мастер.
Далее. Выбираем DLL.
Готово. Открывается проект. Кликаем на dllmain.cpp
DllMain - точка старта, запускаемая в перечисленных ниже случаях, подключении-отключении процесса, подключении-отключении в поток, в общем, можно почитать на MSDN.
Нас интересует чистый старт (DLL_PROCESS_ATTACH). Но перед тем как стереть все к чертовой матери, нужно (хотя и не обязательно) отключить предкомпилированные заголовки.
Это такая сомнительная фича, которая сделана для ускорения компиляции кода. Другое дело, что она заодно превращает деревья инклудов в труднопредсказуемую лапшу. Хм. В общем, отключаем.
С/С++ -> Предварительно скомпилированные заголовки.
Переключаем конфигурации на "Все", выставляем "Не использовать предварительно скомпилированные заголовки".
Окей. Теперь время ВЫРЕЗАТЬ ВЫРЕЗАТЬ ВЫРЕЗАТЬ ВЫРЕЗАТЬ.
Можно выпилить stdafx.h и stdafx.cpp (и их упоминания в инклудах), но это не так важно уже.
Заменяем код в dllmain.cpp на
Код
#include <windows.h>
#include <stdio.h>
#include "..\..\include\era.h"
#include "..\..\include\patcher_x86_commented.hpp"
Patcher * globalPatcher;
PatcherInstance *patcher;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
globalPatcher = GetPatcher();
patcher = globalPatcher->CreateInstance("itsmustbeveryuniuename");
ConnectEra();
}
return TRUE;
}
Ну, пути к инклудам - свои: у меня инклуды лежат на одном уровне с папками проектов.
Создаем и инициализируем объект патчера, коннектимся к Эре.
Пишем хук.
В DllMain, ставим хук:
Код
patcher->WriteLoHook(0x464F9C, (void*)hook_464F9C);
LoHook - низкоуровневый ход, предназначенный для мелких правок уровнем чуть выше ассемблера. При активном использовании начисто лишает шансов разобраться, что ваще происходит на пытаемом участке.
Есть еще HiHook, служит для перехвата вызовов функций.
много что еще есть, лучше посмотреть в прекрасно документированном заголовочнике.
перед DllMain создаем функцию хука:
Цитата
int __stdcall hook_464F9C(LoHook* h, HookContext* c)
{
FireErmEvent(77012);
return EXEC_DEFAULT;
}
FireErmEvent- эрошная функция. EXEC_DEFAULT - выполнить затертый хуком код.
Из с можно выдрать, например, значения регистров, если надо.
Таким образом, код сейчас выглядит так:
Компилируем (F5 или кнопка с зеленой стрелочкой, стоит переключиться перед этим в Release)
Появляется окно с предложением приаттачиться к процессу, отказываемся.
Наша длл лежит в <project_name>/release/Test.dll
все, кладем, тестируем (я не гонял, ага)
скачать:
https://dl.dropboxusercontent.com/u/61759222/HoMM/fish.zip