注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

熊猫正正的博客

熊猫正正的天空

 
 
 

日志

 
 

Win7 中创建远程线程(摘)  

2012-03-07 17:24:18|  分类: C/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
转自一毛的空间http://www.free-fly.org/cnblog/?p=349

以前在xp下创建远程线程的代码到了win7下就跑不起来了.在网上找一种比较简单的办法,摘过来备忘,下面是原文:

同样的代码,在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也很难找到相关资料!
下面是看看这个结构体伪代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 
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.dll"), "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;

}

  评论这张
 
阅读(273)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017