目录
进程基本概念
基本定义
进程的组成
深入理解
进程相关操作
进程的创建
示例代码
进程提权
开机自启动
进程基本概念
基本定义
一般进程可以狭义地被定义为正在运行的程序。程序是计算机指令的集合,它以文件的形式存储在磁盘上,进程通常被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动。 一个程序可以对应多个进程。
进程是资源申请,高度和独立运行的单位,因此,它使用系统中的运行资源,而程序不能申请系统资源,不能被系统调度也不能作为独立运行的单位,因此它不占系统运行资源。
进程的组成
<1> 操作系统用来管理进行的内核对象
内核对象也是系统用来存放关于进程的统计信息的地方,内核对象是操作系统内部分配的一个内存块,该内存块是一种数据结构,其成员负责维护该对象的各种信息。
<2> 地址空间
它包含所有可执行模块或DLL模块的代码和数据.另外,它也包含动态内存分配的空间,例如线程的栈和堆分配空间。
深入理解
进程从来不执行任何东西,它只是纯种的容器,若要使进行完成某项操作,它必须拥有一个在它的环境中运行的纯种,此线程负责执行包含在进程的地址空间的中的代码,也就是,真正完成代码执行的是线程,而进程只是纯种的容器,或者说是线程的执行环境。
进程相关操作
进程的创建
Windows提供CreateProcess函数创建线程。 微软文档点击
CreateProcessW(
_In_opt_ LPCWSTR lpApplicationName,// 该字符串可以指定要执行的模块的完整路径和文件名,参数可以为 NULL。在这种情况下,模块名称必须是 lpCommandLine 字符串中的第一个空格分隔标记
_Inout_opt_ LPWSTR lpCommandLine, //命令行,如果 lpApplicationName 为 NULL,则命令行的第一个空格分隔标记指定模块名称。如果使用的是包含空格的长文件名,请使用带引号的字符串来指示文件名的结束位置和参数的开始位置
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
//该 结构确定子进程是否可以继承返回到新进程对象的句柄。如果//lpProcessAttributes为NULL,则不能继承该句柄
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
//该 结构确定子进程是否可以继承返回到新线程对象的句柄。如果//lpThreadAttributes为NULL,则不能继承该句柄
_In_ BOOL bInheritHandles,
//如果此参数为TRUE,则新进程将继承调用进程中的每个可继承句柄。如果参//数为FALSE,则不会继承句柄。请注意,继承的句柄与原始句柄具有相同的值和//访问权限
_In_ DWORD dwCreationFlags,// 控制优先级类别和流程创建的标志
CREATE_NEW_CONSOLE
0x00000010
新进程具有新的控制台,而不是继承其父进程的控制台(默认值)
CREATE_SUSPENDED
0x00000004
新进程的主线程在挂起状态下创建,并且在调用 ResumeThread 函数之前不会运行。 点击查看所有标志
_In_opt_ LPVOID lpEnvironment,// 指向新进程的环境块的指针。如果此参数为//NULL,则新进程将使用调用进程的环境
_In_opt_ LPCWSTR lpCurrentDirectory,// 进程当前目录的完整路径
_In_ LPSTARTUPINFOW lpStartupInfo, //设置扩展属性
点击查看 LPSTARTUPINFOW结构文档
_Out_ LPPROCESS_INFORMATION lpProcessInformation // 该结构接收有关新进程的标识//信息
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
示例代码
创建进程运行Edge浏览器打开一个网站
#include#include int main() { char cmdLine[] = ""C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" www.baidu.com/"; STARTUPINFOA strStartInfo; ZeroMemory(&strStartInfo, sizeof(strStartInfo)); PROCESS_INFORMATION procInfo; ZeroMemory(&procInfo, sizeof(procInfo)); int bRet = CreateProcessA( NULL, cmdLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &strStartInfo, &procInfo); if (bRet) WaitForSingleObject(procInfo.hProcess, 4000); else printf("createProcess error %d!n", GetLastError()); system("pause"); return 0; }
进程提权
参考官网文档封装的进程提权函数- 函数功能:指定进程获取管理员权限
BOOL EnableShutDwonProv(HANDLE hProcess)
{
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tkp = {};
BOOL bRet = FALSE;
do
{
// Get a token for this process.
if (!OpenProcessToken(hProcess,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
break;
// Get the LUID for the shutdown privilege.
if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
&tkp.Privileges[0].Luid))
break;
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Get the shutdown privilege for this process.
if (AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES)NULL, 0) == 0)
break;
bRet = TRUE;
} while (FALSE);
if (FALSE == bRet)
{
SetLastError(GetLastError());
}
if (hToken)
{
CloseHandle(hToken);
}
return bRet;
}
开机自启动
进程提权以后,进程具有了修改注册表权限。本人封装了更为通用的自启动函数。注:该代码具有破坏性,可能报毒,未经允许禁止转载。
//设置的自启动文件必须与本程序在同一目录下 @Author:See QQ3492625357. 未经允许禁止转载.
void SystemSelfStart(const char *exeName)
{
HKEY hKEY;
char CurrentPath[MAX_PATH];
char SysPath[MAX_PATH];
long ret = 0;
LPSTR FileNewName;
LPSTR FileCurrentName;
DWORD type = REG_SZ;
DWORD size = MAX_PATH;
LPCSTR Rgspath = "Software\Microsoft\Windows\CurrentVersion\Run"; //regedit win + R
GetSystemDirectoryA(SysPath, size);
GetModuleFileNameA(NULL, CurrentPath, size);
//Copy File
FileCurrentName = CurrentPath;
FileNewName = lstrcatA(SysPath, "\");
FileNewName = lstrcatA(SysPath, exeName);
struct _finddata_t exe;
if (_findfirst(FileNewName, &exe) != -1)
return;//已经安装!
//复制文件
ret = CopyFileA(FileCurrentName, FileNewName, TRUE);
if (!ret)
{
return;
}
//加入注册表
ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, Rgspath, 0, KEY_WRITE, &hKEY);
if (ret != ERROR_SUCCESS)
{
RegCloseKey(hKEY);
return;
}
//Set Key
ret = RegSetValueExA(hKEY, exeName, NULL, type, (const unsigned char*)FileNewName, size);
if (ret != ERROR_SUCCESS)
{
RegCloseKey(hKEY);
return;
}
RegCloseKey(hKEY);
}



