CreateRemoteThread注入DLL奇怪的问题

greatws 2009-04-27 04:21:34

PROCESS_INFORMATION pi;
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
BOOL bRet = CreateProcess(_T("C:\\111.exe"), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
if (bRet)
{
WCHAR wFilePath[256] = _T("C:\\EmptyDLL.dll");
LPWSTR pszLibFile = NULL;
int len = (lstrlenW(wFilePath) + 1) * 2;
pszLibFile = (PWSTR)VirtualAllocEx(pi.hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(pi.hProcess, pszLibFile, (PVOID) wFilePath, len, NULL);
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
HANDLE hRemoteThread = CreateRemoteThread(pi.hProcess, NULL, 0, pfnThreadRtn, pszLibFile, 0, NULL);
WaitForSingleObject(hRemoteThread, INFINITE);
if (pszLibFile != NULL)
{
VirtualFreeEx(pi.hProcess, pszLibFile, 0, MEM_RELEASE);
}
CloseHandle(hRemoteThread);
ResumeThread(pi.hThread);
DWORD dwErr = GetLastError();
CString str;
str.Format(_T("0x%08x"), dwErr);
MessageBox(str);
}




上段代码在一个exe里调用,就是在新进程主线程CREATE_SUSPENDED时注入一个DLL,CreateProcess的第一个参数111.exe,是MFC程序,注入之后无论如何都无法启动,没有任何报错迹象,GetLastError是0。但如果是console程序注入之后是可以启动的,比如启动cmd.exe。EmptyDLL.dll是一个空的DLL,DllMain直接返回TRUE。

各位大大看看,是哪里有问题?
...全文
1403 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
A381560388 2012-07-24
  • 打赏
  • 举报
回复
(在XP系统下)目标主线程运行之前,过早的退出子线程就会使进程出错 (WIN7下没问题)
你把你建立的远线程实行的代码里加一个sleep(Infinite);
bluhar 2011-06-24
  • 打赏
  • 举报
回复
看到好多陌生东西,createprocess注入dll不好整.
djh512 2009-05-14
  • 打赏
  • 举报
回复
看着头晕 很好很强大
sunlin7 2009-05-10
  • 打赏
  • 举报
回复
楼主试试在一个静态链接的win32程序里面加载comctl32.dll,系统会怎样报错。
我现在的电脑是没有windows环境,没有办法测试。
sunlin7 2009-05-10
  • 打赏
  • 举报
回复
我以前在写某个加载内存中PE文件的程序时遇到这个问题,当时用的是VS2005,发现在在加载某些带XP样式的DLL或EXE时,程序里面依赖DLL的加载与.manifest有关,这个控制文件可能以"程序名+.manifest"独立的放置在程序所在目录,也可能以二零几的编号保存在PE资源里面(我实在记不起来编号了),当时没有解决如何总是正确加载此类DLL的问题。
你可以试试在一个静态链接的Win32程序里面试着加载VC7.1或VC8.0的redist文件,比如加载msvcr80.dll,则会返回错误,原因是宿主文件没有相就的manifest信息,系统无法确定加载依赖的文件(是无法确定msvcr80.dll依赖的XP界面功能dll)。

如果有mainfest信息,则系统会从C:\Windows\winsxs\下选择相应的DLL。

希望楼主可以从网上找到或自己找到解决此问题的方法,到时候不要忘了共享一下经验哟。
greatws 2009-05-04
  • 打赏
  • 举报
回复
关键让我想不通的是,只要加载uxtheme.dll的程序,就不行,其它的都可以。
TianChong 2009-05-04
  • 打赏
  • 举报
回复
楼主的错误在于:随意的插入到exe进程中,而没有计算相关数据节,例如PIMAGE_DOS_HEADER我就没有看到。
再转换成PIMAGE_NT_HEADERS,然后还要根据DLL的FileHeader.NumberOfSections;计算Sections,再产生一个PIMAGE_SECTION_HEADER数据,还要将上面的Sections值dwSections * sizeof(IMAGE_SECTION_HEADER),总之相当复杂,手上现在也没有代码,但以前成功实现过,我之前的做法是将DLL读出来写入到SVCHOST.exe中并启动(和你先启动111.exe是一样的)。不过无论如何这种方法最终还是要用到WriteProcessMemory()和CreateRemoteThread(),这就无法跳过防病毒软件这一关,所以我想,你最后直接挂SSDT的NtCreateProcessEx应该是更优的选择。
greatws 2009-05-03
  • 打赏
  • 举报
回复
总结一下


21楼说的vc redist选择性加载不知道是什么,网上也没找到资料。
22楼的方法不能保证线程同步。
23楼,PAGE_EXECUTE_READWRITE我又没有在那个分页执行,所以EXECUTE属性是没必要的。
24楼:我这里还没有到执行代码的那一步,注入都运行不了,执行更不用说了。


LS的方法不能保正调用时机,有可能进程一启动立刻退出了呢?这种就没办法了。
最后用ntdll.dll的LdrLoadDll的方法我也试了,还是不行。
代码如下


WCHAR wFilePath[256] = _T("C:\\EmptyDLL.dll");
UNICODE_STRING us;
LPWSTR pszLibFile = NULL;
int len = (lstrlenW(wFilePath) + 1) * 2;
pszLibFile = (PWSTR)VirtualAllocEx(pi.hProcess, NULL, len + 50 + 50 + 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, pszLibFile, (PVOID) wFilePath, len, NULL);
DWORD addr = (DWORD)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "LdrLoadDll");
unsigned char asm1[] = {
0x68, 0x0, 0x0, 0x0, 0x0, //push, OUT PHANDLE
0x68, 0x0, 0x0, 0x0, 0x0, //push, IN PUNICODE_STRING
0x6a, 0x0,
0x6a, 0x0,
0xbe, 0x0, 0x0, 0x0, 0x0, //mov esi, LdrLoadDll
0xff, 0xd6, //call esi
0xc3};


us.MaximumLength = len;
us.Length = len - 2;
us.Buffer = pszLibFile;

WriteProcessMemory(pi.hProcess, (LPVOID)((DWORD)pszLibFile + len), (PVOID)&us, sizeof(us), NULL);

*((DWORD*)(asm1 + 1)) = (DWORD)((DWORD)pszLibFile + len + 50 + 50);
*((DWORD*)(asm1 + 6)) = (DWORD)((DWORD)pszLibFile + len + 50);
*((DWORD*)(asm1 + 15)) = addr;
WriteProcessMemory(pi.hProcess, (LPVOID)((DWORD)pszLibFile + len + 50), (PVOID)asm1, sizeof(asm1), NULL);


PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)((DWORD)pszLibFile + len + 50);
HANDLE hRemoteThread = CreateRemoteThread(pi.hProcess, NULL, 0, pfnThreadRtn, NULL, 0, NULL);





