【发布时间】:2019-06-07 07:50:18
【问题描述】:
我正在使用 CreateRemoteThread() + LoadLibrary() 方法注入代码。 当我在我的 Windows7 64 位操作系统笔记本电脑上运行我的注入器时一切正常,并且对于某些目标应用程序,它仍然可以在 Windows Server 2012 R2 64 位中工作。
但是,在这个 Windows Server 2012 环境中,对于一些目标应用程序,它是旧的 MFC 应用程序,CreateRemoteThread 成功但 DllMain 没有被调用,我发现 LoadLibrary() 似乎失败了,通过使用 GetExitCodeThread()创建远程线程。
为了写入目标进程的内存,我计算了终止的0字节。
另外,我已经知道 kernel32.dll 地址对于 Windows 7 和 Windows Server 2012 是相同的,使用下面 URL 回答部分介绍的方法。
下面的 GetExitCodeThread() 的退出代码为零。
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
if(hThread == NULL) {
OutputDebugString(_T("Error: the remote thread could not be created.\n"));
writeLog("Error: the remote thread could not be created.");
}
else {
DWORD dResult = WAIT_OBJECT_0;
dResult = WaitForSingleObject(hThread, 1000*3);// the thread may already exited, so do not wait INFINITE
DWORD dwExitCode = 0;
GetExitCodeThread(hThread, &dwExitCode);
if(dwExitCode == 0)
{
writeLog("Error: LoadLibraryA failed.");
}
else
{
OutputDebugString(_T("Success: the remote thread was successfully created.\n"));
writeLog("Success: the remote thread was successfully created.");
}
}
你知道我接下来应该怀疑什么吗?
总而言之,在下图中,您可以看到唯一的失败是我在 Windows Server 2012 上运行注入器以注入一些旧的 MFC 应用程序。
在下图中,有关于 MFC 应用程序有多旧的信息:
我正在努力提供足够的信息,如果您需要更多信息,请告诉我。
下面是注入我的 dll 的完整代码:
void inject(int procID, char* pszHookDll)
{
g_nTargetProcId = procID;
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
g_hTargetProc = process;
BOOL bInit = SymInitialize(g_hTargetProc, g_sPdbFolder, TRUE);// for analysing the information spy.dll send out
if(process == NULL) {
writeLog("Error: the specified process couldn't be found.");
}
/*
* Get address of the LoadLibrary function.
*/
LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if(addr == NULL) {
writeLog("Error: the LoadLibraryA function was not found inside kernel32.dll library.");
}
//addr = getProcAddrInTargetProcess(procID, process);
/*
* Allocate new memory region inside the process's address space.
*/
int nBufSize = strlen(pszHookDll)+1;
LPVOID arg = (LPVOID)VirtualAllocEx(process, NULL, nBufSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if(arg == NULL) {
writeLog("Error: the memory could not be allocated inside the chosen process.");
}
/*
* Write the argument to LoadLibraryA to the process's newly allocated memory region.
*/
int n = WriteProcessMemory(process, arg, pszHookDll, nBufSize, NULL);
if(n == 0) {
writeLog("Error: there was no bytes written to the process's address space.");
}
/*
* Inject our DLL into the process's address space.
*/
HANDLE hThread = CreateRemoteThread(process, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
if(hThread == NULL) {
writeLog("Error: the remote thread could not be created.");
}
else {
DWORD dResult = WAIT_OBJECT_0;
dResult = WaitForSingleObject(hThread, 1000*3);
DWORD dwExitCode = 0;
GetExitCodeThread(hThread, &dwExitCode);
if(dwExitCode == 0)
{
writeLog("Error: LoadLibraryA failed.");
}
else
{
OutputDebugString(_T("Success: the remote thread was successfully created.\n"));
writeLog("Success: the remote thread was successfully created.");
}
}
/*
* Close the handle to the process, becuase we've already injected the DLL.
*/
//CloseHandle(process);close after symcleanup
}
【问题讨论】:
-
我假设您正在使用 WriteProcessMemory 和 VirtualAllocEx 将 LoadLibrary 参数写入目标内存。如果是这种情况,您能否发布其余的代码?另外,两个系统上的测试应用程序是否相同?您确定 LoadLibrary 签名是相同的(它没有被钩住或类似的东西)吗?您确定您没有尝试将 64 位编译的 DLL 加载到 32 位进程中吗?如果其他一切都失败了,我建议附加 x64dbg 并在 LoadLibrary(A,无论你调用哪个) 上放置一个断点,看看那里有什么。
-
那里超出了字符限制,所以是新评论。您的 DLL 是否具有目标系统上可能不存在的任何依赖项?尤其是可再发行包以及您正在使用的其他任何东西都非常重要。在某些情况下,缺少这些可能会导致完全静默且无错误的注入失败。
-
一个可能的罪魁祸首是将错误的文件路径传递给
LoadLibrary()。请显示您传递给它的实际值。更糟糕的情况是,您可以在调用LoadLibrary()和GetLastError()的远程进程中分配整个函数,并将错误代码存储在您可以使用ReadProcessMemory()读取的位置。此外,在调用WaitForSingleObject()时,您应该使用无限超时。线程句柄在远程线程结束时发出信号。您需要等待结束才能致电GetExitCodeThread()。如果线程在你进入等待之前结束就可以了 -
我发布了我的完整源代码。我只是无法理解:我可以将我的 dll 注入到我的 windows 7 操作系统上的旧式 MFC 应用程序和新式 MFC 应用程序中,但对于 windows Server 2012 上的旧式 mFC 应用程序却失败了..
-
老实说,我发现依赖关系在这里是一个非常可能的问题,尤其是因为它是一个旧版本。您确定您已经设置了正确的目标平台,所有可再发行包/外部依赖项都存在或静态链接吗?您可以使用 /MT 来避免依赖外部可再发行包。除了@RemyLebeau 提到的,代码看起来还不错
标签: c++ dll loadlibrary createremotethread dllmain