星绽紫辉(rawdata)的Blog

快乐地学习,快乐地工作!

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  16 Posts :: 0 Stories :: 37 Comments :: 0 Trackbacks

常用链接

留言簿(5)

我参与的团队

搜索

  •  

最新评论

阅读排行榜

评论排行榜

        原创 : 星绽紫辉     转载请注明出处   http://www.cppblog.com/rawdata 

       我写的一个用到的WinXP下的隐藏SysListView32界面窗口子项目的C++类,它可以实现界面级的隐藏。用它可以隐藏任务管理器的进程,隐藏MMC外壳程序(如Windows服务窗口)的子项。隐藏后目标界面无明显刷新,调用方法如下:
       CHideProc hide;

       hide.HideReset();
       hide.HideScan();

       hide.HideReset();
       hide.HideScan();

       hide.HideQuit();

        http://www.cppblog.com/rawdata
       那么让我来看看它是怎么样工作的:首先,声明声明一个CHideProc 类,然后调用HideReset();之后就可以传入一个进程参数,让它调用  HideScan();实现隐藏了。当要隐藏其他子项时(如:对于任务管理器,当前隐藏的是system子项,我想换成word.exe子项),只需重复调用HideReset()再调用HideScan()即可(详见后面的代码清单)。最后调用HideQuit();退出。

        实现目的:    
         1.学习API
         2.让某些重要数据安全的进程不被轻易结束(界面级)
         3.了解一些内核原理

        现在我大致说一下实现的过程及原理

            第一步: 找目标主程序(如taskmgr.exe/mmc.exe)的PID(进程句柄 HANDLE)和窗口句柄(HWND)。通过 ToolHelp32系列函数可以很方便地找出,如果你对这些函数不了解,参见《Windows核心编程》一书。

            第二步:调用AllocateMemoryEx在目标进程分配空间,然后用WriteProcessMemory写入一些数据,至于写入什么数据,先保留。然后调用CreateRemoteThread创建远程线程到目标进程,创建成功的话,我们的程序就可以调用进程隐藏类的函数了。

           那么我们到底要写了一些什么东西到目标进程的地址空间呢?  首先是CreateRemoteThread的参数,因为该线程在目标的地址空间运行,所以不能直接使用本进程的任何变量和函数,否则会造成内存访问错误。既然如此,我们就在目标进程分配空间来存贮我们的变量和函数,然后就在CreateRemoteThread的回调函数中使用这些变量和函数。就像我们把自己的代码插入了目标进程让它和在我们自己的进程里运行一样。呵呵,不要用它来做坏事哦~

            然后看看CreateRemoteThread的回调函数,我们要隐藏SysListView32窗口类的子项,显然只要对它发送WM_DELETEITEMW消息就可以了(当然有一些细节问题还要注意,详见后面的代码)。然而,回调函数只被设计成调用一次,那么我们怎么样才能让它持续隐藏呢?显然,不断的调用CreateRemoteThread是不切实际的。
           
             这里,我们直接拦截目标进程的窗口消息,很简单,只需要调用SetWindowLongA(W)改变它的原来的窗口过程地址,并且要保存原来的窗口过程地址,这样才能保证调用了我们自己的函数之后能调用它本身的窗口过程。

            其中,非常关键的是,有些变量在“窗口过程代码区”(我们写到目标进程代码区)中是无法使用的。虽然我们能将变量写到目标进程,但是我们却无法在NewWindowProc中对它进行定位和使用(函数就不同了,所有的系统函数都是被映射到所有的进程的相同的地址上,而我们自己的函数直接拷贝到目标进程并引用其地址即可)。要解决定位问题,我所采用的方法是直接将变量写到NewWindowProc函数入口地址的开头,当我要在NewWindowProc中引用这些变量的时候,只需要根据当前的EIP计算出NewWindowProc函数入口地址,然后根据需要读取变量,这样就能实现在目标代码区使用我们自己变量和函数的目的。

           计算函数入口地址的汇编代码如下(不同的编译器/系统计算可能不同,但是都可以通过反汇编计算出来):
         


LRESULT __stdcall CHideProc::NewWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)


    DWORD dwTest 
= NULL;
    _asm 
    
