当前位置: 首页 > wzjs >正文

做网站用的字体上海seo有哪些公司

做网站用的字体,上海seo有哪些公司,承德建设网站,asp.net 网站开发的技术优势获取SSDT基址 在32位Windows系统中,SSDT(System Service Descriptor Table)作为系统服务调用的核心数据结构,其基址信息是公开且稳定的。由于ntoskrnl.exe内核模块默认导出KeServiceDescriptorTable符号,开发者只需使…

获取SSDT基址

在32位Windows系统中,SSDT(System Service Descriptor Table)作为系统服务调用的核心数据结构,其基址信息是公开且稳定的。由于ntoskrnl.exe内核模块默认导出KeServiceDescriptorTable符号,开发者只需使用extern声明即可直接访问:

extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;

然而,64位系统架构带来了重大变化。微软出于安全考虑,不再导出SSDT相关符号,并引入了以下保护机制:

  1. SSDT表基址变为动态变化,每次系统启动都会重新随机化
  2. 移除了直接的符号导出
  3. 增加了内核PatchGuard保护
    因此,想要获取64位SSDT基址就需要一些特殊技术手段来实现,常见方法包括:
  • 借助第三方符号(PDB)或调试器
    在这里插入图片描述

  • 通过msr寄存器读取

通过读取msr 0xC0000082可得到 KiSystemCall64的函数地址,从此函数地址向下可以定位到KiSystemServiceRepeat函数,从而间接获取 SSDT。
在这里插入图片描述
从上图中可以看出,4C 8D 15[lea r10] 指令后面的操作数即为SSDT地址的相对偏移,因此在通过特征值定位到此处时,可以通过以下公式计算出实际的SSDT地址。

SSDT地址 = Rip + offset = 0x140070FF9 + 0x237847

这种方法的实现在网络上可以轻松获取,这里就不详细展开了。值得注意的一点是,win10 1903版本之后,由于引入了内核隔离机制,通过msr获取到的地址不再是 KiSystemCall64,而是KiSystemCall64Shadow,这也导致了无法按照以上方法找到SSDT表。
在这里插入图片描述

  • 通过特征码扫描内核映像

由于无法再通过msr来实现查找,因此在此基础上又延伸出了类似的方案。即通过某些确定的系统函数地址,向上或向下寻找SSDT的特征值。通过IDA分析内核模块中Zw* 系统调用接口(这里并非ntdll中的用户态调用接口,而是提供给wdm驱动使用的内核态接口),可以看出内核模块中的系统调用实际上同样是通过SSDT表实现的。以ZwCreateFile 函数为例,内部调用KiServiceInternal ,然后通过jmp指令跳转到KiSystemCall64函数中。
在这里插入图片描述
在这里插入图片描述

PLONG HookHandler::GetSSDTBase() {
#ifdef _WIN64const PVOID zw_close = ZwClose;const ULONG offset = 0x400;static PSSDTEntry ssdt_address = nullptr;__try {if (ssdt_address) return ssdt_address->ServiceTableBase;PUCHAR service_internal_address = nullptr;PUCHAR zw_route_address = (PUCHAR)zw_close;// .text:000000014006A653 50               push    rax// .text:000000014006A654 B8 0C 00 00 00   mov     eax, 0Ch// .text:000000014006A659 E9 E2 67 00 00   jmp     KiServiceInternalconst UCHAR service_internal_code[] = {0x50, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xE9, 0x00};for (ULONG i = 0; i < offset; i++) {if ((*(PULONGLONG)&zw_route_address[i] & *(PULONGLONG)&service_internal_code) ==*(PULONGLONG)&service_internal_code) {ULONG jmp_offset = *(PULONG)&zw_route_address[i + 7];service_internal_address = &zw_route_address[i + 6] + 5 + jmp_offset;break;}}if (!service_internal_address) return nullptr;// .text:0000000140070FF2 4C 8D 15 47 78 23 00   lea     r10, KeServiceDescriptorTable// .text:0000000140070FF9 4C 8D 1D 80 78 23 00   lea     r11, KeServiceDescriptorTableShadowconst UCHAR ssdt_table_code[] = {0x4C, 0x8D, 0x15, 0x00};for (ULONG i = 0; i < offset; i++) {if ((*(PULONG)&service_internal_address[i] & *(PULONG)&ssdt_table_code) ==*(PULONG)&ssdt_table_code) {ULONG jmp_offset = *(PULONG)&service_internal_address[i + 3];ssdt_address = (PSSDTEntry)(&service_internal_address[i] + 7 + jmp_offset);break;}}if (!ssdt_address) return nullptr;return ssdt_address->ServiceTableBase;} __except (EXCEPTION_EXECUTE_HANDLER) {return nullptr;}
#elsereturn KeServiceDescriptorTable.ServiceTableBase;
#endif
}

除了上述方法,在网上还见过一种通过在_strnicmp函数到KdDebuggerNotPresent之间搜索8b f8 c1 ef 07 83 e7 20 25 ff 0f 00 00的定位方式。

SSDT解析

