shadow ssdt学习笔记

Windows内核新手上路2——挂钩shadow SSDT <br />Windows内核新手上路2——挂钩shadow SSDT<br />         文章核心内容:安全软件窗口保护、安全输入、截屏保护的一些思路。挂钩NtUserFindWindowEx、NtUserGetForegroundWindow、NtUserBuildHwndList、NtUserQueryWindow、NtUserWindowFromPoint、NtUserSetParent、NtUserPostMessage、NtUserMessageCall、NtUserSetWindowL 阅读详情
1。取得shadow ssdt真实地址
系统只提供了KeServiceDescriptorTable导出
KeServiceDescriptorTableShadow是个未导出结构

定义
typedef struct _SYSTEM_SERVICE_TABLE
{
      PNTPROC  ServiceTable;  // array of entry points
      PDWORD  CounterTable;  // array of usage counters
      DWORD  ServiceLimit;    // number of table entries
      PBYTE    ArgumentTable;  // array of byte counts
}
SYSTEM_SERVICE_TABLE,
*PSYSTEM_SERVICE_TABLE,
**PPSYSTEM_SERVICE_TABLE;
//-----------------------------------------------------------------------------------------------------------
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
      SYSTEM_SERVICE_TABLE ntoskrnl;  // ntoskrnl.exe ( native api )
    SYSTEM_SERVICE_TABLE win32k;    // win32k.sys (gdi/user support)
      SYSTEM_SERVICE_TABLE Table3;    // not used
      SYSTEM_SERVICE_TABLE Table4;    // not used
}
SYSTEM_DESCRIPTOR_TABLE,
*PSYSTEM_DESCRIPTOR_TABLE,
**PPSYSTEM_DESCRIPTOR_TABLE;

其实 KeServiceDescriptorTableShadow包含4个子结构,其中第一个就是ntoskrnl.exe ( native api ),和KeServiceDescriptorTable指向一样 我们真正需要获得的是第二个win32k.sys (gdi/user support),第三个和第四个一般不使用

定位方法
1。硬编码
//for xp
if(gKernelVersion==WINXP)
  KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0x40;
//for 2k
if(gKernelVersion==WIN2K)
  KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0xE0;

2。搜索KeAddSystemServiceTable
反汇编代码可以看出
lkd> u KeAddSystemServiceTable l 40
nt!KeAddSystemServiceTable:
805ba589 8bff            mov    edi,edi
805ba58b 55              push    ebp
805ba58c 8bec            mov    ebp,esp
805ba58e 837d1803        cmp    dword ptr [ebp+18h],3
805ba592 774e            ja      nt!KeAddSystemServiceTable+0x6b (805ba5e2)
805ba594 8b4518          mov    eax,dword ptr [ebp+18h]
805ba597 c1e004          shl    eax,4
805ba59a 83b880a6558000  cmp    dword ptr nt!KeServiceDescriptorTable (8055a680)[eax],0
805ba5a1 753f            jne    nt!KeAddSystemServiceTable+0x6b (805ba5e2)
805ba5a3 8d8840a65580    lea    ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
805ba5a9 833900          cmp    dword ptr [ecx],0
805ba5ac 7534            jne    nt!KeAddSystemServiceTable+0x6b (805ba5e2)
805ba5ae 837d1801        cmp    dword ptr [ebp+18h],1
805ba5b2 8b5508          mov    edx,dword ptr [ebp+8]
805ba5b5 56              push    esi
805ba5b6 8b7510          mov    esi,dword ptr [ebp+10h]
805ba5b9 57              push    edi
805ba5ba 8b7d14          mov    edi,dword ptr [ebp+14h]
805ba5bd 8911            mov    dword ptr [ecx],edx
805ba5bf 8b4d0c          mov    ecx,dword ptr [ebp+0Ch]
805ba5c2 898844a65580    mov    dword ptr nt!KeServiceDescriptorTableShadow+0x4 (8055a644)[eax],ecx
805ba5c8 89b048a65580    mov    dword ptr nt!KeServiceDescriptorTableShadow+0x8 (8055a648)[eax],esi
805ba5ce 89b84ca65580    mov    dword ptr nt!KeServiceDescriptorTableShadow+0xc (8055a64c)[eax],edi
805ba5d4 0f855a3e0300    jne    nt!KeAddSystemServiceTable+0x4d (805ee434)
805ba5da 5f              pop    edi
805ba5db b001            mov    al,1
805ba5dd 5e              pop    esi
805ba5de 5d              pop    ebp
805ba5df c21400          ret    14h
805ba5e2 32c0            xor    al,al
805ba5e4 ebf8            jmp    nt!KeAddSystemServiceTable+0x6d (805ba5de)
805ba5e6 90              nop
805ba5e7 90              nop
805ba5e8 90              nop
805ba5e9 90              nop
805ba5ea 90              nop

