C#能调用windows底层的文件驱动不?

miss__zhang 2012-08-16 03:44:37
C#能调用windows底层的文件驱动不? 求助,呵呵
...全文
440 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
miss__zhang 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

Hook只能用C写,Hook基本都是内存操作的函数,用C写更加容易。还有,我说的那个NtCreateFile指的是内核中的,不是Ntdll里的,这个得写驱动来实现,如果你需要,我可以给你写一个简单的例子,不过是C的代码
[/Quote]
感谢了,如果你有简单的vc++的例子的话给我一个行不?我研究下, 就是能在所有进程创建文件的时候我先解惑消息,如果文件不是我想要的就不让创建,再次感谢!这样我就结贴了!
fly4free 2012-08-17
  • 打赏
  • 举报
回复
c# 能 dllimport 使用用 extern c 方式 导出的函数

还可以用 COM ,使得 C# 能看见接口

都不容易啊……

窗户纸 2012-08-17
  • 打赏
  • 举报
回复
底层驱动C#没法直接做,但可以通过管道等方式与直接与你用其他语言做的底层驱动进行通信
miss__zhang 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

Hook只能用C写,Hook基本都是内存操作的函数,用C写更加容易。还有,我说的那个NtCreateFile指的是内核中的,不是Ntdll里的,这个得写驱动来实现,如果你需要,我可以给你写一个简单的例子,不过是C的代码
[/Quote]
哎,疯了,自学了C#之后看来又要自学C了,哥子,你是好人啊!
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复
Hook只能用C写,Hook基本都是内存操作的函数,用C写更加容易。还有,我说的那个NtCreateFile指的是内核中的,不是Ntdll里的,这个得写驱动来实现,如果你需要,我可以给你写一个简单的例子,不过是C的代码
miss__zhang 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

引用 3 楼 的回复:

引用 2 楼 的回复:

可以的,底层和应用层的API都可以,

要怎么实现呢?能否给个思路,在网上大部分都是用vc++写的不太懂,想实现对一个特定的文件夹里面的所有文件进行监控,并且防止其他进程创建一些特殊文件,谢谢!


如果要防止其他进程创建文件,应用层的话需要注入你要防止的进程,但这个只是防止了某一个进程,如果要防止所有进程往特定目录创建文……
[/Quote]
呵呵,我比你还新手,C#如果要HOOK NtCreatFile这个函数应该怎么实现呢?谢谢帮助啊!
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]

引用 18 楼 的回复:
要不我给你传文件,我这已经成功了,win7和XP都可以,在C盘根目录下无法创建1.txt。

QQ:1075375145

对了,能把项目打包一个不?我学习学习
[/Quote]
恩,源码在包里了
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 的回复:]

引用 18 楼 的回复:

要不我给你传文件,我这已经成功了,win7和XP都可以,在C盘根目录下无法创建1.txt。

QQ:1075375145

要不晚上加你,现在在公司不能上私人qq,抓到要被当迟到一次处理,哎,蛋疼的公司!或者发我qq邮箱250303142@qq.com,晚上回去加你,哥子,太感谢了!可以结贴了!
[/Quote]
好了,给你发邮件了
miss__zhang 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]
要不我给你传文件,我这已经成功了,win7和XP都可以,在C盘根目录下无法创建1.txt。

QQ:1075375145
[/Quote]
对了,能把项目打包一个不?我学习学习
miss__zhang 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 的回复:]

要不我给你传文件,我这已经成功了,win7和XP都可以,在C盘根目录下无法创建1.txt。

QQ:1075375145
[/Quote]
要不晚上加你,现在在公司不能上私人qq,抓到要被当迟到一次处理,哎,蛋疼的公司!或者发我qq邮箱250303142@qq.com,晚上回去加你,哥子,太感谢了!可以结贴了!
yp19910928 2012-08-17
  • 打赏
  • 举报
回复
可以调用
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复
要不我给你传文件,我这已经成功了,win7和XP都可以,在C盘根目录下无法创建1.txt。

QQ:1075375145
miss__zhang 2012-08-17
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

好的,稍等,我写一个
[/Quote]
谢了谢了,一直在关注中!
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复

#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
#include <wdm.h>
#include <string.h>
#include <windef.h>
#ifdef __cplusplus
}; // extern "C"
#endif

