怎样做动漫照片下载网站,企业网站多大空间,seo链接优化建议,百度商桥代码后网站上怎么不显示前言
在 R3 下防护动态加载的模块不被意外卸载需要很多的策略#xff0c;比如#xff1a;LDR 断链、VAD 记录擦除、PE 头擦除、修改入口函数、内存注入等。文本我们将浅析模块静态化技术这一项技术。模块静态化是一个很常见的模块保护技术#xff0c;它通过修改模块的引用计…前言
在 R3 下防护动态加载的模块不被意外卸载需要很多的策略比如LDR 断链、VAD 记录擦除、PE 头擦除、修改入口函数、内存注入等。文本我们将浅析模块静态化技术这一项技术。模块静态化是一个很常见的模块保护技术它通过修改模块的引用计数为 -1来使得模块不可被标准的 API 成功卸载。
系列文章
R3 下动态加载的模块的保护一分析模块伪静态化技术 [本文]R3 下动态加载的模块的保护二分析重映射擦除 VAD 信息[暂未发布]更多 ... ... 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 下哪种工具只需要在加载了模块的进程内修改即可。
本文参考文献 1The covert way to find the Reference Count of DLL - www.SecurityXploded.com 2Make 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(LEr:Exception occurred while accessing memory.\n);return FALSE;}return bResponse;
}
这样我们只需要在模块初始化和脱钩时调用该函数就可以在进程中简单地保护/脱保护钩子模块。
总结后记
文本浅析模块静态化技术这一项技术。是一种有效的实践。 发布于2024.02.03更新于2024.02.03