使用 Native API 创建进程

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

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

1.       使用 ZwOpenFile 打开文件,创建映射 ZwCreateSection.

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

2.       调用 ZwCreateProcess

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

3.       创建堆栈、 CONTEXT 、进程参数等,并创建主线程 ZwCreateThread(SUSPEND)

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

1)    堆栈的创建

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

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

typedef struct _INITIAL_TEB{

PVOID OldStabckBase;

PVOID OldStackLimit;

PVOID StackBase;

PVOID StackLimit;

PVOID StackAllocationBase;

}INITIAL_TEB, *PINITIAL_TEB;

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

2)    进程参数

我们使用 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 来清除内存空间。

4.       通知 Csrss.exe

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

5.       调用 ZwResumeThread 恢复线程的执行。

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

代码下载:

http://download.csdn.net/detail/swanabin/6582277

参考文章:

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

2.       CreateProcess 进程创建的内核跟踪分析 ,gz1X

3.       gloomy ——研究 CreateProcess

4.       浅谈 CreateProcess

5.       Windows NT/2000 本机 API 参考手册

6.       一段 CreateProcess 的强悍代码

7.       Window via C/C++ 第四章 Process

8.       Microsoft windows Internals, Fourth Edition (深入解析 Windows 操作系统 第 4 版) , Chapter 6.

使用Native API 创建进程的更多相关文章

  1. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

  2. 用Windows Native API枚举所有句柄及查找文件句柄对应文件名的方法

    枚举所有句柄的方法 由于windows并没有给出枚举所有句柄所用到的API,和进程所拥有的句柄相关的只有GetProcessHandleCount这个函数,然而这个函数只能获取到和进程相关的句柄数,不 ...

  3. 从创建进程到进入main函数,发生了什么?

    前几天,读者群里有小伙伴提问:从进程创建后,到底是怎么进入我写的main函数的? 今天这篇文章就来聊聊这个话题. 首先先划定一下这个问题的讨论范围:C/C++语言 这篇文章主要讨论的是操作系统层面上对 ...

  4. android,JNI创建进程,使用fork()

    long add(long x,long y) { pid_t fpid; //fpid表示fork函数返回的值 int count=0; fpid=fork(); if (fpid < 0) ...

  5. Java中如何创建进程(转)

    在Java中,可以通过两种方式来创建进程,总共涉及到5个主要的类. 第一种方式是通过Runtime.exec()方法来创建一个进程,第二种方法是通过ProcessBuilder的start方法来创建进 ...

  6. 使用hbase的api创建表时出现的异常

    /usr/lib/jvm/java-7-openjdk-amd64/bin/java -Didea.launcher.port=7538 -Didea.launcher.bin.path=/usr/l ...

  7. Java并发编程:如何创建进程?

    转载自:http://www.cnblogs.com/dolphin0520/p/3913517.html 在前面一篇文章中已经讲述了在进程和线程的由来,今天就来讲一下在Java中如何创建线程,让线程 ...

  8. Java 多线程详解(二)------如何创建进程和线程

    Java 多线程详解(一)------概念的引入:http://www.cnblogs.com/ysocean/p/6882988.html 在上一篇博客中,我们已经介绍了并发和并行的区别,以及进程和 ...

  9. 关于Windows创建进程的过程

    之前有听到别人的面试题是问系统创建进程的具体过程是什么,首先想到的是CreateProcess,但是对于具体过程却不是很清楚,今天整理一下. 从操作系统的角度来说 创建进程步骤:        1.申 ...

随机推荐

  1. 分享一套高级Java笔试题(实拍高清图)

    分享一套高级Java笔试题 微信群里群友分享的 刚好他在笔试 有些问题不会发到群里求助 如果你最近正好在面试 需要参考需要提升 这套试题或许对你有用 下面是部分分享原图 下面是微信群中群友的热议 非常 ...

  2. 【2018ACM/ICPC网络赛】徐州赛区

    呃.自闭了自闭了.我才不会说我写D写到昏天黑地呢. I  Characters with Hash 题目链接:https://nanti.jisuanke.com/t/31461 题意:给你一个字符串 ...

  3. jdbc出现中文乱码的解决办法

  4. BBS论坛 注册功能

    三.注册功能 # views.py文件 def register(request): back_dic = {'code': 100, 'msg': ''} form_obj = myforms.My ...

  5. ionic js ion-tabs选项卡栏操作

    ionic 选项卡栏操作 ion-tabs ion-tabs 是有一组页面选项卡组成的选项卡栏.可以通过点击选项来切换页面. 对于 iOS,它会出现在屏幕的底部,Android会出现在屏幕的顶部(导航 ...

  6. Jupyter NoteBook输出的图表太小看不清怎么办?

    如果使用的是matplotlib绘图,可以通过以下命令更改图片的大小: %matplotlib linline 如果是 plt.figure(figsize=(5,3)) #其中(5, 3)用于控制图 ...

  7. SQL 标量函数-----日期函数 day() 、month()、year() 转载

      select day(createtime) from life_unite_product     --取时间字段的天值 select month(createtime) from life_u ...

  8. GCRoots 对象

    GC Roots 虚拟机栈(栈帧中的本地变量表)中引用的对象 方法区中的类静态属性引用的对象 方法区中的常量引用的对象 原生方法栈(Native Method Stack)中 JNI 中引用的对象 可 ...

  9. 解析JQuery Ajax

    jQuery是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 先来看一些简单的方法,这些方法都是对jQuery.ajax()进行封 ...

  10. 阿里云宣布 Serverless 容器服务 弹性容器实例 ECI 正式商业化

    摘要: 阿里云宣布弹性容器实例 ECI(Elastic Container Instance)正式商业化,ECI 是阿里云践行普惠的云计算理念,将 Serverless 和 Container 技术结 ...