ring3上的核心编程总结

来源:互联网 发布:farfetch是正品吗 知乎 编辑:程序博客网 时间:2024/06/10 10:23

其实这些是从<windows高级编程指南>总结下来的

觉得书本的例子还是太少了,可能我比较喜欢操作系统功能的例子吧 ^_^

总觉得看完 还想继续研究更深点或者,更多用到更多的地方

这本书的作者是<window核心编程>的作者Jeffrey Richter

 

句柄和计数器 为结构体中,为0则释放对象
内核是被多其他程序所调用
子父孙,3者继承handle

查看进程是否可继承 GetHandleInfomation

Mutex
Event

2个对象能共享内核对象,当可能非派生关系
ProcessA : CreateMutex(NULL,FALSE,"JeffObj");
ProcessB : CreateMutex(NULL,FALSE,"JeffObj");

DuplicateHandle 复制进程内核句柄表一个,到目标内核句柄表/// 交换相同的内核操作
GetCurrentProcess
WaitForSingleObject 等待内核对象,堵塞状态

hMoudule =  hInstance
GetModuleFIleName
GetModuleHandle 返回基地址

GetCommandLine
GetEnvironment
GetCurrentDirectory
GetFullPathName
GetExitCodeProcess

ExitProcess
ExitThread

GetTickCount
GetThreadTimes
GetProcessTimes

TerminateThread
SetPriorityClass提升
GetCurrentThread           return handle //伪句柄
GetCurrentProcessID
GetCurrentThreadID

0-31 动态变更线城优先级
starvation

Explorer.exe
SetThreadPriority
SetProcessPriorityBoost

SuspendThread
ResumeThread

errNo多线程中全局变量问题

_beginthreadEx   C(CreateThread) 代替API 
//带有独立的与线程关联的数据结构start_address arglist,安全,释放时通知DLL flush
_endThreadEx


线程同步malloc同一块内存问题

CreateRemoteThread
GetProcessHeap

VirtualAlloc 保留一个区域
VirtualFree  释放
VirtualProtect 设置属性
LoadLibrary
VirtualLock
VirtualUnlock   页为单位
虚拟内存独立


C0000000-FFFFFFFF  VXD驱动,管理领空 可读写
80000000-BFFFFFFF  1GB DLL 内存影射,可读写 可用 共享

00400000-7FFFFFFF win32进程 可用
00001000-003FFFFF DOS WINDOW
00000000-00000FFF  4096bytes = 4k NULL指针区 禁止访问
NT:System
0001000C-7FFFFFFF  for win32 process,privated

VirtualAlloc      open the free memory area that reserving(保留)
64K分配单元页
以单元页提交物理储存 --将物理储存影射到内存保留区域
低RAM数共享内存--减量
多个磁盘读写数据,运行更快
硬盘映射到物理内存。
EXE不同过页面直接映射到RAM
以页面大小倍数申请保留区域


舍入页大小,如VirtualAlloc()  size = 0  非法
MEM_RESET只能单独用

物理->页->堆->影射RAM

Ring0_Ring3
ZwQuerySystemInformation

GetSystemInfo
GlobalMemoryStatus  虚拟内存状态
VirtualQuery自身
VirtualQueryEx其他进程

SetClipboarData
heap 最适合管理大量小对象

虚拟内存来提升二维数组的速度
resever 并不开销
申请多大,就要FREE多大

PAGE_NOACCESS保障安全性 -malloc的链表

线程stack 中多个保留页里的警戒线_ Exception_stack_overflow
SEH
当stack满时继续使用。并且“再次”超出范围 程序崩溃
stack前64K(防向上OVERFLOW) 后64K
线城STACK增长问题
char buf[10]
buf[11]='a'
buf[111111]='a'
问题
访问到保留内存

---------------------------------
文件对象

CreateFile 创建|打开文件对象
CreateFileMapping 创建对象]
OpenFileMapping
MapViewOfFile     开始映射
MapViewOfFileEx  中基地址能实验多个进程MAP连接
UnmapViewOfFile
FlushViewOfFile
SetFilePointer
SetEndOfFile
GetFileSize
IsTextUnicode