搜索办法很简单
就是找到
805ba5a3 8d8840a65580    lea    ecx,nt!KeServiceDescriptorTableShadow (8055a640)[eax]
的8d88 40a65580    lea    ecx, nt!KeServiceDescriptorTableShadow
代码如下
void GetKeServiceDescriptorTableShadow()
{
    PUCHAR cPtr, pOpcode;
    ULONG Length;
   
    for (cPtr = (PUCHAR)KeAddSystemServiceTable;
        cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
        cPtr += Length)
    {
        if (!MmIsAddressValid(cPtr)) break;

        Length = SizeOfCode(cPtr, &pOpcode);

        if (!Length || (Length == 1 && *pOpcode == 0xC3)) break;
       
        if (*(PUSHORT)pOpcode == 0x888D)
        {
            KeServiceDescriptorTableShadow = *(PVOID *)(pOpcode + 2);
            break;
        }
    }
}

3。从KTHREAD.ServiceTable里面搜索
如果是GUI线程 那么就是指向ServiceDescriptorTableShadow
其实个人更加倾向这个办法 稳定安全可靠,上面那个代码也许会受到以后系统代码变化影响 但是这个肯定不会

GetServiceDescriptorTableShadowAddress proc uses esi edi ebx

local dwThreadId:DWORD

    xor ebx, ebx                ; = NULL. Assume ServiceDescriptorTableShadow will be not found

    mov eax, KeServiceDescriptorTable
    mov esi, [eax]

    ; Find KTHREAD.ServiceTable field
    ; For non-GUI threads this field == KeServiceDescriptorTable
    ; and it points to ServiceDescriptorTable
    ; For GUI threads
    ; ServiceDescriptorTableShadow

    invoke KeGetCurrentThread
    mov edi, 200h-4
    .while edi
        .break .if dword ptr [eax][edi] == esi
        dec edi
    .endw

    .if edi != 0
        ; edi = offset to ServiceTable field in KTHREAD structure
        mov dwThreadId, 080h
        .while dwThreadId < 400h
            push eax                    ; reserve DWORD on stack
            invoke PsLookupThreadByThreadId, dwThreadId, esp
            pop ecx                        ; -> ETHREAD/KTHREAD
            .if eax == STATUS_SUCCESS
                push dword ptr [ecx][edi]
                fastcall ObfDereferenceObject, ecx
                pop eax
                .if eax != esi
                    mov edx, MmSystemRangeStart
                    mov edx, [edx]
                    mov edx, [edx]
                    .if eax > edx        ; some stupid error checking
                        mov ebx, eax
                        invoke DbgPrint, $CTA0("FindShadowTable: Found in thread with ID: %X/n"), dwThreadId
                        .break
                    .endif
                .endif
            .endif
            add dwThreadId, 4
        .endw
    .endif

    mov eax, ebx
    ret

GetServiceDescriptorTableShadowAddress endp

4.mj0011所说的搜索有效内存地址的办法
/*
define structure for the system service table
*/
struct SYS_SERVICE_TABLE {
void **ServiceTable;
unsigned long CounterTable;
unsigned long ServiceLimit;
void **ArgumentsTable;
};

SYSTEM_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow;

