/*注意这里的所有偏移仅为xp sp3中的*/
我在之前的一篇文章提到了监控进程启动的方法
同理可以监控进程结束 打开 我之前使用ssdt+inline的方式保护我自己的进程不被结束
但是显然太单薄了 这只能拦截r3的动作 以及r0直接使用ZWopenprocess的动作
一旦使用了更底层的 将无能为力
所以我尝试跟踪ntopenprocess来看看他到底怎么获取句柄的
一开始 我们就不通过ssdt+服务号的方式了
直接 u openprocess
我们一直跟踪到 openprocess+0x224的地方 发现这里是一个e8的call
我这里通过指令dd看到的代码是fefe7de8 各个机器可能不一样
但是末尾肯定是个e8
u看到的是
805c261c e87dfefeff call nt!ObOpenObjectByPointer (805b249e)
也就是说 这是call到ObOpenObjectByPointer这个函数
我记得之前有个函数是通过函数名取得地址的 但是我这里还是通过自己算到然后取出来的方式
e8这种call的规律是 自己的地址+代码地址+5=目标地址
也就是说这里 是0x805c261c+0xfffefe7d + 5,得到的是1805B249E
一个address是4个字节 也就是8个16位的数 所以最高的那个1 会溢出
也就是说会被无视掉,最终我们得到的是805B249E这个地址
这与windbg算到的地址是相同的 为了验证 我们u过去
u 805B249E
nt!ObOpenObjectByPointer:
805b249e 8bff mov edi,edi
805b24a0 55 push ebp
805b24a1 8bec mov ebp,esp
805b24a3 81ec94000000 sub esp,94h
好的 符号文件告诉我们这里确实是ObOpenObjectByPointer的地址
而我们通过逆向n多程序得到的经验告诉我们编译器喜欢在开头加上
mov edi,edi 以及保存ebp 并将esp作为ebp
而这里也符合这个特征
ObOpenObjectByPointer的原型是:
NTSTATUS ObOpenObjectByPointer( __in PVOID Object,
__in ULONG HandleAttributes,
__in_opt PACCESS_STATE PassedAccessState,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PHANDLE Handle);
第一个参数是一个指向一个EPROCESS类型的结构体的指针
虽然他的类型是空
但是这不妨碍我们 根据系统来获取进程pid所在偏移直接read出来就可以了