type
status
date
slug
summary
tags
category
icon
password
WIN32编程
1、字符格式:
unicode:
ASCII
2、进程:
内存空间地址划分:
进程内存空间的地址划分:
分区 | x86 32位Windows |
空指针赋值区 | 0x00000000-0x0000FFFF |
用户模式区 | 0x00010000-0x7FFEFFFF |
64KB禁入区 | 0x7FFF0000-0x7FFFFFFF |
内核区 | 0x80000000-0xFFFFFFFF |
进程的创建:
过程:
1、通过CreateProcess()进行对exe文件的映射,将这个文件按照PE格式进行映射到内存
2、创建内核对象EPROCESS(在高2g区域)
3、映射系统DLL,ntdll.dll (在用户区域)
4、创建线程内核对象ETHREAD(也在高2g区域)
5、系统启动线程
映射DLL(ntdll.Ldrlnitialize Thunk)
线程开始运行
句柄:
每个进程都有一个句柄,对内核进行映像,句柄表是一个私有对象,句柄可以看作是对其他对象进行引用的一个方式,可以起到类似指针的作用,但是他一定不是指针的含义,这点要明确
常见API函数
CreateProcess
CreateProcess函数用于创建一个新的进程并返回进程句柄:
如下是PROCESS_INFORMATION结构的成员:
如下是STARTUPINFO结构的成员
实例:
若需要以挂起的形式创建进程, 可将
CreateProcess
函数的第六个参数设置为CREATE_SUSPENDED
, 这样创建的进程一开始并不会自动启动线程, 而是需要自己手动执行ResumeThread
函数恢复线程后才会启动,需要注意的是,每次进行挂起操作,挂起几次就需要使用几次ResumeThread进行恢复,否则不会将进程唤醒例子:
在例子中,我引用了SuspendThread(pi.hThread);函数,这个函数是进行挂起操作的,因为createprocess函数里面与一个挂起操作,所以我需要两个rusumeThread函数进行恢复操作。
OpenProcess:
OpenProcess
函数用于打开一个已存在的进程对象,以便对该进程执行操作,例如向该进程发送信号或从该进程读取内存。此函数的调用者必须具有足够的权限来打开目标进程如果函数执行成功,返回打开进程的句柄,否则返回NULL,并可通过调用
GetLastError
函数获取错误码要注意的是, 使用
CloseHandle
函数释放句柄后, 就不能再使用OpenProcess
函数来打开这个进程了, 因为CloseHandle
函数会将句柄从进程的句柄表中移除,并且在所有引用计数都归零之后释放内存资源OpenProcess函数的语法如下:
以下是dwDesireAccess参数的可取值:
给个具体例子进行说明:
此处的操作可以是对这个进程创建相关线程、读取内存、写入内存、分配内存、终止进程、查询信息、设置信息、虚拟内存操作、同步等等
TerminateProcess
TerminateProcess
函数是Windows操作系统提供的函数之一,用于终止指定进程, 当调用TerminateProcess
函数时,会向指定进程发送一个中断信号,强制其终止。这个过程是非常暴力的,会直接终止进程的所有线程,不会给进程和线程任何清理资源的机会,因此使用该函数需要非常慎重
具体例子,配合上面的openprocess函数进行使用
GetModuleFileName
GetModuleFileName函数用于获取指定模块的完整路径名。通常情况下,可以通过指定NULL作为参数hModule,来获取当前应用程序的完整路径名,该函数的声明如下:
GetCurrentDirectory
GetCurrentDirectory函数用于获取当前进程的工作目录。其函数原型为
这个GetCurrentDirectory函数的路径是指当前进程的工作目录,而不是当前模块的目录。如果需要获取当前模块的目录,需要使用GetModuleFileName函数来获取模块文件的路径
例子:
GetStartupInfo
GetStartupInfo函数用于检索当前进程的启动信息,它的主要功能是获取STARTUPINFO结构体,其中包含了进程的启动信息,如命令行参数、标准输入输出句柄、窗口显示方式等
调用GetStartupInfo函数需传递一个指向STARTUPINFO类型的指针
GetCurrentProcessID
GetCurrentProcessID函数是Windows API中的一部分,它返回当前进程的进程ID(Process ID, 其返回值是一个无符号长整型
GetCurrentProcess
GetCurrentProcess函数是Windows API提供的一个函数,用于获取当前进程的句柄。该函数没有任何参数,调用后将返回一个类型为HANDLE的句柄,该句柄指向当前进程
GetCurrentProcess 获取当前进程的一个伪句柄GetCurrentProcess 总是返回-1(即0xFFFFFFFF),代表当前进程。这个句柄不在句柄表中,不是真正的句柄,所以叫伪句柄
EnumProcesses
EnumProcesses函数是Windows API中的一个函数,用于列举当前正在运行的进程的ID号,通常用于获取系统中所有进程的ID号列表。若函数执行成功则返回TRUE, 否则返回FLASE, 它的声明如下:
如果包含了Windows.h头文件, 还提示"EnumProcesses"未定义标识符, 请检查是否正确链接了psapi.lib库文件。
可以通过在Visual Studio中转到“项目”菜单,然后选择“属性”来查看和配置链接器选项。在属性页面的左侧选择“链接器”,然后选择“输入”。在“附加依赖项”字段中添加“Psapi.lib”,然后包含头文件:
include "psapi.h"
3、线程:
线程是进程中的每一段代码的执行
线程与进程之间的关系:
一个进程可以拥有多个线程
常见线程的API函数:
CreateThreat:
线程函数:
线程函数是线程执行的代码,它会在调用
CreateThread
函数创建线程后被调用, 其返回值为DOWRD类型, 此值会传递给GetExitCodeThread
函数。如果线程函数执行完毕后不返回任何值,则默认返回0给个实例,也可以展示一下多线程的实现以及常见的线程创建
GetExitCodeThread
可以用于获取指定线程的退出代码:
线程参数的生命周期:
创建线程时需要注意向线程传递的参数的生命周期,我们要保证这个参数的存在时间要比这个线程地结束时间要短,否则就会导致出错,举个例子,我们如果要在一个线程中打印一个字符串,但是他在主函数运行结束后就销毁了,我们传递地值就消失了,那么就会出现错误
SuspendThread
线程的挂起操作
ResumeThread
线程的恢复函数
WaitForSingleObject
WaitForSingleObject函数是一个Windows API函数,它可以等待一个指定的内核对象变为可用。它的作用是使当前线程暂停执行,直到指定的内核对象变为有信号(signaled)状态,或者直到超时时间已过。简单来说就是等待指定线程执行结束后当前线程才能恢复执行
WaitForMutipleObjects
与WaitForSingleObjects函数不同的是, WaitForMutipleObjects函数可支持等待多个线程执行结束, 或者等待多个线程中其中一个执行结束
- Author:xiaowaaa
- URL:https://www.xiaowaaa.asia//article/247ea41c-cdf8-4aa1-b7fc-cf26d9e72fa3
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!