/*
Define KeServiceDescriptorTable based on the SST structure
*/
extern struct SYS_SERVICE_TABLE *KeServiceDescriptorTable;

/*
Declare function GetServiceDescriptorShadowTableAddress()
*/
//struct SYS_SERVICE_TABLE * GetServiceDescriptorShadowTableAddress ();
/*
Declare the KeAddSystemServiceTable. This is just a
handle to the call function, it will be used by the function
above to obtain the correct address of the KeServiceDescriptorShadowTable
*/
__declspec(dllimport) KeAddSystemServiceTable (ULONG, ULONG, ULONG, ULONG, ULONG);

struct SYS_SERVICE_TABLE * GetServiceDescriptorShadowTableAddress ()
{
// First, obtain a pointer to KeAddSystemServiceTable
unsigned char *check = (unsigned char*)KeAddSystemServiceTable;
int i;
  //Initialize an instance of System Service Table, will be used to
//obtain an address from KeAddSystemServiceTable
struct SYS_SERVICE_TABLE *rc=0;
// Make 100 attempts to match a valid address with that of KeServiceDescriptorTable
for (i=0; i<=99; i++) {
  __try {
  // try to obtain an address from  KeAddSystemServiceTable
  rc = *(struct SYS_SERVICE_TABLE**)check;
  // if this address is NOT valid OR it itself is the address of
  //KeServiceDescriptorTable OR its first entry is NOT equal
  //to the first entry of KeServiceDescriptorTable
  if (!MmIsAddressValid (rc) || (rc == KeServiceDescriptorTable)
    || (memcmp (rc, KeServiceDescriptorTable, sizeof (*rc)) != 0)) {
    // Proceed with the next address
    check++;
    // don't forget to reset the old address
    rc = 0;
  }
  } __except (EXCEPTION_EXECUTE_HANDLER) { rc = 0; }
  // when the loop is completed, check if it produced a valid address
  if (rc)
  // because if it didn't, we failed to find the address of KeServiceDescriptorTableShadow
  break;
}
// otherwise, there is a valid address! So return it!
return rc;
}

5。老V提出的搜索.data区段开头的办法


如图所示 开始地方就是地址表 用这个办法的好处是不会受到KeServiceDescriptorTableShadow .win32k.ServiceTable被重定位的影响,可以从win32k的基址直接+区段VA获得
代码如下
DWORD FindPeSection( DWORD pModuleBase, PCHAR SectionName )
{
    PIMAGE_DOS_HEADER        pDosHdr;
    PIMAGE_NT_HEADERS        pNtHdr;
    PIMAGE_SECTION_HEADER    pSecHdr;
    PIMAGE_EXPORT_DIRECTORY  pExtDir;

    UINT                    ui,uj;
    PCHAR                    FunName;
    DWORD                    *dwAddrName;
    DWORD                    *dwAddrFun;
    FARPROC                    pOldFun;
    ULONG                    uAttrib;


    pDosHdr = ( PIMAGE_DOS_HEADER )pModuleBase;

    if ( IMAGE_DOS_SIGNATURE == pDosHdr->e_magic )
    {
        pNtHdr = ( PIMAGE_NT_HEADERS )( pModuleBase + pDosHdr->e_lfanew );

        if( IMAGE_NT_SIGNATURE  == pNtHdr->Signature ||    IMAGE_NT_SIGNATURE1 == pNtHdr->Signature )
        {
            pSecHdr = ( PIMAGE_SECTION_HEADER )( pModuleBase + pDosHdr->e_lfanew + sizeof( IMAGE_NT_HEADERS ) );

            for ( ui = 0; ui < (UINT)pNtHdr->FileHeader.NumberOfSections; ui++ )
            {
                if ( !strcmp( pSecHdr->Name, SectionName ) )
//                if ( !strcmp( pSecHdr->Name, ".data" ) )
                { 
                    dprintf("find it %s",pSecHdr->Name);
                    return pModuleBase + pSecHdr->VirtualAddress;


                }

                pSecHdr++;
            }
        }
    }

    return 0;
}


