R3 下动态加载的模块的保护(一)

前言

在 R3 下防护动态加载的模块不被意外卸载需要很多的策略,比如:LDR 断链、VAD 记录擦除、PE 头擦除、修改入口函数、内存注入等。文本我们将浅析模块静态化技术这一项技术。模块静态化是一个很常见的模块保护技术,它通过修改模块的引用计数为 -1,来使得模块不可被标准的 API 成功卸载。

系列文章:

  1. R3 下动态加载的模块的保护(一):分析模块伪静态化技术 [本文]
  2. R3 下动态加载的模块的保护(二):分析重映射擦除 VAD 信息[暂未发布]
  3. 更多  ... ... 

1 关于 DLL 引用计数

DLL 的引用计数(或加载计数)是 DLL 被请求加载到进程中的次数记录。每次加载 DLL 时(通过 LoadLibrary) 添加到进程中,其引用计数递增 1 ,每次从进程中释放 DLL(通过 FreeLibrary)时, 引用计数递减 1。进程中初次加载模块时会将模块映射到地址空间中,当之后多次加载同一个模块时,并不会重新加载这个模块,而是只返回相同的地址。当引用计数达到 0 时, DLL 完全从进程中取消映射。并且规定,静态加载的模块,其引用计数为 -1,并且不能增加计数或通过 FreeLibrary / LdrUnLoadDll 等卸载模块。
 
Windows API 没有提供有关加载的 DLL 的大量信息。 Windows 提供 ToolHelp 库来检索加载到进程中的 DLL 的信息,但它只提供了非常基本的信息:例如模块名称、模块句柄等。为了获得更多信息,需要更深入地挖掘。

2 关于 uFlags 位域中的 Mask

另一种类似的技术是通过 uFlags 位域覆盖修改系统用于区别静态模块和动态模块的标志位,修改后系统会认为模块是静态的进而阻止模块的卸载。

修改前,动态加载的模块可以被 RemoteDll 等工具卸载:

修改后,按钮灰显,表明这个模块不可以被卸载:

这种修改不需要针对 R3 下哪种工具,只需要在加载了模块的进程内修改即可。

本文参考文献:

        (1)The covert way to find the Reference Count of DLL - www.SecurityXploded.com

        (2)Make Your Dynamic Module Unfreeable (Anti-FreeLibrary) | secrary[dot]com

3 原理和应用

3.1 获取结构体和模块的遍历

DLL 的引用计数存储在 PEB (Process Environment Block)中。PEB 包含 DLL 的链表,而链表中包含有关该特定 DLL 的结构化信息。

任何进程的 PEB 块通常位于地址 0x7ffdf000。 但是,有标准方法可以获取此地址。有 NTDLL.DLL 的无文档函数 NtQueryInformationProcess 可用于检索PROCESS_BASIC_INFORMATION 结构。PBI 结构如下:

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

第二个成员 PebBaseAddress 是指向 PEB 结构体的指针,该结构体可用于获取已加载模块的信息列表。

也可以使用 fs/gs 寄存器偏移来获取,这是 MSVC 编译器支持的接口:

#ifdef _WIN64PPEB_LDR_DATA64 pPebLdrData = NULL;ULONGLONG ModuleSum = NULL;PPEB64 peb = (PPEB64)__readgsqword(0x60);
#elsePPEB_LDR_DATA32 pPebLdrData = NULL;ULONG ModuleSum = NULL;PPEB32 peb = (PPEB32)__readfsdword(0x30);
#endif

而对于 PEB 结构体,微软是没有公开文档的,需要自己进行重定义(原始结构体定义中缺少我们需要的部分),经查阅逆向文献,得到如下的结构体定义(部分不需要用到的成员已经被截断):