HANDLE CreateFileMapping(
  HANDLE hFile,                       // handle to file   //映射from页面数据时候0xFFFFFFFF
  LPSECURITY_ATTRIBUTES lpAttributes, // security
  DWORD flProtect,                    // protection
  DWORD dwMaximumSizeHigh,            // high-order DWORD of size
  DWORD dwMaximumSizeLow,             // low-order DWORD of size
  LPCTSTR lpName                      // object name
);

0xFFFFFFFF与


SendMessage
PostMessage

磁盘映射

180G映射到内存 ~

内存映射来共享数据——映射内核名要相同
MAPPING共享,VIRTUALALLOC提交数据提高内存效率

16位系统---全局堆

HeapCreate
HeapAlloc
HeapReAlloc
HeapSize
HeapFree
HeapDestroy
new..delete
GetProcessHeaps
HeapValidate 验证堆的完整性
HeapCompact
HeapLock
HeapUnlock
HeapWalk
----------------------------------------------线程同步
在多线程编程中, 同一个变量, 如果要让多个线程共享访问, 那么这个变量可以使用关键字volatile进行声明
调度时注意线程运行速度,适当改变线程优先级

临界区critical section   -----单个进程线城
 单个线城独占
 可以建立多个临界区
 2个临界同时一个线城中,第一个进入 第二个等待,进程立刻deadlock
  -未知的时间动作
 InitializeCriticalSetion
 WaitForMutipleObject
 EnterCriticalSetion
 LeaveCriticalSetion
 DeleteCriticalSetion
 TryEnterCriticalSetion
 
互斥量mutex ----进程间通信的线程同步的提出
 CreateMutex
 OpenMutex
 ReleaseMutex 释放就能得到信号
 CloseHandle
 WaitForSingleObject 等待信号发出,对信号量减1
 WaitForMutiSingleObject
 
信号量semaphore  -----对于优先权限的用途
 CreateSemaphore 大于0个信号量能唤醒waitforsingleobject
 OpenSemaphore
 ReleaseSemaphore ---msdn说增加信号量
  中间追加堵塞。
 WaitForSingleObject 接收信号量
 
事件event  ---最简单的信号形式
 CreateEvent //人工重设方法不会被WaitForSingleObject所重设
 OpenEvent
 SetEvent   //single
 ResetEvent //no single
 PulseEvent //有信号,再重设
 解决单作者/多读者问题
 
记时器waitable time  ---内核中的SetTimer
 多个线程的SetTimer
 CreateWaitableTimer
 OpenWaitableTimer
 SetWaitableTimer
 SystemTimeToFileTime
 CancleWaitableTimer

异步文件IO
 WaitForInputIdle  //可模拟键盘
 MsgWaitForMutipleObjects
 WaitForDebugEvent
 SingleObjectAndWait //高性能的等待对象,使pulseEvent后立即触发
 
函数族  ---保证单写的问题
 InterlockedCompareExchange,
 InterlockedDecrement,
 InterlockedExchangeAdd,
 InterlockedExchangePointer,
 InterlockedIncrement
 
-----------------------------------------
消息与异步
_虚拟消息队列
_投递消息队列
 多任务
 抢先调度--中断一线程去做其他事
 窗口-钩子函数属于线程
 PeekMessage 的控制权问题,异步操作,不等待返回
 GetMessage
 DispatchMessage 窗口消息时
 SendMessage 发送后空闲。等待返回-------当一进程发送消息到另一进程而进入死循环,消息没返回,则这个进程被挂起
 SendMessageTimeOut
 SendMessageCallBack
 ReplyMessage //用于线程间
 SendNotifyMessage  //更高优先级,作用与sendmessage一样
 InSendMessage //判断线程内外的消息
 每个CreateWindow具有自己的消息列——支配THREADINFO结构
  STRUCT THREADINFO
  投递消息指针
  入队消息指针 指向消息队列链表头
  发送消息指针 PostMessage PostThreadMessage
  回答消息指针
  唤醒标志
TranslateMessage //把键盘事件转换成WM_CHAR WM_SYSCHAR发送
GetQueueStatus //检查队列消息
 QS_PAINT //一直存在,直接所有窗口被画出来
