您的位置:首页 > 其它

Win7 CreateRemoteThread 另类使用方法

2014-03-14 17:05 330 查看
同样的代码,在XP下面随便你怎么整,WIN7的话是相当纠结的,具体哪些错误就不解释了 ~~

gg点了二十多页,在韩国某大牛的博客上总算找到一点思路(虽然看不懂韩文,但代码还算勉强看得懂吧)

原来是要用动态调用ntdll.dll >>
NtCreateRemoteThreadEx
,于是over~~

说明:

1、InjectDll.exe 是注入DLL的EXE

2、dummy.dll 是一个普通DLL,加载后弹出MessageBox

下面是一个XP中远程线程注入DLL的代码,在WIN7 + OD调试的例子:



看看错误信息:



杯具了,接着看! 重新运行OD调试,bp CreateRemoteThread :



看看CreateRemoteThread 中的几个参数:



上图重要标记的几个参数:

(1) svchost.exe (PID: 3184) 句柄

(2) kernel32.dll ! LoadLibarayA

(3) 在svchost中为C://Work//dummy.dll字符串所分配的首地址

进入CreateRemoteThread :



我们发现,实际上是调用kernelbase >>
CreateRemoteThreadEx 函数。

(GG了这个DLL,原来是它是继VISTA/WIN7之后额外的DLL,负责协助Kernel32.dll的调用!)

那我们看看这个函数调用栈中的参数吧:



发现与kernel32.dll >>
CreateRemoteThread 参数一模一样!

OK ! 我们再继续跟进kernelbase.dll >>
CreateRemoteThreadEx :



那我们看看这个函数调用栈中的参数吧:



OK,这算到底儿了,因为ntdll.dll >>
ZwCreateThreadEx 已经运行到了内核代码,我们的OD没办法再调试了!

于是请google sysenter吧!

特别说明,kernelbase.dll >>
CreateRemoteThreadEx 是对 ntdll.dll >>
ZwCreateThreadEx 的补充扩展!

那我们都得到这样的结果 :



ntdll.dll >> ZwCreateThreadEx 是未公开的API,MSDN、GG也很难找到相关资料!

下面是看看这个结构体伪代码:

typedef DWORD (WINAPI *PFNTCREATETHREADEX)
(
PHANDLE                 ThreadHandle,
ACCESS_MASK             DesiredAccess,
LPVOID                  ObjectAttributes,
HANDLE                  ProcessHandle,
LPTHREAD_START_ROUTINE  lpStartAddress,
LPVOID                  lpParameter,
BOOL	                CreateSuspended,
DWORD                   dwStackSize,
DWORD                   dw1,
DWORD                   dw2,
LPVOID                  Unknown
);


OK ,那剩下的我们只需要重写CreateThreadEx 函数即可!

为了保证XP的兼容,所以需要判断一下OS版本,下面是完整的测试代码:

#include "windows.h"
#include "stdio.h"
#include "tchar.h"
#pragma comment(lib,"Advapi32.lib")
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
TOKEN_PRIVILEGES tp;
HANDLE hToken;
LUID luid;
if( !OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hToken) )
{
_tprintf("OpenProcessToken error: %u/n", GetLastError());
return FALSE;
}
if( !LookupPrivilegeValue(NULL,
lpszPrivilege,
&luid) )
{
_tprintf("LookupPrivilegeValue error: %u/n", GetLastError() );
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if( bEnablePrivilege )
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
if( !AdjustTokenPrivileges(hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL) )
{
_tprintf("AdjustTokenPrivileges error: %u/n", GetLastError() );
return FALSE;
}
if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
{
_tprintf("The token does not have the specified privilege. /n");
return FALSE;
}
return TRUE;
}
typedef DWORD (WINAPI *PFNTCREATETHREADEX)
(
PHANDLE                 ThreadHandle,
ACCESS_MASK             DesiredAccess,
LPVOID                  ObjectAttributes,
HANDLE                  ProcessHandle,
LPTHREAD_START_ROUTINE  lpStartAddress,
LPVOID                  lpParameter,
BOOL	                CreateSuspended,
DWORD                   dwStackSize,
DWORD                   dw1,
DWORD                   dw2,
LPVOID                  Unknown
);
BOOL IsVistaOrLater()
{
OSVERSIONINFO osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
if( osvi.dwMajorVersion >= 6 )
return TRUE;
return FALSE;
}
BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
{
HANDLE      hThread = NULL;
FARPROC     pFunc = NULL;
if( IsVistaOrLater() )    // Vista, 7, Server2008
{
pFunc = GetProcAddress(GetModuleHandle("ntdll.dl"), "NtCreateThreadEx");
if( pFunc == NULL )
{
printf("MyCreateRemoteThread() : GetProcAddress(/"NtCreateThreadEx/") 调用失败!错误代码: [%d]/n",
GetLastError());
return FALSE;
}
((PFNTCREATETHREADEX)pFunc)(&hThread,
0x1FFFFF,
NULL,
hProcess,
pThreadProc,
pRemoteBuf,
FALSE,
NULL,
NULL,
NULL,
NULL);
if( hThread == NULL )
{
printf("MyCreateRemoteThread() : NtCreateThreadEx() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
}
else                    // 2000, XP, Server2003
{
hThread = CreateRemoteThread(hProcess,
NULL,
0,
pThreadProc,
pRemoteBuf,
0,
NULL);
if( hThread == NULL )
{
printf("MyCreateRemoteThread() : CreateRemoteThread() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
}
if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )
{
printf("MyCreateRemoteThread() : WaitForSingleObject() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
return TRUE;
}
BOOL InjectDll(DWORD dwPID, char *szDllName)
{
HANDLE hProcess = NULL;
LPVOID pRemoteBuf = NULL;
FARPROC pThreadProc = NULL;
DWORD dwBufSize = strlen(szDllName)+1;
if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
{
printf("[错误] OpenProcess(%d) 调用失败!错误代码: [%d]/n",
dwPID, GetLastError());
return FALSE;
}
pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,
dwBufSize, NULL);
pThreadProc = GetProcAddress(GetModuleHandle("kernel32.dl"),
"LoadLibraryA");
if( !MyCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf) )
{
printf("[错误] CreateRemoteThread() 调用失败!错误代码: [%d]/n", GetLastError());
return FALSE;
}
VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
CloseHandle(hProcess);
return TRUE;
}
int main(int argc, char *argv[])
{
SetPrivilege(SE_DEBUG_NAME, TRUE);
// InjectDll.exe <PID> <dllpath>
if( argc != 3 )
{
printf("用法 : %s <进程PID> <dll路径>/n", argv[0]);
return 1;
}
if( !InjectDll((DWORD)atoi(argv[1]), argv[2]) )
{
printf("InjectDll调用失败!/n");
return 1;
}
printf("InjectDll调用成功!/n");
return 0;
}


DLL就不贴了吧,有兴趣的友友可以参考一下~~

<转载请注明出处: http://blog.csdn.net/wangningyu/archive/2011/05/31/6456607.aspx>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: