- 注册时间
 - 2021-4-16
 
- 最后登录
 - 2023-9-20
 
- 在线时间
 - 2 小时
 
 
 
 
 
编程入门 
  
	- 龙马币
 - 40 
 
 
 
 
 | 
 
 
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 
 |   
 
 
 
 |