darkelf,
в основном модуле программы (тот, который станет .exe) надо сделать дырку (backdoor):
__declspec(dllexport) void set_errno(int code) {
errno = code;
}
В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию.
typedef void (*SETINT)(int);
SETINT g_set_errno = NULL;
void set_errno_in_exe(int code) {
if (g_set_errno != NULL) g_set_errno(code);
}
BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
)
{
HANDLE hModule; // Handle to the main module
if ( fdwReason == DLL_PROCESS_ATTACH ) {
hModule = GetModuleHandle(NULL);
if (hModule == NULL) return FALSE;
g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno");
}
return TRUE;
}
В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию
void inside_dll_func() {
// bla-bla-bla
set_errno_in_exe(ERROR_CODE);
// foo-foo
}
Проблема вызвана тем, что каждая влинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию errno. Поэтому приходится пробивать дырку в адресное пространство исполняемого файла чтобы установить errno для него.