typedef struct _PEB_LDR_DATA32
{ULONG Length; // +0x00BOOLEAN Initialized; // +0x04PVOID SsHandle; // +0x08LIST_ENTRY InLoadOrderModuleList; // +0x0cLIST_ENTRY InMemoryOrderModuleList; // +0x14LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA32, * PPEB_LDR_DATA32; // +0x24typedef struct _PEB32
{UCHAR InheritedAddressSpace;                                            //0x0UCHAR ReadImageFileExecOptions;                                         //0x1UCHAR BeingDebugged;                                                    //0x2union{UCHAR BitField;                                                     //0x3struct{UCHAR ImageUsesLargePages : 1;                                    //0x3UCHAR IsProtectedProcess : 1;                                     //0x3UCHAR IsImageDynamicallyRelocated : 1;                            //0x3UCHAR SkipPatchingUser32Forwarders : 1;                           //0x3UCHAR IsPackagedProcess : 1;                                      //0x3UCHAR IsAppContainer : 1;                                         //0x3UCHAR IsProtectedProcessLight : 1;                                //0x3UCHAR IsLongPathAwareProcess : 1;                                 //0x3};};PVOID Mutant;                                                           //0x4PVOID ImageBaseAddress;                                                 //0x8PEB_LDR_DATA32* Ldr;                                              //0xcRTL_USER_PROCESS_PARAMETERS* ProcessParameters;                 //0x10PVOID SubSystemData;                                                    //0x14PVOID ProcessHeap;                                                      //0x18RTL_CRITICAL_SECTION* FastPebLock;                              //0x1cSLIST_HEADER* volatile AtlThunkSListPtr;                         //0x20PVOID IFEOKey;                                                          //0x24
} PEB32, * PPEB32;typedef struct _STRING64
{USHORT Length;                                                          //0x0USHORT MaximumLength;                                                   //0x2ULONGLONG Buffer;                                                       //0x8
}STRING64, * LPSTRING64;typedef struct _PEB_LDR_DATA64
{ULONG Length;                                                           //0x0UCHAR Initialized;                                                      //0x4PVOID SsHandle;                                                         //0x8LIST_ENTRY InLoadOrderModuleList;                               //0x10LIST_ENTRY InMemoryOrderModuleList;                             //0x20LIST_ENTRY InInitializationOrderModuleList;                     //0x30PVOID EntryInProgress;                                                  //0x40UCHAR ShutdownInProgress;                                               //0x48PVOID ShutdownThreadId;                                                 //0x50
}PEB_LDR_DATA64, *PPEB_LDR_DATA64;typedef struct _PEB64
{UCHAR InheritedAddressSpace;                                            //0x0UCHAR ReadImageFileExecOptions;                                         //0x1UCHAR BeingDebugged;                                                    //0x2union{UCHAR BitField;                                                     //0x3struct{UCHAR ImageUsesLargePages : 1;                                    //0x3UCHAR IsProtectedProcess : 1;                                     //0x3UCHAR IsImageDynamicallyRelocated : 1;                            //0x3UCHAR SkipPatchingUser32Forwarders : 1;                           //0x3UCHAR IsPackagedProcess : 1;                                      //0x3UCHAR IsAppContainer : 1;                                         //0x3UCHAR IsProtectedProcessLight : 1;                                //0x3UCHAR IsLongPathAwareProcess : 1;                                 //0x3};};UCHAR Padding0[4];                                                      //0x4ULONGLONG Mutant;                                                       //0x8ULONGLONG ImageBaseAddress;                                             //0x10PEB_LDR_DATA64* Ldr;                                                          //0x18ULONGLONG ProcessParameters;                                            //0x20ULONGLONG SubSystemData;                                                //0x28ULONGLONG ProcessHeap;                                                  //0x30ULONGLONG FastPebLock;                                                  //0x38ULONGLONG AtlThunkSListPtr;                                             //0x40ULONGLONG IFEOKey;                                                      //0x48
}PEB64, *PPEB64;

在 PEB 结构中,我们需要获取 PEB_LDR_DATA 结构,也就是这里的 Ldr 成员:

PPEB_LDR_DATA Ldr

它是指向 PEB_LDR_DATA 结构的指针。

PEB_LDR_DATA 包含我们感兴趣的加载器数据结构,它包含已加载模块的链表:

typedef struct _PEB_LDR_DATA64
{ULONG Length;                                                           //0x0UCHAR Initialized;                                                      //0x4PVOID SsHandle;                                                         //0x8LIST_ENTRY InLoadOrderModuleList;                               //0x10LIST_ENTRY InMemoryOrderModuleList;                             //0x20LIST_ENTRY InInitializationOrderModuleList;                     //0x30PVOID EntryInProgress;                                                  //0x40UCHAR ShutdownInProgress;                                               //0x48PVOID ShutdownThreadId;                                                 //0x50
}PEB_LDR_DATA64, *PPEB_LDR_DATA64;

数据结构为 LIST_ENTRY 的三个链表分别为:InLoadOrderModuleList、 InMemoryOrderModuleList 和 InInitializationOrderModuleList。他们存储按照不同排序方式对模块排序的结果。

那么问题就转化为了如何解析链表来遍历每一个模块的信息。

具体遍历原理可以参考我的这篇文章:利用 PEB_LDR_DATA 结构枚举进程模块信息。就不再重复解释了。

3.2 修改的成员位置

这两个技术都通过 LDR_DATA_TABLE_ENTRY 中的成员来完成:

前者通过修改 DdagNode 结构中的 LoadCount 以及 LDR 中废弃的(旧系统用到) ObsoleteLoadCount 成员,将他们赋值为 -1,即可修改模块属性为静态:

pLdrDataEntry->DdagNode->LoadCount = 0xffffffff;
pLdrDataEntry->ObsoleteLoadCount = 0xffff;

后者通过修改位域 ProcessStaticImport 为 TRUE(1) 来实现的,该位域结构如下:

union
    {
        UCHAR FlagGroup[4];                                                 //0x68
        ULONG Flags;                                                        //0x68
        struct
        {
            ULONG PackagedBinary : 1;                                         //0x68
            ULONG MarkedForRemoval : 1;                                       //0x68
            ULONG ImageDll : 1;                                               //0x68
            ULONG LoadNotificationsSent : 1;                                  //0x68
            ULONG TelemetryEntryProcessed : 1;                                //0x68
            ULONG ProcessStaticImport : 1;                                    //0x68
            ULONG InLegacyLists : 1;                                          //0x68
            ULONG InIndexes : 1;                                              //0x68
            ULONG ShimDll : 1;                                                //0x68
            ULONG InExceptionTable : 1;                                       //0x68
            ULONG ReservedFlags1 : 2;                                         //0x68
            ULONG LoadInProgress : 1;                                         //0x68
            ULONG LoadConfigProcessed : 1;                                    //0x68
            ULONG EntryProcessed : 1;                                         //0x68
            ULONG ProtectDelayLoad : 1;                                       //0x68
            ULONG ReservedFlags3 : 2;                                         //0x68
            ULONG DontCallForThreads : 1;                                     //0x68
            ULONG ProcessAttachCalled : 1;                                    //0x68
            ULONG ProcessAttachFailed : 1;                                    //0x68
            ULONG CorDeferredValidate : 1;                                    //0x68
            ULONG CorImage : 1;                                               //0x68
            ULONG DontRelocate : 1;                                           //0x68
            ULONG CorILOnly : 1;                                              //0x68
            ULONG ChpeImage : 1;                                              //0x68
            ULONG ReservedFlags5 : 2;                                         //0x68
            ULONG Redirected : 1;                                             //0x68
            ULONG ReservedFlags6 : 2;                                         //0x68
            ULONG CompatDatabaseProcessed : 1;                                //0x68
        }uFlags;
    };

其实,开启 ProcessStaticImport 标志位保护模块的官方的方法是调用一次 GetModuleHandleEx 并指定 GET_MODULE_HANDLE_EX_FLAG_PIN 标志,但似乎通过官方方法并没法取消掉,我们通过编程方式枚举 LDR 信息的可以取消掉该机制。

HMODULE hTestModule = 0;
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, L"模块名称", &hTestModule);