{
        call    dummy
    dummy:
        pop     ecx                    
        sub        ecx,
0x00000013    //得到EIP    
        mov     dwTest, ecx        //得到NewWindowProc的入口地址    
    }


    RemoteParam
* pRP = (RemoteParam*)(dwTest-sizeof(RemoteParam));

    
}

       


      好了,整个过程大概就是这样,下面贴出完整代码:
   
        http://www.cppblog.com/rawdata



      后记:代码只能在Release版本运行,因为debug版本会有堆栈cookie检查(_chkesp),这是VC++堆栈保护机制,但这是不必要的,因为我们的代码在另外的进程中运行。(2009-4-6)
   
        头文件:    
       

  1#pragma once
  2
  3
  4/* 忽略指针强制转换的警告 */
  5#pragma warning(disable:4312)     
  6#pragma warning(disable:4311)
  7
  8
  9/* STL 链表 */
 10#include <list>         //STL容器
 11#include <algorithm> //STL算法
 12using namespace std;
 13
 14
 15
 16/* 必须包含的头文件 */
 17#include <windows.h>
 18#include <windowsx.h>
 19#include <TlHelp32.h>
 20#include <commctrl.h>
 21
 22#include <Winternl.h>
 23
 24
 25#define LMAXSIZE        512                //一个字符串的最大长度
 26#define LMAXSTR            64                //最多可以支持多少个字符串
 27#define LMAXBUF            256                //临时缓冲区的最大长度
 28#define TDSIZE            4096            //定义线程体或远程函数体的代码尺寸    
 29#define LCTRLMAX        8
 30
 31typedef struct _RemoteParam {
 32    DWORD dwSendMessage;                            //SendMessage的入口函数地址
 33    DWORD dwSetWindowLong;                            //SetWindowLong函数
 34    DWORD dwNewSubClass;                            //新的SubClass的入口地址
 35    DWORD dwCharLowerBuff;                            //CharLowerBuff函数的入口地址
 36    DWORD dwlstrlen;                                //lstrlen函数的入口地址
 37    DWORD dwMsgBox;                                    //MessageBox函数的入口地址
 38    DWORD dwlstrcmp;                                //lstrcmp函数的入口地址
 39    DWORD dwOldSubClass[LCTRLMAX];                    //原来的SubClass入口地址
 40    HWND  hWndArray[LCTRLMAX];                        //SysListView32控件的窗口句柄数组
 41    UINT  nWndCount;                                //SysListView32控件窗口句柄的数量
 42    int      iCount;                                    //存贮实际要隐藏名字串的数量
 43    UINT  iOffset[LMAXSTR];                            //存贮名字串在szProcessName中的首地址索引
 44    char  szItemName[LMAXBUF];                        //用做远程过程的临时缓冲区
 45    char  szProcessName[LMAXSIZE * LMAXSTR];        //存储要隐藏服务项目的字符串
 46}
 RemoteParam;
 47
 48
 49
 50/* SendMessageA 和 WindowProc */
 51typedef LRESULT    (__stdcall* PFN_SENDMSG)(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
 52/* SetWindowLongW */
 53typedef LONG    (__stdcall* PFN_SETWINDOWLONG)(HWND hWnd,int nIndex,LONG dwNewLong);
 54/* MessageBoxA */
 55typedef int        (__stdcall* PFN_MSGBOX)(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
 56/* lstrcmp */
 57typedef int        (__stdcall* PFN_LSTRCMP)(LPCTSTR lpString1,LPCTSTR lpString2);
 58/* lstrlen */
 59typedef int        (__stdcall* PFN_LSTRLEN)(LPCTSTR lpString);
 60/* CharLowerBuf */
 61typedef DWORD    (__stdcall* PFN_CHARLOWERBUFF)(LPTSTR lpsz,DWORD cchLength);
 62
 63
 64
 65
 66class CHideProc
 67{
 68public:
 69    CHideProc(void);
 70    ~CHideProc(void);
 71
 72    /* 接口函数 */
 73
 74    /* 初始化 */
 75    BOOL HideReset(HWND hWnd,char* pszStrArray[],int iStrCount);
 76    BOOL HideReset(HANDLE hProcess,char* pszStrArray[],int iStrCount);
 77    BOOL HideReset(const char* pszExeName,char* pszStrArray[],int iStrCount);
 78    BOOL HideReset(DWORD dwPID,char* pszStrArray[],int iStrCount);
 79
 80    /* 扫描 */
 81    BOOL HideScan();
 82
 83    /* 结束 */
 84    void HideQuit();
 85    
 86    
 87private:
 88    
 89    /* 找到目标控件窗口,并存入链表 */
 90    void FindChildWindow(HWND hWndTopLever,const char* pszWndText,
 91        const char* pszWndClass);
 92
 93    /* 转化字符串 */
 94    BOOL ConvertFitString();
 95
 96    /* 复位 */
 97    BOOL Reset();
 98
 99    /* 根据程序名得到PID并存入链表 */
100    void GetPIDByNameToList();
101
102    /* DeleteUselessPID的子程序 */
103    void FindAndDelete(DWORD dwPID,const char * pszKeyName);
104
105    /* 删除失效的PID */
106    BOOL DeleteUselessPID();
107
108    /* 检查PID是否已经注入过线程 */
109    BOOL CheckPID(DWORD pid);
110    
111    /* 提升进程权限 */
112    BOOL EnableDebugPriv();
113
114    /* 注入线程 */
115    BOOL InsertRemoteThread(DWORD dwProcessId);
116
117    /* 新的窗口过程 */
118    static LRESULT __stdcall NewWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,
119                            LPARAM lParam);
120
121    /* 远程线程 */
122    static DWORD __stdcall ThreadProc(LPVOID lParam);
123
124    /* 分配空间存贮字符串列表 */
125    BOOL InitStringSet(char* pszStrArray[],int iStrCount);
126
127private:
128     list<DWORD>    m_ListPIDDone;    //存贮所有已经注入的PID
129     list<HWND>        m_ListHWND;        //某个PID对应的所有SysListView32窗口列表
130     list<DWORD>    m_ListPIDAdd;    //待注入线程的PID列表
131     HANDLE            m_hProcess;        //专用于进程句柄
132     HWND            m_hWndCur;        //专用于传入参数为窗口句柄
133     DWORD            m_dwPID;        //专用于PID
134     BYTE*            m_pByte;        //用于存贮转化后的字符串
135     char*            m_pszExeName;    //专用于进程名字
136     char**            m_ppszItemList;    //存贮要隐藏的字符串
137     UINT            m_iCount;        //偏移索引数组元素的个数
138     UINT*            m_pUint;        //偏移索引数组
139}
;
140

















      /*********************************************************************************************************
      *
      * 实现文件:
      *
      *********************************************************************************************************/
           

  1#include "hideproc.h"
  2
  3CHideProc::CHideProc(void)
  4{   
  5    m_dwPID = -1;
  6    m_hProcess = NULL;
  7    m_hWndCur = NULL;
  8    m_iCount = -1;
  9
 10    m_ListHWND.clear();
 11    m_ListPIDAdd.clear();
 12    m_ListPIDDone.clear();
 13
 14    
 15    m_pByte = NULL;
 16    m_ppszItemList = NULL;
 17
 18    
 19    m_pszExeName = NULL;
 20    m_pUint = NULL;
 21
 22    EnableDebugPriv();
 23}

 24
 25CHideProc::~CHideProc(void)
 26{
 27}

 28
 29
 30/* 转换大小写,并建立常量字符串数据字典 */
 31BOOL CHideProc::ConvertFitString()
 32{
 33    m_pByte = new BYTE[LMAXSIZE * LMAXSTR];
 34    char* pStrBuf = (char*)m_pByte;
 35    m_pUint = new UINT[LMAXSTR];
 36
 37    ZeroMemory(pStrBuf,LMAXSIZE * LMAXSTR);
 38    ZeroMemory(m_pUint,LMAXSTR*sizeof(UINT));
 39
 40    for(UINT i=0;i<m_iCount;i++)
 41    {
 42        __try  
 43        {
 44            lstrcat(pStrBuf,m_ppszItemList[i]);
 45            lstrcat(pStrBuf,"#");
 46        }

 47        __except(EXCEPTION_EXECUTE_HANDLER)
 48        {
 49            ::MessageBoxA(NULL,"错误:输入的字符串长度不匹配或转换错误,程序将结束!"
 50                ,"信息提示:",MB_ICONINFORMATION | MB_OK);
 51            return FALSE;    
 52        }

 53        m_pUint[i+1= (UINT)lstrlen(pStrBuf)-1;
 54    }

 55
 56    ::CharLowerBuff(pStrBuf,(DWORD)lstrlen(pStrBuf));
 57
 58    for(i=0;i<m_iCount;i++)
 59        m_pByte[m_pUint[i+1]]    = 0;
 60
 61    for(i=0;i<m_iCount;i++)
 62        m_pUint[i+1= m_pUint[i+1+ 1;
 63
 64    m_pUint[i] = 0;
 65
 66    return 0;
 67}

 68
 69/* 新的窗口过程 */
 70LRESULT __stdcall CHideProc::NewWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
 71
 72
 73    DWORD dwTest = NULL;
 74    _asm 
 75    {
 76        call    dummy
 77    dummy:
 78        pop     ecx                    
 79        sub        ecx,0x00000013    //得到EIP    
 80        mov     dwTest, ecx        //得到NewWindowProc的入口地址    
 81    }

 82
 83    RemoteParam* pRP = (RemoteParam*)(dwTest-sizeof(RemoteParam));
 84    for(UINT i=0;i<(pRP->nWndCount);i++)
 85    {
 86        if(pRP->hWndArray[i] == hWnd)
 87            break;
 88    }

 89
 90    PFN_SENDMSG    pfnOldWindowProc = (PFN_SENDMSG)(DWORD)pRP->dwOldSubClass[i];
 91    PFN_SENDMSG pfnSendMessage = (PFN_SENDMSG)pRP->dwSendMessage;
 92//    PFN_MSGBOX pfnMSGBOX =    (PFN_MSGBOX)pRP->dwMsgBox;
 93    PFN_LSTRCMP pfnlstrcmp = (PFN_LSTRCMP)pRP->dwlstrcmp;
 94    PFN_CHARLOWERBUFF pfnCharLowerBuf = (PFN_CHARLOWERBUFF)pRP->dwCharLowerBuff;
 95    PFN_LSTRLEN pfnlstrlen = (PFN_LSTRLEN)pRP->dwlstrlen;
 96
 97    LV_ITEM Item;
 98    Item.iSubItem = 0;
 99    Item.mask = LVIF_TEXT;
100    Item.pszText = pRP->szItemName;
101    Item.cchTextMax = LMAXBUF;
102    char * pszName = NULL;
103    switch(uMsg)
104    {      
105        case WM_PAINT:
106            {  
107            
108                int nCount = pfnSendMessage(hWnd,LVM_GETITEMCOUNT,0,0);
109                for(int i=0;i<nCount;i++)
110                {
111F:
112                    for(int k=0;k<LMAXBUF;k++)
113                        (pRP->szItemName)[k] = 0;
114
115                    pfnSendMessage(hWnd,LVM_GETITEMTEXT,(WPARAM)i,(LPARAM)&Item);
116                    pfnCharLowerBuf(Item.pszText,pfnlstrlen(Item.pszText));
117
118                    for(int j=0;j<(pRP->iCount);j++)
119                    {
120                        pszName = (char*)((pRP->szProcessName)+(pRP->iOffset[j]));
121                        
122                        if(pfnlstrcmp(pszName,pRP->szItemName) == 0)
123                        {    
124                            pfnSendMessage(hWnd,WM_SETREDRAW,(WPARAM)FALSE,0); 
125                            pfnSendMessage(hWnd,LVM_DELETEITEM,(WPARAM)i,0);
126                            pfnSendMessage(hWnd,WM_SETREDRAW,(WPARAM)TRUE,0);
127                            goto F;
128                        }

129                    }

130                }

131            }
 
132    }

133    return pfnOldWindowProc(hWnd,uMsg,wParam,lParam);
134}

135
136
137/* 远程线程调用 */
138DWORD __stdcall CHideProc::ThreadProc(LPVOID lParam)
139{
140    RemoteParam* pRP = (RemoteParam*)lParam;
141 
142    PFN_SENDMSG pfnSendMessage = (PFN_SENDMSG)pRP->dwSendMessage;
143    HWND hWnd;
144    for(UINT i=0;i<(pRP->nWndCount);i++)
145    {
146        hWnd = (pRP->hWndArray)[i];
147        PFN_SETWINDOWLONG pfnSetWindowLong = (PFN_SETWINDOWLONG)pRP->dwSetWindowLong;
148        pRP->dwOldSubClass[i] = (DWORD)pfnSetWindowLong(hWnd,GWL_WNDPROC,(LONG)(pRP->dwNewSubClass));
149        pfnSendMessage(hWnd,WM_PAINT,0,0);
150    }

151    return 0;
152}

153
154
155/* 提升自己的进程访问权限 */
156BOOL CHideProc::EnableDebugPriv()
157{
158    HANDLE hToken;
159    LUID sedebugnameValue;
160    TOKEN_PRIVILEGES tkp;
161  
162    if (!OpenProcessToken(GetCurrentProcess(), 
163        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
164        return FALSE;
165  
166
167    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue)) {
168        CloseHandle(hToken);
169        return FALSE;
170    }

171
172    tkp.PrivilegeCount = 1;
173    tkp.Privileges[0].Luid = sedebugnameValue;
174    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
175
176    //更改权限
177    if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
178        CloseHandle(hToken);
179        return FALSE;
180    }

181    return TRUE;
182}

183
184
185/* 线程注入的详细实现 */
186BOOL CHideProc::InsertRemoteThread(DWORD dwProcessId)
187{
188    //控件窗口链
189    if(    m_ListHWND.empty())
190        return FALSE;
191
192    HANDLE hTargetProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
193    if (!hTargetProcess) 
194    {
195        MessageBox(NULL, "打开句柄失败,不能对目标进程进行访问!"
196            "信息提示:", MB_ICONINFORMATION | MB_OK);
197        return FALSE;
198    }

199
200    RemoteParam remoteData;      
201    ZeroMemory(&remoteData, sizeof(RemoteParam));
202 
203    HINSTANCE hUser32 = ::LoadLibrary("User32.dll");
204    remoteData.dwSendMessage = (DWORD)GetProcAddress(hUser32, "SendMessageA");
205    remoteData.dwSetWindowLong = (DWORD)GetProcAddress(hUser32, "SetWindowLongW"); 
206    remoteData.dwMsgBox = (DWORD)GetProcAddress(hUser32, "MessageBoxA");
207    remoteData.dwCharLowerBuff = (DWORD)GetProcAddress(hUser32, "CharLowerBuffA");
208    ::FreeLibrary(hUser32);
209
210    HINSTANCE hKernel32 = ::LoadLibraryA("kernel32.dll");
211    remoteData.dwlstrcmp = (DWORD)GetProcAddress(hKernel32, "lstrcmp");
212    remoteData.dwlstrlen = (DWORD)::GetProcAddress(hKernel32,"lstrlenA");
213    
214    //主窗口下的所有SysListView32子窗口
215    remoteData.nWndCount = (UINT)m_ListHWND.size();
216    list<HWND>::iterator pos;
217    int i=0;
218    for(pos = m_ListHWND.begin();pos != m_ListHWND.end(); ++pos,++i)
219        remoteData.hWndArray[i] = *pos;
220    
221    /////////////////////////
222    ZeroMemory(remoteData.szProcessName,sizeof(remoteData.szProcessName));
223    memcpy(remoteData.szProcessName,m_pByte,LMAXSIZE * LMAXSTR);
224
225    /////////////////////////
226    ZeroMemory(remoteData.iOffset,sizeof(remoteData.iOffset));
227    memcpy(remoteData.iOffset,m_pUint,sizeof(int)*m_iCount);
228    remoteData.iCount = m_iCount;
229
230    /////////////////////////
231    ZeroMemory(remoteData.szItemName,sizeof(remoteData.szItemName));
232
233    DWORD dwThreadSize = TDSIZE;
234    void* pRemoteThread = NULL;       
235    void* pNewWindowProc = NULL;  
236    __try
237    {    
238        pNewWindowProc = VirtualAllocEx(hTargetProcess, 0
239            dwThreadSize+sizeof(remoteData), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
240
241        if(pNewWindowProc == NULL)
242        {
243            MessageBox(NULL, "在目标进程分配内存页面失败!"
244            "信息提示:", MB_ICONINFORMATION | MB_OK);
245
246            CloseHandle(hTargetProcess);
247            return FALSE;
248        }

249
250        remoteData.dwNewSubClass = (DWORD)(void*)((char*)pNewWindowProc+sizeof(remoteData));
251
252        ///////////////////
253        WriteProcessMemory(hTargetProcess,pNewWindowProc,
254                &remoteData, sizeof(remoteData), 0);
255        
256        WriteProcessMemory(hTargetProcess,(void*)((char*)pNewWindowProc + sizeof(remoteData)),
257                &NewWindowProc, dwThreadSize, 0);
258
259        pRemoteThread = VirtualAllocEx(hTargetProcess, 0
260            dwThreadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
261        if(pRemoteThread == NULL)
262        {
263            MessageBox(NULL, "在目标进程分配内存页面失败!"
264            "信息提示:", MB_ICONINFORMATION | MB_OK);
265
266            CloseHandle(hTargetProcess);
267            return FALSE;
268        }

269        ///////////////////
270        WriteProcessMemory(hTargetProcess, 
271                pRemoteThread, &ThreadProc, dwThreadSize, 0);
272
273    }

274    __except(EXCEPTION_EXECUTE_HANDLER)
275    {
276        MessageBox(NULL, "出现错误,无法在远程进程中分配或读写页面!。"
277            "信息提示:",  MB_ICONINFORMATION | MB_OK);
278        
279        CloseHandle(hTargetProcess);
280        return FALSE;
281    }

282
283
284    HANDLE hRemoteThread = NULL;
285    __try
286    {
287        //////////
288        hRemoteThread = CreateRemoteThread(hTargetProcess, NULL, 0,
289        (DWORD (__stdcall *)(void *))pRemoteThread, pNewWindowProc, 00);
290    }

291    __except(EXCEPTION_EXECUTE_HANDLER)
292    {
293        MessageBox(NULL, "出现错误,创建远程线程失败,程序将结束!。"
294            "信息提示:",  MB_ICONINFORMATION | MB_OK);
295
296        
297        ::VirtualFreeEx(hTargetProcess,pNewWindowProc,dwThreadSize+sizeof(remoteData),
298            MEM_RELEASE);
299        ::VirtualFreeEx(hTargetProcess,pRemoteThread,dwThreadSize,MEM_RELEASE);
300
301        CloseHandle(hTargetProcess);
302        return FALSE;
303    }

304
305    CloseHandle(hRemoteThread);
306    CloseHandle(hTargetProcess);
307
308    return TRUE;
309}

310
311 /* 用递归的方法实现查找某个窗口的子控件窗口 */
312void CHideProc::FindChildWindow(HWND hWndTopLever,const char* pszWndText,const char* pszWndClass)
313{
314    if(pszWndClass == NULL || !IsWindow(hWndTopLever))return;
315    
316
317    HWND hWndChild = GetWindow(hWndTopLever,GW_CHILD);
318    if(hWndChild == NULL)return;
319
320    char szClass[256];
321    char szText[256];
322
323    while(hWndChild)
324    {
325        ZeroMemory(szClass,sizeof(szClass));
326        ZeroMemory(szText,sizeof(szText));
327        GetClassName(hWndChild,szClass,sizeof(szClass));
328        if(lstrcmp(szClass,pszWndClass) == 0)
329        {
330            GetWindowText(hWndChild,szText,sizeof(szText));
331            if(pszWndText != NULL)
332            {
333                if(lstrcmp(szText,pszWndText) == 0)
334                     m_ListHWND.push_back(hWndChild);
335            }

336            else
337                 m_ListHWND.push_back(hWndChild);;
338        }

339        FindChildWindow(hWndChild,pszWndText,pszWndClass);
340        hWndChild = GetWindow(hWndChild,GW_HWNDNEXT);
341    }

342    return;
343}

344
345
346/* DeleteUselessPID的子程序 */
347void CHideProc::FindAndDelete(DWORD dwPID,const char * pszKeyName)
348{
349    list<DWORD>::iterator pos;
350    pos = find(m_ListPIDDone.begin(),m_ListPIDDone.end(),dwPID);
351    if(pos != m_ListPIDDone.end())
352    
353        if(lstrcmp(pszKeyName,m_pszExeName) != 0)
354            m_ListPIDDone.remove(dwPID);
355    }

356}

357
358
359/* 删除无效的PID */
360BOOL CHideProc::DeleteUselessPID()
361{
362    if(m_ListPIDDone.empty())
363        return TRUE;
364
365    HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);
366    PROCESSENTRY32 pe;
367    pe.dwSize = sizeof(pe);
368    if(!::Process32First(hSnap,&pe))
369        return FALSE;
370    FindAndDelete(pe.th32ProcessID,pe.szExeFile);
371
372    while(::Process32Next(hSnap,&pe))
373       FindAndDelete(pe.th32ProcessID,pe.szExeFile);
374    
375    return TRUE;
376}

377
378/* 检查重复的PID */
379BOOL CHideProc::CheckPID(DWORD pid)
380{
381    if(m_ListPIDDone.empty())
382        return FALSE;
383    list<DWORD>::iterator pos;
384    pos = find(m_ListPIDDone.begin(),m_ListPIDDone.end(),pid);
385    if(pos != m_ListPIDDone.end())
386        return TRUE;
387
388    return FALSE;
389}

390
391
392
393
394/* 进程名 */
395BOOL CHideProc::HideReset(const char* pszExeName,char* pszStrArray[],int iStrCount)
396{    
397    if(pszExeName == NULL)
398        return FALSE;
399
400    Reset();
401
402    UINT uLen = lstrlen(pszExeName) + 1;
403    m_pszExeName = new char[uLen];
404    ZeroMemory(m_pszExeName,uLen);
405    lstrcpy(m_pszExeName,pszExeName);
406
407    m_iCount = iStrCount;
408
409    InitStringSet(pszStrArray,iStrCount);
410
411    ConvertFitString();
412
413    return TRUE;
414}

415
416/* 进程句柄 */
417BOOL CHideProc::HideReset(HANDLE hProcess,char* pszStrArray[],int iStrCount)
418{
419    if(hProcess == NULL)
420        return FALSE;
421    
422    Reset();
423
424    m_hProcess = hProcess;
425
426    InitStringSet(pszStrArray,iStrCount);
427
428    ConvertFitString();
429
430    return TRUE;
431}

432
433/* 进程主窗口 */
434BOOL CHideProc::HideReset(HWND hWnd,char* pszStrArray[],int iStrCount)
435{
436    if(hWnd == NULL)
437        return FALSE;
438
439    Reset();
440
441    m_hWndCur = hWnd;
442
443    InitStringSet(pszStrArray,iStrCount);
444
445    ConvertFitString();
446
447    return TRUE;
448}

449
450/* 给定PID */
451BOOL CHideProc::HideReset(DWORD dwPID,char* pszStrArray[],int iStrCount)
452{
453
454    if(dwPID == -1)
455        return FALSE;
456    
457    Reset();
458
459    m_dwPID = dwPID;
460
461    InitStringSet(pszStrArray,iStrCount);
462
463    ConvertFitString();
464
465    return 0;
466}

467
468/* 复位状态,释放内存 */
469BOOL CHideProc::Reset()
470{
471    if(m_pszExeName != NULL)
472        delete []m_pszExeName;
473
474
475    if(m_ppszItemList != NULL){
476        for(UINT i=0;i<m_iCount;i++)
477            delete []m_ppszItemList[i];
478        delete m_ppszItemList;
479    }

480
481    if(m_pByte != NULL)
482        delete []m_pByte;
483
484    if(m_pUint != NULL)
485        delete []m_pUint;
486
487
488    
489    m_dwPID = -1;
490    m_hProcess = NULL;
491    m_hWndCur = NULL;
492    m_iCount = -1;
493
494    m_ListHWND.clear();
495    m_ListPIDAdd.clear();
496    
497    m_pByte = NULL;
498    m_ppszItemList = NULL;
499
500    
501    m_pszExeName = NULL;
502    m_pUint = NULL;
503
504    return 0;
505}

506
507/* 退出时释放动态内存 */
508void CHideProc::HideQuit()
509{
510    Reset();
511    m_ListPIDDone.clear();
512}

513
514/* 根据进程名字得到PID并存入链表 */
515void CHideProc::GetPIDByNameToList()
516{
517    if(m_pszExeName == NULL)
518        return ;
519
520    HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
521        NULL);
522    
523    PROCESSENTRY32 pe;
524    pe.dwSize = sizeof(pe);
525    if(!::Process32First(hSnap,&pe))
526        return;
527    
528    if(lstrcmp(pe.szExeFile,m_pszExeName) == 0)
529        m_ListPIDAdd.push_back(pe.th32ProcessID);
530
531    while(::Process32Next(hSnap,&pe))
532        if(lstrcmp(pe.szExeFile,m_pszExeName) == 0)
533            m_ListPIDAdd.push_back(pe.th32ProcessID);
534}

535
536/* 一次扫描注入进程 */
537BOOL CHideProc::HideScan()
538
539    DeleteUselessPID();
540    m_ListPIDAdd.clear();
541    //给出进程名
542    GetPIDByNameToList();
543    //给出进程
544    if(m_hProcess != NULL)
545        m_ListPIDAdd.push_back(GetProcessId(m_hProcess));
546    //给出PID
547    if(m_dwPID != -1)
548        m_ListPIDAdd.push_back(m_dwPID);
549    //给出窗口句柄
550    DWORD dwProcessID = 0;
551    if(m_hWndCur != NULL)
552        if(!IsWindow(m_hWndCur))
553            return FALSE;
554        else
555        {
556            GetWindowThreadProcessId(m_hWndCur,&dwProcessID);
557            if(CheckPID(dwProcessID))
558                return FALSE;
559
560            m_ListHWND.clear();
561            FindChildWindow(m_hWndCur,NULL,"SysListView32");
562            if(m_ListHWND.empty())
563                return FALSE;
564
565            if(InsertRemoteThread(dwProcessID))
566                m_ListPIDDone.push_back(dwProcessID);
567            m_ListHWND.clear();
568            return TRUE;
569        }

570
571    if(m_ListPIDAdd.empty())
572        return FALSE;
573
574
575    HWND hWndTop= ::GetDesktopWindow();
576    HWND hWndChild = hWndTop;
577    list<DWORD>::iterator pos;
578
579    BOOL bFirst = TRUE;
580    while(hWndChild)
581    {
582        dwProcessID = 0;
583        if(bFirst){
584            hWndChild = ::GetWindow(hWndChild,GW_CHILD);
585            bFirst = FALSE;
586        }
else{//枚举窗口
587            hWndChild = ::GetWindow(hWndChild,GW_HWNDNEXT);
588        }

589        
590        GetWindowThreadProcessId(hWndChild,&dwProcessID);
591        if(CheckPID(dwProcessID))
592            continue;
593    
594        pos = find(m_ListPIDAdd.begin(),m_ListPIDAdd.end(),dwProcessID);
595        if(pos == m_ListPIDAdd.end())
596            continue;
597
598        if(CheckPID(dwProcessID))
599            continue;
600    
601
602        m_ListHWND.clear();
603        FindChildWindow(hWndChild,NULL,"SysListView32");
604        if(m_ListHWND.empty())
605            continue;
606
607        //注入线程
608        if(InsertRemoteThread(dwProcessID))
609            m_ListPIDDone.push_back(dwProcessID);
610        m_ListHWND.clear();
611    }

612
613    Sleep(5);
614    return TRUE;
615}

616
617BOOL CHideProc::InitStringSet(char* pszStrArray[],int iStrCount)
618{
619    UINT  uLen;
620    m_ppszItemList = (char**)new char[iStrCount*(sizeof(char*))];
621    m_iCount = iStrCount;
622    for(int i=0; i<iStrCount; i++)
623    {
624        uLen = lstrlen(pszStrArray[i]) + 1;
625        m_ppszItemList[i] = new char[uLen];
626        ZeroMemory(m_ppszItemList[i],uLen);
627        lstrcpy(m_ppszItemList[i],pszStrArray[i]);
628    }

629    return 0;
630}


      希望以上的代码和介绍能对你学习Windows编程有所帮助,代码如果有谬误或者你有更好的解决方法,请留言或者EmailToMe:xiaolu69soft@yahoo.com.cn。

         星绽紫辉2008-12-30完稿


       http://www.cppblog.com/rawdat


      
 

posted on 2008-12-29 11:12 星绽紫辉 阅读(1658) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理