二。函数名定位
这个似乎没有多少好办法,解析pdb可以是可以 但是很麻烦
不过还好的是 同一个版本的系统 调用号一样
所以只需要3套 2k xp 2k3的调用号就可以完成hook
pdb办法
SymInitialize初始化
SymSetSearchPath “srv**symbols* http://msdl.microsoft.com/”
SymLoadModule
SymGetSymFromName
老v曾经发出1个获取shadow地址和函数名称的工具 使用他可以很方便的获取
具体代码可以F5查看
以上读取pdb的方法测试使用的可以的
但是实际使用很麻烦

经过分析 我找到了1个比较好的定位办法
我们以SetWindowsHookExA为例子
.text:77D311D1 ; HHOOK __stdcall SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId)
.text:77D311D1                public _SetWindowsHookExA@16
.text:77D311D1 _SetWindowsHookExA@16 proc near
.text:77D311D1
.text:77D311D1 idHook          = dword ptr  8
.text:77D311D1 lpfn            = dword ptr  0Ch
.text:77D311D1 hModule        = dword ptr  10h
.text:77D311D1 dwThreadId      = dword ptr  14h
.text:77D311D1
.text:77D311D1                mov    edi, edi
.text:77D311D3                push    ebp
.text:77D311D4                mov    ebp, esp
.text:77D311D6                push    2              ; int
.text:77D311D8                push    [ebp+dwThreadId] ; int
.text:77D311DB                push    [ebp+hModule]  ; hModule
.text:77D311DE                push    [ebp+lpfn]      ; int
.text:77D311E1                push    [ebp+idHook]    ; int
.text:77D311E4                call    _SetWindowsHookExAW@20 ; SetWindowsHookExAW(x,x,x,x,x)
.text:77D311E9                pop    ebp
.text:77D311EA                retn    10h
.text:77D311EA _SetWindowsHookExA@16 endp

.text:77D2DCFD ; int __stdcall SetWindowsHookExAW(int, int, HMODULE hModule, int, int)
.text:77D2DCFD _SetWindowsHookExAW@20 proc near        ; CODE XREF: SetWindowsHookExW(x,x,x,x)+13p
.text:77D2DCFD                                        ; SetWindowsHookExA(x,x,x,x)+13p
.text:77D2DCFD
.text:77D2DCFD Filename        = word ptr -20Ch
.text:77D2DCFD var_4          = dword ptr -4
.text:77D2DCFD arg_0          = dword ptr  8
.text:77D2DCFD arg_4          = dword ptr  0Ch
.text:77D2DCFD hModule        = dword ptr  10h
.text:77D2DCFD arg_C          = dword ptr  14h
.text:77D2DCFD arg_10          = dword ptr  18h
.text:77D2DCFD
.text:77D2DCFD                mov    edi, edi
.text:77D2DCFF                push    ebp
.text:77D2DD00                mov    ebp, esp
.text:77D2DD02                sub    esp, 20Ch
.text:77D2DD08                mov    eax, ___security_cookie
.text:77D2DD0D                push    esi
.text:77D2DD0E                mov    esi, [ebp+hModule]
.text:77D2DD11                test    esi, esi
.text:77D2DD13                push    edi
.text:77D2DD14                mov    edi, [ebp+arg_4]
.text:77D2DD17                mov    [ebp+var_4], eax
.text:77D2DD1A                jz      short loc_77D2DD33
.text:77D2DD1C                push    104h            ; nSize
.text:77D2DD21                lea    eax, [ebp+Filename]
.text:77D2DD27                push    eax            ; lpFilename
.text:77D2DD28                push    esi            ; hModule
.text:77D2DD29                call    ds:__imp__GetModuleFileNameW@12 ; GetModuleFileNameW(x,x,x)
.text:77D2DD2F                test    eax, eax
.text:77D2DD31                jz      short loc_77D2DD52
.text:77D2DD33
.text:77D2DD33 loc_77D2DD33:                          ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+1Dj
.text:77D2DD33                push    [ebp+arg_10]
.text:77D2DD36                mov    eax, esi
.text:77D2DD38                push    edi
.text:77D2DD39                push    [ebp+arg_0]
.text:77D2DD3C                neg    eax
.text:77D2DD3E                push    [ebp+arg_C]
.text:77D2DD41                sbb    eax, eax
.text:77D2DD43                lea    ecx, [ebp+Filename]
.text:77D2DD49                and    eax, ecx
.text:77D2DD4B                push    eax
.text:77D2DD4C                push    esi
.text:77D2DD4D                call    __SetWindowsHookEx@24 ; _SetWindowsHookEx(x,x,x,x,x,x)
.text:77D2DD52
.text:77D2DD52 loc_77D2DD52:                          ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+34j
.text:77D2DD52                mov    ecx, [ebp+var_4]
.text:77D2DD55                pop    edi
.text:77D2DD56                pop    esi
.text:77D2DD57                call    @__security_check_cookie@4 ; __security_check_cookie(x)
.text:77D2DD5C                leave
.text:77D2DD5D                retn    14h
.text:77D2DD5D _SetWindowsHookExAW@20 endp
.text:77D2DD5D