#include "HookNtCreateFile.h"

#ifdef __cplusplus
namespace {
#endif
PDRIVER_OBJECT pdoGlobalDrvObj = 0;
#ifdef __cplusplus
};
#endif

DWORD NtCreateFileIndex=0;
PDWORD isChange=0;
HANDLE hEvent=NULL;

typedef struct ServiceDescriptorTable
{
DWORD ServiceTableBase;
PVOID pvServiceCounterTable;
ULONG ulNumberOfServices;
PVOID pvParamTableBase;
}SSDT, *PSSDT;
extern "C" PSSDT KeServiceDescriptorTable;

typedef NTSTATUS (NTAPI *_RealNtCreateFile)(__out PHANDLE FileHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__out PIO_STATUS_BLOCK IoStatusBlock,
__in_opt PLARGE_INTEGER AllocationSize,
__in ULONG FileAttributes,
__in ULONG ShareAccess,
__in ULONG CreateDisposition,
__in ULONG CreateOptions,
__in_opt PVOID EaBuffer,
__in ULONG EaLength);

_RealNtCreateFile RealNtCreateFile;

NTSTATUS GetNtCreateFileIndex(VOID)
{
UNICODE_STRING usZwCreateFile;
RtlInitUnicodeString(&usZwCreateFile,L"ZwCreateFile");
DWORD ZwCreateFile_func= (DWORD)MmGetSystemRoutineAddress(&usZwCreateFile);
NtCreateFileIndex = *(DWORD*)(ZwCreateFile_func + 1);
KdPrint(("NtCreateFile 函数在SSDT表中的序号是: %x\n",NtCreateFileIndex));
RealNtCreateFile=(_RealNtCreateFile)(*(DWORD*)(KeServiceDescriptorTable->ServiceTableBase+NtCreateFileIndex*4));
KdPrint(("NtCreateFile 函数的地址是:%x",(DWORD)RealNtCreateFile));
return STATUS_SUCCESS;
}

NTSTATUS NTAPI MyNtCreateFile(__out PHANDLE FileHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__out PIO_STATUS_BLOCK IoStatusBlock,
__in_opt PLARGE_INTEGER AllocationSize,
__in ULONG FileAttributes,
__in ULONG ShareAccess,
__in ULONG CreateDisposition,
__in ULONG CreateOptions,
__in_opt PVOID EaBuffer,
__in ULONG EaLength)
{
UNICODE_STRING FilePath;
RtlInitUnicodeString(&FilePath,L"\\??\\C:\\1.txt");
if(!RtlCompareUnicodeString(&FilePath,ObjectAttributes->ObjectName,TRUE)) //如果是你指定的文件名则返回失败
{
KdPrint((ObjectAttributes->ObjectName->Buffer));
return STATUS_UNSUCCESSFUL;
}
return RealNtCreateFile(
FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocationSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength);
}

