1.数据类型重定义U**--->x86-->x64-->指针从4字节变为8字节
2.在ntstatus.h查找NTSTATUS值
3.Winobj.exe查看所有内核对象
4.分发函数HOOK技术
5.wdd 有help文件chm---在help目录下
6.中断级Dispatch级>Passive级---》PAGE节不可用在Dispatch级调用(缺页中断)
获取当前中断级:KeGetCurrentIrql
7.因为char*字符串不一定有\0结束符,所以定义了驱动层的字符串类型STRUCT_*_STRING
RtlInitUnicodeString/RtlCopyUnicodeString/RtlAppendUnicodeToString/RtlStringCbPrintfW
PASSIVE_LEVEL中断级可用--》DbgPrintf
8.ExFreePool不能用来释放栈空间的指针,否则会蓝屏
9.(队列)自旋锁-KSPIN_LOCK:自由所有线程共用一个锁才有意义
10.对象路径:\\?\\c:\\a.bat --->符号链接路径:c:\\a.bat
11.注册表内核对应:HKLM-->\Registry\Machine
HKUS-->\Registry\User
HKLM\SOFTWARE\Microsoft\windows nt\currentversion -->SystemRoot
其他无对应
12.定时器KeSetTimer需要重复调用----且在APC中断级
13.关闭句柄并不结束线程
14.事件不需要销毁
--------------------------
1.IoCreateDevice--->管理员权限
IoCreateDeviceSecure--->可用于非管理员--"D:P(A;;GA;;;WD)"
2.一个驱动只有一个控制设备
3.GUID访问设备>符号链接(IoCreateSymbolicLink)访问设备
4.创建设备-》符号----删除-----《符号--设备
内核:\\??\\abc
应用层:\\\\.\\abc
5.请求可以由只一个分发函数处理,也可以创建多个分发函数来处理
---》获取当前站空间-》判断处理请求--》返回请求
6.通信:R3定义功能号(CTL_CODE 其中0x0~0x7ff 微软---且不能超过0xfff
R1获得功能号,输入输出缓冲区长度(其缓冲区是共享的)
注:特别注意内存溢出
7.如何生成内核态和用户态共享的事件句柄?--1.使用同步事件来等待
8.测试--》缓冲区极小/极大/刚好? 字符串没有结束符/字符串长度为0?
检查字符串长度不要用strlen---->用 strnlen
不用strcpy---->用 strncpy
9.断言(ASSERT)与安全检查:
断言只在检查版本中才被编译,是为了提示开发者,仅仅用于调试。不能出现在发行版本中--》会极大可能导致蓝屏,攻击者发出输入缓冲区指针为NULL,电脑直接蓝屏。
10.释放所有分配过的内核内存
------------------------------------------------------
1.WOW64位子系统
%windir%\system32:包含64位系统二进制文件。
%windir%\syswow64:包含32位系统二进制文件。
访问真实的System32目录:1:c:\windows\sysnative\
2:Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection
注册表:用打开注册表时用KEY_WOW64_64KEY/KEY_WOW64_32KEY参数
2.PatchGuard技术
3.64位环境下调试、安装、运行:
1.拷贝文件到64位系统的system32目录下要特别注意
2.可以禁用驱动程序数字签名
3.64位模式下不允许嵌入汇编---》把汇编代码写成函数放到一个单独的asm文件,然后通过函数的方式调用。
DbgBreakPoint()<--->_asm int 3
4.预处理:
_M_AMD64/_M_IX64 _WIN64
5.数据结构:
使用固定长度的类型来定义变量-》在不同平台下大小不再有歧义
------------------------------------------------------
1.汇编常用操作对象:寄存器、内存--》堆栈
指令:mov(=)、push、pop
关键字:_asm
2.mov:从内存到内存的操作是不允许的,必须要有个寄存器来中转
3.寄存器:x86-8个:eax、ebx、ecx、edx、esi、edi、esp、ebp
x64-16个:rax、rbx、rcx、rdx、rsi、rdi、rsp、rbp、r8~r15
记忆:1.a、b、c、d 最常用
2.source、destination用来指向源esi和目标edi
3.esp、edp关联堆栈
4.x64数量多一倍
4.内存:使用数据总线和处理器内核直接通信的外部器件
5.vc\vs调试环境打开反汇编窗口查看汇报代码
6.堆栈到堆栈操作:push、pop ---》主要用于备份寄存器和参数传递
esp保存栈顶数据
push备份 和pop回复先进后出
入栈和出栈要一致,push-pop相当于new-delet /malloc-free
保持堆栈平衡---》esp在栈顶
ebp用来保存esp--》ebp-x 等价 esp + y
7.变量
内存寻址模式:[eax]寄存器间接寻找、[0x11223344]直接内存寻址、[eax+ebx*4+0x0c]基址加变址寻址
lea---取地址,类似指针赋值 lea eax, [ebp-8] ==== int *p = &i;
lea指令不会修改标志寄存器eflags
rep stos--rep,重复前缀,执行时,ecx会减少1,直到ecx为0为止。
stosd,每次操作4字节。stosw,每次操作2字节。stosb,每次操作1字节。
xor-->异或操作 xor eax, eax 相当于 ^x
8.函数调用--call
call指令在转移控制前,是一个提取eip值的过程。
call指令只能实现压入返回地址和跳转
eip是一个特殊的、不能直接访问的寄存器,它指示处理器下一条执行的指令的地址。
9.函数传参
1.通过内存(一般是堆栈)传递
2.整型参数可以通过寄存器传递
3.浮点型参数可以通过浮点寄存器传递
10.函数返回
ret
ret n-->首先完成ret,然后esp的值增加n
调用协议:ccall(调用者平衡堆栈——cdecl)、stdcall(用函数本身平衡堆栈_stdcall)、fastcall(用寄存器ecx、edx =< 参数2 < 用堆栈 _fastcall)
11.不同的架构:IA-32(x86)、IA-64、PowerPC、ARM、MIPS、
IA-32的拓展AMD64、Inter 64 (x64)
参考手册:Intel指令手册
指令的要素:操作码+工作模式(x64 x86)+操作数宽度+地址宽度
安装64位系统的要求:处理器必须支持Intel 64 或者 AMD64指令集
x64典型变化:不支持_stdcall、_fastcall关键字
12.通用寄存器
存储器:往往通过地址来访问
寄存器:通过名字来进行访问
-------------------------------------------------------------
1.虚拟地址到线性地址公式:虚拟地址偏移+段基址=线性地址
2.段:cs代码段、ss堆栈段、ds\es\fs\gs数据段
IA-32没有段描述表,只有全局描述符表:指令sgdt/lgdt
DPL权集:IA-32:r0-r3 4个;linux:r0、r3 2个
段的加载会导致寄存器的隐藏部分被改写
一些跳转指令会改写寄存器cs的值
3.gdtr长度:64位-80 32位:-48
eg:
1.汇编
.686p ;带点行相当于预编译宏指令
.model flat,Stdcall
option casemap:none ;指明编译器不要考虑大小写区别
.CODE
slbkSgdt32 PROC Stdcall pgdtr ;原型 void slbkSgdt32(PIA32_SYS_TR pgdtr) 、PROC定义函数、stdcall表明函数参数传递规则
;pgdtr 为参数---汇编没有类型概念
move eax,pgdtr
sgdt [eax]
ret
ENDP
END
2.c调用汇编函数
;声明
void NTAPI slbkSgdt32(PIA32_SYS_TR)
;调用
void ia32Sgdt32(PIA32_SYS_TR gdtr)
{
slbkSgdt32(gdtr)
}
4.WinDbg报告的错误的点,不一定是程序有错误的地方。--》往前追朔
值是否正常,写入数据的根源
函数是否正确?代码调用顺序是否正确?
5.汇编语言不追求跨平台,而是简单的为不同的目标平台各实现一份代码
_WIN64宏区分32-64
2.在ntstatus.h查找NTSTATUS值
3.Winobj.exe查看所有内核对象
4.分发函数HOOK技术
5.wdd 有help文件chm---在help目录下
6.中断级Dispatch级>Passive级---》PAGE节不可用在Dispatch级调用(缺页中断)
获取当前中断级:KeGetCurrentIrql
7.因为char*字符串不一定有\0结束符,所以定义了驱动层的字符串类型STRUCT_*_STRING
RtlInitUnicodeString/RtlCopyUnicodeString/RtlAppendUnicodeToString/RtlStringCbPrintfW
PASSIVE_LEVEL中断级可用--》DbgPrintf
8.ExFreePool不能用来释放栈空间的指针,否则会蓝屏
9.(队列)自旋锁-KSPIN_LOCK:自由所有线程共用一个锁才有意义
10.对象路径:\\?\\c:\\a.bat --->符号链接路径:c:\\a.bat
11.注册表内核对应:HKLM-->\Registry\Machine
HKUS-->\Registry\User
HKLM\SOFTWARE\Microsoft\windows nt\currentversion -->SystemRoot
其他无对应
12.定时器KeSetTimer需要重复调用----且在APC中断级
13.关闭句柄并不结束线程
14.事件不需要销毁
--------------------------
1.IoCreateDevice--->管理员权限
IoCreateDeviceSecure--->可用于非管理员--"D:P(A;;GA;;;WD)"
2.一个驱动只有一个控制设备
3.GUID访问设备>符号链接(IoCreateSymbolicLink)访问设备
4.创建设备-》符号----删除-----《符号--设备
内核:\\??\\abc
应用层:\\\\.\\abc
5.请求可以由只一个分发函数处理,也可以创建多个分发函数来处理
---》获取当前站空间-》判断处理请求--》返回请求
6.通信:R3定义功能号(CTL_CODE 其中0x0~0x7ff 微软---且不能超过0xfff
R1获得功能号,输入输出缓冲区长度(其缓冲区是共享的)
注:特别注意内存溢出
7.如何生成内核态和用户态共享的事件句柄?--1.使用同步事件来等待
8.测试--》缓冲区极小/极大/刚好? 字符串没有结束符/字符串长度为0?
检查字符串长度不要用strlen---->用 strnlen
不用strcpy---->用 strncpy
9.断言(ASSERT)与安全检查:
断言只在检查版本中才被编译,是为了提示开发者,仅仅用于调试。不能出现在发行版本中--》会极大可能导致蓝屏,攻击者发出输入缓冲区指针为NULL,电脑直接蓝屏。
10.释放所有分配过的内核内存
------------------------------------------------------
1.WOW64位子系统
%windir%\system32:包含64位系统二进制文件。
%windir%\syswow64:包含32位系统二进制文件。
访问真实的System32目录:1:c:\windows\sysnative\
2:Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection
注册表:用打开注册表时用KEY_WOW64_64KEY/KEY_WOW64_32KEY参数
2.PatchGuard技术
3.64位环境下调试、安装、运行:
1.拷贝文件到64位系统的system32目录下要特别注意
2.可以禁用驱动程序数字签名
3.64位模式下不允许嵌入汇编---》把汇编代码写成函数放到一个单独的asm文件,然后通过函数的方式调用。
DbgBreakPoint()<--->_asm int 3
4.预处理:
_M_AMD64/_M_IX64 _WIN64
5.数据结构:
使用固定长度的类型来定义变量-》在不同平台下大小不再有歧义
------------------------------------------------------
1.汇编常用操作对象:寄存器、内存--》堆栈
指令:mov(=)、push、pop
关键字:_asm
2.mov:从内存到内存的操作是不允许的,必须要有个寄存器来中转
3.寄存器:x86-8个:eax、ebx、ecx、edx、esi、edi、esp、ebp
x64-16个:rax、rbx、rcx、rdx、rsi、rdi、rsp、rbp、r8~r15
记忆:1.a、b、c、d 最常用
2.source、destination用来指向源esi和目标edi
3.esp、edp关联堆栈
4.x64数量多一倍
4.内存:使用数据总线和处理器内核直接通信的外部器件
5.vc\vs调试环境打开反汇编窗口查看汇报代码
6.堆栈到堆栈操作:push、pop ---》主要用于备份寄存器和参数传递
esp保存栈顶数据
push备份 和pop回复先进后出
入栈和出栈要一致,push-pop相当于new-delet /malloc-free
保持堆栈平衡---》esp在栈顶
ebp用来保存esp--》ebp-x 等价 esp + y
7.变量
内存寻址模式:[eax]寄存器间接寻找、[0x11223344]直接内存寻址、[eax+ebx*4+0x0c]基址加变址寻址
lea---取地址,类似指针赋值 lea eax, [ebp-8] ==== int *p = &i;
lea指令不会修改标志寄存器eflags
rep stos--rep,重复前缀,执行时,ecx会减少1,直到ecx为0为止。
stosd,每次操作4字节。stosw,每次操作2字节。stosb,每次操作1字节。
xor-->异或操作 xor eax, eax 相当于 ^x
8.函数调用--call
call指令在转移控制前,是一个提取eip值的过程。
call指令只能实现压入返回地址和跳转
eip是一个特殊的、不能直接访问的寄存器,它指示处理器下一条执行的指令的地址。
9.函数传参
1.通过内存(一般是堆栈)传递
2.整型参数可以通过寄存器传递
3.浮点型参数可以通过浮点寄存器传递
10.函数返回
ret
ret n-->首先完成ret,然后esp的值增加n
调用协议:ccall(调用者平衡堆栈——cdecl)、stdcall(用函数本身平衡堆栈_stdcall)、fastcall(用寄存器ecx、edx =< 参数2 < 用堆栈 _fastcall)
11.不同的架构:IA-32(x86)、IA-64、PowerPC、ARM、MIPS、
IA-32的拓展AMD64、Inter 64 (x64)
参考手册:Intel指令手册
指令的要素:操作码+工作模式(x64 x86)+操作数宽度+地址宽度
安装64位系统的要求:处理器必须支持Intel 64 或者 AMD64指令集
x64典型变化:不支持_stdcall、_fastcall关键字
12.通用寄存器
存储器:往往通过地址来访问
寄存器:通过名字来进行访问
-------------------------------------------------------------
1.虚拟地址到线性地址公式:虚拟地址偏移+段基址=线性地址
2.段:cs代码段、ss堆栈段、ds\es\fs\gs数据段
IA-32没有段描述表,只有全局描述符表:指令sgdt/lgdt
DPL权集:IA-32:r0-r3 4个;linux:r0、r3 2个
段的加载会导致寄存器的隐藏部分被改写
一些跳转指令会改写寄存器cs的值
3.gdtr长度:64位-80 32位:-48
eg:
1.汇编
.686p ;带点行相当于预编译宏指令
.model flat,Stdcall
option casemap:none ;指明编译器不要考虑大小写区别
.CODE
slbkSgdt32 PROC Stdcall pgdtr ;原型 void slbkSgdt32(PIA32_SYS_TR pgdtr) 、PROC定义函数、stdcall表明函数参数传递规则
;pgdtr 为参数---汇编没有类型概念
move eax,pgdtr
sgdt [eax]
ret
ENDP
END
2.c调用汇编函数
;声明
void NTAPI slbkSgdt32(PIA32_SYS_TR)
;调用
void ia32Sgdt32(PIA32_SYS_TR gdtr)
{
slbkSgdt32(gdtr)
}
4.WinDbg报告的错误的点,不一定是程序有错误的地方。--》往前追朔
值是否正常,写入数据的根源
函数是否正确?代码调用顺序是否正确?
5.汇编语言不追求跨平台,而是简单的为不同的目标平台各实现一份代码
_WIN64宏区分32-64