.text:77D2DD65 ; __stdcall _SetWindowsHookEx(x, x, x, x, x, x)
.text:77D2DD65 __SetWindowsHookEx@24 proc near        ; CODE XREF: SetWindowsHookExAW(x,x,x,x,x)+50p
.text:77D2DD65
.text:77D2DD65 var_10          = byte ptr -10h
.text:77D2DD65 var_8          = dword ptr -8
.text:77D2DD65 var_4          = dword ptr -4
.text:77D2DD65 arg_0          = dword ptr  8
.text:77D2DD65 arg_4          = dword ptr  0Ch
.text:77D2DD65 arg_8          = dword ptr  10h
.text:77D2DD65 arg_C          = dword ptr  14h
.text:77D2DD65 arg_10          = dword ptr  18h
.text:77D2DD65 arg_14          = dword ptr  1Ch
.text:77D2DD65
.text:77D2DD65                mov    edi, edi
.text:77D2DD67                push    ebp
.text:77D2DD68                mov    ebp, esp
.text:77D2DD6A                sub    esp, 10h
.text:77D2DD6D                push    [ebp+arg_4]
.text:77D2DD70                and    [ebp+var_4], 0
.text:77D2DD74                lea    eax, [ebp+var_10]
.text:77D2DD77                push    eax
.text:77D2DD78                mov    [ebp+var_8], eax
.text:77D2DD7B                call    ds:__imp__RtlInitUnicodeString@8 ; RtlInitUnicodeString(x,x)
.text:77D2DD81                push    [ebp+arg_14]
.text:77D2DD84                push    [ebp+arg_10]
.text:77D2DD87                push    [ebp+arg_C]
.text:77D2DD8A                push    [ebp+arg_8]
.text:77D2DD8D                push    [ebp+var_8]
.text:77D2DD90                push    [ebp+arg_0]
.text:77D2DD93                call    _NtUserSetWindowsHookEx@24 ; NtUserSetWindowsHookEx(x,x,x,x,x,x)
.text:77D2DD98                leave
.text:77D2DD99                retn    18h
.text:77D2DD99 __SetWindowsHookEx@24 endp
.text:77D2DD99

.text:77D2DDA1 ; __stdcall NtUserSetWindowsHookEx(x, x, x, x, x, x)
.text:77D2DDA1 _NtUserSetWindowsHookEx@24 proc near    ; CODE XREF: _SetWindowsHookEx(x,x,x,x,x,x)+2Ep
.text:77D2DDA1                mov    eax, 1225h
.text:77D2DDA6                mov    edx, 7FFE0300h
.text:77D2DDAB                call    dword ptr [edx]
.text:77D2DDAD                retn    18h
.text:77D2DDAD _NtUserSetWindowsHookEx@24 endp

