MCPcopy Create free account
hub / github.com/GJDuck/e9patch / e9loader

Function e9loader

src/e9patch/e9loader_pe.cpp:459–646  ·  view source on GitHub ↗

* Main loader code. */

Source from the content-addressed store, hash-verified

457 * Main loader code.
458 */
459void *e9loader(PEB *peb, const struct e9_config_s *config)
460{
461 // Step (0): Sanity checks & initialization:
462 const uint8_t *loader_base = (const uint8_t *)config;
463 const uint8_t *image_base = loader_base - config->base;
464 void *entry = (void *)(image_base + config->entry);
465 static bool inited = false;
466 if (inited)
467 return entry; // Enforce single execution
468 inited = true;
469
470 // Step (1): Parse the PEB/LDR for kernel32.dll and our image path:
471 PEB_LDR_DATA* ldr = peb->Ldr;
472 LIST_ENTRY *curr = ldr->InMemoryOrderModuleList.Flink;
473 const uint8_t *kernel32 = NULL, *user32 = NULL, *ntdll = NULL;
474 const wchar_t *self = NULL;
475
476 while (curr != NULL && curr != &ldr->InMemoryOrderModuleList &&
477 (kernel32 == NULL || self == NULL || user32 == NULL))
478 {
479 const LDR_DATA_TABLE_ENTRY* entry =
480 CONTAINING_RECORD(curr, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
481 const UNICODE_STRING *name = &entry->FullDllName;
482 if (entry->DllBase == (void *)image_base)
483 self = name->Buffer;
484 name++; // BaseDllName immediately follows FullDllName
485 if (e9wcscasecmp(name->Buffer, L"kernel32.dll") == 0)
486 kernel32 = (const uint8_t *)entry->DllBase;
487 else if (e9wcscasecmp(name->Buffer, L"ntdll.dll") == 0)
488 ntdll = (const uint8_t *)entry->DllBase;
489 else if (e9wcscasecmp(name->Buffer, L"user32.dll") == 0)
490 user32 = (const uint8_t *)entry->DllBase;
491 curr = curr->Flink;
492 }
493 if (kernel32 == NULL || self == NULL)
494 e9panic();
495
496 // Step (2): Get critical functions necessary for output:
497 get_proc_address_t GetProcAddress =
498 (get_proc_address_t)e9get(kernel32, "GetProcAddress");
499 if (GetProcAddress == NULL)
500 e9panic();
501 attach_console_t AttachConsole =
502 (attach_console_t)GetProcAddress(kernel32, "AttachConsole");
503 get_std_handle_t GetStdHandle =
504 (get_std_handle_t)GetProcAddress(kernel32, "GetStdHandle");
505 if (AttachConsole == NULL || GetStdHandle == NULL)
506 e9panic();
507 (void)AttachConsole(-1);
508 void *stderr = GetStdHandle(STD_ERROR_HANDLE);
509 write_console_t WriteConsole =
510 (write_console_t)GetProcAddress(kernel32, "WriteConsoleA");
511 if (WriteConsole == NULL)
512 e9panic();
513
514 if (config->magic[0] != 'E' || config->magic[1] != '9' ||
515 config->magic[2] != 'P' || config->magic[3] != 'A' ||
516 config->magic[4] != 'T' || config->magic[5] != 'C' ||

Callers

nothing calls this directly

Calls 4

e9wcscasecmpFunction · 0.85
e9getFunction · 0.85
e9debugFunction · 0.85
e9panicFunction · 0.70

Tested by

no test coverage detected