Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >7.2 通过API创建新进程

7.2 通过API创建新进程

原创
作者头像
王瑞MVP
发布于 2023-09-22 01:02:54
发布于 2023-09-22 01:02:54
24702
代码可运行
举报
运行总次数:2
代码可运行

创建新的进程是Windows程序开发的重要部分,它可以用于实现许多功能,例如进程间通信、并行处理等。其中,常用的三种创建进程的方式分别是WinExec()ShellExecute()CreateProcessA(),这三种创建进程的方式各有特点。如果需要创建简单进程或从其他程序启动新进程,可以使用WinExec()ShellExecute()函数。如果需要对新进程进行更精细的配置,例如控制进程参数、指定安全级别、传递特定的命令和参数等,可以使用CreateProcessA()函数。

首先介绍WinExec函数,该函数是创建进程的一种方式,它使用较为简单,但缺乏对进程参数和安全性等方面的控制。使用WinExec()函数,可以传递一个字符串类型的参数,该参数中指定了要启动的进程名和参数等信息。但是,由于WinExec()函数没有提供区分进程启动成功和失败的返回值,且无法从函数返回的进程句柄获得与进程相关的信息,因此使用较为有限。

该函数的原型为:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
UINT WinExec(
  LPCSTR lpCmdLine,
  UINT   uCmdShow
);

其参数说明如下:

  • lpCmdLine:需要执行的命令行字符串
  • uCmdShow:指定程序窗口最初显示方式,如SW_SHOW,即窗口正常大小和位置显示

WinExec 函数的返回值是一个无符号整数,它表示进程是否成功启动。若成功启动,则返回值为任务句柄。否则,返回值为0。但是该函数也存在一些问题,例如ANSI编码、不支持进程标识符等,建议在实际开发中使用更为灵活的CreateProcess()ShellExecute()函数。

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <Windows.h>

BOOL WinExec(char *pszExePath, UINT uiCmdShow)
{
  UINT uiRet = 0;
  uiRet = WinExec(pszExePath, uiCmdShow);
  if (31 < uiRet)
  {
    return TRUE;
  }
  return FALSE;
}

int main(int argc, char * argv[])
{
  int ret = 0;
  ret = WinExec("c:\\windows\\system32\\notepad.exe",TRUE);
  printf("执行状态: %d \n", ret);

  system("pause");
  return 0;
}

创建进程的第二个函数是ShellExecute,该函数提供了很多功能,例如可以启动进程、打开文件、运行脚本等等。ShellExecute()函数的优点是可以控制进程的启动方式、传递命令参数,并对返回值进行判断,通过传递参数来控制启动进程的方式,比如最大化或最小化窗口,或者在后台启动进程。

该函函数原型如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
HINSTANCE ShellExecute(
  HWND    hwnd,
  LPCTSTR lpOperation,
  LPCTSTR lpFile,
  LPCTSTR lpParameters,
  LPCTSTR lpDirectory,
  INT     nShowCmd
);

参数说明:

  • hwnd:执行的窗口的句柄。可以为NULL,如果为NULL则表示没有窗口。
  • lpOperation:操作类型,可以是open或print。如果为NULL,则此函数将尝试打开文件。
  • lpFile:需要执行的目标文件、应用程序或者URL地址。
  • lpParameters:命令行参数。
  • lpDirectory:指定被启动程序的执行路径,如果为NULL,则使用当前程序路径。
  • nShowCmd:指定被启动程序的窗口状态。

该函数返回HINSTANCE类型的值,如果没有执行或则执行失败,它将返回一个值为ERROR_FILE_NOT_FOUNDERROR_BAD_FORMAT的值。

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <Windows.h>

BOOL MyShellExecute(char *pszExePath, UINT uiCmdShow)
{
  HINSTANCE hInstance = 0;
  hInstance = ShellExecute(NULL, NULL, pszExePath, NULL, NULL, uiCmdShow);
  if (32 < (DWORD)hInstance)
  {
    return TRUE;
  }
  return FALSE;
}

int main(int argc, char * argv[])
{
  int ret = 0;
  ret = MyShellExecute("c:\\windows\\system32\\notepad.exe", TRUE);
  printf("执行状态: %d \n", ret);

  system("pause");
  return 0;
}

最后一个创建进程的函数是CreateProcess()该函数提供了比较灵活的进程控制,相比于其他API函数,例如WinExec()ShellExecute() ,它可以更详细地控制进程的执行,如进程窗口的大小和位置,输出、输入和错误信息的控制等,并且能够获取到新进程的标识符以及进程句柄。同时CreateProcess()也具有更高的系统安全性。因此,在实际开发中,开发人员往往使用 CreateProcess()函数进行进程控制、管理和处理。