我们看这里 .text:77D2DDA1                mov    eax, 1225h
里面有和ssdt一样的调用号 但是有个问题 NtUserSetWindowsHookEx在user32里面没有导出,我们需要多次搜索才行
HHOOK STDCALL    NtUserSetWindowsHookEx (HINSTANCE Mod, PUNICODE_STRING UnsafeModuleName, DWORD ThreadId, int HookId, HOOKPROC HookProc, BOOL Ansi)
这个就是原型 不过搜索起来确实是比较麻烦的,不知道还有无其他好办法了

 
深入解析Shadow SSDT服务函数原始地址获取技术 回顾这场长达二十年的攻防拉锯战,你会发现:SSDT Hook 曾经是 Rootkit 的标配技能;Shadow SSDT 的出现标志着微软开始推行纵深防御理念;PatchGuard 让“默认拒绝”成为内核设计的新哲学;如今的终端安全早已超越单一技术点,走向体系化对抗。而对于我们这些技术人员来说,理解这些底层机制的意义远不止于“炫技”。当你知道不仅是一个隐藏的结构,更是现代操作系统自我保护思想的具体体现时,你会更加敬畏每一行代码背后的工程智慧。 阅读详情

相关推荐

R0层获取ShadowSSDT函数原始地址实例

本实例由VS2008开发,在提供了一套驱动开发框架的同时,又演示了如何获取Shadow SSDT表函数原始地址的办法。 主要函数:ULONG GetShadowSSDT_Function_OriAddr(ULONG index); 原理说明: 根据特征码搜索导出函数KeAddSystemServiceTable来获取Shadow SSDT基址,以及通过ZwQuerySystemInformation()函数获取win32k.sys基址,然后解析PE定位到Shadow SSDT在win32k.sys的偏移地址,并通过进一步计算来得到Shadow SSDT表函数的原始地址。 这里只测试了三个函数:(460)NtUserMessageCall、(475)NtUserPostMessage和(502)NtUserSendInput,具体使用时可以举一反三,网上完整的源代码实例并不太多,希望可以帮到真正有需要的朋友。 系统环境: 在WinXP SP3系统 + 瑞星杀毒软件 打印输出: [ LemonInfo : Loading Shadow SSDT Original Address Driver... ] [ LemonInfo : 创建“设备”值为:0 ] [ LemonInfo : 创建“设备”成功... ] [ LemonInfo : 创建“符号链接”状态值为:0 ] [ LemonInfo : 创建“符号链接”成功... ] [ LemonInfo : 驱动加载成功... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 开始... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP Enter IRP_MJ_DEVICE_CONTROL... ] [ LemonInfo : 获取ShadowSSDT表 (460)NtUserMessageCall 函数的“当前地址”为:0xB83ECFC4,“起源地址”为:0xBF80EE6B ] [ LemonInfo : 获取ShadowSSDT表 (475)NtUserPostMessage 函数的“当前地址”为:0xB83ECFA3,“起源地址”为:0xBF8089B4 ] [ LemonInfo : 获取ShadowSSDT表 (502)NtUserSendInput 函数的“当前地址”为:0xBF8C31E7,“起源地址”为:0xBF8C31E7 ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP_MJ_DEVICE_CONTROL 成功执行... ] [ LemonInfo : 派遣函数(DispatchRoutine) IRP 结束... ] [ LemonInfo : UnLoading Shadow SSDT Original Address Driver... ] [ LemonInfo : 删除“符号链接”成功... ] [ LemonInfo : 删除“设备”成功... ] [ LemonInfo : 驱动卸载成功... ]

WINDOWS内核学习笔记1—Shadow SSDT表

近期学习内核的

rosykee的专栏 1086

别再用MounRiver了!在VSCode里用PlatformIO搞定CH32V208开发(附完整配置流程)

本文详细介绍了如何在VSCode中使用PlatformIO进行CH32V208开发,替代传统的MounRiver Studio。通过完整的配置流程和优化技巧,开发者可以构建高效、现代化的RISC-V开发环境,显著提升编译速度和开发效率。

weixin_28711397的博客 537

shadow ssdt

