|
|
|
|
|
|
|
[求助]SSDT 和Shadow SSDT
嗯..我果然理解错误..呵呵.. 感谢指导..我以为切换就是第一项和第二项的切换.. 原来他们有两个整体... 那个KeServiceDescriptorTableShadow和KeServiceDescriptorTable结构一样 也是四项..只不过.前者以SSDT为主.后者以ShadowSSDT为主?.等需要调用SSDT内函数的时候.. 系统就会用你说的函数自动完成转换对吧.. 如果是这样.我就明白了. 第三个问题.主要是我理解上的错误..导致这个字段修改也是错误.呵呵.. 我说的移动.意思是.如果指向KeServiceDescriptorTable..我就从内核文件中把这个 KeServiceDescriptorTable整个结构复制出去.换个地方放哪里.然后修改线程的指针指向到这个地方.. 但是还是那个问题.就在这个时候线程要求立刻切换到KeServiceDescriptorTableShadow..怎么办? 就算我把KeServiceDescriptorTableShadow也复制出来.系统也不知道该往哪里切换啊.. 怎么告诉系统如何切换? |
|
|
|
[求助]SSDT 和Shadow SSDT
首先十分感谢一楼大牛的指导.. 不过.我看了你的说法后.反而迷糊了.. 为什么呢. 我的个人理解是. typedef struct _SYSTEM_SERVICE_TABLE { PVOID ServiceTableBase; // SSDT (System Service Dispatch Table)的基地址 PULONG ServiceCounterTableBase; // 用于checked builds, 包含SSDT中每个服务被调用的次数 ULONG NumberOfService; // 服务函数的个数, NumberOfService*4 就是整个地址表的大小 ULONG ParamTableBase; // SSPT (System Service Parameter Table)的基地址 } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; typedef struct _SERVICE_DESCRIPTOR_TABLE { SYSTEM_SERVICE_TABLE ntoskrnl; // ntoskrnl.exe的服务函数 SYSTEM_SERVICE_TABLE win32k; // win32k.sys的服务函数,(gdi.dll/user.dll的内核支持) SYSTEM_SERVICE_TABLE NotUsed1; SYSTEM_SERVICE_TABLE NotUsed2; } SYSTEM_DESCRIPTOR_TABLE, *PSYSTEM_DESCRIPTOR_TABLE; PSYSTEM_DESCRIPTOR_TABLE 才是真正的 KeServiceDescriptorTable (这也是系统导出的.可惜只导出部分) SSDT只是这个KSSDT中的第一项.(这也是为什么好多人偷懒.总喜欢直接强制转换指针.把KSSDT直接当SSDT用也是对的)..Shadow SSDT是这个表中的第二项..但很可惜.没导出.用的时候不能直接操作.得自己搜地址.赋值和强制转换一次才行. (比如 PShadowSSDT=(ShadowSSDT结构)地址.).. 所以.我看了Shadow SSDT Hook系列的文章后觉得.如果指向了ShadowSSDT就认为.是指向了.第二项... 看来或许我的理解是错的吧..是不是这个指针直接指向的是 KeSSDT.(也就是他们全部).. 如果是..那么就又迷糊了.既然都包含全部了.为什么说指向第一项SSDT为主的时候.ShadowSSDT地址却是无效的?(这也是ShadowSSDT HOOK文章上经常说的)..是不是因为它没导出?还是? ..至于第三个问题.我的本意是说.如果线程指向SSDT..我就把SSDT移动一个位置.把修改指向.不知道万一这个线程要求立刻切换到ShadowSSDT内.这个时候系统怎么才能知道该切换到那..呵呵.. 不过我想到这里.感觉.如果是直接指向他们全部..那么就一切好说了.不知道是不是这样??谢谢. |
|
[求助]如何查看Ntopenprocess的函数长度
糊涂.. 用代码动态计算指令不好.. 难道非要硬编码? 如果真要硬编码也简单.. 对函数 u 函数 L 25(一般大多函数这个行数都够了). 就能清楚的看见函数的结尾了.结尾地址-头地址. |
|
[求助]如何查看Ntopenprocess的函数长度
晕..这问题还不好解决.. 反汇编引擎嘛 ULONG TotalLenth=0; for(ULONG CurrentAddr=(ULONG)函数;CurrentAddr!=CurrentAddr+PAGE_SIZE;++CurrentAddr) { Length = SizeOfCode(cPtr, &pOpcode); if ((!Length)||((Length == 1) && (*pOpcode == 0xC3))||((Length == 3) && (*pOpcode == 0xC2))) { TotalLenth+= Length; break; } TotalLenth+= Length; } 这里就已经取得长度保存于TotalLenth.... |
|
[原创]详谈内核三步走Inline Hook实现
其实也没什么大错误.. 感觉不必要为这个咬文嚼字.. 一个内核模式的线程..把自己所在的处理器的IRQL提高至IRQL为2的DPC/DISPATCH 级别之后.. CPU的IRQL设置一旦改变(在PCR里面保存着)...则当前处理器.就不会再接受同等级别的请求 和低于此级别的请求(如果有.则插入当前处理器的DPC队列.等候处理)..注意一点: windows的线程调度以及分发工作.也不过是运行在IRQL为2的DPC/DISPATCH级别....所以..线程调度请求.通知当前处理器处理的时候.会被暂时屏蔽(保留起来).或者线程分发器交给其他处理器处理.....如果当前系统是单处理器.则实际上线程调度也就暂时被延迟了....所以不能说是禁止了线程调度产生的中断..(虽然我知道你想表达的也是这个意思).... 说这个了.把那个指令也啰嗦下.虽然大家都知道了.. 就是sti 和cli..因为处理器要处理的请求..不仅仅来自软件请求..(比如说那个线程分发). 还有大量的硬件请求.. 其中通过INTR引脚或者本地APIC传递到处理器的外部硬件中断都是可屏蔽中断.. 为了减少CPU处理事情时候被打扰..这些可屏蔽的硬件中断.适当的使用指令(实质就是修改CPU的EFLAGES寄存器的IF位)屏蔽下也没太大坏处.... 说这么多了..最后把楼主的帖子说一下吧.. 其实这一篇写的不错的..毕竟面向的对象不一样.. 纵然是天上的天阳般万丈光芒.也不见得会得到所有人的喜欢.. 所以..知道自己发帖的目的.和对象即可..不必要过于仅仅计较了..呵呵. 万事物极必反.. 我就在后面跟上Anti 这种InLine的办法吧..新手可以用一下.. 这种Hook大多针对的对象是那种 函数头前5字节.特别是stdcall约定的函数. 函数头大多喜欢是这样 80820cc1 8bff mov edi,edi 80820cc3 55 push ebp 80820cc4 8bec mov ebp,esp 这样的指令..完全可以自己实现一下这三句 比如写成这样 __declspec(naked) PVOID g_Safe_ExAllocatePoolWithTag( IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag ) { __asm { mov edi,edi push ebp mov ebp,esp mov eax,g_ExAllocatePoolWithTag 这里你可以随意按需要修改.就是被挂钩的函数的地址.. add eax,5因为上面自己实现前5字节了.这里直接转移到5子节后执行..也就绕过了那5个字节的Hook.. ..当然了.还有一点切记..有些函数会检查调用者的PreviousMode..注意修改.这两个东西.论坛都有专门的文章解释..就不废话了. jmp eax } } |
|
|
|
|
|
[求助]监视windows服务创建的问题
呵呵.. 你要和我一样懒的话...就直接点.. 把IopLoadDriver给HOOK了..或者 MmLoadImage也行.. 不管是ZwLoadDriver还是SCM法.这两个地方必走的....省的还要单独处理..(说实话.这也很老套了.某杀软几百年前都用过了.).. Hook一个就代替了上面那么多. |
|
|
|
[求助]获取进程的全路径遇到困难
我有点好奇.. 楼主为什么有着现成的结构不用呢? typedef struct _PS_CREATE_NOTIFY_INFO { __in SIZE_T Size; union { __in ULONG Flags; struct { __in ULONG FileOpenNameAvailable : 1; __in ULONG Reserved : 31; }; }; __in HANDLE ParentProcessId; __in CLIENT_ID CreatingThreadId; __inout struct _FILE_OBJECT *FileObject; //可执行映像的文件对象.有了这个拿路径还不容易么? __in PCUNICODE_STRING ImageFileName; //这里就是名字. __in_opt PCUNICODE_STRING CommandLine; __inout NTSTATUS CreationStatus; } PS_CREATE_NOTIFY_INFO, *PPS_CREATE_NOTIFY_INFO; |
|
|
|
[求助]获取内核文件名字 诡异错误
嗯..我的思路是这样的... 首先.有一个算法..检查出系统装在什么分区.获取了这个.就很轻松知道了windows目录.. 然后..还需要一个内核文件名与之配合.. 所以.遍历PsLoadMoudleList表.第一项就是文件名..我用这个文件名.再配合前面的算法获得出来的路径.. 最后组合成一个原始内核文件名字的全路径.. 以这个路径打开内核文件.(这里假设是IoCreateFile)..然后映射入内存.(假设是 MmCreateSection..和MmMapViewOfSection等函数)..映射完毕,会返回一个基地址.我用这个基地址.开始搜索.办法就是遍历EAT...最后得出偏移..偏移+内核当前基地址(这个基地址.我用其他算法获取出来了.假设为内存暴搜)...这样就可以得出一个函数的当前真实地址了对不对.. 但是.就在这个情况下...就会出现.我描述的情况..如果在Intel 双核..获取 出的地址是错的... 如果在AMD双核.更严重.直接提示文件就是错的.不能映射. 如果在单核机器(不管AMD还是Intel都完美运行).. 并且.在Intel双核和AMD双核上..用ARK工具查看内核文件.明明是 nt***mp.exe 或者nt***pa.exe..但是这个PsLoadMoudleList一直就是显示 ntoskrnl.exe.. 所以就出现了最后的错误.. 这就是我的整个环节..我仔细审查了每一个环节.就出在这个名字错误上了. 谢谢楼上大牛的耐心指导..不知道还有没有其他办法准确的获取内核文件名字. |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值