<写在最后的话>
写到这里,我发现后面想要表达的意思越来越难说清楚,比如说我前面使用工具做的事情,根本就没有按照网上教程那样,提前修改第一处call ObOpenObjectByPointer的代码,而且第二处的call ObOpenObjectByPointer每次都用手工修改实在太累,如果用驱动来实现的话,需要用到irp的请求处理,还要单独写一个驱动的控制器,这根本不是三言两语就能说清的,况且本身很多东西连我自己都是模棱两可的,更别提说清楚了,发本帖的目的,第一是为了弄一个邀请码,希望能够和看雪的一些大牛请教,以及交换一些想法,以前我做java的时候,我并不喜欢编写代码,我更喜欢的是去攻克一个难关;第二个目的就是希望能找一些志同道合的朋友一起来研究驱动技术,尤其是和我一样新学驱动的朋友,话说三人行,必有我师,但是我看回帖里,基本上很少有人对此表示兴趣,在这里,我不知道能不能留QQ联系方式,不过我还是留一个(如果不能留,请回帖或站内消息通知我)我的QQ是623509,希望初学,已入门,驱动高手都能来指导交流。本帖将不再更新,感谢支持的朋友!
<4.19更新>
附件是我所学教程里面的一个驱动框架,希望给下载了DDK,但是不会编译的同学看看,里面我抄送了教程里面的VS2003的编译配置,但是记住哈,这个配置也只能检查驱动编写是否正确,编译出来的驱动文件一样是不能用的,还是需要用DDK来编译,建议使用3790.1830,反正我是用这个来编译的,发这个出来希望教程老师勿怪哈,毕竟我没有将一些核心的代码发出来的,这些基本上网上都能找到的
<4.16更新>
这两天在做一些生意,累死了,汗,没更新此贴,抱歉,听已过TP的大牛讲,俺的思路错了,所以俺决定考虑其他办法,否认前面的想法。继续努力!
<4.14 12点更新>
通过查看前面光海的帖子,再通过直接用记事本打开tessafe.sys,发现驱动里很多关键字都和光海那篇帖子里面提到的函数相似,(以下也是一些臆测,无事实依据)于是我们假设TP就是用帖子的办法来hook ObOpenObjectByPointer的,那么我们应该如何来搞定它呢?百度以下,又发现一个很有用的信息:
听驴子说函数PsLookupProcessByProcessId先得到PID对应的EPROCESS(进程对象),然后再由函数ObOpenObjectByPointer(Object -> Handle),最后返回的是句柄。KV拦截了函数ObOpenObjectByPointer,所以没办法获得江民的句柄乃至调用NtQueryVirtualMemory枚举进程模块。
后记:其实TX的大部分游戏也拦截了这个函数...寻仙等
估计只要想保护某个进程,这个函数以后是必争之地,全给inlinehook了。
于是,我的想法是:如果,假设,比如,咱们自己Hook住PsLookupProcessByProcessId(这个TP没Hook的),然后咱们自己写一个空.exe文件,运行它,当TP调用PsLookupProcessByProcessId的时候,我们不是要返回一个进程对象么,咱们返回空.exe的进程对象给他,不知道会咋样。。。。。。。。
这个实现起来有点麻烦,所以请高手帮忙判断下,我这个想法能否成立
<4.14 11点更新>
否认前面的猜测,并且找了一些关于ObOpenObjectByPointer的资料,我不知道看雪能不能发外链,不过这里我也发出来,如果看雪不允许发,请回帖或站内消息通知我
http://ghoffice.com/bbs/read-htm-tid-62624.html
<4.14更新>
经过昨晚4小时,加今天1小时的努力,对于QQ堂,我发现其对NTOpenProcess有两处修改,均在call ObOpenObjectByPointer处,其中第二处可以直接用工具修改到原始的ObOpenObjectByPointer地址,第一处用工具修改,机器自动重启,于是俺决定俺网上某文章,在call ObOpenObjectByPointer之前,我们跳转到自己的代码,并且call原始的ObOpenObjectByPointer,我用驱动HOOK住NTOpenEventPair,并在处理代码处不断添加int 3代码(毫无意义的代码,只是为了开辟一个空的空间出来放置我们的代码,我并不知道这样是不是走了弯路,但是至少可以实现。因为是新手,所以我并不知道其他办法,高手就别笑了)
最后将我们自己要call真正ObOpenObjectByPointer的代码手工填写到NTOpenEventPair+6的位置,修改NTOpenProcess里面,call ObOpenObjectByPointer-13的位置,jmp 到NTOpenEventPair+6,未蓝屏,未重启,但是过一会,TP会报非法,正在想其他思路,希望志同道合的朋友一起多研究
想法(仅仅是一些思考,也许很多都是无稽之谈,高手别见笑):在我jmp 到NTOpenEventPair+6位置的时候,TP并未马上报非法模块,而是一会再报出错误,会不会想回复里某说的,TP进行了定时检测呢?我更倾向于TP会检测自己的代码,但不应该会检测OpenProcess的代码啊,为什么这么说?因为我们直接修改第二处的call ObOpenObjectByPointer是没有问题的哦~~~,那么会不会TP自动检测第一处ObOpenObjectByPointer附近的代码呢?恩,先想办法证实一下这个猜测!
<4.13更新>
本人菜鸟一只,大牛请轻轻的走,不带来一块砖头,近期正在学习驱动编程,花了几百大洋购买的驱动教程,看后深感值得,以下代码是今晚我用30分钟编写的,比较乱,但是好在简单,至于为什么要这样,主要是考虑到和我一样的菜鸟,怕他们看不懂,因此我未用任何的驱动框架来完成这个小东西,但是坏处也是肯定的,这段代码可以说很多驱动基本的要求都没有实现,比如创建,卸载设备,IRP请求的处理等等
我忘记什么时候注册看雪的,不过这么久还是临时会员,每思及此,深感自责,因为人比较懒,重要的是比较菜,赚KX实在是要俺的小命,因此只能厚颜申请邀请码一只,忘版主,管理员通融通融,谢谢!
看过图片应该看到,俺虚拟机里装QQ堂啦,俺准备不知量力,尝试腾讯的驱动了,希望有同样正在菜鸟阶段徘徊的我们能互相交流,共同进步!!!!!!
#ifdef __cplusplus
extern "C" //以C的方式编译,方便我们在IDE中编译
{
#endif
#include <NTDDK.h>
#include <windef.h>
#ifdef __cplusplus
}
#endif
#define INITCODE code_seg("INIT")
#pragma INITCODE
#define PAGEDDATA data_seg("PAGE")
#pragma pack(1)
typedef struct _JMPCODE
{
BYTE E9; //E9是jmp的16进制编码
ULONG JMPADDR; //教程老师说这是“跳转到的地址”,我的理解是,这是要跳转地址的16进制编码,当然也不能这么说,也许高手能说清楚,反正理解了你就懂了,我在这里卡了几个小时才弄懂
}JMPCODE,*PJMPCODE;
#pragma pack()
typedef struct _ServiceDescriptorTable {
PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
PVOID ServiceCounterTable; //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;
extern "C" PServiceDescriptorTable KeServiceDescriptorTable;
VOID Unloaddriver(PDRIVER_OBJECT driver);
ULONG Get_CurNTOpenProcess_Addr();
ULONG Get_OrgNTOpenProcess_Addr();
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver,PUNICODE_STRING reg_path)
{
ULONG Cur,Org;
DbgPrint("驱动被加载");
Cur=Get_CurNTOpenProcess_Addr();
Org=Get_OrgNTOpenProcess_Addr();
if(Cur==Org)
{
DbgPrint("NTOpenProcess未被Hook");
}
else
{
DbgPrint("NTOpenProcess被HOOK!");
JMPCODE JmpCode;
PJMPCODE pCur;
JmpCode.E9=0xe9;
JmpCode.JMPADDR=Org-Cur-5;
KdPrint(("要跳转地址的16进制编码是:%X",JmpCode));
__asm //去掉页面保护
{
cli
mov eax,cr0 //80010000
and eax,not 10000h mov cr0,eax //80000000
}
//写入代码
pCur=(PJMPCODE)Cur;
pCur->E9=JmpCode.E9;
pCur->JMPADDR=JmpCode.JMPADDR;
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
}
driver->DriverUnload=Unloaddriver;
return STATUS_SUCCESS;
}
VOID Unloaddriver(PDRIVER_OBJECT driver)
{
DbgPrint("驱动被卸载");
}
//---获得NTOpenProcess的原始地址和当前地址,这里我按照教程里学的,用了汇编和C两种方式-------
ULONG Get_CurNTOpenProcess_Addr()
{
//获得NTOpenProcess当前地址
ULONG Cur_NTOpenProcess_Addr;
_asm
{
//int 3
push eax
mov eax,KeServiceDescriptorTable
mov eax,[eax]
push ebx
mov ebx,0x7a
shl ebx,2
add eax,ebx
pop ebx
mov eax,[eax]
mov Cur_NTOpenProcess_Addr,eax
pop eax
}
KdPrint(("NTOpenProcess当前地址是:%x",Cur_NTOpenProcess_Addr));
return Cur_NTOpenProcess_Addr;
}
ULONG Get_OrgNTOpenProcess_Addr()
{
//获得NTOpenProcess原始地址
UNICODE_STRING Old_NtOpenProcess;
ULONG Org_NTOpenProcess_Addr;
RtlInitUnicodeString(&Old_NtOpenProcess,L"NtOpenProcess");
Org_NTOpenProcess_Addr=(ULONG)MmGetSystemRoutineAddress(&Old_NtOpenProcess);//取得NtOpenProcess的地址
KdPrint(("NTOpenProcess原始地址是:%x",Org_NTOpenProcess_Addr));
return Org_NTOpenProcess_Addr;
}
//------------------------------------------------------------------------------------------
运行某款游戏
使用工具发现其Hook了NTOpenprocess
使用MSH附加,发现无法附加进程(废话,勾住了NTOpenProcess当然无法附加)
运行Driver加载工具,加载咱们的驱动UnHook.sys
让驱动运行
再使用MSH附加,发现可以附加
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课