开启该标志位后,无论使用多少次 FreeLibrary 都不会真正卸载模块。

3.3 完整代码

下面的代码实现上述所有功能,需要注意是,有三个链表都需要枚举并修改,关于这个结构枚举的原理可以看我的另一篇文章“利用 LDR_DATA_TABLE 枚举进程模块信息”,此外需要注意如果包含 winternl 头文件,它里面有 ldrp.h 部分结构的重复声明(微软给的结构体不完整)。

ldrp.h:

#pragma once
#include <winnt.h>
#include <WTypesbase.h>
//#include <winternl.h>// Kernels | x64 | Windows 10 | 2016 | 2210 22H2(May 2023 Update)//0x18 bytes (sizeof)
typedef struct _RTL_BALANCED_NODE
{union{_RTL_BALANCED_NODE* Children[2];                             //0x0struct{_RTL_BALANCED_NODE* Left;                                //0x0_RTL_BALANCED_NODE* Right;                               //0x8};};union{struct{UCHAR Red : 1;                                                    //0x10UCHAR Balance : 2;                                                //0x10};ULONGLONG ParentValue;                                                //0x10};
}RTL_BALANCED_NODE, * PRTL_BALANCED_NODE, * LPRTL_BALANCED_NODE;//0x4 bytes (sizeof)
enum _LDR_DLL_LOAD_REASON
{LoadReasonStaticDependency = 0,LoadReasonStaticForwarderDependency = 1,LoadReasonDynamicForwarderDependency = 2,LoadReasonDelayloadDependency = 3,LoadReasonDynamicLoad = 4,LoadReasonAsImageLoad = 5,LoadReasonAsDataLoad = 6,LoadReasonEnclavePrimary = 7,LoadReasonEnclaveDependency = 8,LoadReasonUnknown = -1
};typedef _LDR_DLL_LOAD_REASON    LDR_DLL_LOAD_REASON;//0x10 bytes (sizeof)
typedef struct _LDR_SERVICE_TAG_RECORD
{_LDR_SERVICE_TAG_RECORD* Next;                                           //0x0ULONG ServiceTag;                                                       //0x8
}LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD;//0x8 bytes (sizeof)
typedef struct _LDRP_CSLIST
{SINGLE_LIST_ENTRY* Tail;                                                //0x0
}LDRP_CSLIST;//0x4 bytes (sizeof)
enum _LDR_DDAG_STATE
{LdrModulesMerged = -5,LdrModulesInitError = -4,LdrModulesSnapError = -3,LdrModulesUnloaded = -2,LdrModulesUnloading = -1,LdrModulesPlaceHolder = 0,LdrModulesMapping = 1,LdrModulesMapped = 2,LdrModulesWaitingForDependencies = 3,LdrModulesSnapping = 4,LdrModulesSnapped = 5,LdrModulesCondensed = 6,LdrModulesReadyToInit = 7,LdrModulesInitializing = 8,LdrModulesReadyToRun = 9
};typedef _LDR_DDAG_STATE   LDR_DDAG_STATE;//0x50 bytes (sizeof)
typedef struct _LDR_DDAG_NODE
{LIST_ENTRY Modules;                                                     //0x0PLDR_SERVICE_TAG_RECORD ServiceTagList;                                 //0x10ULONG LoadCount;                                                        //0x18ULONG LoadWhileUnloadingCount;                                          //0x1cULONG LowestLink;                                                       //0x20LDRP_CSLIST Dependencies;                                               //0x28LDRP_CSLIST IncomingDependencies;                                       //0x30LDR_DDAG_STATE State;                                                   //0x38SINGLE_LIST_ENTRY CondenseLink;                                         //0x40ULONG PreorderNumber;                                                   //0x48
}LDR_DDAG_NODE, * PLDR_DDAG_NODE;typedef struct _UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR  Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING* PUNICODE_STRING;
typedef const UNICODE_STRING* PCUNICODE_STRING;//0x120 bytes (sizeof)
typedef struct _LDR_DATA_TABLE_ENTRY
{LIST_ENTRY InLoadOrderLinks;                                            //0x0LIST_ENTRY InMemoryOrderLinks;                                          //0x10LIST_ENTRY InInitializationOrderLinks;                                  //0x20VOID* DllBase;                                                          //0x30VOID* EntryPoint;                                                       //0x38ULONG SizeOfImage;                                                      //0x40UNICODE_STRING FullDllName;                                             //0x48UNICODE_STRING BaseDllName;                                             //0x58union{UCHAR FlagGroup[4];                                                 //0x68ULONG Flags;                                                        //0x68struct{ULONG PackagedBinary : 1;                                         //0x68ULONG MarkedForRemoval : 1;                                       //0x68ULONG ImageDll : 1;                                               //0x68ULONG LoadNotificationsSent : 1;                                  //0x68ULONG TelemetryEntryProcessed : 1;                                //0x68ULONG ProcessStaticImport : 1;                                    //0x68ULONG InLegacyLists : 1;                                          //0x68ULONG InIndexes : 1;                                              //0x68ULONG ShimDll : 1;                                                //0x68ULONG InExceptionTable : 1;                                       //0x68ULONG ReservedFlags1 : 2;                                         //0x68ULONG LoadInProgress : 1;                                         //0x68ULONG LoadConfigProcessed : 1;                                    //0x68ULONG EntryProcessed : 1;                                         //0x68ULONG ProtectDelayLoad : 1;                                       //0x68ULONG ReservedFlags3 : 2;                                         //0x68ULONG DontCallForThreads : 1;                                     //0x68ULONG ProcessAttachCalled : 1;                                    //0x68ULONG ProcessAttachFailed : 1;                                    //0x68ULONG CorDeferredValidate : 1;                                    //0x68ULONG CorImage : 1;                                               //0x68ULONG DontRelocate : 1;                                           //0x68ULONG CorILOnly : 1;                                              //0x68ULONG ChpeImage : 1;                                              //0x68ULONG ReservedFlags5 : 2;                                         //0x68ULONG Redirected : 1;                                             //0x68ULONG ReservedFlags6 : 2;                                         //0x68ULONG CompatDatabaseProcessed : 1;                                //0x68}uFlags;};USHORT ObsoleteLoadCount;                                               //0x6cUSHORT TlsIndex;                                                        //0x6eLIST_ENTRY HashLinks;                                                   //0x70ULONG TimeDateStamp;                                                    //0x80struct ACTIVATION_CONTEXT* EntryPointActivationContext;                 //0x88VOID* Lock;                                                             //0x90LDR_DDAG_NODE* DdagNode;                                                //0x98LIST_ENTRY NodeModuleLink;                                              //0xa0struct LDRP_LOAD_CONTEXT* LoadContext;                                  //0xb0VOID* ParentDllBase;                                                    //0xb8VOID* SwitchBackContext;                                                //0xc0RTL_BALANCED_NODE BaseAddressIndexNode;                                 //0xc8RTL_BALANCED_NODE MappingInfoIndexNode;                                 //0xe0ULONGLONG OriginalBase;                                                 //0xf8LARGE_INTEGER LoadTime;                                                 //0x100ULONG BaseNameHashValue;                                                //0x108LDR_DLL_LOAD_REASON LoadReason;                                         //0x10cULONG ImplicitPathOptions;                                              //0x110ULONG ReferenceCount;                                                   //0x114ULONG DependentLoadFlags;                                               //0x118UCHAR SigningLevel;                                                     //0x11c
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;//0x58 bytes (sizeof)
typedef struct _PEB_LDR_DATA32
{ULONG Length; // +0x00BOOLEAN Initialized; // +0x04PVOID SsHandle; // +0x08LIST_ENTRY InLoadOrderModuleList; // +0x0cLIST_ENTRY InMemoryOrderModuleList; // +0x14LIST_ENTRY InInitializationOrderModuleList;// +0x1c
} PEB_LDR_DATA32, * PPEB_LDR_DATA32; // +0x24typedef struct _PEB32
{UCHAR InheritedAddressSpace;                                            //0x0UCHAR ReadImageFileExecOptions;                                         //0x1UCHAR BeingDebugged;                                                    //0x2union{UCHAR BitField;                                                     //0x3struct{UCHAR ImageUsesLargePages : 1;                                    //0x3UCHAR IsProtectedProcess : 1;                                     //0x3UCHAR IsImageDynamicallyRelocated : 1;                            //0x3UCHAR SkipPatchingUser32Forwarders : 1;                           //0x3UCHAR IsPackagedProcess : 1;                                      //0x3UCHAR IsAppContainer : 1;                                         //0x3UCHAR IsProtectedProcessLight : 1;                                //0x3UCHAR IsLongPathAwareProcess : 1;                                 //0x3};};PVOID Mutant;                                                           //0x4PVOID ImageBaseAddress;                                                 //0x8PEB_LDR_DATA32* Ldr;                                                    //0xcstruct RTL_USER_PROCESS_PARAMETERS* ProcessParameters;                  //0x10PVOID SubSystemData;                                                    //0x14PVOID ProcessHeap;                                                      //0x18RTL_CRITICAL_SECTION* FastPebLock;                                      //0x1cSLIST_HEADER* volatile AtlThunkSListPtr;                                //0x20PVOID IFEOKey;                                                          //0x24
} PEB32, * PPEB32;typedef struct _STRING64
{USHORT Length;                                                          //0x0USHORT MaximumLength;                                                   //0x2ULONGLONG Buffer;                                                       //0x8
}STRING64, * LPSTRING64;typedef struct _PEB_LDR_DATA64
{ULONG Length;                                                           //0x0UCHAR Initialized;                                                      //0x4PVOID SsHandle;                                                         //0x8LIST_ENTRY InLoadOrderModuleList;                                       //0x10LIST_ENTRY InMemoryOrderModuleList;                                     //0x20LIST_ENTRY InInitializationOrderModuleList;                             //0x30PVOID EntryInProgress;                                                  //0x40UCHAR ShutdownInProgress;                                               //0x48PVOID ShutdownThreadId;                                                 //0x50
}PEB_LDR_DATA64, * PPEB_LDR_DATA64;typedef struct _PEB64
{UCHAR InheritedAddressSpace;                                            //0x0UCHAR ReadImageFileExecOptions;                                         //0x1UCHAR BeingDebugged;                                                    //0x2union{UCHAR BitField;                                                     //0x3struct{UCHAR ImageUsesLargePages : 1;                                    //0x3UCHAR IsProtectedProcess : 1;                                     //0x3UCHAR IsImageDynamicallyRelocated : 1;                            //0x3UCHAR SkipPatchingUser32Forwarders : 1;                           //0x3UCHAR IsPackagedProcess : 1;                                      //0x3UCHAR IsAppContainer : 1;                                         //0x3UCHAR IsProtectedProcessLight : 1;                                //0x3UCHAR IsLongPathAwareProcess : 1;                                 //0x3};};UCHAR Padding0[4];                                                      //0x4ULONGLONG Mutant;                                                       //0x8ULONGLONG ImageBaseAddress;                                             //0x10PEB_LDR_DATA64* Ldr;                                                    //0x18ULONGLONG ProcessParameters;                                            //0x20ULONGLONG SubSystemData;                                                //0x28ULONGLONG ProcessHeap;                                                  //0x30ULONGLONG FastPebLock;                                                  //0x38ULONGLONG AtlThunkSListPtr;                                             //0x40ULONGLONG IFEOKey;                                                      //0x48
}PEB64, * PPEB64;#ifdef _WIN64
typedef PEB64                   PEB;
typedef PPEB64                  PPEB;
typedef PEB_LDR_DATA64          PEB_LDR_DATA;
typedef PPEB_LDR_DATA64         PPEB_LDR_DATA;
#else
typedef PEB32                   PEB;
typedef PPEB32                  PPEB;
typedef PEB_LDR_DATA32          PEB_LDR_DATA;
typedef PPEB_LDR_DATA32         PPEB_LDR_DATA;
#endif

main.cpp:

DWORD WINAPI EasyProtectLibrary(LPVOID lpThreadParameter)
{auto ldrpt = (LPLDR_PROTECT_STRUCT)lpThreadParameter;if (ldrpt == nullptr) return 0;BOOL bNewValue = ldrpt->bEnableProtect;BOOL bOldProtect = 0;DWORD index = 0;DWORD bResponse = 0;const WCHAR lpFileName[] = HOOK_MODULE_NAME;PPEB_LDR_DATA pPebLdrData = nullptr;PLDR_DATA_TABLE_ENTRY pLdrDataEntry = nullptr;PLIST_ENTRY pListEntryStart = nullptr;PLIST_ENTRY pListEntryEnd = nullptr;SIZE_T ulTestSize = 0;SIZE_T ulRealSize = wcsnlen_s(lpFileName, MAX_PATH);
#ifdef _WIN64ULONGLONG ModuleSum = NULL;PPEB peb = (PPEB)__readgsqword(0x60);
#elseULONG ModuleSum = NULL;PPEB32 peb = (PPEB32)__readfsdword(0x30);
#endif__try {pPebLdrData = peb->Ldr;// 以模块加载顺序排列的链表pListEntryStart = pPebLdrData->InLoadOrderModuleList.Flink;pListEntryEnd = pPebLdrData->InLoadOrderModuleList.Blink;for (index = 0; pListEntryStart != pListEntryEnd; index++){pLdrDataEntry = CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);ulTestSize = wcsnlen_s(pLdrDataEntry->BaseDllName.Buffer, MAX_PATH);if (ulTestSize != ulRealSize || ulTestSize == MAX_PATH){pListEntryStart = pListEntryStart->Flink;continue;}if (!_wcsicmp(pLdrDataEntry->BaseDllName.Buffer, lpFileName)){if (bNewValue == TRUE){// 引用计数主要有两个成员,引用计数为 -1 表示静态加载的模块,// 并且不允许卸载pLdrDataEntry->DdagNode->LoadCount = 0xffffffff;pLdrDataEntry->ObsoleteLoadCount = 0xffff;}else {// 引用计数主要有两个成员,引用计数为 -1 表示静态加载的模块,// 并且不允许卸载pLdrDataEntry->DdagNode->LoadCount = 1;pLdrDataEntry->ObsoleteLoadCount = 1;}// ProcessStaticImport 位域如果为 1, 则任何卸载调用都将直接返回 TRUE// 而不做任何资源释放操作pLdrDataEntry->uFlags.ProcessStaticImport = bNewValue;bResponse |= 0x1;break;}pListEntryStart = pListEntryStart->Flink;}// 以内存位置排列的模块链表pListEntryStart = pPebLdrData->InMemoryOrderModuleList.Flink;pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Blink;for (index = 0; pListEntryStart != pListEntryEnd; index++){pLdrDataEntry = CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);ulTestSize = wcsnlen_s(pLdrDataEntry->BaseDllName.Buffer, MAX_PATH);if (ulTestSize != ulRealSize || ulTestSize == MAX_PATH){pListEntryStart = pListEntryStart->Flink;continue;}if (!_wcsicmp(pLdrDataEntry->BaseDllName.Buffer, lpFileName)){if (bNewValue == TRUE){pLdrDataEntry->DdagNode->LoadCount = 0xffffffff;pLdrDataEntry->ObsoleteLoadCount = 0xffff;}else {pLdrDataEntry->DdagNode->LoadCount = 1;pLdrDataEntry->ObsoleteLoadCount = 1;}pLdrDataEntry->uFlags.ProcessStaticImport = bNewValue;bResponse |= 0x2;break;}pListEntryStart = pListEntryStart->Flink;}// 以初始化顺序加载的模块列表pListEntryStart = pPebLdrData->InInitializationOrderModuleList.Flink;pListEntryEnd = pPebLdrData->InInitializationOrderModuleList.Blink;for (index = 0; pListEntryStart != pListEntryEnd; index++){pLdrDataEntry = CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);ulTestSize = wcsnlen_s(pLdrDataEntry->BaseDllName.Buffer, MAX_PATH);if (ulTestSize != ulRealSize || ulTestSize == MAX_PATH){pListEntryStart = pListEntryStart->Flink;continue;}if (!_wcsicmp(pLdrDataEntry->BaseDllName.Buffer, lpFileName)){if (bNewValue == TRUE){pLdrDataEntry->DdagNode->LoadCount = 0xffffffff;pLdrDataEntry->ObsoleteLoadCount = 0xffff;}else {pLdrDataEntry->DdagNode->LoadCount = 1;pLdrDataEntry->ObsoleteLoadCount = 1;}pLdrDataEntry->uFlags.ProcessStaticImport = bNewValue;bResponse |= 0x4;break;}pListEntryStart = pListEntryStart->Flink;}}__except (EXCEPTION_EXECUTE_HANDLER) {OutputDebugStringW(L"Er:Exception occurred while accessing memory.\n");return FALSE;}return bResponse;
}

这样,我们只需要在模块初始化和脱钩时,调用该函数就可以在进程中简单地保护/脱保护钩子模块。

总结&后记

文本浅析模块静态化技术这一项技术。是一种有效的实践。


发布于:2024.02.03;更新于:2024.02.03

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/666595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

建筑工程答案在哪搜?九个免费好用的大学生搜题工具 #经验分享#知识分享

大学生必备&#xff0c;这条笔记大数据一定定要推给刚上大学的学弟学妹&#xff01;&#xff01; 1.七燕搜题 这是一个公众号 解题步骤详细解析&#xff0c;帮助你理解问题本质。其他考试领域也能找到答案。 下方附上一些测试的试题及答案 1、据《素问太阴阳明论》所论&…

爬取58二手房并用SVR模型拟合

目录 一、前言 二、爬虫与数据处理 三、模型 一、前言 爬取数据仅用于练习和学习。本文运用二手房规格sepc(如3室2厅1卫)和二手房面积area预测二手房价格price&#xff0c;只是练习和学习&#xff0c;不代表如何实际意义。 二、爬虫与数据处理 import requests import cha…

关于Clone

关于Clone 一般情况下&#xff0c;如果使用clone()方法&#xff0c;则需满足以下条件。 1、对任何对象o&#xff0c;都有o.clone() ! o。换言之&#xff0c;克隆对象与原型对象不是同一个对象。 2、对任何对象o&#xff0c;都有o.clone().getClass() o.getClass()。换言之&a…

背景样式de七七八八

一&#xff0c;简介 背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等。 1.1背景颜色&#xff08;background-color&#xff09; background-color&#xff1a;transparent/color&#xff1b; 默认值为transparent&#xff08;透明的&#xff…

Rust 第一个rust程序Hello Rust️

文章目录 前言一、vscode 安装rust相关插件二、Cargo New三、vscode调试rustLLDB 前言 Rust学习系列。今天就让我们掌握第一个rust程序。Hello Rust &#x1f980;️。 在上一篇文章我们在macOS成功安装了rust。 一、vscode 安装rust相关插件 以下是一些常用的 Rust 开发插件…

从传统到现代:易点易动固定资产管理系统利用RFID技术高效管理固定资产

近年来,随着RFID技术的发展与成熟,它被越来越多地应用于企业资产管理领域。易点易动推出的固定资产管理系统就将RFID技术深度整合,实现了企业固定资产管理模式的跨越式变革。 传统管理模式的不足 传统的手工登记式管理模式在企业固定资产管理中存在很多问题: 信息录入缺乏规范…

幻兽帕鲁服务器自动重启备份-python

幻兽帕鲁服务器自动重启备份-python 1. 前置知识点2. 目录结构3. 代码内容4. 原理解释5. 额外备注 基于python编写的服务器全自动管理工具&#xff0c;能够实现自动定时备份存档&#xff0c;以及在检测到服务器崩溃之后自动重新启动&#xff0c;并且整合了对于frp端口转发工具的…

c语言:贪吃蛇的实现

目录 贪吃蛇实现的技术前提&#xff1a; Win32 API介绍 控制台程序&#xff08;console&#xff09; 控制台屏幕上的坐标 GetStdHandle GetConsoleCursorInfo CONSOLE_CURSOR_INFO SetConsoleCursorInfo SetConsoleCursorPosition GetAsyncKeyState 宽字符的打印 …

进程中线程使用率偏高问题排查

1. top命令查看CPU使用率高的进程 2. top -H -p 15931(进程PID) 查看进程下的线程 3. printf "%x\n" 17503(线程PID) 线程PID 10进制转16进制 0x445f 4. jstack -l 15931(JVM进程PID) 导出java进程栈信息&#xff0c;里面包含线程nid0x445f和所在的类&#xff0…

【AG32VF407】国产MCU+FPGA Verilog双边沿检测输出方波

视频讲解 [AG32VF407]国产MCUFPGA Verilog双边沿检测输出方波 实验过程 本次使用使用AG32VF407开发板中的FPGA&#xff0c;使用双clk的双边沿进行检测&#xff0c;同步输出方波 同时可以根据输出的方波检测clk的频率&#xff0c;以及双clk的相位关系&#xff0c;如下为verilog…

生活资料 伊舍小镇

生活资料 伊舍小镇 电费交付—国家电网 咨询&#xff1a;95598 用户&#xff1a;*** 查询&#xff1a;微信“国网北京电力”公众号→我的用电→余额查询→立即购电 支付&#xff1a;微信→我→服务→生活缴费→自动缴费 燃气费交付-北京燃气 咨询&#xff1a;96777 用户&am…

考研/计算机二级数据结构刷题之顺序表

目录 第一题 顺序表的初始化&#xff0c;销毁&#xff0c;头插&#xff0c;尾插&#xff0c;头删&#xff0c;尾删&#xff0c;指定位置插入&#xff0c;指定删除以及打印 第二题 移除元素 题目链接&#xff1a; OJ链接 题目详解&#xff1a;移除元素 第三题&#xff1a;删…

ONLYOFFICE 8.0 测评:重塑办公新标杆,你绝对不能错过的版本!

ONLYOFFICE 8.0 测评&#xff1a;办公新境界的全新突破 一、全新的界面设计二、可填写的 PDF 表单 免费表单模板三、双向文本四、电子表格中的新增功能五、协作功能升级六、跨平台性能优化七、强化安全性八、更丰富的插件生态九、辅助功能&#xff1a;优化的屏幕朗读器 随着科…

华为数通方向HCIP-DataCom H12-821题库(单选题:421-440)

第421题 以下关于IS-IS中路由器分类的描述,错误的是哪一项? A、Level-1路由器无法与Level-2路由器建立邻接关系 B、华为路由器上配置IS-IS时,缺省时,路由器全局Level为Level-1-2 C、Level-2的LSDB只包含Level-2路由器所在区域的路由信息 D、Level-1路由器可以和Level-1-2路…

c语言--二进制和其他进制之间的转换

目录 一、前言二、二进制、十进制、十六进制、八进制的组成2.1二进制的组成2.2十进制的组成2.3八进制的组成2.4十六进制的组成 三、二进制转换为十进制3.1 二进制转换为十进制3.2十进制转换为二进制 四、二进制转八进制和十六进制4.1二进制转八进制4.2二进制转换为十六进制 五、…

[c++]多态的原理

引言 OOP的核心思想是多态性。多态性这个词源自希腊语&#xff0c;其含义是“多种形式”。我们把具有继承关系的多个类型称为多态类型&#xff0c;因为我们能使用这些类型的“多种形式”而无须在意它们的差异。引用或指针的静态类型与动态类型不同这一事实正是C语言支持多态性的…

ios搭建OpenGL环境

前言 本篇文章介绍在ios搭建OpenGL开发环境 在app的启动文章中&#xff0c;讲述了一个ios应用是如何启动的以及在IOS 13之后苹果公司推出的多窗口功能&#xff0c;通过app的启动这篇文章&#xff0c;我们基本能随心所欲的搭建一个app应用环境&#xff0c;搭建完成后的基本文件…

基于Python的深度学习的身份证识别考勤系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Text Mesh Pro图文混排如何对任何图片都能实现

1&#xff09;Text Mesh Pro图文混排如何对任何图片都能实现 2&#xff09;Unity iOS平台的小图占用特别大的内存 3&#xff09;只在编辑器内&#xff0c;纹理不开启Read&Write情况下&#xff0c;如何获取纹理所有颜色值 4&#xff09;准备在海外发行游戏&#xff0c;有哪些…

【3DGS】从新视角合成到3D Gaussian Splatting

文章目录 引言&#xff1a;什么是新视角合成任务定义一般步骤NeRF的做法NeRF的三维重建NeRF的渲染 3DGS的三维重建从一组图片估计点云高斯点云模型球谐函数参数优化损失函数和协方差矩阵的优化高斯点的数量控制(Adaptive Density Control)新的问题 3DGS的渲染&#xff1a;快速可…