| #include <windows.h> |
| #include <nt.h> |
| |
| #define malloc(S) RtlAllocateHeap(Heap, 0, S) |
| #define realloc(P, S) RtlReAllocateHeap(Heap, 0, P, S) |
| #define free(P) RtlFreeHeap(Heap, 0, P) |
| |
| extern int main(int, char **, char **); |
| static void *Heap; |
| |
| void __main() {} |
| |
| static int _parse_tokens(char *string, char ***tokens, int length) |
| { |
| /* Extract whitespace- and quotes- delimited tokens from the given string |
| and put them into the tokens array. Returns number of tokens |
| extracted. Length specifies the current size of tokens[]. |
| THIS METHOD MODIFIES string. */ |
| |
| const char * whitespace = " \t\r\n"; |
| char * tokenEnd; |
| const char * quoteCharacters = "\"\'"; |
| char * end = string + strlen (string); |
| |
| if (!string) return length; |
| |
| while (1) { |
| const char *q; |
| /* Skip over initial whitespace. */ |
| string += strspn(string, whitespace); |
| if (*string == '\0') break; |
| |
| for (q = quoteCharacters; *q; ++q) { |
| if (*string == *q) break; |
| } |
| if (*q) { |
| /* Token is quoted. */ |
| char quote = *string++; |
| tokenEnd = strchr(string, quote); |
| /* If there is no endquote, the token is the rest of the string. */ |
| if (!tokenEnd) tokenEnd = end; |
| } else { |
| tokenEnd = string + strcspn(string, whitespace); |
| } |
| |
| *tokenEnd = '\0'; |
| |
| { |
| char **new_tokens; |
| int newlen = length + 1; |
| new_tokens = realloc (*tokens, sizeof(char *) * newlen); |
| if (!new_tokens) { |
| /* Out of memory. */ |
| return -1; |
| } |
| |
| *tokens = new_tokens; |
| (*tokens)[length] = string; |
| length = newlen; |
| } |
| if (tokenEnd == end) break; |
| string = tokenEnd + 1; |
| } |
| exit: |
| return length; |
| } |
| |
| static void _getmainargs(int *argc, char ***argv, wchar_t *CommandLinePtrW) |
| { |
| int CommandLineLen = 0; |
| if (CommandLinePtrW) CommandLineLen = wcslen(CommandLinePtrW) * 2 - 1; |
| |
| *argv = malloc(sizeof (char *) * 1); |
| if (!*argv) ExitProcess(-1); |
| |
| **argv = malloc(CommandLineLen + 1); |
| if (!**argv) ExitProcess(-1); |
| |
| if (CommandLineLen > 0) { |
| char *argv0 = **argv; |
| wcstombs(argv0, CommandLinePtrW, CommandLineLen + 1); |
| *argc = _parse_tokens(argv0, argv, 0); |
| if (*argc < 0) ExitProcess(-1); |
| } |
| (*argv)[*argc] = 0; |
| return; |
| } |
| |
| void NtProcessStartup(){ |
| int _argc = 0; |
| char **_argv = 0; |
| char **_envp = 0; |
| PROCESS_BASIC_INFORMATION pbi; |
| RTL_USER_PROCESS_PARAMETERS *ProcessParameters; |
| NtQueryInformationProcess((void *)-1, ProcessBasicInformation, &pbi, sizeof pbi, NULL); |
| ProcessParameters = RtlNormalizeProcessParams(pbi.PebBaseAddress->ProcessParameters); |
| Heap = pbi.PebBaseAddress->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL); |
| _getmainargs(&_argc, &_argv, ProcessParameters->CommandLine.Buffer); |
| wchar_t *s = ProcessParameters->Environment; |
| if(s) { |
| char **e = _envp = malloc(256 * sizeof(char *)); |
| size_t len; |
| while(*s) { |
| len = wcslen(s) * 2 - 1; |
| *e = malloc(len * sizeof(char)); |
| wcstombs(*e++, s, len); |
| while(*s++); |
| } |
| *e++ = NULL; |
| } |
| NtTerminateProcess((void *)-1, main(_argc, _argv, _envp)); |
| } |