其函数原型如下:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
BOOL CreateProcess(
  LPCSTR                lpApplicationName,   // 可执行文件名或命令行调用
  LPSTR                 lpCommandLine,       // 字符串形式的命令行参数
  LPSECURITY_ATTRIBUTES lpProcessAttributes,// 进程的安全属性
  LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性
  BOOL                  bInheritHandles,     // 建立进程时是否继承父句柄
  DWORD                 dwCreationFlags,     // 进程标记
  LPVOID                lpEnvironment,       // 进程环境空间块的指针
  LPCSTR                lpCurrentDirectory,  // 当前工作目录的指针
  LPSTARTUPINFOA        lpStartupInfo,       // 指向 StartupInfo 结构的指针
  LPPROCESS_INFORMATION lpProcessInformation // 指向 ProcessInformation 结构的指针
);

参数说明:

  • lpApplicationName:需要执行的可执行文件名或命令行调用。如果为NULL,则将使用lpCommandLine参数中的文件名
  • lpCommandLine:命令行参数,可以传递参数给可执行文件
  • lpProcessAttributes:进程的安全属性。一般为NULL
  • lpThreadAttributes:线程的安全属性。一般为NULL
  • bInheritHandles:指定新进程是否继承父进程的句柄
  • dwCreationFlags:指定进程的标记。常用的标记有NORMAL_PRIORITY_CLASS,表示新进程在普通优先级类中运行
  • lpEnvironment:进程环境空间块的指针,用于设置新进程的环境变量
  • lpCurrentDirectory:指定新进程的初始工作目录,如果为NULL,则使用与调用进程相同的当前目录
  • lpStartupInfo:指向STARTUPINFO结构体的指针
  • lpProcessInformation:进程信息结构,包括新进程的句柄和进程ID

如果仅仅只是需要将一个进程拉起来,那么只需要传递三个参数即可,其余参数可以全部使用0进行填充,如下所示;

代码语言:c
代码运行次数:0
运行
复制

#include <iostream>

#include <Windows.h>

BOOL ExecRun(LPCSTR exe_file)

{

PROCESS_INFORMATION pi = { 0 };

STARTUPINFO si = { 0 };

si.cb = sizeof(STARTUPINFO);

BOOL bRet = CreateProcessA(exe_file, 0, 0, 0, 0, 0, 0, 0, &si, &pi);

if (bRet != FALSE)

代码语言:txt
AI代码解释
复制
CloseHandle(pi.hProcess);

return TRUE;

return FALSE;

}

int main(int argc, char * argv[])

{

int ret = 0;

ret = ExecRun("c:\windows\system32\notepad.exe");

printf("执行状态: %d \n", ret);

system("pause");

return 0;

}

代码语言:txt
复制

本文作者: 王瑞

本文链接: https://www.lyshark.com/post/89068d1f.html

版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WinExec, ShellExecute,CreateProcess 区别
本文转载自WinExec, ShellExecute,CreateProcess 区别 其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂。
ccf19881030
2020/05/29
1.3K0
WinExec、ShellExecute和CreateProcess
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。CreateProcess因为使用复杂,比较少用。
全栈程序员站长
2022/09/14
1.1K0
WinExec、ShellExecute和CreateProcess
Windows黑客编程技术详解 --第四章 木马启动技术(内含赠书福利)
病毒木马植入模块成功植入用户计算机之后,便会启动攻击模块来对用户计算机数据实施窃取和回传等操作。通常植入和攻击是分开在不同模块之中的,这里的模块指的是DLL、exe或其他加密的PE文件等。只有当前植入模块成功执行后,方可继续执行攻击模块,同时会删除植入模块的数据和文件。模块化开发的好处不单单是便于开发管理,同时也可以减小因某一模块的失败而导致整个程序暴露的可能性。
用户1631416
2019/05/14
4.1K0
实战 | 进程启动技术的思路和研究
通过常用的api来创建进程是常规启动进程的方式,最常用的几个api有WinExec、ShellExecute、CreateProcess,我们一个一个来看一下
HACK学习
2021/11/12
1.2K0
VC 调用外部程序接口
  返回值     =-1:出现错误     =0:调用成功但是没有出现子进程     >0:成功退出的子进程的id
阳光岛主
2019/02/19
1.2K0
6.3 应用动态内存补丁
动态内存补丁可以理解为在程序运行时动态地修改程序的内存,在某些时候某些应用程序会带壳运行,而此类程序的机器码只有在内存中被展开时才可以被修改,而想要修改此类应用程序动态补丁将是一个不错的选择,动态补丁的原理是通过CreateProcess函数传递CREATE_SUSPENDED将程序运行起来并暂停,此时程序会在内存中被解码,当程序被解码后我们则可以通过内存读写实现对特定区域的动态补丁。
王瑞MVP
2023/10/11
2020
6.3 应用动态内存补丁
1.6 编写双管道ShellCode
本文将介绍如何将CMD绑定到双向管道上,这是一种常用的黑客反弹技巧,可以让用户在命令行界面下与其他程序进行交互,我们将从创建管道、启动进程、传输数据等方面对这个功能进行详细讲解。此外,本文还将通过使用汇编语言一步步来实现这个可被注入的ShellCode后门,并以此提高代码通用性。最终,我们将通过一个实际的漏洞攻击场景来展示如何利用这个后门实现内存注入攻击。
王瑞MVP
2023/10/11
1910
1.6 编写双管道ShellCode
一种解决启动进程传递参数过长的方法
        工作中,QA同学在测试我们程序的时候,发现在XP下,我们的A进程无法启动我们的B进程。而在Win7 64bit系统下功能正常。RD同学调试后,发现我们A进程中使用ShellExcute去启动了B进程(转载请指明出于breaksoftware的csdn博客)