AttachThreadInput //强制共享线程队列
GetWindowThreadProcessId
WM_TIMER的优先等级
SendMessage(WM_COPYDATA)进程间通信
非序列化消息---解决由于一个消息没法处理导致系统挂起
 键盘消息连接到RIT,RIT再到线程队列
 RIT检查组合键
SetActiveWindow
GetActiveWindow
SetForeGroundWindow
GetAsyncKeyStats
 鼠标弹起了就属于线程,而是系统。。例如拖拉情况,系统控制到别的地方

-----------------------------------------------
动态连接库

GetModuleFile()
FreeLibraryAndExitThread
DisableThreadLibraryCalls
_DllMainCRTStartup
GetProcAddress

4种情况调用DLL MAIN(重复调用)
 fdwReason
  case DLL_PROCESS_ATTACH: 主
  case DLL_THREAD_ATTACH:
  case DLL_THREAD_DETACH:
  case DLL_PROCESS_DETACH:
  
隐式。LIB,
动态式(显式)LoadLibrary,创建新线程映射到内存
重复时不会创建新的计数,但释放需要FREE多次

标准规则
 Extern "C" _declspec(dllexport)
 增加DEF文件(新建文件,改后缀可以了)
  EXPORTS
   导出函数名
   
#pragma data_seg(lpszname) 增加节段
int test=0;
#pragma data_seg()
//编译时 /setion:lpszname,rws
#pragma comment(linker,"/setion:lpszname,RWS")
出于安全问题,不建议使用

----------------------------------------------
13。线程局部储存——实际上为DLL设计
TLS thread local storage(线程本地存储) 变量
 线程自己的数组---CreateThread(,,,LPVOID lpParameter) ___64个TLS位置
静态式
_declspec(thread) C Run time library
动态式
 DLL中用TLS
 TlsAlloc
 TlsSetValue(LPVOID...)
 TlsGetValue
 TlsFree --置0

-----------------------------------------------
14。文件系统

FAT格式
 字节->扇区512(bytes)->簇
 可分配最小单位是(1)簇
 越小的磁盘支配使用簇越细
FAT32

磁盘序列号唯一,判断光盘是否更换

GetLogicalDrivers
DWORD GetLogicalDriveStrings
GetDriveType
GetDiskFreeSpace
GetVolumeInformation
DoesDrivesExists
GetNumDrivesInSys

SetVolumeLabel 卷标可改变

GetCurrentDirectory
SetCurrentDirectory
GetSystemDirectory
GetWindowsDirectory
CreateDirectory
RemoveDirectory
CopyFile
LPPROGRESS_ROUTINE lpProgressRoutine,实验进度条
DeleteFile
MoveFileEx _ReNameFile=MoveFile
 MOVEFILE_DELAY_UNTIL_REBOOT
GetFullPathName
SearchPath
FindFirstFileEx 包含通配*?
FineNextFileEx
FindClose

文件变化通知
使用内核文件对象
FindFirstChangNotification 监视目录/文件
 返回内核句柄
 WaitForSingleObject
  MsgWaitForMutipleObject
FindNextChangeNotification 变成没信号状态
ReadDirectoryChangesW   .//unicode版本

操作文件属性
GetFileInfomationByHandle//需要句柄
GetBinaryType
GetFileAttributes
SetFileAttributes
GetFileSize  //需要句柄
GetCompressFileSize
GetFileTime
SetFileTime
CompareFileTime
FileTimeToSystemTime
FileTimeToLocalFileTime
临时文件
GetTempPath
GetTempFile

--------------------------------
设备IO
File中被当做设备
CreateFile
CreateMailSlots
CreatePipe

SetCommConfig
SetMailslotInfo

GetFileType //查看内核类型
临时文件读写速最快,不存在RAM中

文件偏移指针_每次Read Write File时,指针指到最后的地方,
必须要注意偏移到正确位置
SetFilePointer 支持负值,倒退
SetEndOfFile
 SetFilePointer(hFile,1024,)
  SetEndOfFile(hFile) //减短文件尾
