首页
社区
课程
招聘
[求助]DLL隐藏, 64位操作系统,需要做哪些变更?
发表于: 2014-3-31 16:53 8978

[求助]DLL隐藏, 64位操作系统,需要做哪些变更?

2014-3-31 16:53
8978
#define  GDI_HANDLE_BUFFER_SIZE   34

typedef struct _UNICODE_STRING {
        USHORT Length;
        USHORT MaximumLength;
        PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _RTL_DRIVE_LETTER_CURDIR {
        USHORT Flags;
        USHORT Length;
        ULONG TimeStamp;
        UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
        ULONG MaximumLength;
        ULONG Length;
        ULONG Flags;
        ULONG DebugFlags;
        PVOID ConsoleHandle;
        ULONG ConsoleFlags;
        HANDLE StdInputHandle;
        HANDLE StdOutputHandle;
        HANDLE StdErrorHandle;
        UNICODE_STRING CurrentDirectoryPath;
        HANDLE CurrentDirectoryHandle;
        UNICODE_STRING DllPath;
        UNICODE_STRING ImagePathName;
        UNICODE_STRING CommandLine;
        PVOID Environment;
        ULONG StartingPositionLeft;
        ULONG StartingPositionTop;
        ULONG Width;
        ULONG Height;
        ULONG CharWidth;
        ULONG CharHeight;
        ULONG ConsoleTextAttributes;
        ULONG WindowFlags;
        ULONG ShowWindowFlags;
        UNICODE_STRING WindowTitle;
        UNICODE_STRING DesktopName;
        UNICODE_STRING ShellInfo;
        UNICODE_STRING RuntimeData;
        RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB_FREE_BLOCK {
        struct _PEB_FREE_BLOCK *Next;
        ULONG Size;
} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union
    {
        LIST_ENTRY HashLinks;
        PVOID SectionPointer;
    };
    ULONG CheckSum;
    union
    {
        ULONG TimeDateStamp;
        PVOID LoadedImports;
    };
    PVOID EntryPointActivationContext;
    PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB_LDR_DATA
{
        ULONG Length;
        BOOLEAN Initialized;
        BYTE reserved[3];
        PVOID SsHandle;
        LIST_ENTRY InLoadOrderModuleList;
        LIST_ENTRY InMemoryOrderModuleList;
        LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _PEB {
    BOOLEAN InheritedAddressSpace;   
    BOOLEAN ReadImageFileExecOptions;
    BOOLEAN BeingDebugged;           
    BOOLEAN SpareBool;               
    HANDLE Mutant;                  
       
    PVOID ImageBaseAddress;
    PPEB_LDR_DATA Ldr;
    struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
    PVOID SubSystemData;
    PVOID ProcessHeap;
    PVOID FastPebLock;
    PVOID FastPebLockRoutine;
    PVOID FastPebUnlockRoutine;
    ULONG EnvironmentUpdateCount;
    PVOID KernelCallbackTable;
    HANDLE EventLogSection;
    PVOID EventLog;
    PPEB_FREE_BLOCK FreeList;
    ULONG TlsExpansionCounter;
    PVOID TlsBitmap;
    ULONG TlsBitmapBits[2];         // relates to TLS_MINIMUM_AVAILABLE
    PVOID ReadOnlySharedMemoryBase;
    PVOID ReadOnlySharedMemoryHeap;
    PVOID *ReadOnlyStaticServerData;
    PVOID AnsiCodePageData;
    PVOID OemCodePageData;
    PVOID UnicodeCaseTableData;
       
    // Useful information for LdrpInitialize
    ULONG NumberOfProcessors;
    ULONG NtGlobalFlag;
       
    // Passed up from MmCreatePeb from Session Manager registry key
       
    LARGE_INTEGER CriticalSectionTimeout;
    ULONG HeapSegmentReserve;
    ULONG HeapSegmentCommit;
    ULONG HeapDeCommitTotalFreeThreshold;
    ULONG HeapDeCommitFreeBlockThreshold;
       
    // Where heap manager keeps track of all heaps created for a process
    // Fields initialized by MmCreatePeb.  ProcessHeaps is initialized
    // to point to the first free byte after the PEB and MaximumNumberOfHeaps
    // is computed from the page size used to hold the PEB, less the fixed
    // size of this data structure.
       
    ULONG NumberOfHeaps;
    ULONG MaximumNumberOfHeaps;
    PVOID *ProcessHeaps;
       
    //
    //
    PVOID GdiSharedHandleTable;
    PVOID ProcessStarterHelper;
    PVOID GdiDCAttributeList;
    PVOID LoaderLock;
       
    // Following fields filled in by MmCreatePeb from system values and/or
    // image header.
       
    ULONG OSMajorVersion;
    ULONG OSMinorVersion;
    ULONG OSBuildNumber;
    ULONG OSPlatformId;
    ULONG ImageSubsystem;
    ULONG ImageSubsystemMajorVersion;
    ULONG ImageSubsystemMinorVersion;
    ULONG ImageProcessAffinityMask;
    ULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];
} PEB, *PPEB;

typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;

typedef unsigned long (__stdcall *pfnNtQueryInformationProcess)(IN  HANDLE, IN  unsigned int, OUT PVOID, IN ULONG, OUT PULONG);

char *w2c(char *pcstr,const wchar_t *pwstr, size_t len)
{
        int nlength=wcslen(pwstr);
       
        //获取转换后的长度
        int nbytes = WideCharToMultiByte( 0, // specify the code page used to perform the conversion
                0,         // no special flags to handle unmapped characters
                pwstr,     // wide character string to convert
                nlength,   // the number of wide characters in that string
                NULL,      // no output buffer given, we just want to know how long it needs to be
                0,
                NULL,      // no replacement character given
                NULL );    // we don't want to know if a character didn't make it through the translation
       
        // make sure the buffer is big enough for this, making it larger if necessary
        if(nbytes>len)   nbytes=len;
       
        // 通过以上得到的结果,转换unicode 字符为ascii 字符
        WideCharToMultiByte( 0, // specify the code page used to perform the conversion
                0,         // no special flags to handle unmapped characters
                pwstr,   // wide character string to convert
                nlength,   // the number of wide characters in that string
                pcstr, // put the output ascii characters at the end of the buffer
                nbytes,                           // there is at least this much space there
                NULL,      // no replacement character given
                NULL );
       
        return pcstr ;
       
}

BOOL HideModule(char *ModuleName)
{

        char cModuleName[MAX_PATH*2]={0};

        pfnNtQueryInformationProcess p = (pfnNtQueryInformationProcess)::GetProcAddress( hMod, "NtQueryInformationProcess");
       
        PROCESS_BASIC_INFORMATION stInfo = {0};
        DWORD dwRetnLen = 0;
        DWORD dw = p( GetCurrentProcess(), 0, &stInfo, sizeof(stInfo), &dwRetnLen);
       
        PPEB pPeb = stInfo.PebBaseAddress;
        PLIST_ENTRY ListHead, Current;
        PLDR_DATA_TABLE_ENTRY pstEntry = NULL;
       
        ListHead = &( stInfo.PebBaseAddress->Ldr->InLoadOrderModuleList);
        Current = ListHead->Flink;
        while ( Current != ListHead)
        {
                pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
                //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);

                memset(cModuleName,0,sizeof(cModuleName));
                w2c(cModuleName,pstEntry->FullDllName.Buffer,sizeof(cModuleName));

                if ( pstEntry->DllBase == hHideMod)
                {
                        pstEntry->InLoadOrderLinks.Flink->Blink = pstEntry->InLoadOrderLinks.Blink;
                        pstEntry->InLoadOrderLinks.Blink->Flink = pstEntry->InLoadOrderLinks.Flink;
                        //DebugOut( _T( "Hide injected dll."));

                        break;
                }
                Current = pstEntry->InLoadOrderLinks.Flink;
        }
       
        ListHead = &( stInfo.PebBaseAddress->Ldr->InMemoryOrderModuleList);
        Current = ListHead->Flink;
        while ( Current != ListHead)
        {
                pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
                //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);

                memset(cModuleName,0,sizeof(cModuleName));
                w2c(cModuleName,pstEntry->FullDllName.Buffer,sizeof(cModuleName));

                if ( pstEntry->DllBase == hHideMod)
                {
                        pstEntry->InMemoryOrderModuleList.Flink->Blink = pstEntry->InMemoryOrderModuleList.Blink;
                        pstEntry->InMemoryOrderModuleList.Blink->Flink = pstEntry->InMemoryOrderModuleList.Flink;
                        //DebugOut( _T( "Hide injected dll."));       
                        break;
                }
                Current = pstEntry->InMemoryOrderModuleList.Flink;
        }
        //DebugOutW( L"\r\n");
       
        ListHead = &( stInfo.PebBaseAddress->Ldr->InInitializationOrderModuleList);
        Current = ListHead->Flink;
        while ( Current != ListHead)
        {
                pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
                //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
                memset(cModuleName,0,sizeof(cModuleName));
                w2c(cModuleName,pstEntry->FullDllName.Buffer,sizeof(cModuleName));
                if ( pstEntry->DllBase == hHideMod)
                {
                        pstEntry->InInitializationOrderModuleList.Flink->Blink = pstEntry->InInitializationOrderModuleList.Blink;
                        pstEntry->InInitializationOrderModuleList.Blink->Flink = pstEntry->InInitializationOrderModuleList.Flink;
                        //DebugOut( _T( "Hide injected dll."));
                        break;
                }
                Current = pstEntry->InInitializationOrderModuleList.Flink;
        }
        //DebugOut( _T("Out HideMyself\r\n"));
        return TRUE;
}

32位的基本代码如上, 很多的数据结构网络上也可以查询到.

问题是, 这些代码编译成纯粹的64位的DLL在64BIT的OS上是不能工作的,是数据结构发生了变化么?

请赐教!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 53
活跃值: (528)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你用windbg看一下peb的结构。
2014-3-31 18:23
0
雪    币: 182
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
再次搜索了些资料, 发现PROCESS_BASIC_INFORMATION这个结构体中的关键成员:
PPEB PebBaseAddress; 在32位和64位下的PVOID指针的长度不同.

拼命搜索并更新后一些关键的64位书记结构体如下:

typedef unsigned __int64 HANDLE64;
typedef unsigned __int64 PVOID64_;
typedef unsigned __int64 PPROCESS_PARAMETERS64;
typedef PVOID64_ PPEB_FREE_BLOCK64;

typedef struct _PEB64 {
    BOOLEAN InheritedAddressSpace;
    HANDLE64 Mutant;            
    PVOID64_ ImageBaseAddress;
    PVOID64_ Ldr;
    PPROCESS_PARAMETERS64 ProcessParameters;
    PVOID64_ SubSystemData;
    PVOID64_ ProcessHeap;
    PVOID64_ FastPebLock;
    PVOID64_ FastPebLockRoutine;
    PVOID64_ FastPebUnlockRoutine;
    PVOID64_ Spare[4];
    PPEB_FREE_BLOCK64 FreeList;
    ULONG TlsExpansionCounter;
    PVOID64_ TlsBitmap;
    ULONG TlsBitmapBits[2];
    PVOID64_ ReadOnlySharedMemoryBase;
    PVOID64_ ReadOnlySharedMemoryHeap;
    PVOID64_ *ReadOnlyStaticServerData;
    PVOID64_ AnsiCodePageData;
    PVOID64_ OemCodePageData;
    PVOID64_ UnicodeCaseTableData;
    LARGE_INTEGER CriticalSectionTimeout;
} PEB64,*PPEB64;

typedef struct _PROCESS_BASIC_INFORMATION64 {
    PVOID64 Reserved1;
    PVOID64 PebBaseAddress;
    PVOID64 Reserved2[2];
    PVOID64 UniqueProcessId;
    PVOID64 Reserved3;
} PROCESS_BASIC_INFORMATION64,*PPROCESS_BASIC_INFORMATION64;

然后, 依然是依葫芦画瓢, 用X86的流程处理纯粹的64位的DLL隐藏过程代码如下:

        if(Is64BitOS()&&B_IsWow64Process==FALSE)
        {
                PROCESS_BASIC_INFORMATION64 stInfo = {0};
                DWORD dwRetnLen = 0;
                DWORD dw = p( GetCurrentProcess(), 0, &stInfo, sizeof(stInfo), &dwRetnLen);
               
                PPEB64 pPeb = (PEB64 *)stInfo.PebBaseAddress;
                PLIST_ENTRY ListHead, Current;
                PLDR_DATA_TABLE_ENTRY pstEntry = NULL;
               
                ListHead = &((PPEB_LDR_DATA)(pPeb->Ldr))->InLoadOrderModuleList;
                Current = ListHead->Flink;
                while ( Current != ListHead)
                {
                        pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
                        //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
                       
                        memset(cModuleName,0,sizeof(cModuleName));
                        w2c(cModuleName,pstEntry->FullDllName.Buffer,sizeof(cModuleName));
                        sprintf(SendBuf,"Module:%s, base:0x%X\r\n", cModuleName, pstEntry->EntryPoint);
                       
                       
                        if ( pstEntry->DllBase == hHideMod)
                        {
                                pstEntry->InLoadOrderLinks.Flink->Blink = pstEntry->InLoadOrderLinks.Blink;
                                pstEntry->InLoadOrderLinks.Blink->Flink = pstEntry->InLoadOrderLinks.Flink;
                                //DebugOut( _T( "Hide injected dll."));
                                sprintf(SendBuf,"\r\nHide dll '%s' In InLoadOrderList.\r\n\r\n",cModuleName);
                                       
                                break;
                        }
                        Current = pstEntry->InLoadOrderLinks.Flink;
                }
               
                ListHead = &((PPEB_LDR_DATA)(pPeb->Ldr))->InMemoryOrderModuleList;
                Current = ListHead->Flink;
                while ( Current != ListHead)
                {
                        pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);
                        //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
                       
                        memset(cModuleName,0,sizeof(cModuleName));
                        w2c(cModuleName,pstEntry->FullDllName.Buffer,sizeof(cModuleName));
                        sprintf(SendBuf,"Module:%s, base:0x%X\r\n", cModuleName, pstEntry->EntryPoint);
                       
                       
                        if ( pstEntry->DllBase == hHideMod)
                        {
                                pstEntry->InMemoryOrderModuleList.Flink->Blink = pstEntry->InMemoryOrderModuleList.Blink;
                                pstEntry->InMemoryOrderModuleList.Blink->Flink = pstEntry->InMemoryOrderModuleList.Flink;
                                //DebugOut( _T( "Hide injected dll."));
                                sprintf(SendBuf,"\r\nHide dll '%s' In InMemoryOrderList.\r\n\r\n",cModuleName);
                               
                                break;
                        }
                        Current = pstEntry->InMemoryOrderModuleList.Flink;
                }
                //DebugOutW( L"\r\n");
               
                ListHead =  &((PPEB_LDR_DATA)(pPeb->Ldr))->InInitializationOrderModuleList;
                Current = ListHead->Flink;
                while ( Current != ListHead)
                {
                        pstEntry = CONTAINING_RECORD( Current, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);
                        //DebugOutW( L"Module:%s, base:0x%X\r\n", pstEntry->FullDllName.Buffer, pstEntry->EntryPoint);
                        memset(cModuleName,0,sizeof(cModuleName));
                        w2c(cModuleName,pstEntry->FullDllName.Buffer,sizeof(cModuleName));
                        sprintf(SendBuf,"Module:%s, base:0x%X\r\n", cModuleName, pstEntry->EntryPoint);
                       
                       
                        if ( pstEntry->DllBase == hHideMod)
                        {
                                pstEntry->InInitializationOrderModuleList.Flink->Blink = pstEntry->InInitializationOrderModuleList.Blink;
                                pstEntry->InInitializationOrderModuleList.Blink->Flink = pstEntry->InInitializationOrderModuleList.Flink;
                                //DebugOut( _T( "Hide injected dll."));
                                sprintf(SendBuf,"\r\nHide dll '%s' In InInitializationOrderList.\r\n\r\n",cModuleName);
                               
                                break;
                        }
                        Current = pstEntry->InInitializationOrderModuleList.Flink;
                }
        //DebugOut( _T("Out HideMyself\r\n"));
        }

特意在64位环境编写了一个TEST64.EXE ,
并隐藏自己进程的kernel32.dll, 用辅助工具观察也正常实现了.

现在问题在于, 32位平台的DLL隐藏后, 功能一切正常.
而64位平台,一旦调用该处代码,功能立刻无效.

奇妙的64位OS,到底做了什么事情?
2014-4-1 16:53
0
雪    币: 27
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
完全多余改变量类型。
2014-4-3 11:19
0
雪    币: 182
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
是的, 那些基本是多余的, 只是直接粘贴过来的.
2014-4-4 21:22
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
好东西!我也碰到了类似的问题!
2014-4-8 08:40
0
游客
登录 | 注册 方可回帖
返回
//