MCPcopy Create free account
hub / github.com/NetSPI/BOF-PE / MappedModule

Method MappedModule

loader/mappedmodule.cpp:396–475  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

394}
395
396MappedModule::MappedModule(Logger logger, const std::vector<std::byte>& peBytes) : _mappedPe(Pe::ImgType::module, nullptr), _logger(logger) {
397
398 auto pe = Pe::PeNative::fromFile(peBytes.data());
399
400 if (!pe.valid()) {
401 throw std::runtime_error("PE file is not valid");
402 }
403
404 //We try to allocate at the preferred base, this will save relocation later
405 _mappedImage = VirtualAlloc((LPVOID)(pe.headers().opt()->ImageBase), pe.imageSize(), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
406
407 //Preferred base was not available, so just allocate at any available address
408 if (_mappedImage == nullptr) {
409 _mappedImage = VirtualAlloc(nullptr, pe.imageSize(), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
410 }
411
412 _logger("Allocated image @ 0x%p\n", _mappedImage);
413
414 if (_mappedImage == nullptr) {
415 throw std::bad_alloc();
416 }
417
418 try {
419
420 //Wipe the mapped image space and copy the Pe headers across
421 memset(_mappedImage, 0, pe.imageSize());
422 memcpy(_mappedImage, pe.base(), pe.headers().nt()->OptionalHeader.SizeOfHeaders);
423
424 //Now map each section into it's correct RVA location, ignoring the .discard section
425 for (auto section : pe.sections()) {
426 if (section.PointerToRawData && strncmp((const char*)section.Name, ".discard", 8) != 0) {
427 memcpy(reinterpret_cast<void*>(uintptr_t(_mappedImage) + section.VirtualAddress), pe.byOffset<void*>(section.PointerToRawData), section.SizeOfRawData);
428 _logger("Copied section %.8s @ 0x%p\n", section.Name, PVOID(uintptr_t(_mappedImage) + section.VirtualAddress));
429 }
430 else {
431 _logger("Skipped .discard section @ 0x%p\n", PVOID(uintptr_t(_mappedImage) + section.VirtualAddress));
432 }
433 }
434
435 //Now that we have laid out the PE in mapped form,
436 //Parse the PE from memory
437 _mappedPe = std::move(Pe::PeNative::fromModule(_mappedImage));
438
439 //If our mapped base address doesn't match the preferred base
440 //then process the reloc section
441 if (uintptr_t(_mappedImage) != pe.headers().opt()->ImageBase) {
442 ProcessRelocations(_mappedPe, uintptr_t(_mappedImage) - uintptr_t(pe.headers().opt()->ImageBase));
443 _logger("Processed relocations\n");
444 }
445 else {
446 _logger("Skipped relocations\n");
447 }
448
449 //Now process our import table, paying special attention to imports
450 //from beacon.dll
451 ProcessImports(_mappedPe);
452 _logger("Processed imports\n");
453

Callers

nothing calls this directly

Calls 13

ProcessRelocationsFunction · 0.85
ProcessImportsFunction · 0.85
UpdateSectionPermissionsFunction · 0.85
AddExceptionSupportFunction · 0.85
TlsCallbacksFunction · 0.85
optMethod · 0.80
headersMethod · 0.80
imageSizeMethod · 0.80
baseMethod · 0.80
ntMethod · 0.80
dataMethod · 0.45
validMethod · 0.45

Tested by

no test coverage detected