`
jinghuainfo
  • 浏览: 1525163 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

使用Native API 创建进程

 
阅读更多

<!-- [if !mso]> <mce:style><!-- v/:* {behavior:url(#default#VML);} o/:* {behavior:url(#default#VML);} w/:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} --> <!-- [endif]--><!-- [if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!-- [if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><!-- [if !mso]> <object classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui> </object> <mce:style><!-- st1/:*{behavior:url(#ieooui) } --> <!-- [endif]--> <!-- [if gte mso 10]> <mce:style><!-- /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} table.MsoTableGrid {mso-style-name:网格型; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; border:solid windowtext 1.0pt; mso-border-alt:solid windowtext .5pt; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-border-insideh:.5pt solid windowtext; mso-border-insidev:.5pt solid windowtext; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} --> <!-- [endif]-->

使用 Native API 创建进程

最近几个星期一直在研究这个题目。因为关于方面的资料比较多(可以看下面的参考文章),所以开始时以为很快就结束了。谁知道真正动起手来才发现有很多要考虑的地方,不过还好今天终于成功了,还是很高兴的。写下来,做个小结吧。(纸上得来终觉浅 , 须知此事要躬行。)

我们一般是使用 CreateProcess 来创建进程的,而使用 Native API 来创建进程其实说白了就是模拟 CreateProcess 的实现。一开始我以为 CreateProcess 就是调用 NtCreateProcess 的(毕竟和 CreateProcess 名称一样嘛),但是读了许多文章后才知道 NtCreateProcess 只是完成了 CreateProcess 一小部分工作。 CreateProcess 是由下面几个步骤完成的:

<!-- [if !supportLists]-->1. <!-- [endif]-->使用 ZwOpenFile 打开文件,创建映射 ZwCreateSection.

本步骤打开文件,并创建一个属性为 SEC_IMAGE SECTION 对象。

<!-- [if !supportLists]-->2. <!-- [endif]-->调用 ZwCreateProcess

本步骤主要是创建进程的 PEB EPROCESS VAD 等核心内核结构。

<!-- [if !supportLists]-->3. <!-- [endif]-->创建堆栈、 CONTEXT 、进程参数等,并创建主线程 ZwCreateThread(SUSPEND)

尽管 ZwCreateProcess 创建了进程对象,但是并没有同时创建一个主线程。主线程需要调用函数 ZwCreateThread 来创建,这个过程同时会建立堆栈、 CONTEXT 、进程的参数等等。有点要注意的是:创建的进程 CreateSuspended TRUE ,于是线程创建后是不能立即执行的。

<!-- [if !supportLists]-->1) <!-- [endif]-->堆栈的创建

一般情况我们都会从可执行文件( PE )文件头中取出需要堆栈的大小,这个大小是在程序编译的时候指定的。

我们将需要堆栈的结构放到一个 INITIAL_TEB 结构中:

typedef struct _INITIAL_TEB{

PVOID OldStabckBase;

PVOID OldStackLimit;

PVOID StackBase;

PVOID StackLimit;

PVOID StackAllocationBase;

}INITIAL_TEB, *PINITIAL_TEB;

分配堆栈内存后,将地址填入上面的结构中,下面是堆栈的结构 :

<!-- [if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"> <v:stroke joinstyle="miter"/> <v:formulas> <v:f eqn="if lineDrawn pixelLineWidth 0"/> <v:f eqn="sum @0 1 0"/> <v:f eqn="sum 0 0 @1"/> <v:f eqn="prod @2 1 2"/> <v:f eqn="prod @3 21600 pixelWidth"/> <v:f eqn="prod @3 21600 pixelHeight"/> <v:f eqn="sum @0 0 1"/> <v:f eqn="prod @6 1 2"/> <v:f eqn="prod @7 21600 pixelWidth"/> <v:f eqn="sum @8 21600 0"/> <v:f eqn="prod @7 21600 pixelHeight"/> <v:f eqn="sum @10 21600 0"/> </v:formulas> <v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/> <o:lock v:ext="edit" aspectratio="t"/> </v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:358.5pt; height:219.75pt'> <v:imagedata src="file:///C:/DOCUME~1/qgmis/LOCALS~1/Temp/msohtml1/01/clip_image001.gif" mce_src="file:///C:/DOCUME~1/qgmis/LOCALS~1/Temp/msohtml1/01/clip_image001.gif" o:title="STACK"/> </v:shape><![endif]--><!-- [if !vml]--><!-- [endif]-->

<!-- [if !supportLists]-->2) <!-- [endif]-->进程参数

我们使用 RtlCreateProcessParameters 来建立一个数据结构:

ULONG NTSYSAPI WINAPI RtlCreateProcessParameters(

OUT PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,

IN PUNICODE_STRING ImagePathName,

IN PUNICODE_STRING DllPath OPTIONAL,

IN PUNICODE_STRING CurrentDirectory OPTIONAL,

IN PUNICODE_STRING CommandLine OPTIONAL,

IN PVOID Environment OPTIONAL,

IN PUNICODE_STRING WindowTitle OPTIONAL,

IN PUNICODE_STRING DesktopInfo OPTIONAL,

IN PUNICODE_STRING ShellInfo OPTIONAL,

IN PUNICODE_STRING RuntimeData OPTIONAL

);

结构如下:

typedef struct _RTL_USER_PROCESS_PARAMETERS {

ULONG MaximumLength;

ULONG Length;

ULONG Flags;

ULONG DebugFlags;

HANDLE ConsoleHandle;

ULONG ConsoleFlags;

HANDLE StandardInput;

HANDLE StandardOutput;

HANDLE StandardError;

CURDIR CurrentDirectory; // ProcessParameters

UNICODE_STRING DllPath; // ProcessParameters

UNICODE_STRING ImagePathName; // ProcessParameters

UNICODE_STRING CommandLine; // ProcessParameters

PVOID Environment; // NtAllocateVirtualMemory

ULONG StartingX;

ULONG StartingY;

ULONG CountX;

ULONG CountY;

ULONG CountCharsX;

ULONG CountCharsY;

ULONG FillAttribute;

ULONG WindowFlags;

ULONG ShowWindowFlags;

UNICODE_STRING WindowTitle; // ProcessParameters

UNICODE_STRING DesktopInfo; // ProcessParameters

UNICODE_STRING ShellInfo; // ProcessParameters

UNICODE_STRING RuntimeData; // ProcessParameters

RTL_DRIVE_LETTER_CURDIR CurrentDirectores[ RTL_MAX_DRIVE_LETTERS ];

} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

调用这个函数后返回一个当前进程(非新建的进程)的内存块,该内存中除了上面的这个结构还包括该结构中指针成员所指向的内容。只有一个成员除外: Environment 。函数仅仅将参数拷贝进这个指针成员中,并没有分配其他空间。所以你需要在新建进程中调用 ZwAllocateVirtualMemory 分配 Environment 内容的内存空间,然后调用 ZwWriteVirtualMemory 写进去,并将内存空间更新到 Environment 成员。

由于函数返回的内存空间是在当前进程中,所以下面需要调用 ZwAllocateVirtualMemory 分配一块内存空间,并调用 ZwWriteVirtualMemory 将函数的返回空间拷贝进去,最后还得调用 RtlDestroyProcessParameters 来清除内存空间。

<!-- [if !supportLists]-->4. <!-- [endif]-->通知 Csrss.exe

每个新创建的进程都需要通知 Csrss.exe 子系统。使用的参数结构如下:


<!-- [if !supportLists]-->5. <!-- [endif]-->调用 ZwResumeThread 恢复线程的执行。

上面的一切都完成了,就可以调用 ZwResumeThread 恢复线程的执行了。

代码下载:

http://download.csdn.net/source/1585086

参考文章:

<!-- [if !supportLists]-->1. <!-- [endif]-->利用 Native API 创建进程 , 炉子 [0GiNr], < 黑客防线 >2008.12

<!-- [if !supportLists]-->2. <!-- [endif]-->CreateProcess 进程创建的内核跟踪分析 ,gz1X

<!-- [if !supportLists]-->3. <!-- [endif]-->gloomy ——研究 CreateProcess

<!-- [if !supportLists]-->4. <!-- [endif]-->浅谈 CreateProcess

<!-- [if !supportLists]-->5. <!-- [endif]-->Windows NT/2000 本机 API 参考手册

<!-- [if !supportLists]-->6. <!-- [endif]-->一段 CreateProcess 的强悍代码

<!-- [if !supportLists]-->7. <!-- [endif]-->Window via C/C++ 第四章 Process

<!-- [if !supportLists]-->8. <!-- [endif]-->Microsoft windows Internals, Fourth Edition (深入解析 Windows 操作系统 4 版) , Chapter 6.

分享到:
评论

相关推荐

    精通Windows.API-函数、接口、编程实例.pdf

    6.2.1 创建进程、获取进程相关信息、获取启动参数 153 6.2.2 编写控制台程序和图形用户界面应用程序 158 6.2.3 获取和设置环境变量 158 6.3 线程、纤程 162 6.3.1 创建线程、退出线程、获取线程信息 162 ...

    精通WindowsAPI 函数 接口 编程实例

    6.2.1 创建进程、获取进程相关信息、获取启动参数 153 6.2.2 编写控制台程序和图形用户界面应用程序 158 6.2.3 获取和设置环境变量 158 6.3 线程、纤程 162 6.3.1 创建线程、退出线程、获取线程信息 162 ...

    react-native-queue:React Native作业队列

    目录高级用法示例高级作业完整示例操作系统后台任务完整示例讲解 特征简单的API:只需两个基本的API调用,即可设置工作工作者并在几分钟之内开始创建您的工作queue.addWorker(name,workerFunction,options = {})...

    react-native-background-downloader:React-Native的库可帮助您在前台和最重要的是在后台下载iOS和Android上的大文件

    使用此方法的真正挑战是,确保应用程序的UI始终与其他进程中正在下载的文件保持最新,因为在下载仍在运行时,您的应用程序可能会从头启动。 react-native-background-downloader为您提供了一个简单的API,既可以...

    Windows编程循序渐进.part2

    12.3.3 实例:使用Native API示例 235 第13章 内存管理 239 13.1 虚拟内存 239 13.1.1 进程虚拟地址空间 239 13.1.2 实例:查看虚拟内存状态 240 131.3 实例:演示虚拟内存的“保留—提交”特性 243 13.1.4 ...

    Windows编程循序渐进.part3

    12.3.3 实例:使用Native API示例 235 第13章 内存管理 239 13.1 虚拟内存 239 13.1.1 进程虚拟地址空间 239 13.1.2 实例:查看虚拟内存状态 240 131.3 实例:演示虚拟内存的“保留—提交”特性 243 13.1.4 ...

    精通WindowsAPI.pdf

    1.1.2 Windows API......................................................................................................17 1.1.3 程序入口函数...............................................................

    一个进程池的服务器程序

    当父进程发现请求数 &gt;= 子进程数时,父进程创建新的子进程,并把子进程数加1(当然子进程数有个预先上限);当父进程发现子进程数大于请求数加1时,父进程杀死多余的子进程。 总的来说,思想是让子进程accept并处理...

    努班克

    可以在本地配置进程,不可以在进程中使用任意模板,也可以在进程中使用通用模板。 ,atrapalhando assim o fluxo de desenvolvimento。 Feito Com Abaixo segue o que foi utilizado nacriaçãodeste模板: -O ...

    gitrepo_realmdb_app

    模板Rocketseat BasicTabela deConteúdo Sobre o Projeto 可以随时使用模板创建模板,也可以使用任意模板创建模板。可以在本地配置进程,不可以在进程中使用任意模板,也可以在进程中使用通用模板。 ,atrapalhando...

Global site tag (gtag.js) - Google Analytics