假设.有一个目标进程A.. 在驱动中首先获取其EPROCESS.. 然后用这个PsGetNextProcessThread取出其线程.. 然后取出ETHREAD...也等同于KTHREAD..(是第一个字段). 然后关键就是这个ServiceTable..字段.. 关于这个指针..ShadowSSDT Hook系列的文章会说.如果其不是GUI进程则此字段不会指向Sha

lionzl的专栏 1228

MinerU安装指南:从源码到验证的完整流程

本文详细介绍了MinerU文档转换工具的安装流程,从源码获取、依赖安装到验证步骤,提供了完整的安装指南和常见问题解决方案。特别适合技术写作者和开发者快速部署这款高效的文档转换工具,提升工作效率。

weixin_29243279的博客 547

PaddleOCR 3.x 最新版使用教程(2025)——从安装到实战身份证识别,一步到位!

本文针对PaddleOCR 3.x大版本更新带来的参数变化和兼容性问题,提供从环境配置到实际应用的全流程解决方案。

qq_58607032的博客 9790

Windbg查看Shadow SSDT

关于SSDT即系统描述符表,《SSDT Hook的妙用-对抗ring0 inline hook》这篇文章描述的已经很清楚了。引用文章中的一段话: “内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable(由ntoskrnl.exe导出),一个是KeServieDescriptorTableShadow(没有导出)。两者的区别是,KeServiceDescript

debugge的专栏 1857

Greenplum基础

CREATE DATABASE 是 SQL 命令,用于创建一个新的数据库。name 是你要创建的数据库的名称。这个名称是必须的,并且在同一个数据库服务器上必须是唯一的。可选项,OWNER 指定了新数据库的所有者,如果未指定,新数据库的所有者默认是执行该命令的用户。dbowner 是数据库所有者的用户名。可选项,TEMPLATE 指定了用于创建新数据库的模板。在 PostgreSQL 和 GreenPlum 中,通常有一个名为 template1 的默认模板。如果不指定,就会使用这个默认模板。

m0_57697768的博客 1207

win 64 Shadow ssdt hook

以下参考黑客防线2012合订本 339页 //下午调代码 搞了这个一天,总是蓝屏,不断检查代码,后来发现了很怪的现象. 自己写的代码不能读取shadow ssdt的偏移内容,但是通过和调试作者的代码输出发现地址确实是一模一样的,但是自己的读不出来,而作者的能 读出来,当直接使用windbg调试时也读不出来. 后来将作者的代码完全复制过来,发现能读取了, ,但是又找不到原因, 只能等以后再...

weixin_30709929的博客 567

Dify沙箱权限配置实战:解决‘operation not permitted‘报错的完整指南

本文详细解析了Dify平台中常见的'operation not permitted'报错根源,即沙箱安全机制对系统调用的限制。通过实战步骤,指导用户定位并修改config.yaml配置文件,精准配置allowed_syscalls白名单以解决权限问题,涵盖从文件操作、进程控制到网络通信等关键系统调用的编号详解与配置示例,帮助用户在保障安全的前提下,顺利运行依赖特定库的代码工作流。

tech5的博客 1204

Python爬虫实战:逆向工程与异步爬虫技术,高效抓取国家知识产权局专利数据

相比于传统的Selenium,Playwright由微软开发,支持多浏览器(Chromium, Firefox, WebKit),API更现代,执行速度更快,并且能轻松录制用户操作生成代码。通常,列表中的摘要信息是缩略的,我们需要进入每个专利的详情页获取完整信息(如主权要求、法律状态等)。我们的第一步是手动操作一遍搜索流程,并用Playwright的“录制”功能或开发者工具,找出真正返回专利数据的那一个或多个网络请求。以友好的、对人类行为模拟的方式爬取数据是基本的网络礼仪,也能有效避免你的IP被封锁。

2201_76125261的博客 2424

转shadow ssdt学习笔记

