2009-10-18 7 views
0

J'ai écrit un exemple de programme et de DLL pour apprendre le concept de l'injection de DLL.LoadLibraryW ne fonctionne pas pendant que LoadLibraryA fait le travail

Mon code d'injection pour injecter la DLL au programme d'échantillonnage est la suivante (gestion des erreurs omise):

std::wstring dll(L"D:\\Path\\to\\my\\DLL.dll"); 
LPTHREAD_START_ROUTINE pLoadLibraryW = 
    (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryW"); 
int bytesNeeded = WideCharToMultiByte(CP_UTF8, 0, dll.c_str(), dll.length(), 
    NULL, 0, NULL, NULL); 
std::vector<byte> dllName(bytesNeeded); 
WideCharToMultiByte(CP_UTF8, 0, dll.c_str(), dll.length(), 
    (LPSTR)&dllName[0], bytesNeeded, NULL, NULL); 
// Memory is a class written by me to simplify memory processes. 
// Constructor takes desired permissions. 
Memory mem (pid, false, true, false, true, false, false, false, 
    false, false, true, true, true, false); 
// Ensures deletion of the allocated range. 
// true/true/false = read and write access, no execute permissions 
std::tr1::shared_ptr<void> allocated = 
    mem.AllocateBytes(dllName.size(), true, true, false); 
mem.WriteBytes((unsigned int)allocated.get(), dllName); 
mem.CreateThread(pLoadLibraryW, allocated.get()); 

mémoire :: CreateThread est la suivante:

void Memory::CreateThread(LPTHREAD_START_ROUTINE address, LPVOID parameter) const { 
    std::tr1::shared_ptr<void> hThread(CreateRemoteThread(m_hProcess.get(), 
     NULL, 0, address, parameter, 0, NULL), CloseHandle); 
    if (hThread.get() == NULL) { 
     throw std::runtime_error("Memory::CreateThread: CreateRemoteThread failed"); 
    } 
    DWORD returned = WaitForSingleObject(hThread.get(), INFINITE); 
    if (returned != WAIT_OBJECT_0) { 
     throw std::runtime_error("Memory::CreateThread: The remote thread did not complete properly"); 
    } 
} 

Le problème est, que le module n'est pas chargé. Cependant, quand je change la deuxième ligne à

LPTHREAD_START_ROUTINE pLoadLibraryW = 
    (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA"); 

il fonctionne (depuis le dll de test n'a pas de caractères unicode dans son nom). Comment le faire fonctionner avec LoadLibraryW?

+0

semble que le problème était que j'ai mal compris le comportement de WCHAR et les caractères normaux. – Etan

Répondre

2
HMODULE WINAPI LoadLibrary(
    __in LPCTSTR lpFileName 
); 

Il faut un TCHAR - si l'argument en faveur LoadLibraryW doit être une grande chaîne; le code ci-dessus transmet la forme multi-octets de l'argument, qui est la forme que LoadLibraryA veut.

+0

Et comment convertir la chaîne large en octets? – Etan

+1

const char * ptrToWide = (const char *) dll.c_str() vous donne un pointeur; la longueur à allouer pour une copie est 2 * (wcslen (dll.c_str()) + 1) –

1

Je ne sais pas pourquoi vous créez un thread et lui transmettez l'adresse de la fonction LoadLibraryW. Ne serait-il pas plus facile et plus sûr d'appeler directement le LoadLibraryW?

De toute façon, vous n'avez certainement pas besoin d'effectuer d'appels WideCharToMultiByte. LoadLibraryW attend un nom de module de caractères larges.

Y a-t-il une raison pour laquelle vous ne pouvez pas faire cela?

HMODULE hLibHandle = LoadLibraryW(L"D:\\Path\\to\\my\\DLL.dll"); 
+0

Oui, vous devez l'appeler à partir de l'autre processus afin que la DLL soit chargée à l'intérieur de celui-ci. – Etan

+0

Quel autre processus? Vous avez un deuxième thread, mais cela va se terminer dès que 'LoadLibraryW' revient. –

+0

@Charles - voir l'appel à CreateRemoteThread? Remarquez, ça a l'air un peu douteux. Pouvez-vous garantir que kernel32.dll a été chargé (et potentiellement relocalisé) à la même adresse dans les deux processus? –

Questions connexes