NTSTATUS HookNtCreateFile(VOID)
{
GetNtCreateFileIndex();
__asm
{
cli
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
*(DWORD*)(KeServiceDescriptorTable->ServiceTableBase+NtCreateFileIndex*4)=(DWORD)MyNtCreateFile;
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
if(*(DWORD*)(KeServiceDescriptorTable->ServiceTableBase+NtCreateFileIndex*4)==(DWORD)MyNtCreateFile)
return STATUS_SUCCESS;
else
return STATUS_UNSUCCESSFUL;
}

NTSTATUS UnHookNtCreateFile(VOID)
{
__asm
{
cli
mov eax, cr0
and eax, not 10000h
mov cr0, eax
}
if(RealNtCreateFile)
{
*(DWORD*)(KeServiceDescriptorTable->ServiceTableBase+NtCreateFileIndex*4)=(DWORD)RealNtCreateFile;
KdPrint(("NtCreateFile Restored!\n"));
}
__asm
{
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
if(RealNtCreateFile)
{
return STATUS_SUCCESS;
}
else
{
return STATUS_UNSUCCESSFUL;
}
}

NTSTATUS HOOKNTCREATEFILE_DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

NTSTATUS HOOKNTCREATEFILE_DispatchDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PVOID InBuffer,OutBuffer;
InBuffer = OutBuffer = (PCHAR)Irp->AssociatedIrp.SystemBuffer;
ULONG uOutSize=irpSp->Parameters.DeviceIoControl.OutputBufferLength;
//isChange=(DWORD*)MmMapIoSpace(MmGetPhysicalAddress((void*)(*(DWORD*)InBuffer)),4,MmNonCached);
switch(irpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HOOKNTCREATEFILE_OPERATION:
// status = SomeHandlerFunction(irpSp);
if(HookNtCreateFile()==STATUS_SUCCESS)
{
CHAR cInfo[] = "Hook NtCreateFile成功了";
int cInfoLen = strlen(cInfo)+1;
memcpy(OutBuffer,cInfo,cInfoLen);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
default:
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
break;
}
if(status==STATUS_SUCCESS)
Irp->IoStatus.Information=uOutSize;
else
Irp->IoStatus.Information=0;
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

VOID HOOKNTCREATEFILE_DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
UnHookNtCreateFile();
ZwClose(hEvent);
PDEVICE_OBJECT pdoNextDeviceObj = pdoGlobalDrvObj->DeviceObject;
IoDeleteSymbolicLink(&usSymlinkName);

while(pdoNextDeviceObj)
{
PDEVICE_OBJECT pdoThisDeviceObj = pdoNextDeviceObj;
pdoNextDeviceObj = pdoThisDeviceObj->NextDevice;
IoDeleteDevice(pdoThisDeviceObj);
}
}

#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
PDEVICE_OBJECT pdoDeviceObj = 0;
NTSTATUS status = STATUS_UNSUCCESSFUL;
pdoGlobalDrvObj = DriverObject;

if(!NT_SUCCESS(status = IoCreateDevice(
DriverObject,
0,
&usDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&pdoDeviceObj
)))
{
return status;
};

if(!NT_SUCCESS(status = IoCreateSymbolicLink(
&usSymlinkName,
&usDeviceName
)))
{
IoDeleteDevice(pdoDeviceObj);
return status;
}

DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = HOOKNTCREATEFILE_DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HOOKNTCREATEFILE_DispatchDeviceControl;
DriverObject->DriverUnload = HOOKNTCREATEFILE_DriverUnload;

return STATUS_SUCCESS;
}
#ifdef __cplusplus
}; // extern "C"
#endif
bigbaldy 2012-08-17
  • 打赏
  • 举报
回复
好的,稍等,我写一个
bigbaldy 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

引用 2 楼 的回复:

可以的,底层和应用层的API都可以,

要怎么实现呢?能否给个思路,在网上大部分都是用vc++写的不太懂,想实现对一个特定的文件夹里面的所有文件进行监控,并且防止其他进程创建一些特殊文件,谢谢!
[/Quote]

如果要防止其他进程创建文件,应用层的话需要注入你要防止的进程,但这个只是防止了某一个进程,如果要防止所有进程往特定目录创建文件,那就得注入所有的进程了,比较麻烦,也许有其他方法,不过我也新手不太清楚。而内核里就比较容易了,你只需要把SSDT表中NtCreateFile函数的地址改成你自己的函数,然后判断传进来的参数,如果是你所指定的目录,直接返回失败即可
bigbaldy 2012-08-16
  • 打赏
  • 举报
回复
还有,C#本身就有FileSystemWatcher,用起来很方便
bigbaldy 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 4 楼 的回复:

非常肯定的告诉你,可以调用

确认是可以调用,但是能否起到文件以改变就会通知用户呢?因为看了些例子在c++里面调用这个函数是比较方便的,但是不晓得在C#里面调用这个api函数能否起到监控的作用,谢谢了!
[/Quote]

能调用就一定起作用,只不过用C#写有些结构得自己声明,例如PFILE_NOTIFY_INFORMATION,还得调用一些其他API,如果用C写就很方便了,你可以用C写dll再用C#调,反正我一向的原则是,哪个方便就用哪个,没必要非得用C#
miss__zhang 2012-08-16
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

非常肯定的告诉你,可以调用
[/Quote]
确认是可以调用,但是能否起到文件以改变就会通知用户呢?因为看了些例子在c++里面调用这个函数是比较方便的,但是不晓得在C#里面调用这个api函数能否起到监控的作用,谢谢了!
bigbaldy 2012-08-16
  • 打赏
  • 举报
回复
非常肯定的告诉你,可以调用
加载更多回复(3)

110,532

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