<input id="imkq6"><samp id="imkq6"></samp></input>
<bdo id="imkq6"></bdo>
  • <input id="imkq6"><samp id="imkq6"></samp></input>
    <strong id="imkq6"></strong>
  • <bdo id="imkq6"></bdo>
  • 挂海论坛

     找回密码
     立即注册

    QQ登录

    只需一步,快速开始

    搜索
    超级变速器为电脑系统、软件程序、游戏加速平均提速100%有技术,来挂海,申请版主?#29486;?#36816;营!QQ游戏小号-和平精英15级批发 █DNF█绝地█和平█全网最低货源卡盟█诚招代理█
    新卡盟,超低价,新新卡盟 CC卡盟 全网第一辅助货源批发站点 0利润总端放卡 CC卡盟 全网第一辅助货源批发站点 0利润总端放卡 CC卡盟 全网第一辅助货源批发站点 0利润总端放卡
    █老牌货源站█0利润出卡█诚招项目上架█?#29486;?#20849;赢█ █老牌货源站█0利润出卡█诚招项目上架█?#29486;?#20849;赢█ 月薪百万诚邀PUBG实力作者和平精英作者骗子绕! 月薪百万诚邀PUBG实力作者和平精英作者骗子绕!
    月薪百万诚邀PUBG实力作者和平精英作者骗子绕! 月薪百万诚邀PUBG实力作者和平精英作者骗子绕! 月薪百万诚邀PUBG实力作者和平精英作者骗子绕! 传奇私服−-外挂/反挂--暴力分成!
    传奇私服−-外挂/反挂--暴力分成!传奇私服−-外挂/反挂--暴力分成!?#32423;?#21345;盟 全网最低 ?#29486;?#20849;赢15级和平精英小号----单价只需0.8!0.8!0.8!价格低质量硬!!
    124卡盟正式起航,至尊版为你打开更多资源,卡盟点击?#20013;?#21457;卡网 2%费率 D1结算 辅助专业发卡?#25945;?/b>██【我要租此广告位?#21345;█ 
    查看: 5775|回复: 49
    打印 上一主题 下一主题

    [转载] 代码注入之远程线程篇

    [复制链接]
    6高级会员
    605/1100

    605

    积分

    171

    主题

    14

    听众
    已帮网友解决0 个问题
    贡献
    404
    海币
    1542
    交易币
    0
    跳转到指定楼层
    楼主
    发表于 2014-6-3 15:52:58 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
    如果您下载的软件是收费的"请千万不要付款",那绝对是骗子,请立即联系本站举报,若您执意要付款被骗后本站概不负责。
    引子

    前些日子由于项目要求,在网上到处?#26131;?#26009;,于无意中发现了 CodeProject ?#31995;?#19968;篇很?#31995;?#25991;章,文章标题为:
    Three Ways to Inject Your Code into Another Process
    这篇文章呢,出来很?#27599;?#36824;是 03 年的文章了,?#19978;?#25105;弄底层弄得时间不?#38376;叮?#19981;然应该早就看过这篇大作了,
    由于是大作,而?#39029;?#26469;的又久了,自然在网上也就到处流传咯,
    所以也有?#31169;?#36825;篇文章翻译成了中文版?#27169;?/font>下面给出这篇大作的两个链接:

    中文版:http://www.vckbase.com/document/viewdoc/?id=1886
    英文版:http://www.codeproject.com/KB/threads/winspy.aspx
    然后呢,这边由于老大给弄了蛮多好书过来了,其中一本就是所谓的骇客之类的东西,
    虽然是繁体?#27169;?#20294;是知识点都很不错哦,所以也拿过来看了看,就发现其中对这个远程线程的注入有很多的介绍,
    而且貌似前些年的很多病毒或者木马就是通过这屁东西来隐藏?#27169;?/font>
    看着看着就来劲了,而后呢,自己就根据书中的思路,
    然后再结?#29486;?#24049;的理解,将理解整理出了代码,然后?#32479;?#20102;这篇文章咯 !
    然后注意一点的是,在 CodeProject ?#31995;?#37027;篇文章中介绍了三种注入代码技术,
    第一种就是众所周知的 Hook 了;
    第二?#36136;?#30452;接将所要执行的代码全部?#22870;?#21040;宿主进程中,即代码远程注入技术;
    第三种则是 DLL 的远程注入技术了,其通过在宿主进程加载自己写的另外的一个 DLL 来实现注入;
    然后在我的这篇博文中,我也只是总结前人的思想,然后再加入?#26131;?#24049;的立即,
    同时由于 Hook 太常见了,常见得不行了,所以我并?#25442;?#20171;绍 Hook 了,而只介绍后面的两?#22336;?#24335;。


    代码远程注入技术

    Demo 的效果:
    创建的项目为 RemoteThreadCode,即远程注入代码,其实?#20540;?#21151;能是当运行 RemoteThreadCode.exe 时,
    会在 Explorer.exe 进程中创建一个线程,而这个创建的线程功能实现很简单,
    就是弹出一个消息框即 OK !

    Demo 的效果展示:
    当双击执行 RemoteThreadCode.exe 时,则会注入一个线程到 Explorer.exe 中


    当点击确定后,注入到 Explorer.exe 中的线程执行完毕,从而 WaitForSingleObject 等待成功 !


    基本思路以及所对应的代码:
    1. 提升进程权限,如果权限不够的话,很容易造成 OpenProcess 失败;

       1: //=====================================================================================//   2: //Name: bool AdjustProcessTokenPrivilege()                                             //   3: //                                                                                     //   4: //Descripion: 提升当前进程权限                                                                 //   5: //=====================================================================================//   6: bool AdjustProcessTokenPrivilege()   7: {   8:     LUID luidTmp;   9:     HANDLE hToken;  10:     TOKEN_PRIVILEGES tkp;  11:    12:     if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))  13:     {  14:         OutputDebugString("AdjustProcessTokenPrivilege OpenProcessToken Failed ! \n");  15:    16:         return false;  17:     }  18:    19:     if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidTmp))  20:     {  21:         OutputDebugString("AdjustProcessTokenPrivilege LookupPrivilegeValue Failed ! \n");  22:    23:         CloseHandle(hToken);  24:    25:         return FALSE;  26:     }  27:    28:     tkp.PrivilegeCount = 1;  29:     tkp.Privileges[0].Luid = luidTmp;  30:     tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  31:    32:     if(!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))  33:     {  34:         OutputDebugString("AdjustProcessTokenPrivilege AdjustTokenPrivileges Failed ! \n");  35:    36:         CloseHandle(hToken);  37:    38:         return FALSE;  39:     }  40:     return true;  41: }


    2. 确定你的宿主进程,即你所要注入代码的进程,这个其实很好办,你要是不想你的木马或者病毒被别个一下子就结束了的话,
    最好是选择系统要想运行,则必须开启的那种进程,比如资源管理器进程 Explorer.exe,
    Windows 子系统进程 csrss.exe 等等,但是这里注意的是,我注入 System 进程的时候造成了失败哦,
    所以最?#27809;?#26159;别拿 System 做实验,而且如果你注入失败了的话,是会造成宿主进程?#35272;5模?/strong>
    等下一不小心把 System 进程给弄?#35272;?#20102;就不好了;
       1: //=====================================================================================//   2: //Name: bool ProcessIsExplorer(DWORD dwProcessId)                                      //   3: //                                                                                     //   4: //Descripion: 判定一个进程是否为 Explorer 进程                                                 //   5: //=====================================================================================//   6: bool ProcessIsExplorer(DWORD dwProcessId)   7: {   8:     HANDLE hProcess;   9:    10:     hProcess = NULL;  11:    12:     hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);  13:     if(NULL == hProcess)  14:     {  15:         OutputErrorMessage("ProcessIsExplorer - OpenProcess Failed , Error Code Is %d , Error Message Is %s !");  16:    17:         return FALSE;  18:     }  19:    20:     DWORD dwNameLen;  21:     TCHAR pathArray[MAX_PATH];  22:     ZeroMemory(pathArray, MAX_PATH);  23:    24:     dwNameLen = 0;  25:     dwNameLen = GetModuleFileNameEx(hProcess, NULL, pathArray, MAX_PATH);  26:     if(dwNameLen == 0)  27:     {  29:         CloseHandle(hProcess);  30:    31:         return FALSE;  32:     }  33:    34:     TCHAR exeNameArray[MAX_PATH];  35:     ZeroMemory(exeNameArray, MAX_PATH);  36:     _tsplitpath(pathArray, NULL, NULL, exeNameArray, NULL);  37:    38:     string str1 = exeNameArray;  39:     if((str1.compare("Explorer") == 0) || (str1.compare("explorer") == 0))  40:     {  41:         CloseHandle(hProcess);  42:    43:         return TRUE;  44:     }  45:    46:     return FALSE;  47: }


    3. 打开宿主进程了(我这里打开的是 Explorer.exe 进程),思路是首先变量当前系统下运行的所有的进程,
    然后遍历获取到得所有的进程的 PID,再调用 ProcessIsExplorer 函数来判断这个进程是否为 Explorer.exe 进程,
    如果是则记录下这个进程的 PID 就可以了,这样就获得了 Explorer.exe 进程的 PID 了,
    再通过 OpenProcess 来打开这个 Explorer.exe 进程就 OK 了;
       1: //提升当前进程的权限   2: AdjustProcessTokenPrivilege();   3:     4: //第一个?#38382;?#20026;用来保存所有的进程 ID   5: //第二个?#38382;?#21017;是第一个?#38382;?#30340;字节数   6: //第三个?#38382;?#21017;?#20999;?#20837; dwProcess 数组的字节数   7: EnumProcesses(dwProcess, sizeof(dwProcess), &dwNeeded);   8:     9: //找到 explorer.exe 进程的 ID  10: dwExplorerId = 0;  11: for(int i = 0; i < dwNeeded / sizeof(DWORD); i++)  12: {  13:     if(0 != dwProcess)  14:     {  15:         if(ProcessIsExplorer(dwProcess))  16:         {  17:             dwExplorerId = dwProcess;  18:             break;  19:         }  20:     }  21: }  22:    23: hProcess = NULL;  24: hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwExplorerId);  25: if(NULL == hProcess)  26: {  27:     OutputErrorMessage("main - OpenProcess Failed , Error Code Is %d , Error Message Is %s !");  28: }


    4. 在宿主进程中分配?#20040;?#20648;空间,这个存储空间是用来存放我们将要创建的远程线程的线程处理例程的,
    这里需要注意的是:我们分配的内存必须标记必须带有 EXECUTE,因为分配的这块内存是用来存放线程处理例程的,
    而线程处理例程必须得执行,所?#21592;?#39035;?#20040;?#26377; EXECUTE 标记,而至于 WRITE 标记的话,很明显?#20999;?#35201;的,
    因为我们在后面的代码中?#36129;?#39035;调用 WriteProcessMemory 来将线程处理例程写入到这块内存中,自然其必须可写;
       1: //在 hProcess 所代表的进程内部分配虚拟内存来容纳我们将要创建的远程线程   2: PVOID pRemoteThread = VirtualAllocEx(hProcess, NULL, THREAD_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);   3: if(NULL == pRemoteThread)   4: {   5:     OutputErrorMessage("main - VirtualAllocEx Failed , Error Code Is %d , Error Message Is %s !");   6:     7:     //关闭进程句柄   8:     CloseHandle(hProcess);   9: }


    5. 将远程线程处理例程写入到 4 中在宿主进程中所分配的内存中,这个可以直接调用 WriteProcessMemory 来实现;
       1: //往我们在 hProcess 进程中分配的虚拟内存里面写入数据,这里主要是将整个线程都写进去   2: if(WriteProcessMemory(hProcess, pRemoteThread, &RemoteThreadProc, THREAD_SIZE, 0) == FALSE)   3: {   4:     OutputErrorMessage("main - WriteProcessMemory Failed , Error Code Is %d , Error Message Is %s !");   5:     6:     //释放 VirtualAllocEx 分配的内存   7:     VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);   8:     CloseHandle(hProcess);   9: }


    6. 在宿主进程中分配?#20040;?#20648;空间,这个存储空间是用来存放我们将要传递给远程线程线程处理例程的?#38382;?
    从下面的结构体中可以看出,其由三个?#38382;?#32452;成,第一个?#38382;?#20195;表要在对话框中显示的内容,
    第二个?#38382;?#20195;表要在对话框中显示的标题,第三个?#38382;?#21017;是 MessageBox 这个 API 的地址,
    因为在 Explorer.exe 中 MessageBox 的地址会发生重定向,所以需要将其地址通过?#38382;?#20256;递给线程处理例程;
       1: typedef struct _REMOTE_PARAMETER   2: {   3:     CHAR m_msgContent[MAX_PATH];   4:     CHAR m_msgTitle[MAX_PATH];   5:     DWORD m_dwMessageBoxAddr;   6:     7: }RemotePara, * PRemotePara;


       1: //=====================================================================================//   2: //Name: void GetMessageBoxParameter(PRemotePara pRemotePara)                           //   3: //                                                                                     //   4: //Descripion: 获得 MessageBox 这个 API 的地址以及填充的?#38382;?nbsp;                                    //   5: //=====================================================================================//   6: void GetMessageBoxParameter(PRemotePara pRemotePara)   7: {   8:     HMODULE hUser32 = LoadLibrary("User32.dll");   9:       10:     pRemotePara->m_dwMessageBoxAddr = (DWORD)GetProcAddress(hUser32, "MessageBoxA");  11:     strcat(pRemotePara->m_msgContent, "Hello, Zachary.XiaoZhen !\0");  12:     strcat(pRemotePara->m_msgTitle, "Hello\0");  13:       14:     //注意要释放掉 User32  15:     FreeLibrary(hUser32);  16: }



       1: RemotePara remotePara;   2: ZeroMemory(&remotePara, sizeof(RemotePara));   3: GetMessageBoxParameter(&remotePara);   4:     5: //在 hProcess 所代表的进程中分配虚拟内存来容纳线程的?#38382;?#37096;分   6: PRemotePara pRemotePara = (PRemotePara)VirtualAllocEx(hProcess, NULL, sizeof(RemotePara), MEM_COMMIT, PAGE_READWRITE);   7: if(NULL == pRemotePara)   8: {   9:     OutputErrorMessage("main - VirtualAllocEx Failed , Error Code Is %d , Error Message Is %s !");  10:    11:     //释放 VirtualAllocEx 分配的内存  12:     VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);  13:     CloseHandle(hProcess);  14: }


    7. 将?#38382;?#20889;入到 6 中在宿主进程中所分配的内存中,同样是调用 WriteProcessMemory 来完成;
       1: //往在 hProcess 进程中分配的虚拟内存中写入?#38382;?#25968;据   2: if(WriteProcessMemory(hProcess, pRemotePara, &remotePara, sizeof(RemotePara), 0) == FALSE)   3: {   4:     OutputErrorMessage("main - WriteProcessMemory Failed , Error Code Is %d , Error Message Is %s !");   5:     //释放 VirtualAllocEx 分配的内存   6:     VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);   7:     VirtualFreeEx(hProcess, pRemotePara, 0, MEM_RELEASE);   8:     9:     CloseHandle(hProcess);  10: }


    8. 调用 CreateRemoteThread 在 Explorer.exe(宿主进程)中创建远程线程;
    注意,当远程线程没有执行完时,不能够通过 VirtualFreeEx 来将远程进程中的内存释放掉,
    你想啊,我他妈的线程都还在 Explorer.exe 里面执行,你他妈?#33041;?#22806;面把我占的内存给释放掉了,?#19968;?#25191;行个屁啊 !
    所以这里调用了 WaitForSingleObject 来等待这个远程线程执行完毕,
    其执行完毕后再释放在 Explorer.exe 中所分配的存储空间 !
       1: HANDLE hThread;   2: DWORD dwThreadId;   3:     4: hThread = NULL;   5: dwThreadId = 0;   6:     7: //将已经写入到 hProcess 进程中的线程以及线程的?#38382;?#20316;为 CreateRemoteThread 的?#38382;?#20174;而创建远程线程   8: hThread = CreateRemoteThread(hProcess, NULL, 0, (DWORD (WINAPI *)(LPVOID))pRemoteThread, pRemotePara, 0, &dwThreadId);   9: if(NULL == hThread)  10: {  11:     OutputErrorMessage("main - CreateRemoteThread Failed , Error Code Is %d , Error Message Is %s !");  12: }  13: else  14: {  15:     OutputSuccessMessage("Code Inject Success !");  16: }  17:    18: //等待远程线程结束  19: WaitForSingleObject(hThread, INFINITE);  20: CloseHandle(hThread);  21:    22: //必须等到远程线程结束后才能释放宿主进程中所分配的内存,否则宿主进程会直接?#35272;?/font>  23: //释放 VirtualAllocEx 分配的内存  24: VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);  25: VirtualFreeEx(hProcess, pRemotePara, 0, MEM_RELEASE);  26:    27: CloseHandle(hProcess);


    9. 编写好远程线程的线程处理例程即可;
       1: //=====================================================================================//   2: //Name: bool RemoteThreadProc(LPVOID lpParameter)                                      //   3: //                                                                                     //   4: //Descripion: 远程线程处理例程                                                                 //   5: //=====================================================================================//   6: DWORD WINAPI RemoteThreadProc(PRemotePara pRemotePara)   7: {   8:     //这个 MessageBox 的地址必须由外部?#38382;?#20256;入,因为在其他进程中需要重定向   9:     typedef int (WINAPI *MESSAGEBOXA)(HWND, LPCSTR, LPCSTR, UINT);  10:    11:     MESSAGEBOXA MessageBoxA;  12:     MessageBoxA = (MESSAGEBOXA)pRemotePara->m_dwMessageBoxAddr;  13:    14:     //调用 MessageBoxA 来打印消息  15:     MessageBoxA(NULL, pRemotePara->m_msgContent, pRemotePara->m_msgTitle, MB_OK);  16:    17:     return 0;  18: }




    DLL 远程注入技术

    Demo 的效果:
    创建的项目为 RemoteThreadDll,即远程注入 DLL,其实?#20540;?#21151;能是当运行 RemoteThreadDll.exe 时,
    会在 Explorer.exe 进程中创建一个线程,而这个创建的线程功能实现则相对于上面的远程注入代码?#27492;?#22797;杂一点,
    在线程的处理例程中,首先是由线程?#38382;?#20256;递过来的 LoadLibrary 的地址
    和 GetProcAddress 的地址来找到 LoadLibrary 和 GetProcAddress API,
    然后再通过 LoadLibrary(“MyDllName”) 来加载到?#26131;?#24049;的 DLL,
    然后再通过 GetProcAddress 在这个 DLL 中找到我的 DLL 所公开的函数,
    再就是调用这个公开的函数了,我新建的 DLL 项目为 – ZacharyDll.dll,
    该 DLL 中导出了两个函数,一个函数用来弹出一个对话框,一个函数则是用来打印出调试信息;

    Demo 的效果展示:
    当双击执行 RemoteThreadCode.exe 时,则会注入一个线程到 Explorer.exe 中,
    而后注入的这个线程就会调用?#26131;?#24049;的 ZacharyDll.dll,
    再调用 ZacharyDll.dll 中导出的两个函数了,一个输出调试信息,一个弹出对话框:

    当点击确定后,注入到 Explorer.exe 中的线程执行完毕,从而 WaitForSingleObject 等待成功 !


    基本思路以及所对应的代码:
    1. 提升进程权限,如果权限不够的话,很容易造成 OpenProcess 失败;
    这一部?#20540;?#20195;码同上面的远程注入代码是一样的;

    2. 确定你的宿主进程,即你所要注入代码的进程,这个其实很好办,你要是不想你的木马或者病毒被别个一下子就结束了的话,
    最好是选择系统要想运行,则必须开启的那种进程,比如资源管理器进程 Explorer.exe,
    Windows 子系统进程 csrss.exe 等等,但是这里注意的是,我注入 System 进程的时候造成了失败哦,
    所以最?#27809;?#26159;别拿 System 做实验,而且如果你注入失败了的话,是会造成宿主进程?#35272;5模?/strong>
    等下一不小心把 System 进程给弄?#35272;?#20102;就不好了;
    这一部?#20540;?#20195;码同上面的远程注入代码是一样的;

    3. 打开宿主进程了(我这里打开的是 Explorer.exe 进程),思路是首先变量当前系统下运行的所有的进程,
    然后遍历获取到得所有的进程的 PID,再调用 ProcessIsExplorer 函数来判断这个进程是否为 Explorer.exe 进程,
    如果是则记录下这个进程的 PID 就可以了,这样就获得了 Explorer.exe 进程的 PID 了,
    再通过 OpenProcess 来打开这个 Explorer.exe 进程就 OK 了;
    这一部?#20540;?#20195;码同上面的远程注入代码是一样的;

    4. 在宿主进程中分配?#20040;?#20648;空间,这个存储空间是用来存放我们将要创建的远程线程的线程处理例程的,
    这里需要注意的是:我们分配的内存必须标记必须带有 EXECUTE,因为分配的这块内存是用来存放线程处理例程的,
    而线程处理例程必须得执行,所?#21592;?#39035;?#20040;?#26377; EXECUTE 标记,而至于 WRITE 标记的话,很明显?#20999;?#35201;的,
    因为我们在后面的代码中?#36129;?#39035;调用 WriteProcessMemory 来将线程处理例程写入到这块内存中,自然其必须可写;
    这一部?#20540;?#20195;码同上面的远程注入代码是一样的;

    5. 将远程线程处理例程写入到 4 中在宿主进程中所分配的内存中,这个可以直接调用 WriteProcessMemory 来实现;
    这一部?#20540;?#20195;码同上面的远程注入代码是一样的;

    6. 在宿主进程中分配?#20040;?#20648;空间,这个存储空间是用来存放我们将要传递给远程线程线程处理例程的?#38382;?
    从下面的结构体中可以看出,其由六个?#38382;?#32452;成,
    第一个?#38382;?#20195;表 ZacharyDll.dll 中导出的 PrintMessageBox 的名称,
    第二个?#38382;?#20195;表 ZacharyDll.dll 中导出的 PrintDbgStr 的名称题,
    第三个?#38382;?#21017;是 ZacharyDll.dll 所在的路径,
    第四个?#38382;?#21017;是代表 LoadLibrary 的地址,
    第五个?#38382;?#20195;表 FreeLibrary 的地址,
    第六个?#38382;?#20195;表 GetProcAddress 的地址;
       1: #define DLLNAME "\\ZacharyDll.dll\0"   2:     3: typedef struct _REMOTE_PARAMETER   4: {   5:     CHAR m_printMsgBox[MAX_PATH];   6:     CHAR m_printDbgStr[MAX_PATH];   7:     CHAR m_strDllPath[MAX_PATH];   8:     DWORD m_dwLoadLibraryAddr;   9:     DWORD m_dwFreeLibraryAddr;  10:     DWORD m_dwGetProcAddrAddr;  11:    12: }RemotePara, * PRemotePara;



       1: HMODULE hKernel32 = GetModuleHandle("Kernel32");   2: if(NULL == hKernel32)   3: {   4:     OutputErrorMessage("main - GetModuleHandle Failed , Error Code Is %d , Error Message Is %s !");   5:     6:     //释放 VirtualAllocEx 分配的内存   7:     VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);   8:     CloseHandle(hProcess);   9: }  10: else  11: {  12:     RemotePara remotePara;  13:     ZeroMemory(&remotePara, sizeof(RemotePara));  14:    15:     //将 LoadLibraryA、FreeLibrary 和 GetProcAddress 三个 Kernel32 API 的地址保存到 remotePara 中  16:     remotePara.m_dwLoadLibraryAddr = (DWORD)GetProcAddress(hKernel32, "LoadLibraryA");  17:     remotePara.m_dwFreeLibraryAddr = (DWORD)GetProcAddress(hKernel32, "FreeLibrary");  18:     remotePara.m_dwGetProcAddrAddr = (DWORD)GetProcAddress(hKernel32, "GetProcAddress");  19:    20:     string strMsgBox = "PrintMessageBox";  21:     string strBbgStr = "PrintDebugString";  22:    23:     CHAR tmpArray[MAX_PATH];  24:     CHAR * pTmpMsgBoxArray = "PrintMessageBox";  25:     CHAR * pTmpDbgStrArray = "PrintDebugString";  26:       27:     //将 ZacharyDll.dll 中导出的 API 的名称保存到 remotePara 中  28:     strcpy(remotePara.m_printMsgBox, pTmpMsgBoxArray);  29:     strcpy(remotePara.m_printDbgStr, pTmpDbgStrArray);  30:    31:     ZeroMemory(tmpArray, MAX_PATH);  32:    33:     //获取到当前路径  34:     GetCurrentDirectory(MAX_PATH, tmpArray);  35:       36:     //路?#37117;?#19978; DLL 名称(从而可以将 DLL 和 Loader EXE 放在同一个目录下运行了)  37:     //免去了将 DLL 复制到系统目录下的麻烦  38:     string strDllPath = tmpArray;  39:     strDllPath += DLLNAME;  40:    41:     //将 DLL 的路径完整的复制到 remotePara 中  42:     strcpy(remotePara.m_strDllPath, strDllPath.c_str());  43:     //free(tmpArray);  44:    45:     //在宿主进程中分配虚拟内存来容纳远程线程所需要的?#38382;?/font>  46:     PVOID pRemotePara = VirtualAllocEx(hProcess, NULL, sizeof(RemotePara), MEM_COMMIT, PAGE_READWRITE);  47:     if(NULL == pRemotePara)  48:     {  49:         OutputErrorMessage("main - VirtualAllocEx Failed , Error Code Is %d , Error Message Is %s !");  50:    51:         //释放 VirtualAllocEx 分配的内存  52:         VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);  53:         CloseHandle(hProcess);  54:     }


    7. 将?#38382;?#20889;入到 6 中在宿主进程中所分配的内存中,同样是调用 WriteProcessMemory 来完成;
       1: //将远程线程所携带的?#38382;?#20889;入到宿主进程中所分配的虚拟内存   2: if(NULL == WriteProcessMemory(hProcess, pRemotePara, &remotePara, sizeof(RemotePara), 0))   3: {   4:     OutputErrorMessage("main - WriteProcessMemory Failed , Error Code Is %d , Error Message Is %s !");   5:     6:     //释放 VirtualAllocEx 分配的内存   7:     VirtualFreeEx(hProcess, pRemoteThread, 0, MEM_RELEASE);   8:     VirtualFreeEx(hProcess, pRemotePara, 0, MEM_RELEASE);   9:     CloseHandle(hProcess);  10: }


    8. 调用 CreateRemoteThread 在 Explorer.exe(宿主进程)中创建远程线程;
    注意,当远程线程没有执行完时,不能够通过 VirtualFreeEx 来将远程进程中的内存释放掉,
    你想啊,我他妈的线程都还在 Explorer.exe 里面执行,你他妈?#33041;?#22806;面把我占的内存给释放掉了,?#19968;?#25191;行个屁啊 !
    所以这里调用了 WaitForSingleObject 来等待这个远程线程执行完毕,
    其执行完毕后再释放在 Explorer.exe 中所分配的存储空间 !
    这一部?#20540;?#20195;码同上面的远程注入代码是类?#39057;?

    9. 编写好远程线程的线程处理例程即可;
       1: //=====================================================================================//   2: //Name: bool RemoteThreadProc(LPVOID lpParameter)                                      //   3: //                                                                                     //   4: //Descripion: 远程线程处理例程                                                                 //   5: //=====================================================================================//   6: DWORD WINAPI RemoteThreadProc(PRemotePara pRemotePara)   7: {   8:     //对于?#30828;问?pRemotePara 中传过来的 API 都需要重新声明   9:     typedef HMODULE (WINAPI *LOADLIBRARY_ZACHARY)(LPCSTR);  10:     typedef BOOL (WINAPI *FREELIBRARY_ZACHARY)(HMODULE);  11:     typedef FARPROC (WINAPI *GETPROCADDRESS_ZACHARY)(HMODULE hModule, LPCSTR lpProcName);  12:    13:     //这两个 API 是由 ZacharyDLL.dll 导出?#27169;?#20063;需要重新声明  14:     typedef void (* PRINTMESSAGEBOX_ZACHARY)();  15:     typedef void (* PRINTDEBUGSTRING)();  16:    17:     LOADLIBRARY_ZACHARY LoadLibrary_Zachary;  18:     FREELIBRARY_ZACHARY FreeLibrary_Zachary;  19:     GETPROCADDRESS_ZACHARY GetProcAddress_Zachary;  20:     PRINTMESSAGEBOX_ZACHARY PrintMessageBox_Zachary;  21:     PRINTDEBUGSTRING PrintDebugString_Zachary;  22:    23:     //在?#38382;?pRemotePara 中保存了 LoadLibray,FreeLibrary 和 GetProcAddress 这三个 API 的地址  24:     LoadLibrary_Zachary = (LOADLIBRARY_ZACHARY)pRemotePara->m_dwLoadLibraryAddr;  25:     FreeLibrary_Zachary = (FREELIBRARY_ZACHARY)pRemotePara->m_dwFreeLibraryAddr;  26:     GetProcAddress_Zachary = (GETPROCADDRESS_ZACHARY)pRemotePara->m_dwGetProcAddrAddr;  27:    28:     //获得 DLL 所在的地址  29:     PCHAR pDllPath = pRemotePara->m_strDllPath;  30:    31:     //加载我们自己的 DLL - ZacharyDLL.dll  32:     HMODULE hMyDll = LoadLibrary_Zachary(pDllPath);  33:    34:     if(NULL != hMyDll)  35:     {  36:         //从 ZacharyDll.dll 中通过 GetProcAddress 获取 DLL 导出的 API 的地址  37:         PrintDebugString_Zachary = (PRINTDEBUGSTRING)GetProcAddress_Zachary(hMyDll, pRemotePara->m_printDbgStr);  38:         PrintMessageBox_Zachary = (PRINTMESSAGEBOX_ZACHARY)GetProcAddress_Zachary(hMyDll, pRemotePara->m_printMsgBox);  39:    40:         //执行 DLL 中所导出的 API  41:         PrintDebugString_Zachary();  42:         PrintMessageBox_Zachary();  43:         //释放所加载的 DLL  44:         FreeLibrary_Zachary(hMyDll);  45:     }  46:     return 0;  47: }


    10. 编写好要注入的 DLL – ZacharyDll.dll;
       1: BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)   2: {   3:     switch (dwReason)   4:     {   5:     case DLL_PROCESS_ATTACH:   6:         break;   7:     case DLL_PROCESS_DETACH:   8:         break;   9:     case DLL_THREAD_ATTACH:  10:         break;  11:     case DLL_THREAD_DETACH:  12:         break;  13:     }  14:    15:     return TRUE;  16: }  17:    18: //弹出一个对话框  19: void PrintMessageBox()  20: {  21:     MessageBox(NULL, MESSAGE_CONTENT, MESSAGE_TITLE, MB_OK);  22: }  23:    24: //打印语句  25: void PrintDebugString()  26: {  27:     //直接打印出 5 条同样的消息  28:     for(int i=0; i<5; i++)  29:     {  30:         OutputDebugString("In ZacharyDll - PrintDebugString !");  31:     }  32: }




    两种注入技术的优点和缺点总结

    使用代码远程注入技术的话,其相对于使用 DLL 远程注入技术?#27492;擔?/font>
    有一个优点,就是其?#25442;?#26080;缘无?#23454;娜盟?#20027;进程加载其他的 DLL,
    为什?#27492;?#36825;是一个优点 ? 那是因为很多的监控软件或者杀软都在实时监控着每个进程,
    ?#24065;?#20010;进程中加载了其他的 DLL 时(加载 DLL 的动作相对?#27492;?#26159;比较大的)很容易被发觉,
    而?#19994;币?#20010; DLL 被加载到进程中以后,可以利用很多的工具,
    比如 Process Explorer 之类的将该进程所加载的 DLL 枚举出来,这样你所注入的 DLL 也就暴露无遗了 !
    而如果你使用的是代码注入,那相对?#27492;?#20250;安静很多(毕?#25925;切?#21160;作),而且也?#25442;崛盟?#20027;进程加载其他的 DLL,
    所以相对?#27492;擔?#20854;成功?#30446;?#33021;性会更高,但是使用代码远程注入有一个致命的弱点,
    那就是你所注入的代码中所使用的 API 都必须要重定向,
    而且如果是?#36828;?#20041;的函数的话,则必须将这个函数也全部?#22870;?#21040;宿主进程中,
    注入的代码中所使用的全局变量以及所使用的?#22336;?#20018;都必须重新?#22870;?#21040;宿主进程中,
    听起来貌似没什么,但是事实上,这屁东西会搞得很复杂,就比如你在注入的代码中所使用的一个?#22336;?#20018;,
    你也必须先在宿主进程中分配虚拟内存,然后将这个?#22336;?#20018;写入到这个新分配的虚拟内存中,
    如果你?#22336;?#20018;多的话,这样的操作会烦死人去,而且这还仅仅是?#22336;?#20018;,对于你所需要使用的一些 Win32 API,
    你也都得?#28982;?#21462;好这些 API 的地址,然后又重复上面的操作,分配虚拟内存,写入地址,最后才能够在远程线程中调用,
    所以如果你所注入的代码需要完成很复杂的功能的话,还是使用 DLL 的远程注入技术比较好,使用远程注入代码会搞死人的 !

    使用 DLL 的远程注入技术的病毒或者木马通常都位于一个 DLL 中,
    在系统启动时,通过另外的一个 EXE 程序来在另外的一个进程(宿主进程,比如使用 Explorer.exe)中创建一个远程线程,
    然后再在这个远程线程的线程处理函数中将这个带有病毒或者木马主体的 DLL 加载到宿主进程中,
    这样的话,这个带有病毒或者木马主体的 DLL 就会被宿主进程加载,从而得以在宿主进程中执行,
    这样,即使我们自己的 EXE(这个进程通常被称之为 Loader)进程被关闭了也?#25442;?#24433;响到病毒或者木马主体代码的执行,
    因为这些主体代码位于 Explorer.exe 进程中执行,而 Explorer.exe 基本上?#25442;?#34987;关闭的。
    并且使用这?#22336;?#27861;,你的恶意代码也很难被什么任务管理器之类的发现,因为只要宿主进程没有终止运行,
    那么这个 DLL 也就?#25442;?#22312;内存中卸载(当然被卸载还是可能?#27169;?#26432;软就可以利用这点来将这个 DLL 卸载掉)。


    Demo 展望:

    上面的这种注入技术用来实现木马或者其他的恶意程序其实是比?#25103;奖愕模?/font>
    首先由一个 Loader.exe (这个 Loader 可以通过其他的方式来设置为随机器?#36828;?#21551;动,
    这可以通过修改 system.ini 或者注册表或者服务之类的来实现)
    来通过 CreateRemoteThread 来在 Explorer.exe 进程中创建一个远程线程,
    而后由这个远程线程神不知鬼不觉的调用一个另外的 DLL,
    然后在另外的那个 DLL 中,我们就可以做很多的事情了啊,比如最简单?#27169;?#35774;个全局键盘钩子,用来捕获键盘的记录,
    再进行一定的解析就有可能获取用户有效的密码之类的信息,同时,既然 DLL 都注入到 Explorer.exe 中了,
    那么还可以做很多邪恶的事情,比如在其中?#37027;牡纳?#25551;用户?#25490;躺系?#25991;件,只要是 .jpg, .png 之类的就全部给记录下来,
    或者再在 DLL 中创建个什么 SOCKET 之类?#27169;?#24182;且将这些什么 .png 啊,.jpg 啊之类的?#35745;?#25968;据?#37027;?#30340;传出去,
    然后说不准第二个艳照门?#32479;?#26469;了 ~
    当然这些都是后话了,不过有了上面的这几个技术,要实现这种简单的木马功能还是很容易了哦 !
    当然,这里再提一下的是,这样做不道德 ! 针对女朋友的属于合法行为 ! 哈哈哈 !
    然后还有一个要提一下的是,现在这种注入方式,杀软或者安全卫士是能够捕捉到了,也就是过不了杀软或安全卫士这一关了哦 !
    毕竟 03 年就有大牛弄这种东西了,这么些年了,人?#26131;?#21453;病毒做安全的也不是吃饭的 !
    不过如果将上面的技术和 Rootkit 做个结合,可能效果会很不一样了哦,?#20889;?#30740;究 ~


    联系我时,请说是在 挂海论坛 上看到?#27169;?#35874;谢!

    免费评分

    参与人数 1海币 +1 贡献 +1 收起 理由
    491497669 + 1 + 1 ?#34892;?#20998;享,很给力!~

    查看全部评分




    上一篇:硬件指纹提取(机器码绑机)包括CPU,BIOS,硬盘,MAC C++
    下一篇:进程隐藏与进程保护(SSDT Hook 实现)(一)
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏1 转播转播 分享淘帖 支持支持 反对反对

    16

    积分

    7

    主题

    0

    听众
    已帮网友解决0 个问题
    贡献
    9
    海币
    70
    交易币
    0
    沙发
    发表于 2014-7-10 17:07:06 | 只看该作者
    新手啊,求指教 。。。。呵呵

    65

    积分

    33

    主题

    2

    听众
    已帮网友解决0 个问题
    贡献
    32
    海币
    52
    交易币
    0
    板凳
    发表于 2014-7-25 04:47:45 | 只看该作者
    哦 不错 谢?#35805;?/td>
    6高级会员
    605/1100

    605

    积分

    171

    主题

    14

    听众
    已帮网友解决0 个问题
    贡献
    404
    海币
    1542
    交易币
    0
    地板
     楼主| 发表于 2014-8-8 00:08:51 | 只看该作者
    外挂海论坛,我支持你!

    4

    积分

    2

    主题

    2

    听众
    已帮网友解决0 个问题
    贡献
    2
    海币
    7
    交易币
    0
    5#
    发表于 2014-8-17 14:50:38 | 只看该作者
    很好啊!!!!!!!!!!

    0

    积分

    1

    主题

    0

    听众
    已帮网友解决0 个问题
    贡献
    -1
    海币
    1777
    交易币
    0
    6#
    发表于 2014-8-28 11:16:55 | 只看该作者
    帮你顶....
    4中级会员
    313/600

    313

    积分

    91

    主题

    5

    听众
    已帮网友解决0 个问题
    贡献
    222
    海币
    1414
    交易币
    0
    7#
    发表于 2014-9-3 20:15:14 | 只看该作者
    淡定,淡定,淡定……

    16

    积分

    7

    主题

    0

    听众
    已帮网友解决0 个问题
    贡献
    9
    海币
    70
    交易币
    0
    8#
    发表于 2014-12-20 06:01:26 | 只看该作者
    看起来不错

    36

    积分

    24

    主题

    2

    听众
    已帮网友解决0 个问题
    贡献
    12
    海币
    102
    交易币
    0
    9#
    发表于 2014-12-21 22:08:39 | 只看该作者
    看到这帖子真是高兴!

    106

    积分

    70

    主题

    3

    听众
    已帮网友解决0 个问题
    贡献
    36
    海币
    91
    交易币
    0
    10#
    发表于 2014-12-30 21:57:57 | 只看该作者
    支?#31181;?#25345;再支持
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Archiver|?#21482;?#29256;|小黑屋|挂海论坛

    GMT+8, 2019-7-18 08:53 , Processed in 0.343201 second(s), 37 queries , Gzip On.

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表
    11选五开奖结果
    <input id="imkq6"><samp id="imkq6"></samp></input>
    <bdo id="imkq6"></bdo>
  • <input id="imkq6"><samp id="imkq6"></samp></input>
    <strong id="imkq6"></strong>
  • <bdo id="imkq6"></bdo>
  • <input id="imkq6"><samp id="imkq6"></samp></input>
    <bdo id="imkq6"></bdo>
  • <input id="imkq6"><samp id="imkq6"></samp></input>
    <strong id="imkq6"></strong>
  • <bdo id="imkq6"></bdo>
  • 吉林快三全天精准追号计划 湖北快三基本走势图定牛一 江西体彩多乐彩11选5 今晚广东36选7开奖号码 新疆喜乐彩开奖号码公告 象棋千年老二 福彩3d做计划 今晚生肖结果查询 全年固定一尾中特 河南22选5开奖结果53期 德州扑克规则 六肖中特免费公开 4场进球彩去哪里兑奖 上海快三开奖号码今天 浙江快乐彩开奖一定牛