2009-10-18 4 views
0

Я написал несколько примеров программ и DLL, чтобы изучить концепцию DLL-инъекции.LoadLibraryW не работает, пока LoadLibraryA выполняет задание

Мой код инъекции впрыскивать DLL к программе образца следующим образом (транспортная обработка опущена ошибка):

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()); 

памяти :: CreateThread выглядит следующим образом:

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"); 
    } 
} 

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

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

это работает (так как дллы теста не имеют символов Юникода в его имени).

Как заставить его работать с LoadLibraryW?

+0

кажется, что проблема в том, что я неправильно понял поведение WCHAR и нормальных персонажей. – Etan

ответ

2
HMODULE WINAPI LoadLibrary(
    __in LPCTSTR lpFileName 
); 

Он принимает TCHAR - поэтому аргумент LoadLibraryW должен быть широкой струной; приведенный выше код передает многобайтную форму аргумента, которая является формой, которую хочет загрузить LoadLibraryA.

+0

И как преобразовать широкую строку в байты? – Etan

+1

const char * ptrToWide = (const char *) dll.c_str() получает указатель; длина для размещения для копии - 2 * (wcslen (dll.c_str()) + 1) –

1

Я не уверен, почему вы создаете поток и передаете ему адрес функции LoadLibraryW. Было бы проще и безопаснее позвонить по телефону LoadLibraryW?

В любом случае, вам, безусловно, не нужно делать никаких звонков WideCharToMultiByte. LoadLibraryW ожидает широкое имя модуля.

Есть ли причина, по которой вы не можете просто сделать это?

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

Да, вы должны вызвать его из другого процесса, чтобы DLL загружалась внутри него. – Etan

+0

Какой еще процесс? У вас есть второй поток, но это прекратится, как только «LoadLibraryW» вернется. –

+0

@Charles - см. Вызов CreateRemoteThread? Имейте в виду, это выглядит немного изворотливым. Можете ли вы гарантировать, что kernel32.dll был загружен (и, возможно, перемещен) к одному и тому же адресу в обоих процессах? –

Смежные вопросы