← All posts tagged tip

iorlas

Про-tip #1: Не выёбывайся. У тебя есть какие-то внешние функции какого-то API, где необходимо передавать std::string? Есть необходимость делать хитрые вещи со строками? Да ты ещё и юзаешь чужой API, в котором нужно использовать "тупые" массивы байтов? ТАК НАХУЯ ТЫ БЛЯДЬ ИСПОЛЬЗУЕШЬ std?! НЕ ИСПОЛЬЗУЙ ТЫ ИХ БЛЯДЬ. НЕ ВЫЁБЫВАЙСЯ.
Откуда вытек "совет": сейчас юзаю один код, в котором используется wstring просто так, смеха ради. На деле для красоты. В результате, при подключении стороннего дебаггера, выходила ошибка "аксесс виолейшн эксепшн". Почему? Потому что c_str() функция std::string возвращает временный объект(живёт только в текущем скоупе).
Всё бы ничего, да вот только функция этого API сохраняет адрес в очередь, а затем, уже потом, производит использование этого адреса для получения строки. Вот только если функция задержится пока наша функция не выйдет из скоупа, у нас получится что мы как-бы подставили наш API, дав адрес строки, которой уже и нет.

iorlas

Когда полезно то, что описано в #1570139 ? Да много когда.
Например, у меня такая функция:
extern "C" __declspec(dllexport) void* WINAPI __ProxyFunc9(UINT SDKVersion);
Надо чтобы она экспортировалась как Direct3DCreate9. Однако, если даже её назвать "Direct3DCreate9", то экспортнётся она как Direct3DCreate9@16 или _Direct3DCreate9, но не Direct3DCreate9. Через .def файл я смог позволить себе делать что угодно, но получить нужный результат.
Бтв, прокси-длл у меня почти готова, только оказалось что часть хукинг-логики придётся таки поместить внутрь прокси, ну да не беда.

iorlas

Наверно, не многим приходится сталкиваться с Module Definition File в MSVS. Однако, это очень удобно, если необходимо чтобы линковщик экспортировал функции не как подумает, а как нам надо.
Создаём файл .def с любым именем. Содержимое такое:
LIBRARY "имя_выходной_длл_без.dll"
EXPORTS
myfunc = __innerfunc0 @1

Функции добавлять пока не надоест, лол. Суть в том, что можно таким образом назвать функции как захочется, а импортнутся они как надо в результате. Можно и просто объявлять их через def без присваивания.
@1 — для порядка символов. @1, @2, @3 etc.
Но мало просто создать файл! Необходимо указать студии его использовать! Да, об этом на самом деле мало где пишут, но я нарыл в одном экземпле:
Настройки проекта — линковщик — ввод — Module definition file. Вводим имя файла и компилим.