LoadLibraryW在LoadLibraryA完成工作时不起作用

时间:2009-10-18 09:56:14

标签: c++ unicode loadlibrary dll-injection

我已经编写了一些示例程序和DLL来学习DLL注入的概念。

我将注入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());

Memory :: 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");

它有效(因为测试dll的名称中没有unicode字符)。

如何使其与LoadLibraryW一起使用?

2 个答案:

答案 0 :(得分:2)

HMODULE WINAPI LoadLibrary(
  __in  LPCTSTR lpFileName
);

它需要一个TCHAR - 所以LoadLibraryW的参数必须是一个宽字符串;上面的代码传递了参数的多字节形式,这是LoadLibraryA想要的形式。

答案 1 :(得分:1)

我不确定你为什么要创建一个线程并将它传递给LoadLibraryW函数的地址。直接致电LoadLibraryW会不会更容易,更安全?

无论哪种方式,您当然不需要进行任何WideCharToMultiByte次呼叫。 LoadLibraryW需要一个宽字符模块名称。

你有什么理由不能这样做吗?

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