前一篇中提到SSDT中的ServiceTableBase指向的一个ULONG数组,32位系统中的数组元素代表函数地址,而在64位系统中,由于ULONG类型无法存储完整的指针类型,因此实际存储的是函数地址相对于SSDT基址的"偏移"。需要注意的是这里的偏移并不仅仅是简单的偏移,而是需要固定公式计算出的偏移长度。

在这里插入图片描述

// 计算函数地址
PVOID func_addr = (PVOID)(((LONG)ssdt_base[info.func_index] >> 4) + (ULONGLONG)func_addr);
// 计算偏移
ssdt_base[info.func_index] = (LONG)((ULONGLONG)target_addr - (ULONGLONG)ssdt_base) << 4

跳转指令

由于ServiceTableBase中存储的实际上是相对于SSDT基址的"偏移",因此hook函数的地址必须在以SSDT基址为中心的4GB内存范围内。而通常情况下我们自己的驱动的加载地址必然在4GB范围外,因此我们不能简单的将Hook函数的地址写入SSDT表,而应该在范围内选择一块地址作为函数跳转的中转。

第一步,选择合适的跳转指令

这里我们选择长度最小的12字节跳转法,实现从中转地址跳转到Hook函数。

#pragma pack(push, 1)
struct HookShellCode {USHORT mov;ULONG_PTR addr;UCHAR push;UCHAR ret;
};
#pragma pack(pop)
HookShellCode shell_code;
shell_code.mov = 0xB848;
shell_code.addr = (ULONG_PTR)func_addr;
shell_code.push = 0x50;
shell_code.ret = 0xC3;

第二步,遍历所有的代码段,从中找出合适的中转地址

PULONG kernel_base = GetKernelBase();// 获取内核模块基址
if (!kernel_base) return nullptr;// Dos Header
PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)kernel_base;
if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) return nullptr;// NT Header
PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)((PUCHAR)dos_header + dos_header->e_lfanew);
if (nt_header->Signature != IMAGE_NT_SIGNATURE) return nullptr;// Section Header
IMAGE_SECTION_HEADER* section_header = IMAGE_FIRST_SECTION(nt_header);
ULONG rva = (ULONG)((PUCHAR)base_addr - (PUCHAR)kernel_base);
// 遍历代码段
for (USHORT i = 0; i < nt_header->FileHeader.NumberOfSections; i++) {// find the section which function existsif (section_header[i].VirtualAddress <= rva &&section_header[i].VirtualAddress + section_header[i].Misc.VirtualSize > rva) {PUCHAR section_addr = (PUCHAR)kernel_base + section_header[i].VirtualAddress;for (ULONG offset = 0, size = 0; offset < section_header[i].SizeOfRawData; offset++) {if (section_addr[i] == 0x90 || section_addr[i] == 0xCC)  // NOP or INT3size++;elsesize = 0;// 找到大小匹配的空闲内存if (size == HOOK_CODE_SIZE)return (PULONG)(section_addr + offset - HOOK_CODE_SIZE + 1);}}
}

PatchGuard

基于以上内容,就可以实现在64位系统上的SSDT Hook了。然而,当实际运行Hook驱动程序时,会发现正常运行一段时间后,系统就会触发BSOD(错误代码:0x109,内核检测到关键内核代码或数据损坏),而这就是PatchGuard的作用了。

到目前为止,通过PatchGuard的方法未作深入研究,仅通过网络得知可能存在以下两种方法:

  • 通过某种方式伪装骗过PG检测,例如EPT Hook等。
  • 直接与PG对抗
http://www.dtcms.com/wzjs/518786.html

相关文章:

  • 用axure做网站百度手机助手app下载
  • 电子商务网站开发公司项目推广渠道有哪些
  • 网站内图片变换怎么做seo引擎优化是什么
  • 电子商务论文网站建设seo搜索引擎优化是通过优化答案
  • 网站icp备案 技术负责人西安seo引擎搜索优化
  • 程序员不是做网站的活动策划方案
  • 网站图片延时加载武汉网络推广外包公司
  • 张掖做网站风云榜百度
  • 网站建设系统多少钱成品网站1688入口网页版
  • wordpress怎么安装模板百度推广怎么优化排名
  • 公司怎样制作网站seo的优化方案
  • 企业网站建站企业中国软文网官网
  • 网站结构是体现的简述提升关键词排名的方法
  • 城阳网站制作沪深300指数怎么买
  • 软件商店下载安装app网站优化最为重要的内容是
  • 苏州网站制作开发南宁seo
  • 浙江建筑信息网站quark搜索引擎入口
  • 做外贸生意是不是需要建网站近几天发生的新闻大事
  • 如何做资讯网站谷歌搜索广告优化
  • 卖域名的网站要怎么做自媒体是如何赚钱的
  • 平面设计和ui设计哪个简单关键词优化推广公司排名
  • 做动效很好的网站最近的新闻摘抄
  • 新疆网站建设kim培训心得简短
  • 哈尔滨建站模板搭建苏州网站建设费用
  • 淘宝网站怎么做的百度怎么推广自己的店铺
  • 林州网站制作如何制作一个简易网站
  • 枣庄市建设项目环评备案网站培训行业seo整站优化
  • 黄贝建设网站建设sem优化是什么意思
  • 数码庄园的网站建设公司建立网站一般要多少钱
  • wordpress分类文章表格显示网页优化最为重要的内容是