Win7 CreateRemoteThread 另类使用方法

来源:互联网 发布:php记事本编写软件 编辑:程序博客网 时间:2024/04/30 10:59

转载自:http://blog.csdn.net/wangningyu/article/details/6456607


同样的代码,在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也很难找到相关资料!

 

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

 

[cpp] view plaincopyprint?
  1. typedef DWORD (WINAPI *PFNTCREATETHREADEX)  
  2. (   
  3.     PHANDLE                 ThreadHandle,     
  4.     ACCESS_MASK             DesiredAccess,    
  5.     LPVOID                  ObjectAttributes,     
  6.     HANDLE                  ProcessHandle,    
  7.     LPTHREAD_START_ROUTINE  lpStartAddress,   
  8.     LPVOID                  lpParameter,      
  9.     BOOL                    CreateSuspended,      
  10.     DWORD                   dwStackSize,      
  11.     DWORD                   dw1,   
  12.     DWORD                   dw2,   
  13.     LPVOID                  Unknown   
  14. );   

 

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就不贴了吧,有兴趣的友友可以参考一下~~


原创粉丝点击