还是解决不了,直接挂SSDT的NtCreateProcessEx了,明天结贴,就当散分。
xqchang 2009-05-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 greatws 的回复:]
引用 5 楼 cnzdgs 的回复:
EmptyDLL.dll是Win32还是MFC程序?如果是MFC扩展DLL,可能会与被注入的EXE有冲突。
另外,系统中有没有安装反木马之类的软件?


win32的DLL,有卡巴,不过已经退出了。


引用 6 楼 biweilun 的回复:
90%是你安装的杀毒软件的问题。
他们会进行SSDT把CreateRemoteThread给拦截下来的

有道理,我试下恢复SSDT。


现在的问题是,注入是成功的,但是一走过ResumeThread(pi.hThr…
[/Quote]

1、在CreateProcess()后Sleep()上几秒钟,等待111.exe完全启动。
2、把CreateProcess()的参数CREATE_SUSPENDED去掉,线程注入不一定要求宿主进程挂起来。
surge0321 2009-04-30
  • 打赏
  • 举报
回复
学习
djh512 2009-04-30
  • 打赏
  • 举报
回复
顶一下
bluesky396 2009-04-30
  • 打赏
  • 举报
回复
学习
tian_yang_jian 2009-04-30
  • 打赏
  • 举报
回复
弄不来啊,顶你一下吧
Red_angelX 2009-04-29
  • 打赏
  • 举报
回复
我猜测是线程同步的问题
EvilGene 2009-04-29
  • 打赏
  • 举报
回复
只有注入代码 你没有写执行代码啊
GetExitCodeThread (hRemoteThread, int code);
CloseHandle(hRemoteThread);
handle1=LoadLibraryEx ("C:\\EmptyDLL.dll", 0, 0)
int Faddress=GetProcAddress (handle1, DllFunctionName)
int verityaddress=code+Faddress-handle1
CreateRemoteThread (pHandle, 0, 0, verityaddress, 0, 0, 0)
CloseHandle (hRemoteThread)
CloseHandle (pHandle)

我是其他语言转C++刚接触C++没几天 随手翻译的代码 DLL注入我这边有2种完整的代码都是可以编译执行的 可惜不是C++的
哪些翻译的不对请指教 上面只有执行代码 verityaddress=code+Faddress-handle1 这条算法我也没搞清楚
chenhui530 2009-04-29
  • 打赏
  • 举报
回复
pszLibFile = (PWSTR)VirtualAllocEx(pi.hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE);

这句有问题,在多核机器上有问题应该改成这样

pszLibFile = (PWSTR)VirtualAllocEx(pi.hProcess, NULL, len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
cnzdgs 2009-04-28
  • 打赏
  • 举报
回复
重载WindowProc函数并设置断点看看。
WaistCoat19 2009-04-28
  • 打赏
  • 举报
回复
先缩小范围:测试程序不用MFC,直接SDK看是否有问题
zgj828 2009-04-28
  • 打赏
  • 举报
回复
飘过~
greatws 2009-04-28
  • 打赏
  • 举报
回复
调试了一下,走到DoModal()里,CreateDialogIndirect返回NULL,但是后面GetLastError返回0,后面还有一大段注释,看了下我的情况是第二点,However, the user handled WM_CREATE and returned -1.我也没有处理WM_CREATE阿,奇怪死了。


hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,
pParentWnd->GetSafeHwnd(), AfxDlgProc);
#ifdef _DEBUG
dwError = ::GetLastError();
#endif

/* This is a bit tricky. At this point, 1 of 3 things has happened:
* 1) ::CreateDialogIndirect() created successfully and hWnd != NULL.
* 2) ::CreateDialogIndirect() did create a window and then send the appropiate
* creation messages (ie. WM_CREATE). However, the user handled WM_CREATE and
* returned -1. This causes windows to send WM_DESTROY and WM_NCDESTROY to the
* newly created window. Since WM_NCDESTROY has been sent, the destructor of this
* CWnd object has been called. And ::CreateDialogIndirect() returns NULL.
* 3) ::CreateDialogIndirect() did NOT create the window (ie. due to error in template)
* and returns NULL.
*
* (Note: In 3, this object is still valid; whereas in 2, this object has been deleted).
*
* Adding to the complexity, this function needs to do 2 memory clean up (call
* pOccManager->PostCreateDialog() and delete occDialogInfo) if the destructor of
* this object hasn't been called. If the destructor has been called, the clean up is done
* in the destructor.
*
* We can use the return valid of AfxUnhookWindowCreate() to differentiate between 2 and 3.
* - If AfxUnhookWindowCreate() returns true and hWnd==NULL, this means that (2) has happened
* and we don't have to clean up anything. (Cleanup should be done in the destructor).
* - If AfxUnhookWindowCreate() returns false and hWnd== NULL, this means that (3) has happened
* and we need to call PostNcDestroy().
*
* Note: hWnd != NULL implies that AfxUnhookWindowCreate() return TRUE.
*
* Note2: From this point on, don't access any member variables without checking hWnd. If
* hWnd == NULL, the object has been destroyed already.
*/

加载更多回复(18)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