CreateProcess reverse analysis -- character encoding conversion of three ring function parameters

There are two APIs for process creation, createprocessa and CreateProcessW. These two functions only have different character codes of parameters, and will eventually call the same function.

1, Introduction to function parameters

First, let's look at the parameters of the process creation function
Take CreateProcessW as an example:

WINBASEAPI
BOOL
WINAPI
CreateProcessW(
    LPCWSTR lpApplicationName,
    LPWSTR lpCommandLine,
    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    BOOL bInheritHandles,
    DWORD dwCreationFlags,
    LPVOID lpEnvironment,
    LPCWSTR lpCurrentDirectory,
    LPSTARTUPINFOW lpStartupInfo,
    LPPROCESS_INFORMATION lpProcessInformation
);
  • lpApplicationName: points to a NULL terminated string used to specify the executable module
  • lpCommandLine: points to a NULL terminated string that specifies the command line to execute
  • lpProcessAttributes: points to a SECURITY_ATTRIBUTES structure, which determines whether the returned handle can be inherited by the child process
    typedef struct _SECURITY_ATTRIBUTES {
        DWORD nLength;
        LPVOID lpSecurityDescriptor;
        BOOL bInheritHandle;
    } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
    
  • lpThreadAttributes: the same as lpProcessAttribute, but this parameter determines whether the thread is inherited
  • bInheritHandles: indicates whether the new process inherits a handle from the calling process
  • dwCreationFlags: Specifies additional flags that control the creation of priority classes and processes
  • lpEnvironment: refers to the environment block of a new process. If this parameter is empty, the new process uses the environment of the calling process
  • lpCurrentDirectory: points to a NULL terminated string that specifies the working path of the child process
  • lpStartupInfo: points to a STARTUPINFO structure that determines how the main form of a new process is displayed
    typedef struct _STARTUPINFOW {
        DWORD   cb;
        LPWSTR  lpReserved;
        LPWSTR  lpDesktop;
        LPWSTR  lpTitle;
        DWORD   dwX;
        DWORD   dwY;
        DWORD   dwXSize;
        DWORD   dwYSize;
        DWORD   dwXCountChars;
        DWORD   dwYCountChars;
        DWORD   dwFillAttribute;
        DWORD   dwFlags;
        WORD    wShowWindow;
        WORD    cbReserved2;
        LPBYTE  lpReserved2;
        HANDLE  hStdInput;
        HANDLE  hStdOutput;
        HANDLE  hStdError;
    } STARTUPINFOW, *LPSTARTUPINFOW;
    
  • lpProcessInformation: refers to a process used to receive the identification information of the new PROCESS_INFORMATION structure
    typedef struct _PROCESS_INFORMATION {
        HANDLE hProcess;
        HANDLE hThread;
        DWORD dwProcessId;
        DWORD dwThreadId;
    } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
    

The specific meaning of these parameters can be known in the subsequent reverse analysis

2, Detailed analysis of character encoding conversion of CreateProcessA

CreateProcessInternalA is called directly inside CreateProcessA, but two parameters are added at the beginning and end, and the values are zero

The CreateProcessInternalA function is analyzed below
The flow chart is as follows:

(1) First, judge whether lpCommandLine is empty

  • If lpCommandLine is not empty, call basep8bitstringtodynamicunicode string to convert it to UNICODE_STRING type
  • If lpCommandLine is empty, proceed to the next step

(2) Then determine whether lpApplicationName is empty

  • Call basep8bitstringtodynamicunicode string to convert it to UNICODE_STRING type
  • If lpApplicationName is empty, proceed to the next step

(3) Then determine whether the lpCurrentDirectory is empty

  • Call basep8bitstringtodynamicunicode string to convert it to UNICODE_STRING type
  • If lpCurrentDirectory is empty, proceed to the next step

(4) Since lpStartupInfo also has three ANSI strings inside, it also needs to be converted

  • First, create a local variable StartupInfo of StartupInfo type, and copy the parameter lpStartupInfo into StartupInfo. At this time, you also need to convert the string in StartupInfo into UNICODE

(5) When all parameters have been changed to UNICODE, CreateProcessInternalW can be called

For CreateProcessW, CreateProcessInternalW is directly called internally

Tags: Windows

Posted on Thu, 21 Oct 2021 18:59:21 -0400 by skyxmen