方亮
2019/01/16
1K0
WinExec, ShellExecute, CreateProcess
在vc++ 程序中运行另一个程序的方法有三个: WinExec(),ShellExcute()和CreateProcess()
全栈程序员站长
2022/09/18
1.5K0
1.12 进程注入ShellCode套接字
在笔者前几篇文章中我们一直在探讨如何利用Metasploit这个渗透工具生成ShellCode以及如何将ShellCode注入到特定进程内,本章我们将自己实现一个正向ShellCodeShell,当进程被注入后,则我们可以通过利用NC等工具连接到被注入进程内,并以对方的权限及身份执行命令,该功能有利于于Shell的隐藏。本章的内容其原理与《运用C语言编写ShellCode代码》中所使用的原理保持一致,通过动态定位到我们所需的网络通信函数并以此来构建一个正向Shell,本章节内容对Metasploit工具生成的Shell原理的理解能够起到促进作用。
王瑞MVP
2023/09/01
3570
1.12 进程注入ShellCode套接字
创建线程的方式打开记事本
今天操作系统课老师讲到进程,提出了一个有趣的小实验:能否以系统调用的方式利用 Windows 创建进程的系统调用函数来打开一个软件。闲着蛋疼的我立马来了兴趣,姑且写一个玩玩(
浪漫主义狗
2023/09/20
2910
创建线程的方式打开记事本
关于WinExec和System的比较
WinExec是一个WIN32 API,它的第一个参数必须包含一个可执行文件名,
全栈程序员站长
2022/09/18
1.1K0
17.1 隐藏执行CMD命令
本章内容涉及使用Socket API和CMD命令行工具实现本地CMD命令执行、无管道正向CMD和无管道反向CMD三种功能。执行本地CMD实现使用CreateProcess函数创建一个新的CMD进程,并将标准输入、输出和错误输出重定向到当前进程的标准输入、输出和错误输出。无管道正向CMD和无管道反向CMD使用WSASocket函数创建TCP套接字,并将CMD进程的标准输入、输出和错误输出重定向到套接字的句柄上,通过网络连接实现远程命令执行功能。
王瑞MVP
2023/10/22
4810
17.1 隐藏执行CMD命令
Windows内核之进程基本含义以及进程的创建「建议收藏」
1.2 还有一个是地址空间,它包括全部可运行模块或DL L 模块的代码和数据。它还包括动态内存分配的空间。
全栈程序员站长
2022/07/10
7300
Windows内核之进程基本含义以及进程的创建「建议收藏」
win32之进程概念
  学习WindowsAPI. 之前.我们必须理解什么是进程. 在windows环境下.进程就是一个运行起来的exe程序
IBinary
2018/09/28
8300
win32之进程概念
C/C++ 进程代码注入&提权&降权
如果将shellcode注入到具有特定权限的进程中,我们就可以获得与该进程相同的权限,此方法可以用于提权与降权操作,注入有多种方式,最简单的是直接将metasploit生成的有效载荷直接注入到目标进程中,并通过创建远程线程启动,还可以自己实现一个注入器,这里我们自己来实现一个提权器,可提权也可降权。
王瑞MVP
2022/12/28
1K0
C/C++ 进程代码注入&提权&降权
【操作系统】Windows进程间的通信
进程通常上被定义为一个正在运行的程序的实例,是一个程序在其自身的地址空间中的一次执行活动,一个程序可以对应多个进程。
半生瓜的blog
2023/05/13
9570
【操作系统】Windows进程间的通信
WinApi学习笔记-创建进程
#include <windows.h> #include <stdio.h> #include <iostream> DWORD CreateChildProcess(LPSTR szChildProcessCmd); int main() { CreateChildProcess("Child.exe"); } DWORD CreateChildProcess(LPSTR szChildProcessCmd) { //启动信息结构变量 STARTUPINFO si; //被创建进程的信息
liulun
2022/05/09
4280
ShellExecute, WinExec, CreateProcess区别
ShellExecute   ShellExecute的功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等),并对外部程序有一定的控制。
全栈程序员站长
2022/09/18
9890
C/C++ 进程线程操作技术
手动创建多线程: 多线程的创建需要使用CreateThread()其内部应该传递进去ThreadProc()线程执行函数,运行结束后恢复.
王瑞MVP
2023/02/25
7360
相关推荐
WinExec, ShellExecute,CreateProcess 区别
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验