1。取得shadow ssdt真实地址 系统只提供了KeServiceDescriptorTable导出 KeServiceDescriptorTableShadow是个未导出结构 定义 Copy code     typedef struct _SYSTEM_SERVICE_TABLE     {           PNTPROC  ServiceTab

Tommy(凌飞)的专栏 1883

基于YOLO26深度学习框架的人脸识别门禁系统的算法研究实现方法

本文研究了基于YOLO26深度学习框架的人脸识别门禁系统实现方法。系统采用YOLO26目标检测算法,通过CSPDarknet53主干网络、特征金字塔结构和注意力机制实现高效人脸检测。研究内容包括数据预处理、模型训练优化和身份验证等关键技术,使用迁移学习策略和CIoU损失函数提升检测精度。该系统可应用于智能安防场景,具有实时性强、识别准确的特点,为门禁管理提供了智能化解决方案。

一键难忘的博客 766

shadow ssdt学习笔记(一)

转shadow ssdt学习笔记(一)文章作者:zhuwg信息来源:邪恶八进制信息安全团队(www.eviloctal.com)1。取得shadow ssdt真实地址系统只提供了KeServiceDescriptorTable导出KeServiceDescriptorTableShadow是个未导出结构定义复制内容到剪贴板代码:typ

visualassist4680的专栏 1778

MIPI D-PHY IP 使用说明(一)

目录 前言 一、IP 特点 二、IP 可用性 三、IP 总览 四、IP 声明 五、IP 结构 六、IP 分流桥 模式 七、端口描述 1、PPI 接口信号 1、常规 PPI控制信号 2、发送模式 时钟通道 高速 PPI 信号 3、发送模式 时钟通道 逃逸模式PPI 信号 4、发送模式 数据通道 高速 PPI 信号 5、发送模式 数据通道 控制接口PPI 信号 6、发送模式 ...

记录所学,分享知识,结识挚友 2507

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

shadow ssdt学习笔记(一)(二)

作 者: zhuwg时 间: 2007-12-22,22:01链 接: http://bbs.pediy.com/showthread.php?t=569551。取得shadow ssdt真实地址系统只提供了KeServiceDescriptorTable导出KeServiceDescriptorTableShadow是个未导出结构定义Copy code    typedef struct _SY

1246

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【原创】shadow ssdt学习笔记(一)(二)

http://bbs.pediy.com/showthread.php?t=56955 标 题: 【原创】shadow ssdt学习笔记(一)(二) 作 者: zhuwg 时 间: 2007-12-22,22:01:29 链 接: http://bbs.pediy.com/showthread.php?t=56955 1。取得shadow 

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1675

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

shadow ssdt学习笔记(二)

三。如何hook 似乎这个问题并不大,shadow ssdt和ssdt本质上都是1个地址表,最为简单的方法是把你的函数替换地址表的对应项,具体hook代码甚至可以完全照抄ssdt的,这里只说1下几个偶遇到的小问题 1。win32k.sys不是常在内存的,如果不是GUI线程,shadow ssdt地址无效 解决办法: 1。在driverdispatch中hokk driverdispatc

M-先生 975

【原创】shadow ssdt学习笔记(一)

标 题: 【原创】shadow ssdt学习笔记(一) 作 者: zhuwg 时 间: 2007-12-22,22:01:29 链 接: http://bbs.pediy.com/showthread.php?t=56955 1。取得shadow ssdt真实地址 系统只提供了KeServiceDescriptorTable导出 KeServiceDescriptorTableSh

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1162

【原创】shadow ssdt学习笔记(二)

三。如何hook 似乎这个问题并不大,shadow ssdt和ssdt本质上都是1个地址表,最为简单的方法是把你的函数替换地址表的对应项,具体hook代码甚至可以完全照抄ssdt的,这里只说1下几个偶遇到的小问题 1。win32k.sys不是常在内存的,如果不是GUI线程,shadow ssdt地址无效 解决办法: 1。在driverdispatch中hokk driverdispatc

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1454

两种方法获取shadow ssdt

<br />ULONG GetShadowSsdtCurrentAddresses( PSSDT_ADDRESS AddressInfo, PULONG Length ) { PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL; ULONG NumberOfService = 0; ULONG ServiceId = 0; PKAPC_STA

kedebug 2020
上一篇: Using 802.1X to control physical access to LANs
下一篇: 财富快车中的几个比较有用的逆向代码
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值