LockFile
UnlockFile
ReadFile  //改变信号状态
WriteFile //改变信号状态
FlushFileBuffer
 STRUCT OVERLAPPED //保障地址存在,stack释放掉失败
SetProcessWorkingSetSize
GetOverlappedResult
异步过程调用APC队列
 请求时只简单放入队列,不会马上执行回调函数,要回调需要打断线程
 进入警觉状态,前提是APC有消息
FileIOCompletionRoutine
警戒状态,打断线程
 SleepEx
 WaitForSingleObjectEx
 WaitForMutipleObejctEx
 SignalObjectAndWait
 MsgWaitForMutipleObject
APC入队
QueueUserAPC

IO完成端口 IOCP
CreateIOCompletionPort IO完成端口---并发多个线程关联一个IO设备
 线程从队列中提取
GetQueueCompletionStatus //放当前线程ID放入队列,让程序知道谁在处理
PostQueueCompletionStatus
AssociateDeviceWithCompletionPort //关联设备
PostQueueCompletionStatus
CancelIO
CloseHandle
IO完成队列

如果事先开好N个线程,让它们在那hold[堵塞],然后可以将所有用户的请求都投递到一个消息队列中去。
然后那N个线程逐一从消息队列中去取出消息并加以处理。就可以避免针对每一个用户请求都开线程。
不仅减少了线程的资源,也提高了线程的利用率。

----------------------
SEH 结构异常处理  struct expection handling
__try{}
__leavc  退出try进入finally
__finally{} 展开,强执行区
__except(expression1,expression2...){} 不与finally共存,可以嵌套__expression最右的才为最终值
__except(EXCEPTION_CONTINUE_EXECUTION){}
 EXCEPTION_CONTINUE_EXECUTION返回原表达式错误地方再次执行
 EXCEPTION_CONTINUE_SEARCH 寻找处理异常的__except
 EXCEPTION_CONTINUE_HANDLER 全局展开,使未完成try finally块恢复执行
try中有 return时不回立刻返回,而进入finally执行完再返回 EXITPROCESS EXITTHREAD除外
停止展开。finally{return ;}不会再执行__except(){}
__except(GetExceptionCode()==SomeException||GetExceptionCode()==OtherException:
   EXCEPTION_CONTINUE_EXECUTION;EXCEPTION_CONTINUE_SEARCH)
AbnormalTermination 
GetExceptionCode__不能在过滤函数中调用
GetExceptionInfomation__过滤函数中用
struct _EXCEPTION_RECORD *ExceptionRecord 异常链
 try正常进入finally则false
 而做出对应处理
RaiseException 软件异常

DEBUG没有处理异常的情况
UnhandleExceptionFilter
DebugActiveProcess  附加进程
UpdateProcessPrivilege 提升权限
SetErrorMode  防止UnhandleExceptionFilter弹出消息框
SetUnhandleExceptionFilter 
栈空间处理。1MB栈的威力,释放,调用等优化
利用SEH来混乱加密

---------------------------------
Unicode
tchar.h  中可找到
_T()
wchar
size_t
wcscat
wcscmp
wcscpy.
LPWSTR
LPCWSTR

CompareString
GetThreadLocal
isCharUpper
isTextUnicode
MutiByteToWideChar
isWindowUnicode

-----------------------------------------
打开进程的边界
SetWindowLong(,,WinProc) //窗口派生问题
内存地址相对独立, 访问出错的问题
解决方法就是注入DLL。

SetWindowsHookEx
系统要先查看是否安装勾
勾的callbackProc是否被映射到进程
 增加DLL琐定计数
GetMegProc B = hinstDLL B + (GetMsgProc A - hinsDLLA)

CreateRemoteThread
GetThreadContext
SetThreadContext   修改线程寄存器
跳过跳转表

如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止该消息的传递。


AllocProcessMemory+CreateRemoteThread
VirtualAllocEx+VirtualFreeEx

窗口层次问题
ProgMan -- Program Manager
 ShellDll_DefView
  SysListView32
  
LoadLibrary和GetProcAddress从ntdll.dll
WinLogon通知事件
当然,事情还没结束,还需要修改注册表来安装WinLogon通知,需要动的注册表路径是“HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Winlogon/Notify/xxxx