您的位置:首页 > 其它

Win7 CreateRemoteThread 另类使用方法

2012-03-09 18:27 477 查看
<转载请注明出处: http://blog.csdn.net/wangningyu/archive/2011/05/31/6456607.aspx>
同样的代码,在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.dll"), "NtCreateThreadEx");  

        // 函数NtCreateThreadEx只有一种形式,不像LoadLibrary得区别Unicode版本(LoadLibraryW)和非Unicode(LoadLibraryA)

        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就不贴了吧,有兴趣的友友可以参考一下~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: