内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.
一丶内核中的数据类型
在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中.
数据类型都一定重定义了.
|
数据类型 |
重定义数据类型 |
|
Unsigned long |
ULONG |
|
Unsigned char |
UCHAR |
|
Unsigned int |
UINT |
|
Void |
VOID |
|
Unsigned long * |
PULONG |
|
Unsigned char * |
PCHAR |
|
Unsigned int * |
PUINT |
|
Void * |
PVOID |
其中字符串的数据结构也改变了.
typedef struct _UNICODE_STRING{
USHORT Length //字符串长度
USHORT MaximumLength //字符串最大长度
PWSTR Buffer; //字符串指针
}UNICODE_STRING, *PUNICODE_STRING
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;
其中操作字符串都有相应的Kerner API. 可以查询MSDN 或者 WDK Document 进行操作.
二丶内核中的重要数据结构.
IRP请求会发送给设备对象.然后驱动对象会捕获.通过分发函数进行处理. 一个驱动对象可以有多个设备对象.
在内核中. 有驱动对象.设备对象. 以及IRP请求.
驱动对象数据结构
typedef struct _DRIVER_OBJECT {
CSHORT Type; //类型
CSHORT Size; //大小.
PDEVICE_OBJECT DeviceObject; //设备对象链表开始,一个驱动对象可以有多个设备对象.其中DeviceObject结构体中有相关信息.
ULONG Flags;
PVOID DriverStart; //内核模块在内核中间的开始地址跟大小.
ULONG DriverSize;
PVOID DriverSection;
PDRIVER_EXTENSION DriverExtension;
UNICODE_STRING DriverName;//驱动的名字
PUNICODE_STRING HardwareDatabase;
//快速IO分发函数.
PFAST_IO_DISPATCH FastIoDispatch;
PDRIVER_INITIALIZE DriverInit;
PDRIVER_STARTIO DriverStartIo;
//驱动对象的卸载函数.
PDRIVER_UNLOAD DriverUnload;
//一个函数指针数组. 普通的分发函数.数组中保存了分发函数的地址.
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + ];
} DRIVER_OBJECT;
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;
设备对象数据结构
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT {
CSHORT Type; //类型跟大小.
USHORT Size;
//引用计数
LONG ReferenceCount;
//这个设备所属于驱动对象的指针. 保存了驱动对象.
struct _DRIVER_OBJECT *DriverObject;
//下一个设备对象.一个驱动对象可以有n个设备.用单向链表进行连接.
struct _DEVICE_OBJECT *NextDevice;
struct _DEVICE_OBJECT *AttachedDevice;
struct _IRP *CurrentIrp;
PIO_TIMER Timer;
ULONG Flags; // See above: DO_...
ULONG Characteristics; // See ntioapi: FILE_...
__volatile PVPB Vpb;
PVOID DeviceExtension;
//设备对象类型
DEVICE_TYPE DeviceType;
//堆栈大小.
CCHAR StackSize;
union {
LIST_ENTRY ListEntry;
WAIT_CONTEXT_BLOCK Wcb;
} Queue;
ULONG AlignmentRequirement;
KDEVICE_QUEUE DeviceQueue;
KDPC Dpc;
//
// The following field is for exclusive use by the filesystem to keep
// track of the number of Fsp threads currently using the device
//
ULONG ActiveThreadCount;
PSECURITY_DESCRIPTOR SecurityDescriptor;
KEVENT DeviceLock;
USHORT SectorSize;
USHORT Spare1;
struct _DEVOBJ_EXTENSION *DeviceObjectExtension;
PVOID Reserved;
} DEVICE_OBJECT;
typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT;
IRP 请求包.
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _IRP {
CSHORT Type; //类型
USHORT Size; //大小
//
// Define the common fields used to control the IRP.
//
//
// Define a pointer to the Memory Descriptor List (MDL) for this I/O
// request. This field is only used if the I/O is "direct I/O".
//
PMDL MdlAddress; //内核描述符指针.读写的缓冲区.
//
// Flags word - used to remember various flags.
//
ULONG Flags;
//
// The following union is used for one of three purposes:
//
// 1. This IRP is an associated IRP. The field is a pointer to a master
// IRP.
//
// 2. This is the master IRP. The field is the count of the number of
// IRPs which must complete (associated IRPs) before the master can
// complete.
//
// 3. This operation is being buffered and the field is the address of
// the system space buffer.
//
union { //SystemBuffer里面看看请求是那个IO请求.来取决于用上面的缓冲区还是下面的缓冲区.
struct _IRP *MasterIrp;
__volatile LONG IrpCount;
PVOID SystemBuffer;
} AssociatedIrp;
//
// Thread list entry - allows queueing the IRP to the thread pending I/O
// request packet list.
//
LIST_ENTRY ThreadListEntry;
//
// I/O status - final status of operation.
//
IO_STATUS_BLOCK IoStatus; // IO的请求状态.一般请求完成后的返回情况放在这里.
//
// Requestor mode - mode of the original requestor of this operation.
//
KPROCESSOR_MODE RequestorMode;
//
// Pending returned - TRUE if pending was initially returned as the
// status for this packet.
//
BOOLEAN PendingReturned;
//
// Stack state information.
//
CHAR StackCount; //栈空间大小.
CHAR CurrentLocation; //当前的IRP栈空间.
//
// Cancel - packet has been canceled.
//
BOOLEAN Cancel;
//
// Cancel Irql - Irql at which the cancel spinlock was acquired.
//
KIRQL CancelIrql;
//
// ApcEnvironment - Used to save the APC environment at the time that the
// packet was initialized.
//
CCHAR ApcEnvironment;
//
// Allocation control flags.
//
UCHAR AllocationFlags;
//
// User parameters.
//
PIO_STATUS_BLOCK UserIosb;
PKEVENT UserEvent;
union {
struct {
union {
PIO_APC_ROUTINE UserApcRoutine;
PVOID IssuingProcess;
};
PVOID UserApcContext;
} AsynchronousParameters;
LARGE_INTEGER AllocationSize;
} Overlay;
//
// CancelRoutine - Used to contain the address of a cancel routine supplied
// by a device driver when the IRP is in a cancelable state.
//
__volatile PDRIVER_CANCEL CancelRoutine; //用来取消一个未决请求的函数.
//
// Note that the UserBuffer parameter is outside of the stack so that I/O
// completion can copy data back into the user's address space without
// having to know exactly which service was being invoked. The length
// of the copy is stored in the second half of the I/O status block. If
// the UserBuffer field is NULL, then no copy is performed.
//
PVOID UserBuffer; //与MdlAddress 跟SystemBuffer一样都是缓冲区.
//缓冲区的特性不同.
//
// Kernel structures
//
// The following section contains kernel structures which the IRP needs
// in order to place various work information in kernel controller system
// queues. Because the size and alignment cannot be controlled, they are
// placed here at the end so they just hang off and do not affect the
// alignment of other fields in the IRP.
//
union {
struct {
union {
//
// DeviceQueueEntry - The device queue entry field is used to
// queue the IRP to the device driver device queue.
//
KDEVICE_QUEUE_ENTRY DeviceQueueEntry;
struct {
//
// The following are available to the driver to use in
// whatever manner is desired, while the driver owns the
// packet.
//
PVOID DriverContext[];
} ;
} ;
//
// Thread - pointer to caller's Thread Control Block.
//
PETHREAD Thread; //发出这个请求的线程.
//
// Auxiliary buffer - pointer to any auxiliary buffer that is
// required to pass information to a driver that is not contained
// in a normal buffer.
//
PCHAR AuxiliaryBuffer;
//
// The following unnamed structure must be exactly identical
// to the unnamed structure used in the minipacket header used
// for completion queue entries.
//
struct {
//
// List entry - used to queue the packet to completion queue, among
// others.
//
LIST_ENTRY ListEntry;
union {
//
// Current stack location - contains a pointer to the current
// IO_STACK_LOCATION structure in the IRP stack. This field
// should never be directly accessed by drivers. They should
// use the standard functions.
//
// 一个IRP 栈空间的元素.
struct _IO_STACK_LOCATION *CurrentStackLocation;
//
// Minipacket type.
//
ULONG PacketType;
};
};
//
// Original file object - pointer to the original file object
// that was used to open the file. This field is owned by the
// I/O system and should not be used by any other drivers.
//
PFILE_OBJECT OriginalFileObject;
} Overlay;
//
// APC - This APC control block is used for the special kernel APC as
// well as for the caller's APC, if one was specified in the original
// argument list. If so, then the APC is reused for the normal APC for
// whatever mode the caller was in and the "special" routine that is
// invoked before the APC gets control simply deallocates the IRP.
//
KAPC Apc;
//
// CompletionKey - This is the key that is used to distinguish
// individual I/O operations initiated on a single file handle.
//
PVOID CompletionKey;
} Tail;
} IRP;
其中IRP注意的事项. 因为IRP发送给设备对象请求.所以有多个设备对象.而IRP结构体是固定的.所以在操作的时候.会有一些变动的参数.为了存储这些变动的参数.
所以IRP结构体中保存了当前IRP堆栈.如果获取这些变动的参数.可以通过IRP堆栈来操作.
其中: CurrentLocation表示的当前是哪一个IRP堆栈.
三丶内核中常用的kerner API
我们知道.在应用层中.我们有SDK开发工具包. 里面的API供我们使用.现在内核中也提供了Kerner(内核) API给我们使用.
一般名字都有前缀.
IO EX Rtl Ke Zw Nt Ps开头.
常用的kerner API介绍.
1.Ex系列API
|
Ex内存系列API |
|
|
ExAllocatePool |
申请内存,类似于C语言的malloc |
|
ExFreePool |
释放内存,C语言中的free |
|
ExAcquireFastMutex |
获取一个快速互斥体.多线程中使用. |
|
ExReleaseFastMutex |
释放一个快速互斥体 |
|
ExRaiseStatus |
抛出一个异常.带有错误Status的值 |
2.Zw文件操作API (可以是设备)
介绍API前介绍一下Nt函数. Zw函数跟Nt函数是简单的跳转关系. 用户态也有对应的API与之对应. 在内核中Nt函数是查询不到的.因为微软不建议使用Nt函数.
不过我们声明一下还是可以使用的.
|
Zw 文件设备操作API |
对应NT API |
作用 |
|
ZwCreateFile |
NtCreateFile |
打开文件/设备 |
|
ZwReadFile |
NtReadFile |
读文件/设备 |
|
ZwWriteFile |
NtWriteFile |
写文件/设备 |
|
ZwQueryDirctoryFile |
NtQueryDirctoryFile |
目录查询 |
|
ZwDeviceIoControFile |
NtDeviceIoControlFile |
发送设备控制请求 |
|
ZwCreateKey |
NtCreateKey |
打开一个注册表键 |
|
ZwQueryValueKey |
NtQueryValueKey |
打开一个注册表值 |
3.Rtl字符串操作函数
我们知道内核中有了新的UNICODE_STRING 跟 ANSI_STRING的字符串.那么也有与之对应操作的API
|
Rtl函数 |
功能 |
|
RtlInitUnicodeString |
初始化一个Unicode字符串结构 |
|
RtlCopyUnicodeString |
拷贝字符串 |
|
RtlAppendUnicodeToString |
将一个字符串追加到另一个字符串后 |
|
RtlStringCbPrintf |
讲一个字符串打印到字符串中,相当于sprintf |
|
RtlCopyMemory |
内存数据块拷贝. |
|
RtlMoveMemory |
内存数据块移动. |
|
RtlZeroMemory |
内存块清零.注意不是释放内存,而是内存的值都变成0 |
|
RtlCompareMemory |
内存比较 |
|
RtlGetVersion |
获得当前Windows 版本 |
四丶IO管理器API
注意,IO函数比较重要. IO函数涉及IO管理器,而IO管理器就是将用户调用的API 翻译成IRP请求.或者讲等价的请求发送到内核中不同的设备.
是一个关键组件. 这个类别一般涉及到的都是IRP. 很关键.
|
IO函数 |
作用 |
|
IoCreateFile |
创建文件,比ZwCreateFile更加底层 |
|
IoCreateDevice |
生成一个设备对象 |
|
IoCallDriver |
发送请求 |
|
IoCompleteRequest |
完成请求,通知IO管理器完成了IRP请求 |
|
IoCopyCurrentIrpStackLocationToNext |
将当前的IRP堆栈拷贝到下一个栈空间 |
|
IoSkipCurrentIrpStackLoctionToNext |
跳过当前的IRP的栈空间 |
|
IoGetCurrentIrpStackLocation |
获得IRP的当前栈空间指针. |
五丶Ps 进程线程相关的函数.
|
Ps进程相关函数 |
作用 |
|
PsGetCurrentProcess |
获得当前的EPROCESS结构 |
|
PsGetCurrentProcessId |
获得当前的进程ID |
|
PsGetCurrentThread |
获得当前的ETHREAD结构 |
|
PsGetCurrentThreadId |
获得当前的线程ID |
|
PsIsSystemThread |
判断是否是系统线程. |
|
PsTerminateSystemThread |
结束系统线程. |
关于Kerner API, 简单的熟悉这些API.然后多看WDK Document 或者MSDN, 尽快熟悉API使用. 这样编写内核程序才会熟悉. 为以为逆向做准备.
内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.的更多相关文章
- 内核开发知识第二讲,编写Kerner 程序中注意的问题.
一丶函数多线程的安全问题 什么是函数多线程安全. 简单来说就是 ,一个函数在调用过程中.还没有返回的时候.再次被其他线程调用了.但是函数执行的结果是可靠的.就可以了说这个函数是安全的. 比如我们在用户 ...
- 逆向知识第一讲,IDA的熟悉使用,以及TEB,PEB结构
逆向知识第一讲,IDA的熟悉使用,以及TEB,PEB结构 一丶熟悉IDA,以及手工制作sig文件. IDA,静态分析工具,网上随便找一个即可下载. 首先,我们写一个可执行EXE,最简单的 使用IDA打 ...
- 逆向知识第一讲,IDA的熟悉使用
逆向知识第一讲,IDA的熟悉使用 一丶熟悉IDA,以及手工制作sig文件. IDA,静态分析工具,网上随便找一个即可下载. 首先,我们写一个可执行EXE,最简单的 使用IDA打开. 1.提示使用什么格 ...
- Linux基础知识第九讲,linux中的解压缩,以及软件安装命令
目录 Linux基础知识第九讲,linux中的解压缩,以及软件安装命令 一丶Linux Mac Windows下的压缩格式简介 2.压缩以及解压缩 3.linux中的软件安装以及卸载 1.apt进行安 ...
- python学习第九讲,python中的数据类型,字符串的使用与介绍
目录 python学习第九讲,python中的数据类型,字符串的使用与介绍 一丶字符串 1.字符串的定义 2.字符串的常见操作 3.字符串操作 len count index操作 4.判断空白字符,判 ...
- python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍
目录 python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍.md 一丶字典 1.字典的定义 2.字典的使用. 3.字典的常用方法. python学习第八讲,python ...
- python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍
目录 python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍. 二丶列表,其它语言称为数组 1.列表的定义,以及语法 2.列表的使用,以及常用方法. 3.列表的常用操作 ...
- python学习第七讲,python中的数据类型,列表,元祖,字典,之元祖使用与介绍
目录 python学习第七讲,python中的数据类型,列表,元祖,字典,之元祖使用与介绍 一丶元祖 1.元祖简介 2.元祖变量的定义 3.元祖变量的常用操作. 4.元祖的遍历 5.元祖的应用场景 p ...
- C++反汇编第二讲,反汇编中识别虚表指针,以及指向的虚函数地址
讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当然也可以看原博客链接: http://blog.csdn.net ...
随机推荐
- centOS7搭建nexus私服
1.保证JDK,MAVEN已安装,firewalld服务安装 PS:yum install firewalld 2.官网下载:https://www.sonatype.com/download-oss ...
- jsp相关笔记(一)
1.在html中调整两个<p>标签之间的间距,可以用margin属性: p { margin: 0.2em 0;} 2.在jsp中要对页面分成上.左.右三栏时,可以用<framese ...
- Silverlight实用窍门系列:68.Silverlight的资源字典ResourceDictionary
允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://chengxingliang.blog.51cto.com/3972944/886643 ...
- 使用Maven搭建SpringMVC
1.创建Maven Project 注意选择webapp 2.添加Maven依赖 <project xmlns="http://maven.apache.org/POM/4.0.0&q ...
- mysql空值排序
SELECT * FROM lzh_topic_channel_product ORDER BY order_id is null , order_id 其中的ORDER BY order_id i ...
- python之内部函数
1.bool,all,any (1)当内容为空时 >>> a=[] >>> bool(a) False >>> all(a) True >& ...
- 服务器被minerd
cd /opt chmod -x minerd 去/root/.ssh 目录下,清除authorized_keys,KHK75NEOiq 文件 在ssh的配置文件/etc/ssh/sshd_confi ...
- 公司git服务器记录
gitolite:server/web/AmomeWebApp.git gitolite:server/web/AmomeBackendManage.git git@192.168.1.183 === ...
- Paper | 亚像素运动补偿 + 视频超分辨
目录 1. ABSTRACT 2. INTRODUCTION 3. RELATED WORKS 4. SUB-PIXEL MOTION COMPENSATION (SPMC) 5. OUR METHO ...
- WPF学习笔记(6):DataSet更新后台数据库个别列失败的问题
WPF窗体中建有一个DataGrid,运行后修改各行数据,通过Update方法更新后台数据库.发现在数据库中,其中一列FAcctID(文本型)每次都会变为0,还有一列FDebit(货币型)不能更新,其 ...