其实这些是从<windows高级编程指南>总结下来的
觉得书本的例子还是太少了,可能我比较喜欢操作系统功能的例子吧 ^_^
总觉得看完 还想继续研究更深点或者,更多用到更多的地方
这本书的作者是<window核心编程>的作者Jeffrey Richter
句柄和计数器 为结构体中,为0则释放对象内核是被多其他程序所调用子父孙,3者继承handle
查看进程是否可继承 GetHandleInfomation
MutexEvent
2个对象能共享内核对象,当可能非派生关系ProcessA : CreateMutex(NULL,FALSE,"JeffObj");ProcessB : CreateMutex(NULL,FALSE,"JeffObj");
DuplicateHandle 复制进程内核句柄表一个,到目标内核句柄表/// 交换相同的内核操作GetCurrentProcessWaitForSingleObject 等待内核对象,堵塞状态
hMoudule = hInstanceGetModuleFIleNameGetModuleHandle 返回基地址
GetCommandLineGetEnvironmentGetCurrentDirectoryGetFullPathNameGetExitCodeProcess
ExitProcessExitThread
GetTickCountGetThreadTimesGetProcessTimes
TerminateThreadSetPriorityClass提升GetCurrentThread return handle //伪句柄GetCurrentProcessIDGetCurrentThreadID
0-31 动态变更线城优先级starvation
Explorer.exeSetThreadPrioritySetProcessPriorityBoost
SuspendThreadResumeThread
errNo多线程中全局变量问题
_beginthreadEx C(CreateThread) 代替API //带有独立的与线程关联的数据结构start_address arglist,安全,释放时通知DLL flush_endThreadEx
线程同步malloc同一块内存问题
CreateRemoteThreadGetProcessHeap
VirtualAlloc 保留一个区域VirtualFree 释放VirtualProtect 设置属性LoadLibraryVirtualLockVirtualUnlock 页为单位虚拟内存独立
C0000000-FFFFFFFF VXD驱动,管理领空 可读写80000000-BFFFFFFF 1GB DLL 内存影射,可读写 可用 共享
00400000-7FFFFFFF win32进程 可用00001000-003FFFFF DOS WINDOW00000000-00000FFF 4096bytes = 4k NULL指针区 禁止访问NT:System0001000C-7FFFFFFF for win32 process,privated
VirtualAlloc open the free memory area that reserving(保留)64K分配单元页以单元页提交物理储存 --将物理储存影射到内存保留区域低RAM数共享内存--减量多个磁盘读写数据,运行更快硬盘映射到物理内存。EXE不同过页面直接映射到RAM以页面大小倍数申请保留区域
舍入页大小,如VirtualAlloc() size = 0 非法MEM_RESET只能单独用
物理->页->堆->影射RAM
Ring0_Ring3ZwQuerySystemInformation
GetSystemInfoGlobalMemoryStatus 虚拟内存状态VirtualQuery自身VirtualQueryEx其他进程
SetClipboarDataheap 最适合管理大量小对象
虚拟内存来提升二维数组的速度resever 并不开销申请多大,就要FREE多大
PAGE_NOACCESS保障安全性 -malloc的链表
线程stack 中多个保留页里的警戒线_ Exception_stack_overflowSEH当stack满时继续使用。并且“再次”超出范围 程序崩溃stack前64K(防向上OVERFLOW) 后64K线城STACK增长问题char buf[10]buf[11]='a'buf[111111]='a'问题访问到保留内存
---------------------------------文件对象
CreateFile 创建|打开文件对象CreateFileMapping 创建对象]OpenFileMappingMapViewOfFile 开始映射MapViewOfFileEx 中基地址能实验多个进程MAP连接UnmapViewOfFileFlushViewOfFileSetFilePointerSetEndOfFileGetFileSizeIsTextUnicode
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与
SendMessagePostMessage
磁盘映射
180G映射到内存 ~
内存映射来共享数据——映射内核名要相同MAPPING共享,VIRTUALALLOC提交数据提高内存效率
16位系统---全局堆
HeapCreateHeapAllocHeapReAllocHeapSizeHeapFreeHeapDestroynew..deleteGetProcessHeapsHeapValidate 验证堆的完整性HeapCompactHeapLockHeapUnlockHeapWalk----------------------------------------------线程同步在多线程编程中, 同一个变量, 如果要让多个线程共享访问, 那么这个变量可以使用关键字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 //强制共享线程队列GetWindowThreadProcessIdWM_TIMER的优先等级SendMessage(WM_COPYDATA)进程间通信非序列化消息---解决由于一个消息没法处理导致系统挂起 键盘消息连接到RIT,RIT再到线程队列 RIT检查组合键SetActiveWindowGetActiveWindowSetForeGroundWindowGetAsyncKeyStats 鼠标弹起了就属于线程,而是系统。。例如拖拉情况,系统控制到别的地方
-----------------------------------------------动态连接库
GetModuleFile()FreeLibraryAndExitThreadDisableThreadLibraryCalls_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
磁盘序列号唯一,判断光盘是否更换
GetLogicalDriversDWORD GetLogicalDriveStringsGetDriveTypeGetDiskFreeSpaceGetVolumeInformationDoesDrivesExistsGetNumDrivesInSys
SetVolumeLabel 卷标可改变
GetCurrentDirectorySetCurrentDirectoryGetSystemDirectoryGetWindowsDirectoryCreateDirectoryRemoveDirectoryCopyFileLPPROGRESS_ROUTINE lpProgressRoutine,实验进度条DeleteFileMoveFileEx _ReNameFile=MoveFile MOVEFILE_DELAY_UNTIL_REBOOTGetFullPathNameSearchPathFindFirstFileEx 包含通配*?FineNextFileExFindClose
文件变化通知使用内核文件对象FindFirstChangNotification 监视目录/文件 返回内核句柄 WaitForSingleObject MsgWaitForMutipleObjectFindNextChangeNotification 变成没信号状态ReadDirectoryChangesW .//unicode版本
操作文件属性GetFileInfomationByHandle//需要句柄GetBinaryTypeGetFileAttributesSetFileAttributesGetFileSize //需要句柄GetCompressFileSizeGetFileTimeSetFileTimeCompareFileTimeFileTimeToSystemTimeFileTimeToLocalFileTime临时文件GetTempPathGetTempFile
--------------------------------设备IOFile中被当做设备CreateFileCreateMailSlotsCreatePipe
SetCommConfigSetMailslotInfo
GetFileType //查看内核类型临时文件读写速最快,不存在RAM中
文件偏移指针_每次Read Write File时,指针指到最后的地方,必须要注意偏移到正确位置SetFilePointer 支持负值,倒退SetEndOfFile SetFilePointer(hFile,1024,) SetEndOfFile(hFile) //减短文件尾LockFileUnlockFileReadFile //改变信号状态WriteFile //改变信号状态FlushFileBuffer STRUCT OVERLAPPED //保障地址存在,stack释放掉失败 SetProcessWorkingSetSizeGetOverlappedResult异步过程调用APC队列 请求时只简单放入队列,不会马上执行回调函数,要回调需要打断线程 进入警觉状态,前提是APC有消息FileIOCompletionRoutine警戒状态,打断线程 SleepEx WaitForSingleObjectEx WaitForMutipleObejctEx SignalObjectAndWait MsgWaitForMutipleObjectAPC入队QueueUserAPC
IO完成端口 IOCPCreateIOCompletionPort IO完成端口---并发多个线程关联一个IO设备 线程从队列中提取GetQueueCompletionStatus //放当前线程ID放入队列,让程序知道谁在处理PostQueueCompletionStatusAssociateDeviceWithCompletionPort //关联设备PostQueueCompletionStatusCancelIOCloseHandleIO完成队列
如果事先开好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没有处理异常的情况UnhandleExceptionFilterDebugActiveProcess 附加进程UpdateProcessPrivilege 提升权限SetErrorMode 防止UnhandleExceptionFilter弹出消息框SetUnhandleExceptionFilter 栈空间处理。1MB栈的威力,释放,调用等优化利用SEH来混乱加密
---------------------------------Unicodetchar.h 中可找到_T()wcharsize_twcscatwcscmpwcscpy.LPWSTRLPCWSTR
CompareStringGetThreadLocalisCharUpperisTextUnicodeMutiByteToWideCharisWindowUnicode
-----------------------------------------打开进程的边界SetWindowLong(,,WinProc) //窗口派生问题内存地址相对独立, 访问出错的问题解决方法就是注入DLL。
SetWindowsHookEx系统要先查看是否安装勾勾的callbackProc是否被映射到进程 增加DLL琐定计数GetMegProc B = hinstDLL B + (GetMsgProc A - hinsDLLA)
CreateRemoteThreadGetThreadContextSetThreadContext 修改线程寄存器跳过跳转表
如果想要该消息继续传递,那么它必须调用另外一个SDK中的API函数CallNextHookEx来传递它。钩子函数也可以通过直接返回TRUE来丢弃该消息,并阻止该消息的传递。
AllocProcessMemory+CreateRemoteThreadVirtualAllocEx+VirtualFreeEx
窗口层次问题ProgMan -- Program Manager ShellDll_DefView SysListView32 LoadLibrary和GetProcAddress从ntdll.dllWinLogon通知事件当然,事情还没结束,还需要修改注册表来安装WinLogon通知,需要动的注册表路径是“HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Winlogon/Notify/xxxx