FAQ:WinAPI VCPP:значение переменной для вызывающего процесса/потока из своей собственной DLL — различия между версиями

Материал из Весельчак У
Перейти к: навигация, поиск
 
(не показано 6 промежуточных версий 2 участников)
Строка 1: Строка 1:
=== Каким образом можно установить значение переменной для вызывающего процесса/потока из своей собственной DLL? Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке.  ===
+
===Каким образом можно установить значение переменной для вызывающего процесса или потока из своей собственной DLL?===
  
Проблема вызвана тем, что каждая влинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.  
+
''Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке.''
 +
 
 +
 
 +
Проблема вызвана тем, что каждая прилинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.
  
 
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.  
 
1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.  
  
 
2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение:
 
2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение:
<pre>&nbsp;__declspec(dllexport) void set_errno(int code)
+
 
 +
<syntaxhighlight lang="cpp">
 +
__declspec(dllexport) void set_errno(int code)
 
{
 
{
errno = code;
+
errno = code;
 
}
 
}
</pre>
+
</syntaxhighlight>
В dll при подключении к процессу надо извлечь из модуля программы указатель на эту функцию.  
+
 
<pre>typedef void (*SETINT)(int);
+
В dll, при подключении к процессу, надо извлечь из модуля программы указатель на эту функцию.
 +
 
 +
<syntaxhighlight lang="cpp">
 +
typedef void (*SETINT)(int);
 
SETINT g_set_errno=0;
 
SETINT g_set_errno=0;
 
void set_errno_in_exe(int code)
 
void set_errno_in_exe(int code)
 
{
 
{
if(g_set_errno) g_set_errno(code);
+
if(g_set_errno) g_set_errno(code);
 
}
 
}
  
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
 
{
 
{
HANDLE hModule; // Handle to the main module
+
HANDLE hModule; // Handle to the main module
if(fdwReason == DLL_PROCESS_ATTACH )
+
if(fdwReason == DLL_PROCESS_ATTACH )
{
+
{
hModule = GetModuleHandle(NULL);
+
hModule = GetModuleHandle(NULL);
if (hModule == NULL) return FALSE;
+
if (hModule == NULL) return FALSE;
g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno");
+
g_set_errno = (SETINT) GetProcAddress(hModule, "set_errno");
 +
}
 +
return TRUE;
 
}
 
}
return TRUE;
+
</syntaxhighlight>
} </pre>
+
 
В нужном месте в dll вместо присваивания errno нужно вызывать внешнюю функцию  
+
В нужном месте в dll, вместо присваивания errno, нужно вызывать внешнюю функцию.
<pre>void inside_dll_func()
+
 
 +
<syntaxhighlight lang="cpp">
 +
void inside_dll_func()
 
{
 
{
...
+
...
...
+
...
set_errno_in_exe(ERROR_CODE);
+
set_errno_in_exe(ERROR_CODE);
...
+
...
}&nbsp;</pre>
+
}
 +
</syntaxhighlight>
 +
 
 +
[[Category:FAQ:WinAPI VCPP]]

Текущая версия на 18:54, 5 октября 2008

Каким образом можно установить значение переменной для вызывающего процесса или потока из своей собственной DLL?

Проблема заключается в том, что несмотря на то, что все линкуется нормально, значение переменной процесса не изменяется, когда я его устанавливаю вручную в библиотеке.


Проблема вызвана тем, что каждая прилинкованная libc (одна линкуется в исполняемый файл, ещё одна в dll) содержит свою копию переменной.

1) Можно воспользоваться динамически подгружаемой библиотекой С runtime. Для этого приложение и dll надо компилировать с ключом /MD (или MDd для отладки). В таком случае переменная будет общей для приложения и dll.

2) Можно в основном модуле программы (тот, который станет .exe) сделать "дырку" (backdoor), через которую присваивать переменной (int errno) значение:

__declspec(dllexport) void set_errno(int code)
{
	errno = code;
}

В dll, при подключении к процессу, надо извлечь из модуля программы указатель на эту функцию.

typedef void (*SETINT)(int);
SETINT g_set_errno=0;
void set_errno_in_exe(int code)
{
	if(g_set_errno) 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()
{
	...
	...
	set_errno_in_exe(ERROR_CODE);
	...
}