【】【API】CreateProcess 使用及调用流程

概述:windows CreateProcess 调用过程详解

CreateProcess 的系统调用流程参考:

Making NtCreateUserProcess Work - Hack.Learn.Share
CreateProcess 内部实现-CSDN博客

使用说明

函数原型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WINBASEAPI
BOOL
WINAPI
CreateProcessW(
_In_opt_ LPCWSTR lpApplicationName,
_Inout_opt_ LPWSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCWSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);

以上原型是我们在用户层调用时的接口。

参数说明

参数说明直接看官网说明就行
CreateProcessA 函数 (processthreadsapi.h) - Win32 apps | Microsoft Learn

Demo

【DbgHelp】通过PDB在PE中查找函数
【WinFile】credwiz

调用流程

用户层的 CreateProcess 调用并不是直接调用的 ntdll 中的接口。而是经过多次转发,最后通过 ntdll 向内核发起调用,调用堆栈大致如下所示,这里了解即可。

1
2
3
4
[0x0]   ntdll!NtCreateUserProcess   0xdf231fc698   0x7ff9da72b473   
[0x1] KERNELBASE!CreateProcessInternalW+0xfe3 0xdf231fc6a0 0x7ff9da728a03
[0x2] KERNELBASE!CreateProcessAsUserW+0x63 0xdf231fdc70 0x7ff9daa4de30
[0x3] KERNEL32!CreateProcessAsUserWStub+0x60 0xdf231fdce0 0x7ff9d4a4526b

在 syscall 之前,最终调用到 ntdll 中的 NtCrteateUserProcess。

nt层调用代码

可以看到系统调用表的 ID 为 0x2E。

1
2
3
4
5
6
7
8
9
10
11
__int64 NtCreateProcess()
{
__int64 result; // rax

result = 186i64;
if ( (MEMORY[0x7FFE0308] & 1) != 0 )
__asm { int 2Eh; DOS 2+ internal - EXECUTE COMMAND }
else
__asm { syscall; Low latency system call } // syscall 发起系统调用
return result;
}

这里也补充下 Kernel32 和 kernelBase 中的调用
从用户层 CreateProcess 调用开始:

Kernel32

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BOOL __stdcall CreateProcessAsUserWStub(
HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation)
{
return CreateProcessAsUserW(
hToken,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}

KernelBase

  • CreateProcessAsUserW
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    BOOL __stdcall CreateProcessAsUserW(
    HANDLE hToken,
    LPCWSTR lpApplicationName,
    LPWSTR lpCommandLine,
    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    BOOL bInheritHandles,
    DWORD dwCreationFlags,
    LPVOID lpEnvironment,
    LPCWSTR lpCurrentDirectory,
    LPSTARTUPINFOW lpStartupInfo,
    LPPROCESS_INFORMATION lpProcessInformation)
    {
    return CreateProcessInternalW(
    (_DWORD)hToken,
    (_DWORD)lpApplicationName,
    (_DWORD)lpCommandLine,
    (_DWORD)lpProcessAttributes,
    (__int64)lpThreadAttributes,
    bInheritHandles,
    dwCreationFlags,
    (__int64)lpEnvironment,
    (__int64)lpCurrentDirectory,
    (__int64)lpStartupInfo,
    (__int64)lpProcessInformation);
    }
  • CreateProcessInternalW 有点长,截图看下调用即可,感兴趣的可以自己去看下

有什么区别 🤔

看到这里不仅要问,为什么要绕这么一圈,而不是直接调用 ntdll 的 createprocess。可能是为了安全的前提下又能方便调用?
补充一个从 kernel32 调用 CreateProcess 的 Demo

void GetKernel32Proc()
{

    typedef BOOL WINAPI func_CreateProcessW(
        LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD,
        LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);

    HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");

    if (kernel32)
    {
        func_CreateProcessW* fCreateProcessW =
            (func_CreateProcessW*)GetProcAddress(kernel32, "CreateProcessW");

        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
        WCHAR szCommandLine[] = L"calc";
        if (fCreateProcessW)
        {
            fCreateProcessW(0, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
        }
    }

}

【】【API】CreateProcess 使用及调用流程
https://hodlyounger.github.io/A_OS/Windows/API/【winapi】CreateProcess/
作者
mingming
发布于
2024年1月23日
许可协议