From 5f05f4dd3ac9ade357d24738beaa2c7415aa7fd3 Mon Sep 17 00:00:00 2001 From: Demon-Gan-123 <739488ASdiausdnasin-=++48404@qq.com> Date: Tue, 19 Oct 2021 09:21:39 +0800 Subject: [PATCH] Initial commit --- README.md | 331 +++++++++++++++++- src/GetSSDTFunctionIndex_Test.sln | 64 ++++ src/GetSSDTFunctionIndex_Test.v12.suo | Bin 0 -> 33792 bytes src/GetSSDTFunctionIndex_Test/Driver.c | 41 +++ src/GetSSDTFunctionIndex_Test/Driver.h | 12 + .../GetSSDTFunctionIndex_Test.inf | 32 ++ .../GetSSDTFunctionIndex_Test.vcxproj | 261 ++++++++++++++ .../GetSSDTFunctionIndex_Test.vcxproj.filters | 42 +++ .../GetSSDTFunctionIndex_Test.vcxproj.user | 15 + .../SSDTFunctionIndex.c | 116 ++++++ .../SSDTFunctionIndex.h | 19 + src/Win7Debug/GetSSDTFunctionIndex_Test.sys | Bin 0 -> 4608 bytes .../Win8.1Debug/GetSSDTFunctionIndex_Test.sys | Bin 0 -> 6144 bytes 13 files changed, 931 insertions(+), 2 deletions(-) create mode 100644 src/GetSSDTFunctionIndex_Test.sln create mode 100644 src/GetSSDTFunctionIndex_Test.v12.suo create mode 100644 src/GetSSDTFunctionIndex_Test/Driver.c create mode 100644 src/GetSSDTFunctionIndex_Test/Driver.h create mode 100644 src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.inf create mode 100644 src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj create mode 100644 src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.filters create mode 100644 src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.user create mode 100644 src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.c create mode 100644 src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.h create mode 100644 src/Win7Debug/GetSSDTFunctionIndex_Test.sys create mode 100644 src/x64/Win8.1Debug/GetSSDTFunctionIndex_Test.sys diff --git a/README.md b/README.md index 16be916..eafb024 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,330 @@ -# Get-SSDT-Function-Index +# 内核内存映射文件之获取SSDT函数索引号 -内核内存映射文件之获取SSDT函数索引号 \ No newline at end of file +# 背景 + +很多时候,内核下的开发和用户层上的程序开发使用到的技术原理都是相同的,所以,我们可以通过类比学习,快速地对内核开发进行理解与熟悉。 + +正如本文讲解的内存映射文件技术,用户层上有专门的 WIN32 API 提供给我们开发使用。对于内核上,也有相对应的内核函数给我们调用,实现内存映射文件,把磁盘上的文件映射到内核内存空间中来。 + +本文要实现的就是使用内存映射文件技术,将磁盘上的 ntdll.dll 文件映射到内核内存空间中,并从导出表中获取导出函数地址,然后获取 SSDT 函数索引号。所以,这篇文章除了要对内存映射文件技术比较了解之外,还需要对 PE 结构也有一定得了解,否则很难理解透彻这篇文章。现在,我就把实现过程整理成文档,分享给大家。 + +# 函数介绍 + +## ZwOpenFile 函数 + +> 打开现有文件,目录,设备或卷。 +> +> 函数声明 +> +> ```c++ +> NTSTATUS ZwOpenFile( +> _Out_ PHANDLE FileHandle, +> _In_ ACCESS_MASK DesiredAccess, +> _In_ POBJECT_ATTRIBUTES ObjectAttributes, +> _Out_ PIO_STATUS_BLOCK IoStatusBlock, +> _In_ ULONG ShareAccess, +> _In_ ULONG OpenOptions +> ); +> ``` +> +> 参数 +> +> - FileHandle [out] +> 指向接收文件句柄的HANDLE变量的指针。 +> - DesiredAccess [in] +> 指定一个ACCESS_MASK值,用于确定请求的对象访问。有关详细信息,请参阅ZwCreateFile的DesiredAccess参数。其中,GENERIC_READ 包括权限有 STANDARD_RIGHTS_READ、FILE_READ_DATA、FILE_READ_ATTRIBUTES、FILE_READ_EA、以及 SYNCHRONIZE。 +> - ObjectAttributes [in] +> 指向OBJECT_ATTRIBUTES结构的指针,指定对象名称和其他属性。使用InitializeObjectAttributes初始化此结构。如果调用者未在系统线程上下文中运行,则调用InitializeObjectAttributes时必须设置OBJ_KERNEL_HANDLE属性。 +> - IoStatusBlock [out] +> 指向接收最终完成状态的IO_STATUS_BLOCK结构的指针以及有关所请求操作的信息。 +> - ShareAccess [in] +> 指定文件的共享访问类型。有关详细信息,请参阅ZwCreateFile的ShareAccess参数。其中,FILE_SHARE_READ 表示允许其它线程读此文件;FILE_SHARE_WRITE 表示允许其它线程写此文件。 +> - OpenOptions [in] +> 指定打开文件时要应用的选项。有关更多信息,请参阅ZwCreateFile的CreateOptions参数。其中,FILE_SYNCHRONOUS_IO_ALERT 表示文件中的所有操作都是同步执行的。 代表呼叫者的任何等待都会从提醒中提前终止。 该标志还使I / O系统保持文件位置指针。 如果设置此标志,则必须在DesiredAccess参数中设置SYNCHRONIZE标志。 +> +> 返回值 +> +> - 成功,则返回 STATUS_SUCCESS;否则,返回其它 NTSTATUS 错误码。 + +## ZwCreateSection 函数 + +> 创建一个节对象。 +> +> 函数声明 +> +> ```c++ +> NTSTATUS ZwCreateSection( +> _Out_ PHANDLE SectionHandle, +> _In_ ACCESS_MASK DesiredAccess, +> _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, +> _In_opt_ PLARGE_INTEGER MaximumSize, +> _In_ ULONG SectionPageProtection, +> _In_ ULONG AllocationAttributes, +> _In_opt_ HANDLE FileHandle +> ); +> ``` +> +> 参数 +> +> - SectionHandle [out] +> 指向接收段对象的句柄的HANDLE变量的指针。 +> +> - DesiredAccess [in] +> 指定一个ACCESS_MASK值,用于确定请求的对象访问。除了为所有类型的对象定义的访问权限(请参阅ACCESS_MASK)之外,调用者可以指定以下任何访问权限,这些访问权限特定于部分对象: +> DesiredAccess标志允许调用者执行此操作 +> SECTION_EXTEND_SIZE:动态扩展部分的大小。 +> SECTION_MAP_EXECUTE:执行该部分的视图。 +> SECTION_MAP_READ:读取该部分的视图。 +> SECTION_MAP_WRITE:编写该部分的视图。 +> SECTION_QUERY:查询节对象有关该部分的信息。驱动应该设置这个标志。 +> SECTION_ALL_ACCESS:包括上面所有的标志之外,还包括STANDARD_RIGHTS_REQUIRED。 +> +> - ObjectAttributes [in,可选] +> 指向OBJECT_ATTRIBUTES结构的指针,指定对象名称和其他属性。使用InitializeObjectAttributes初始化此结构。如果调用者未在系统线程上下文中运行,则调用InitializeObjectAttributes时必须设置OBJ_KERNEL_HANDLE属性。 +> +> - MaximumSize [in,可选] +> 指定部分的最大大小(以字节为单位)。 ZwCreateSection将此值转换为PAGE_SIZE的最接近的倍数。如果该部分由分页文件支持,则MaximumSize将指定该部分的实际大小。如果该部分由普通文件支持,则MaximumSize指定文件可以扩展或映射到的最大大小。 +> +> - SectionPageProtection [in] +> 指定在该部分的每个页面上放置的保护。使用以下四个值之一:PAGE_READONLY,PAGE_READWRITE,PAGE_EXECUTE或PAGE_WRITECOPY。有关这些值的说明,请参阅CreateFileMapping。其中,PAGE_READWRITE 表示允许将视图映射为只读、写时复制、读/写访问。必须使用 GENERIC_READ 和 GENERIC_WRITE 访问权限创建 hFile 参数指定的文件句柄。 +> +> - AllocationAttributes[in] +> 指定SEC_XXX标志的位掩码,以确定该部分的分配属性。有关这些标志的描述,请参阅CreateFileMapping。其中, +> SEC_COMMIT 是以 PE 结构中的 FileAlignment 大小对齐映射文件。 +> SEC_IMAGE 是以 PE 结构中的 SectionALignment 大小对齐映射文件。 +> +> - FileHandle [in,可选] +> 可选地指定打开的文件对象的句柄。如果FileHandle的值为NULL,则该段由分页文件支持。否则,该部分由指定的文件支持。 +> +> 返回值 +> +> - 成功,则返回 STATUS_SUCCESS;否则,返回其它 NTSTATUS 错误码。 + +## ZwMapViewOfSection 函数 + +> 将一个节表的视图映射到内核的虚拟地址空间。 +> +> 函数声明 +> +> ```c++ +> NTSTATUS ZwMapViewOfSection( +> _In_ HANDLE SectionHandle, +> _In_ HANDLE ProcessHandle, +> _Inout_ PVOID *BaseAddress, +> _In_ ULONG_PTR ZeroBits, +> _In_ SIZE_T CommitSize, +> _Inout_opt_ PLARGE_INTEGER SectionOffset, +> _Inout_ PSIZE_T ViewSize, +> _In_ SECTION_INHERIT InheritDisposition, +> _In_ ULONG AllocationType, +> _In_ ULONG Win32Protect +> ); +> ``` +> +> 参数 +> +> - SectionHandle [in] +> 节对象的句柄。该句柄是通过成功调用ZwCreateSection或ZwOpenSection创建的。 +> - ProcessHandle [in] +> 处理表示视图应该映射到进程的对象。使用ZwCurrentProcess宏来指定当前进程。必须使用PROCESS_VM_OPERATION访问(在Microsoft Windows SDK文档中描述)打开句柄。 +> - BaseAddress [in,out] +> 指向接收视图基地址的变量的指针。如果此参数的值不为NULL,则会从指定的虚拟地址开始分配视图,向下舍入到下一个64K字节的地址边界。 +> - ZeroBits[in] +> 指定截面视图基地址中必须为零的高位地址位数。此参数的值必须小于21,仅当BaseAddress为NULL时才使用 - 换句话说,当调用者允许系统确定在哪里分配视图时。 +> - CommitSize [in] +> 指定视图初始提交的区域的大小(以字节为单位)。 CommitSize仅对页面文件支持的部分有意义,并且四舍五入为PAGE_SIZE的最接近的倍数。 (对于映射文件的部分,数据和图像都将在段创建时提交。) +> - SectionOffset [in,out,optional] +> 指向变量的指针,该变量从字节开始到视图接收以字节为单位的偏移量。如果此指针不为NULL,则向左舍入到下一个分配粒度大小边界。 +> - ViewSize [in,out] +> 指向SIZE_T变量的指针。如果此变量的初始值为零,则ZwMapViewOfSection将在SectionOffset中开始的部分的视图映射到该部分的末尾。否则,初始值指定视图的大小(以字节为单位)。在映射视图之前,ZwMapViewOfSection始终将此值舍入到最接近PAGE_SIZE的倍数。 +> 返回时,该值接收视图的实际大小(以字节为单位)。 +> - InheritDisposition [in] +> 指定视图如何与子进程共享。可能的值是: +> ViewShare +> 该视图将映射到将来创建的任何子进程。 +> ViewUnmap +> 该视图将不会映射到子进程。 +> 驱动程序通常应为此参数指定ViewUnmap。 +> - AllocationType[in] +> 指定一组描述要为指定的页面区域执行的分配类型的标志。有效标志是MEM_LARGE_PAGES,MEM_RESERVE和MEM_TOP_DOWN。虽然不允许MEM_COMMIT,但是除非指定了MEM_RESERVE,否则是默认的。有关MEM_XXX标志的更多信息,请参阅VirtualAlloc例程的说明。MEM_TOP_DOWN 表示在尽可能高的地址分配内存。 +> - Win32Protect [in] +> 指定最初提交的页面区域的保护类型。设备和中间驱动程序应将此值设置为PAGE_READWRITE。 +> +> 返回值 +> +> - 成功,则返回 STATUS_SUCCESS;否则,返回其它 NTSTATUS 错误码。 + +# 实现原理 + +使用WIN32 API来实现内存映射文件,实现步骤如下: + +- 调用 CreatFile 打开想要映射的文件,获得句柄hFile。 + +- 调用 CreatFileMapping 函数生成一个建立在CreatFile函数创建的文件对象基础上的内存映射对象,得到句柄hFileMap。 + +- 调用 MapViewOfFile 函数把整个文件的一个区域或者整个区域映射到内存中,得到指向映射到内存的第一个字节的指针 lpMemory。 + +- 用该指针来读写文件。 + +- 调用 UnmapViewOfFile 来解除文件映射,传入参数为 lpMemory。 + +- 调用 CloseHandle 来关闭内存映射文件,传入参数为 hFileMap。 + +- 调用 CloseHandle 来关闭文件,传入函数为 hFile。 + +那么,在内核下的内存映射文件的实现步骤和用户层的也相同,只是使用的函数不相同而已: + +- 调用 ZwOpenFile 打开想要映射的文件,获得句柄 hFile。 + +- 调用 ZwCreatSection 函数生成一个建立在 ZwOpenFile 函数创建的文件对象基础上的内存映射对象,得到句柄 hSection。 + +- 调用 ZwMapViewOfSection 函数把整个文件的一个区域或者整个区域映射到内存中,得到指向映射到内存的第一个字节的指针 lpMemory。 + +- 用该指针来读写文件。 + +- 调用 ZwUnmapViewOfSection 来解除文件映射,传入参数为进程句柄以及 lpMemory。 + +- 调用 ZwClose 来关闭内存映射文件,传入参数为 hSection。 + +- 调用 ZwClose 来关闭文件,传入函数为 hFile。 + +其中,我们从导入表获取指定导出函数的导出地址的实现流程是: + +- 首先,将文件映射到内核内存后,我们便可以获取文件的映射基址。我们根据 PE 文结构体 IMAGE_DOS_HEADER 和 IMAGE_NT_HEADERS 计算出 OptionahlHeader,接着获取 DataDirectory 中的导出表 RVA 地址。这样,我们可以计算出导出表在内存中的地址。 + +- 然后,我们根据导出表结构 IMAGE_EXPORT_DIRECTORY 获取导出函数名称的个数以及导出函数名称的地址,以此遍历匹配是否是要查找的函数名称。若是,则从 AddressOfNamesOrdinal 中获取导出函数名称对应的导出函数索引值。有了这个导出函数索引值,我们直接就可以在 AddressOfFunctions 导出函数地址表中获取导出函数的地址。 + +- 最后,我们就可以根据 ntdll.dll 导出函数的地址,来获取 SSDT 函数索引号。 + + 其中,对于 32 位系统,ntdll.dll 导出函数总是以下面代码形式为开头: + + ```c++ + mov eax, 函数索引号(4字节) + ``` + + 对于 64 位系统,ntdll.dll 导出函数总是以下面代码形式为开头: + + ```c++ + mov r10, rcx + mov eax, 函数索引号(4字节) + ``` + + 所以,我们对于 32 位系统,只需对导出函数偏移 1 字节处获取 4 字节的数据,那么这 4 字节的数据就是 SSDT 函数索引号;对于 64 位系统,在导出函数的偏移为 4 字节,也是获取 4 字节数据,这 4 字节的数据就是 SSDT 函数索引号。 + +# 编码实现 + +## 内存映射文件 + +```c++ +// 内存映射文件 +NTSTATUS DllFileMap(UNICODE_STRING ustrDllFileName, HANDLE *phFile, HANDLE *phSection, PVOID *ppBaseAddress) +{ + NTSTATUS status = STATUS_SUCCESS; + HANDLE hFile = NULL; + HANDLE hSection = NULL; + OBJECT_ATTRIBUTES objectAttributes = { 0 }; + IO_STATUS_BLOCK iosb = { 0 }; + PVOID pBaseAddress = NULL; + SIZE_T viewSize = 0; + // 打开 DLL 文件, 并获取文件句柄 + InitializeObjectAttributes(&objectAttributes, &ustrDllFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); + status = ZwOpenFile(&hFile, GENERIC_READ, &objectAttributes, &iosb, + FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(status)) + { + KdPrint(("ZwOpenFile Error! [error code: 0x%X]", status)); + return status; + } + // 创建一个节对象, 以 PE 结构中的 SectionALignment 大小对齐映射文件 + status = ZwCreateSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, 0, PAGE_READWRITE, 0x1000000, hFile); + if (!NT_SUCCESS(status)) + { + ZwClose(hFile); + KdPrint(("ZwCreateSection Error! [error code: 0x%X]", status)); + return status; + } + // 映射到内存 + status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &pBaseAddress, 0, 1024, 0, &viewSize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE); + if (!NT_SUCCESS(status)) + { + ZwClose(hSection); + ZwClose(hFile); + KdPrint(("ZwMapViewOfSection Error! [error code: 0x%X]", status)); + return status; + } + + // 返回数据 + *phFile = hFile; + *phSection = hSection; + *ppBaseAddress = pBaseAddress; + + return status; +} +``` + +## 根据导出表获取导出函数地址及获取SSDT函数索引号 + +```c++ +// 根据导出表获取导出函数地址, 从而获取 SSDT 函数索引号 +ULONG GetIndexFromExportTable(PVOID pBaseAddress, PCHAR pszFunctionName) +{ + ULONG ulFunctionIndex = 0; + // Dos Header + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress; + // NT Header + PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew); + // Export Table + PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress); + // 有名称的导出函数个数 + ULONG ulNumberOfNames = pExportTable->NumberOfNames; + // 导出函数名称地址表 + PULONG lpNameArray = (PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfNames); + PCHAR lpName = NULL; + // 开始遍历导出表 + for (ULONG i = 0; i < ulNumberOfNames; i++) + { + lpName = (PCHAR)((PUCHAR)pDosHeader + lpNameArray[i]); + // 判断是否查找的函数 + if (0 == _strnicmp(pszFunctionName, lpName, strlen(pszFunctionName))) + { + // 获取导出函数地址 + USHORT uHint = *(USHORT *)((PUCHAR)pDosHeader + pExportTable->AddressOfNameOrdinals + 2 * i); + ULONG ulFuncAddr = *(PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfFunctions + 4 * uHint); + PVOID lpFuncAddr = (PVOID)((PUCHAR)pDosHeader + ulFuncAddr); + // 获取 SSDT 函数 Index +# ifdef _WIN64 + ulFunctionIndex = *(ULONG *)((PUCHAR)lpFuncAddr + 4); +# else + ulFunctionIndex = *(ULONG *)((PUCHAR)lpFuncAddr + 1); +# endif + break; + } + } + + return ulFunctionIndex; +} +``` + +# 程序测试 + +在 Win7 32 位系统下,驱动程序执行正常: + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/16a4b1d5fb35885f4e7b7c2bb9ee876f.writebug) + +在 Win10 64 位系统下,驱动程序执行正常: + +![](http://www.write-bug.com/myres/static/uploads/2021/10/19/9b672566cc4661b4f9afb5c29d62c309.writebug) + +# 总结 + +其中,我们要注意 3 个地方: + +一是,在调用 ZwCreateSection 函数的时候,第 6 个参数我们要设置为SEC_IMAGE,表示以 PE 结构中的 SectionALignment 大小对齐映射文件。这样映射到内存后,我们就可以直接从导出表中较为方便地获取 SSDT 函数索引值。 + +二是,SSDT 函数索引号在 32 位系统下和 64 位系统下,在 ntdll.dll 的导出函数中的偏移是不同的。32 位系统中,SSDT 函数索引号在 ntdll.dll 导出函数偏移 1 字节处;64 位系统中,SSDT 函数索引号在 ntdll.dll 导出函数偏移 4 字节处。 + +三是,内核下表示的文件或者目录路径要在路径前面加上 \\??\\,例如表示 C 盘下的 ntdll.dll文件路径:\\??\\C:\\Windows\\System32\\ntdll.dll。 + +# 参考 + +参考自《[Windows黑客编程技术详解](https://www.write-bug.com/article/1811.html "Windows黑客编程技术详解")》一书 \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test.sln b/src/GetSSDTFunctionIndex_Test.sln new file mode 100644 index 0000000..99f2e68 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test.sln @@ -0,0 +1,64 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GetSSDTFunctionIndex_Test", "GetSSDTFunctionIndex_Test\GetSSDTFunctionIndex_Test.vcxproj", "{21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Win7 Debug|Win32 = Win7 Debug|Win32 + Win7 Debug|x64 = Win7 Debug|x64 + Win7 Release|Win32 = Win7 Release|Win32 + Win7 Release|x64 = Win7 Release|x64 + Win8 Debug|Win32 = Win8 Debug|Win32 + Win8 Debug|x64 = Win8 Debug|x64 + Win8 Release|Win32 = Win8 Release|Win32 + Win8 Release|x64 = Win8 Release|x64 + Win8.1 Debug|Win32 = Win8.1 Debug|Win32 + Win8.1 Debug|x64 = Win8.1 Debug|x64 + Win8.1 Release|Win32 = Win8.1 Release|Win32 + Win8.1 Release|x64 = Win8.1 Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Release|x64.Build.0 = Win7 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Release|x64.Build.0 = Win8 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Debug|Win32.ActiveCfg = Win8.1 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Debug|Win32.Build.0 = Win8.1 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Debug|Win32.Deploy.0 = Win8.1 Debug|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Debug|x64.ActiveCfg = Win8.1 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Debug|x64.Build.0 = Win8.1 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Debug|x64.Deploy.0 = Win8.1 Debug|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Release|Win32.ActiveCfg = Win8.1 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Release|Win32.Build.0 = Win8.1 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Release|Win32.Deploy.0 = Win8.1 Release|Win32 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Release|x64.ActiveCfg = Win8.1 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Release|x64.Build.0 = Win8.1 Release|x64 + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E}.Win8.1 Release|x64.Deploy.0 = Win8.1 Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/GetSSDTFunctionIndex_Test.v12.suo b/src/GetSSDTFunctionIndex_Test.v12.suo new file mode 100644 index 0000000000000000000000000000000000000000..80251ce065cd5eb403dd0dc9e2739e7d0fd79666 GIT binary patch literal 33792 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⩔$hj^7EUB@v2Wel z9+u;=M65Sy-4c$5VmlMo&R8sx;MIDs&nj56Zp2nl$U|IrD9L0v+Lu^aCt@a#`EA>{ zr}3HHVep=q)13(4rqp(0cM*yN_2-%(%Uicm=(V+TNkxRS)C*B9v#*~Z4N_neo8*wa z{&SMEuV#0WOCXn>SPsio`%l;NN{RgR4?Y|<%Yt{bC H*SG!;XYsYC literal 0 HcmV?d00001 diff --git a/src/GetSSDTFunctionIndex_Test/Driver.c b/src/GetSSDTFunctionIndex_Test/Driver.c new file mode 100644 index 0000000..4a0d25c --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/Driver.c @@ -0,0 +1,41 @@ +#include "Driver.h" +#include "SSDTFunctionIndex.h" + + +NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) +{ + DbgPrint("Enter DriverEntry\n"); + + NTSTATUS status = STATUS_SUCCESS; + pDriverObject->DriverUnload = DriverUnload; + for (ULONG i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + { + pDriverObject->MajorFunction[i] = DriverDefaultHandle; + } + + // ntdll.dll лȡ SSDT + UNICODE_STRING ustrDllFileName; + RtlInitUnicodeString(&ustrDllFileName, L"\\??\\C:\\Windows\\System32\\ntdll.dll"); + ULONG ulSSDTFunctionIndex = GetSSDTFunctionIndex(ustrDllFileName, "ZwOpenProcess"); + DbgPrint("ZwOpenProcess[%d]\n", ulSSDTFunctionIndex); + + DbgPrint("Leave DriverEntry\n"); + return status; +} + + + +VOID DriverUnload(PDRIVER_OBJECT pDriverObject) +{ +} + + +NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp) +{ + NTSTATUS status = STATUS_SUCCESS; + pIrp->IoStatus.Status = status; + pIrp->IoStatus.Information = 0; + IoCompleteRequest(pIrp, IO_NO_INCREMENT); + + return status; +} \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test/Driver.h b/src/GetSSDTFunctionIndex_Test/Driver.h new file mode 100644 index 0000000..0822089 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/Driver.h @@ -0,0 +1,12 @@ +#ifndef _DRIVER_H_ +#define _DRIVER_H_ + + +#include + + +VOID DriverUnload(PDRIVER_OBJECT pDriverObject); +NTSTATUS DriverDefaultHandle(PDEVICE_OBJECT pDevObj, PIRP pIrp); + + +#endif \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.inf b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.inf new file mode 100644 index 0000000..2ce4c80 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.inf @@ -0,0 +1,32 @@ +; +; GetSSDTFunctionIndex_Test.inf +; + +[Version] +Signature="$WINDOWS NT$" +Class= +ClassGuid= +Provider= +DriverVer= +CatalogFile= + +[DestinationDirs] +DefaultDestDir = 12 + + +[SourceDisksNames] +1 = %DiskName%,,,"" + +[SourceDisksFiles] + + +[Manufacturer] +%ManufacturerName%=Standard,NT$ARCH$ + +[Standard.NT$ARCH$] + + +[Strings] +ManufacturerName="" +ClassName="" +DiskName="GetSSDTFunctionIndex_Test Source Disk" diff --git a/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj new file mode 100644 index 0000000..e5a9dd5 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj @@ -0,0 +1,261 @@ + + + + + Win8.1 Debug + Win32 + + + Win8.1 Release + Win32 + + + Win8 Debug + Win32 + + + Win8 Release + Win32 + + + Win7 Debug + Win32 + + + Win7 Release + Win32 + + + Win8.1 Debug + x64 + + + Win8.1 Release + x64 + + + Win8 Debug + x64 + + + Win8 Release + x64 + + + Win7 Debug + x64 + + + Win7 Release + x64 + + + + {21BDE8C9-BD4A-4CB5-AB6D-91F5FE89FA1E} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 11.0 + Win8.1 Debug + Win32 + GetSSDTFunctionIndex_Test + + + + WindowsV6.3 + true + WindowsKernelModeDriver8.1 + Driver + WDM + + + WindowsV6.3 + false + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows8 + true + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows8 + false + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows7 + true + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows7 + false + WindowsKernelModeDriver8.1 + Driver + WDM + + + WindowsV6.3 + true + WindowsKernelModeDriver8.1 + Driver + WDM + + + WindowsV6.3 + false + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows8 + true + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows8 + false + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows7 + true + WindowsKernelModeDriver8.1 + Driver + WDM + + + Windows7 + false + WindowsKernelModeDriver8.1 + Driver + WDM + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + + Level3 + + + + + false + + + false + + + + + Level3 + + + + + false + + + false + + + + + Level3 + + + + + false + + + false + + + + + Level3 + + + + + false + + + false + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.filters b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.filters new file mode 100644 index 0000000..baac145 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.filters @@ -0,0 +1,42 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Driver Files + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.user b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.user new file mode 100644 index 0000000..14e421f --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/GetSSDTFunctionIndex_Test.vcxproj.user @@ -0,0 +1,15 @@ + + + + Off + + + Off + + + Off + + + Off + + \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.c b/src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.c new file mode 100644 index 0000000..d320925 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.c @@ -0,0 +1,116 @@ +#include "SSDTFunctionIndex.h" + + +// ntdll.dll лȡ SSDT +ULONG GetSSDTFunctionIndex(UNICODE_STRING ustrDllFileName, PCHAR pszFunctionName) +{ + ULONG ulFunctionIndex = 0; + NTSTATUS status = STATUS_SUCCESS; + HANDLE hFile = NULL; + HANDLE hSection = NULL; + PVOID pBaseAddress = NULL; + + // ڴӳļ + status = DllFileMap(ustrDllFileName, &hFile, &hSection, &pBaseAddress); + if (!NT_SUCCESS(status)) + { + KdPrint(("DllFileMap Error!\n")); + return ulFunctionIndex; + } + + // ݵȡַ, Ӷȡ SSDT + ulFunctionIndex = GetIndexFromExportTable(pBaseAddress, pszFunctionName); + + // ͷ + ZwUnmapViewOfSection(NtCurrentProcess(), pBaseAddress); + ZwClose(hSection); + ZwClose(hFile); + + return ulFunctionIndex; +} + + +// ڴӳļ +NTSTATUS DllFileMap(UNICODE_STRING ustrDllFileName, HANDLE *phFile, HANDLE *phSection, PVOID *ppBaseAddress) +{ + NTSTATUS status = STATUS_SUCCESS; + HANDLE hFile = NULL; + HANDLE hSection = NULL; + OBJECT_ATTRIBUTES objectAttributes = { 0 }; + IO_STATUS_BLOCK iosb = { 0 }; + PVOID pBaseAddress = NULL; + SIZE_T viewSize = 0; + // DLL ļ, ȡļ + InitializeObjectAttributes(&objectAttributes, &ustrDllFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); + status = ZwOpenFile(&hFile, GENERIC_READ, &objectAttributes, &iosb, + FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(status)) + { + KdPrint(("ZwOpenFile Error! [error code: 0x%X]", status)); + return status; + } + // һڶ, PE ṹе SectionALignment Сӳļ + status = ZwCreateSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE, NULL, 0, PAGE_READWRITE, 0x1000000, hFile); + if (!NT_SUCCESS(status)) + { + ZwClose(hFile); + KdPrint(("ZwCreateSection Error! [error code: 0x%X]", status)); + return status; + } + // ӳ䵽ڴ + status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &pBaseAddress, 0, 1024, 0, &viewSize, ViewShare, MEM_TOP_DOWN, PAGE_READWRITE); + if (!NT_SUCCESS(status)) + { + ZwClose(hSection); + ZwClose(hFile); + KdPrint(("ZwMapViewOfSection Error! [error code: 0x%X]", status)); + return status; + } + + // + *phFile = hFile; + *phSection = hSection; + *ppBaseAddress = pBaseAddress; + + return status; +} + + +// ݵȡַ, Ӷȡ SSDT +ULONG GetIndexFromExportTable(PVOID pBaseAddress, PCHAR pszFunctionName) +{ + ULONG ulFunctionIndex = 0; + // Dos Header + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress; + // NT Header + PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)((PUCHAR)pDosHeader + pDosHeader->e_lfanew); + // Export Table + PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)((PUCHAR)pDosHeader + pNtHeaders->OptionalHeader.DataDirectory[0].VirtualAddress); + // Ƶĵ + ULONG ulNumberOfNames = pExportTable->NumberOfNames; + // Ƶַ + PULONG lpNameArray = (PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfNames); + PCHAR lpName = NULL; + // ʼ + for (ULONG i = 0; i < ulNumberOfNames; i++) + { + lpName = (PCHAR)((PUCHAR)pDosHeader + lpNameArray[i]); + // жǷҵĺ + if (0 == _strnicmp(pszFunctionName, lpName, strlen(pszFunctionName))) + { + // ȡַ + USHORT uHint = *(USHORT *)((PUCHAR)pDosHeader + pExportTable->AddressOfNameOrdinals + 2 * i); + ULONG ulFuncAddr = *(PULONG)((PUCHAR)pDosHeader + pExportTable->AddressOfFunctions + 4 * uHint); + PVOID lpFuncAddr = (PVOID)((PUCHAR)pDosHeader + ulFuncAddr); + // ȡ SSDT Index +#ifdef _WIN64 + ulFunctionIndex = *(ULONG *)((PUCHAR)lpFuncAddr + 4); +#else + ulFunctionIndex = *(ULONG *)((PUCHAR)lpFuncAddr + 1); +#endif + break; + } + } + + return ulFunctionIndex; +} \ No newline at end of file diff --git a/src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.h b/src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.h new file mode 100644 index 0000000..6cbadc7 --- /dev/null +++ b/src/GetSSDTFunctionIndex_Test/SSDTFunctionIndex.h @@ -0,0 +1,19 @@ +#ifndef _SSDT_FUNCTION_INDEX_H_ +#define _SSDT_FUNCTION_INDEX_H_ + + +#include +#include + + +// ntdll.dll лȡ SSDT +ULONG GetSSDTFunctionIndex(UNICODE_STRING ustrDllFileName, PCHAR pszFunctionName); + +// ڴӳļ +NTSTATUS DllFileMap(UNICODE_STRING ustrDllFileName, HANDLE *phFile, HANDLE *phSection, PVOID *ppBaseAddress); + +// ݵȡַ, Ӷȡ SSDT +ULONG GetIndexFromExportTable(PVOID pBaseAddress, PCHAR pszFunctionName); + + +#endif \ No newline at end of file diff --git a/src/Win7Debug/GetSSDTFunctionIndex_Test.sys b/src/Win7Debug/GetSSDTFunctionIndex_Test.sys new file mode 100644 index 0000000000000000000000000000000000000000..21eed41f84fe9684c3ac8bfc420c1ee757498a60 GIT binary patch literal 4608 zcmeGfZEO@(aIU?=wH{ElH6=8fV+X zLj}1|UDgv!Oh_7HqWDYypuvdv!%`Zq=#eynq(2%{O*Kb)A(vQVW2)=Cy(_(505vAY zCd_7bKHj`}^XAQaZGG_*oD<_F86B5c~kw>l17g= z$n?m8PPwIuXGc<_u z;I;ChH<30p`VCsWVcSp`UZvP=({tN<3& ztVn4&r1^*pBAq4WvuJa63Qe>DU_T-zg*gmh0xrieq_(t!L2nbPgnAC(34^=K%K_lV zCYAvxzKaP}d$66OObX1*z5Uu0v0p*k8jR40i_ViSW*RW))+V>NC@nNc*nkQ;XUIcL z0}i0pmNYX`1}rvGJ4|6ZZ~$XLEz$&QWSdc>72jyQRWGzM9JbDDKQ@n8Ai4yw ze<)tyDJ|e2b{P+n(5N{=W|QtL5w2<~pM#YDnOt-qx@c1IJuts6n6C-*8nHy|CpQ6F z&3y0KgkHjY+^H9uaYWA{6g45yppm#Eb}b7)C36}-=ky$>qwO(9vv}U6!i&kFH8PtK zB*xb~VqOf|h_@;gQH0FVNK*kvNR&#I!zvk9$#s=XsAN(lQxP(4=&z`JEJ6~LkC1qh zM2ie*JSk0Z7-U$msKWIKnM~@YDDg2qQ5Mr!hzeSpu3urQ0Ai_Sp6@H#3UQ zjKk&wMj^x-eBhx+gb%_b;qd7iKZ_Y>(%e0%86z0(mO6f<5FLMqdp;T8%sNfT$FbEc zjW57X>Vq07()ff*gQqJ|u$cK|*%$lwmopk;HM!8@wJO3Dc1Q9eQtJ(^JB@DnvCBb!hyw6SqP`jFxj~ z)Ou{Vck@C7r8r!NW_ETMB^fi~FJAK*)~EHT%8yZ57*mB&jf`rwSn*RcIX9bhUDwFe z(gIEHpUgr`RadIkjNKW=@(A+@CtX0?sTiHb8MFPa>zKjNz$^?ryesU7_I*isarsc&bG zC^_Unn-~l(mG+jkH{&SvV#@(BV`RJE|AN;q@-00Kk>!9~f_6zyRGrc>dqvvDwBhGQ zHN*Co?P;b~HL}>Eh%T{B@dl)Om^SsH`(0kKZ)e9}8)L$kFRaI!In4o_LmWoDf%pSr z0`WIQE7sF`T2pDT@Qsy)It6i*LCpA;NHaHBcc$VW$Yz#Xw8o0ega()0^~%| zaQ&&RN8fq2uV)00D5$A+3qes1y6s|jK-%6SArtIU0zK~SqT+Jd8(-*^j7q4J+Qt5T zjbc!7@AgU??P6 zctKIw>3omwxzA}~92-{5n=kejttsC?b*eCbhSJ`Z+C_u;b^HvVjQ7SRg>;S9cG*zH;$)0N_!o@dtt;xG9%@AHZSMWS;u~KciNVx-;$r07(f1yJX34 z6Z^$G&2pLO@Ly~bhFZpMXZN#%Y?wX8o@PH~N7#Y#6Xh4mua@5^&#fq~c)a47ifH98 rm3n1vRZ-QWRlubFf7uV%vn)E`01A*4u}`yA>~pN0>h8n;J_COOo6RLN literal 0 HcmV?d00001 diff --git a/src/x64/Win8.1Debug/GetSSDTFunctionIndex_Test.sys b/src/x64/Win8.1Debug/GetSSDTFunctionIndex_Test.sys new file mode 100644 index 0000000000000000000000000000000000000000..7f0f901802e22f2d6d93cbc854947c625fc6ea27 GIT binary patch literal 6144 zcmeHLU2I!d9sfHY#!Z_xUFWROs@zVuDC5KOnh1GiVi)3cCz?yW+HJfpC3ceA+NyKy zUEeGjVp6K4DA6TSA0{+jQ1Eydm5}y;w5H<0Su16oQWgf2210ZLgj{8eO?{waMdtTE zzQ(s+yA3p?q2)y9{J%fW|9tr59yof2nu(|dy;31M2gps6;|C9`5O4nc`OWn64VQPH z^F%K1j;AvPC2!_Vn5i*kBxM*mOBvP`bKFoeh7vv)Q^sF3>M^`ipl;*iqaDSe*EJ(JvttI{^=6M$&B4m|?V!X!Ltt8aZ2jq$Yct?xu}R zn~2)L;f{90kD)`Nnuh`7O+;Q)qt>M~j}gTgx`)U^NvKwhYT*6!zd6!87$xeGm@{ZZ z!c8Zu`bmXor<>n^FF^j3i{}Fk*SBo}OP{nL{n=+QaLPV(USwBOh|&RbG-aiTHev1r zhSWi++)YEufvQ?{+CfNJpZ&U;M)YDJUsaTI1VifG;Zgz$w&?#>f1J5-4+fqH`@0j} z)fA%PfT?G5BTlF!gsj(z?rIv*H(lg9`X5w4%*E9XF&9yNV*1U{a#&T^SlD4z*b!Bk z6G4fKWi7;l?pK&CD*oSZA%c=3rZ0vrtkhfG-;n`$Oo;jR-?kE!&trghc@)@V9)bmq zG$+!vsB3NPu~M4DIQ?B!*-^MlhCoE9`yZ}UDsaD)UwaMIGjJ&8BWkeX*N}^t538D_ zg?(Mv?=14(y!I0)zT_xsWexiuzEwM}stCWtdEG6g?XNQ4i2(t-FsH=Ox2v;~rEyI# zf>J3Fc-dZ`>3}%(W(nai58lZnfFx>2l9A;Zb(SHTn4eM4Fto3CmlnAm*UmyeUzLSb zt1955dhIOFYO>1kRT)rCOI5g>Vg$|c9t0|Yvv+Pl7XUPz7-7$-tH8zFjQTV~$esn{ z#`tqpRIZQ$98nZLm=P2>A3?^mAkL#tafuTZ|6ki>DWh1XC_VXER5Xf;zKpEPtN1xV z6{A;ozymLJLZDnhxa@)h54+~c^>ttB>n@%50%f1civOoK`IP$)k!)}s_Y3U)v6}l| zz!J^`I|J1CjsOgC-dyAy2h$hEm}jOx1zn~JNB zydc z&`EI7qOj%o3Pbndgni^b@V89A3JEA_p0Ha^HMog#A>@WbtR(vk$%0paaO5QGho})a<%R6OS|$cmh*IJ{G^ko+!fA*VXFM<4g1oT=UaTo;a}cVnAc8M5?h|f z4YBk_lNh;VxA>sMeuPVbtCnYG-qu=x_pG&E-G&^&>A?zd`EFXE`ubGww_14sRW6g9 zV+{$`kS>W}%W3jpJOL+2 zOIdq>ON46yrsb7?N?j~K92;SIiOXB@8+hfg9GBxm4jRHe36vew?l&x@j*s2B=ZW;xFJpS1|ZHI&m_jC8t~l_I4t&djHyr4FxSGgz2L>E?tMqDbaa@=59rT{v=(tNiN_*;~DE&7&!Rox< zXR6$W?@~Mz3&*~(Yv$Mwe%Wzg(R?J;f4c2QT*KadgNF;cSr`oKV>#o&lmVo0(#qur zAJnZ_EF9lIZpdBHZ;a}bLvg)e4NiWwXK)~6gaY@5_2Kaox7WnOdf1hN8*SR$OrB2i zZiYfrM=Lc0?^1z^2>sw&Wd=P>$3+{sbE9b1W3fd>Jnw-LP#{0yLq?z3H-N9V|IZ2tyY<~G_!sDO$@-jFtlb9UYfIKf@%L3R*ZL<&FD&xE zX_xQ8`zsNx&vQS1^Z7f}t=h-^p19yWWM%t}jCI(^@Y5@1nHl2*z8_I|_(T-AMHFi8 z&mHg0jpehtr61BC8^;eU(XI_c1