一丶内核中的数据类型

  在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中.

数据类型都一定重定义了.

数据类型

重定义数据类型

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函数.的更多相关文章

  1. 内核开发知识第二讲,编写Kerner 程序中注意的问题.

    一丶函数多线程的安全问题 什么是函数多线程安全. 简单来说就是 ,一个函数在调用过程中.还没有返回的时候.再次被其他线程调用了.但是函数执行的结果是可靠的.就可以了说这个函数是安全的. 比如我们在用户 ...

  2. 逆向知识第一讲,IDA的熟悉使用,以及TEB,PEB结构

    逆向知识第一讲,IDA的熟悉使用,以及TEB,PEB结构 一丶熟悉IDA,以及手工制作sig文件. IDA,静态分析工具,网上随便找一个即可下载. 首先,我们写一个可执行EXE,最简单的 使用IDA打 ...

  3. 逆向知识第一讲,IDA的熟悉使用

    逆向知识第一讲,IDA的熟悉使用 一丶熟悉IDA,以及手工制作sig文件. IDA,静态分析工具,网上随便找一个即可下载. 首先,我们写一个可执行EXE,最简单的 使用IDA打开. 1.提示使用什么格 ...

  4. Linux基础知识第九讲,linux中的解压缩,以及软件安装命令

    目录 Linux基础知识第九讲,linux中的解压缩,以及软件安装命令 一丶Linux Mac Windows下的压缩格式简介 2.压缩以及解压缩 3.linux中的软件安装以及卸载 1.apt进行安 ...

  5. python学习第九讲,python中的数据类型,字符串的使用与介绍

    目录 python学习第九讲,python中的数据类型,字符串的使用与介绍 一丶字符串 1.字符串的定义 2.字符串的常见操作 3.字符串操作 len count index操作 4.判断空白字符,判 ...

  6. python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍

    目录 python学习第八讲,python中的数据类型,列表,元祖,字典,之字典使用与介绍.md 一丶字典 1.字典的定义 2.字典的使用. 3.字典的常用方法. python学习第八讲,python ...

  7. python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍

    目录 python学习第六讲,python中的数据类型,列表,元祖,字典,之列表使用与介绍. 二丶列表,其它语言称为数组 1.列表的定义,以及语法 2.列表的使用,以及常用方法. 3.列表的常用操作 ...

  8. python学习第七讲,python中的数据类型,列表,元祖,字典,之元祖使用与介绍

    目录 python学习第七讲,python中的数据类型,列表,元祖,字典,之元祖使用与介绍 一丶元祖 1.元祖简介 2.元祖变量的定义 3.元祖变量的常用操作. 4.元祖的遍历 5.元祖的应用场景 p ...

  9. C++反汇编第二讲,反汇编中识别虚表指针,以及指向的虚函数地址

    讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了,当然也可以看原博客链接: http://blog.csdn.net ...

随机推荐

  1. 写一份简单的webpack2 的配置文件,无比简单

    这是一份自己用到的webpack2的配置写法,从看webpack2开始,发现自己越来越懒了,现在html文件都不想自己写了,直接自己生成... 哈哈,这次是可以无比完美的导入css啦 开发的时候在命令 ...

  2. python 根据字符串内数字排序

    当我们使用python给一个由字符串组成的列表排序时,常常会排成这样 [‘10a’, ‘11b’, ‘1c’, ‘20d’, ‘21e’, ‘2f’] 这样的形式 ,然而我们想要 [ ‘1c’,‘2f ...

  3. Eclipse中代码自动提示功能设置

    Eclipse中代码自动提示功能设置 1 打开eclipse→Windows→Preferences→Java→Editor→Content Assist: 修改Auto Activation tri ...

  4. Oracle DBLINk的使用

    Oracle中自带了DBLink功能,它的作用是将多个oracle数据库逻辑上看成一个数据库,也就是说在一个数据库中可以操作另一个数据库中的对象,例如我们新建了一个数据database1,我们需要操作 ...

  5. DL_1_week2_神经网络基础

    二分类问题 在二分分类问题中,目标是训练出一个分类器,这里以图片特征向量x作为输入,预测输出的结果标签y是1还是0,也就是预测图片中是否有猫.          计算机保存一张图片(彩色),要保存三个 ...

  6. ELK学习

    [root@log-node1 ~]# cobbler repo add --name=logstash-2.3 --mirror=http://packages.elastic.co/logstas ...

  7. subarray sum

    public class Solution { /* * @param nums: A list of integers * @return: A list of integers includes ...

  8. Android-Java-构造函数间调用&this内存图

    构造函数间调用: 描述Person对象: package android.java.oop08; // 描述Person对象 public class Person { public String n ...

  9. CPU性能分析

    CPU性能分析工具 lscpu:查看CPU硬件信息 lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Litt ...

  10. [转]kaldi中的在线识别----Online Recognizers

    转自: http://blog.csdn.net/wbgxx333/article/details/24932533 本文是kaldi学习联盟中@冒顿翻译的,下面是@冒顿的翻译结果,在这里感谢@冒顿的 ...