- 注册时间
 - 2021-4-16
 
- 最后登录
 - 2025-3-14
 
- 在线时间
 - 6 小时
 
 
 
 
 
编程入门 
  
	- 龙马币
 - 470 
 
 
 
 
 | 
 
 
1.驱动采用Unicode字符串 
 
typedef struct _STRING { 
USHORT Length; 
USHORT MaximumLength; 
PSTR Buffer; 
} ANSI_STRING, *PANSI_STRING; 
 
UNICODE_STRING str = RTL_CONSTANT_STRING(L“my first string!”); 
 
UNICODE_STRING str; 
RtlInitUnicodeString(&str,L”my first string!”); 
 
UNICODE_STRING dst;   // 目标字符串 
WCHAR dst_buf[256];    // 我们现在还不会分配内存,所以先定义缓冲区 
UNICODE_STRING src = RTL_CONST_STRING(L”My source string!”); 
 
// 把目标字符串初始化为拥有缓冲区长度为256的UNICODE_STRING空串。 
RtlInitEmptyString(dst,dst_buf,256*sizeof(WCHAR)); 
RtlCopyUnicodeString(&dst,&src); // 字符串拷贝 
RtlAppendUnicodeToString(&dst,L”my second string!”); 
RtlAppendUnicodeStringToString  //连接两个UNICODE_STRING 
 
RtlStringCbPrintfW(dst->Buffer,L”file path = %wZ file size = %d \r\n”,&file_path,file_size); 
 
 
2. 内存与链表 
 
#define MEM_TAG ‘MyTt’   // 定义一个内存分配标记 
UNICODE_STRING dst = { 0 };  // 目标字符串,接下来它需要分配空间。 
// 分配空间给目标字符串。根据源字符串的长度。 
dst.Buffer = (PWCHAR)ExAllocatePoolWithTag(NonpagedPool,src->Length,MEM_TAG); 
dst.Length = dst.MaximumLength = src->Length; 
 
ExFreePool(dst.Buffer); 
dst.Buffer = NULL; 
dst.Length = dst.MaximumLength = 0; 
 
LIST_ENTRY  my_list_head; 
InitializeListHead(&my_list_head); 
InsertHeadList(&my_list_head, (PLIST_ENTRY)& my_file_infor); 
LIST_ENTRY中的数据成员Flink指向下一个LIST_ENTRY。 
整个链表中的最后一个LIST_ENTRY的Flink不是空。而是指向头节点。 
 
 
3.内核自旋锁 
KSPIN_LOCK my_spin_lock; 
KeInitializeSpinLock(&my_spin_lock); 
 
KIRQL irql; 
KeAcquireSpinLock(&my_spin_lock,&irql); 
// To do something … 
KeReleaseSpinLock(&my_spin_lock,irql); 
 
ExInterlockedInsertHeadList(&my_list_head, (PLIST_ENTRY)& my_file_infor,&my_list_lock); 
 
my_file_infor = ExInterlockedRemoveHeadList (&my_list_head, &my_list_lock); 
 
 
4.文件操作 
InitializeObjectAttributes 
ZwCreateFile 
ZwReadFile 
ZwWriteFile 
 
 
5. 注册表 
打开注册表键使用函数ZwOpenKey。 
新建或者打开则使用ZwCreateKey。 
使用ZwQueryValueKey来读取注册表中键的值。 
写入值一般使用函数ZwSetValueKey。 
 
 
6.时间与定时器 
KeQueryTickCount()返回系统自启动之后经历的“滴答”数。类似win32的GetTickCount()。 
ULONG KeQueryTimeIncrement(); //获得一个“滴答”的具体的100纳秒数 
 
KeQuerySystemTime得到格林威治时间。之后请使用ExSystemTimeToLocalTime()转换可以当地时间。 
函数RtlTimeToTimeFields转换为TIME_FIELDS 
 
KeSetTimer 
KeInitializeTimer 
KeInitializeDpc 
KeCancelTimer 
OnTimer中还有必要再次调用MyTimerSet(),来保证下次依然得到执行。 
 
 
7.内核线程 
PsCreateSystemThread 
PsTerminateSystemThread(STATUS_SUCCESS); // 结束自己。 
KeDelayExecutionThread    //sleep 
 
 
KEVENT event; 
KeInitializeEvent 
KeSetEvent 
KeWaitSingleObject 
KeSetEvent 
KeResetEvent 
 |   
 
 
 
 |