首页
社区
课程
招聘
[求助] [SSDT HOOK] 调用NtXXX函数问题
发表于: 2013-5-6 18:41 4612

[求助] [SSDT HOOK] 调用NtXXX函数问题

2013-5-6 18:41
4612
问题是这样的:
我SSDT hook了 NtOpenFile,NtCreateFile,NtSetInformationFile,NtWriteFile等函数,同时也保存了原来真正Nt函数的地址OriNtOpenFile,OriCreateFile....
跳转到自己写的MyNtXXX函数中来,做一些事情,再调用原来的OriNtXXX.

我现在在MyNtSetInformationFile中想进行写文件操作,不要再走到自己的MyNtXXX函数中去了,我就调用OriCreateFile和OriWriteFile函数来操作。

问题是,调用OriCreateFile一直不成功(当然后序调用OriWriteFile也不能进行),返回的错误码是OxC000000D(An invalid parameter was passed to a service or function.)。搞了一下午,没有解决。
我又换成调用ZwCreateFile和ZwOriWriteFile,参数都不变,加载驱动,能成功,看DbgView中打印的信息,但是显示被hook到了,走的是MyNtXXX函数,可是我想直接调用Nt的函数啊。

各位大大们,为什么直接调用OriCreateFile不成功啊?

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
附上调用代码:

UNICODE_STRING mystr;//定义字符串结构用来存放字符串
                        UNICODE_STRING temp;//定义字符串结构来存放文件名
                        OBJECT_ATTRIBUTES myoa;//定义一个操作对象
                        HANDLE hfile=NULL;//定义一个句柄用于接收返回的文件句柄
                        IO_STATUS_BLOCK iostatus;//定义结构用来接收打开文件的返回值
                        NTSTATUS ntStatus = 0;
RtlInitUnicodeString(&mystr,L"test!");//初始化字符串
                       
                        mypath.Buffer=(PWCHAR)ExAllocatePoolWithTag(NonPagedPool,256,'My');
                        RtlInitUnicodeString(&temp,L"\\??\\D:\\info\\");//初始化路径字符串
                        RtlCopyUnicodeString(&mypath,&temp);
                        RtlInitUnicodeString(&temp,L"myfile.txt");
                        RtlAppendUnicodeStringToString(&mypath,&temp);
                       
                        DbgPrint("[info] 完整路径 path = %wZ", &mypath);
InitializeObjectAttributes(//初始化操作对象
                                &myoa,//操作对象
                                &mypath,//路径
                                OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,//属性
                                NULL,
                                NULL
                                );
                       
                       
//                DbgPrint("[Info] RootDirectory = %S\n", myoa.RootDirectory);
//                DbgPrint("[Info] ObjectName = %wZ\n", myoa.ObjectName);                       
               
                        ntStatus = OriNtCreateFile(//创建文件
                                &hfile,//返回的句柄
                                FILE_APPEND_DATA|SYNCHRONIZE,//打开文件时候的权限
                                &myoa,//文件对象
                                &iostatus,//返回值
                                NULL,
                                FILE_ATTRIBUTE_NORMAL,
                                FILE_SHARE_READ,//共享权限
                                FILE_OPEN_IF,//打开文件的方式
                                FILE_NON_DIRECTORY_FILE|FILE_RANDOM_ACCESS|FILE_SYNCHRONOUS_IO_NONALERT,
                                NULL,
                                0);
                               
            if (!NT_SUCCESS(ntStatus))
        {   
            DbgPrint("[Info]OriNtCreateFile failed with error:%08x\r\n", ntStatus);   
           
        }
                        ntStatus = OriNtWriteFile(
                                hfile,//文件句柄
                                NULL,
                                NULL,
                                NULL,
                                &iostatus,//返回值
                                mystr.Buffer,//字符串缓冲区
                                mystr.Length,//字符串长度
                                NULL,
                                NULL
                                );
                 if (!NT_SUCCESS(ntStatus))
        {   
            DbgPrint("[Info]OriNtWriteFile failed with error:%08x\r\n", ntStatus);   
         
        }
                        DbgPrint("[info] WriteTest OK\n");
                        ExFreePool(mypath.Buffer);
                        ZwClose(hfile);
2013-5-6 18:42
0
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
3
在内核直接用Nt函数要把PreviousMode换成 KernelMode
2013-5-6 22:08
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
写的是驱动。。。本身就是在内核中的 直接调用内核函数Nt*必须先设置PreMode?
2013-5-6 22:40
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
写的是驱动 直接调用Nt* 也要设置premode吗?
2013-5-6 22:47
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我在MyNtCreateFile中 ,最后也是返回Nt*原函数OriNtCreateFile ,好像没有设置mode,也调用成功了 这个又是为什么啊?
2013-5-6 22:56
0
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
7
2013-5-6 23:27
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
2013-5-7 11:40
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
9
楼主不会调试吗……
2013-5-7 11:43
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
LZ第一次接触驱动,不是很熟练,每次都是改好了编译,用monitor加载,在DbgView看输出情况。
试了好多次了就是调用不成功
2013-5-7 11:51
0
雪    币: 219
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
会不会是你保存的OriNtCreateFile地址错了?挂钩的时候检查一下
2013-5-7 17:52
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢大大!
确实设置一下mode就好了  ,但是还是有点不明白 ,hook的替代函数最后返回Nt*没有设置mode为什么能行呢?
2013-5-8 13:12
0
雪    币: 601
活跃值: (256)
能力值: ( LV11,RANK:190 )
在线值:
发帖
回帖
粉丝
13
用Ori*和Nt*函数是一样的,如果设置kernelmode,系统不会对参数进行合法性检查,如果是usermode,系统会对地址和句柄进行检查,如果发现不是来自应用层的地址或句柄就会发生异常,如果地址正确,会拷贝到内核一份;
hook的替代函数本身来自应用层,参数是否合法以及结果是否成功,只要把参数原版传给Orig*或Nt*就行了
2013-5-8 14:48
0
游客
登录 | 注册 方可回帖
返回
//