|
| 1 | +#include "Win32/Process.hpp" |
| 2 | + |
1 | 3 | #include <accctrl.h> |
2 | 4 | #include <aclapi.h> |
3 | 5 | #include <psapi.h> |
|
10 | 12 | #include "Log.hpp" |
11 | 13 | #include "Utils.hpp" |
12 | 14 | #include "Win32/API.hpp" |
13 | | -#include "Win32/Process.hpp" |
14 | 15 | #include "Win32/System.hpp" |
15 | 16 | #include "Win32/Thread.hpp" |
16 | 17 |
|
|
26 | 27 | GetPebLength(); |
27 | 28 | EXTERN_C_END |
28 | 29 |
|
| 30 | +using CriticalSection = GenericHandle< |
| 31 | + RTL_CRITICAL_SECTION, |
| 32 | + [](auto p) |
| 33 | + { |
| 34 | + ::LeaveCriticalSection(p); |
| 35 | + }>; |
| 36 | + |
29 | 37 |
|
30 | 38 | namespace pwn::Process |
31 | 39 | { |
@@ -570,6 +578,71 @@ Process::QueryInternal(const PROCESSINFOCLASS ProcessInformationClass, const usi |
570 | 578 | return Ok(std::move(Buffer)); |
571 | 579 | } |
572 | 580 |
|
| 581 | +Result<std::vector<LDR_DATA_TABLE_ENTRY>> |
| 582 | +Process::Modules() |
| 583 | +{ |
| 584 | + return IsRemote() ? EnumerateRemoteModules() : EnumerateLocalModules(); |
| 585 | +} |
| 586 | + |
| 587 | + |
| 588 | +Result<std::vector<LDR_DATA_TABLE_ENTRY>> |
| 589 | +Process::EnumerateLocalModules() |
| 590 | +{ |
| 591 | + std::vector<LDR_DATA_TABLE_ENTRY> res; |
| 592 | + auto peb = Peb(); |
| 593 | + CriticalSection csLoaderLock {[&]() |
| 594 | + { |
| 595 | + auto lock = peb->LoaderLock; |
| 596 | + ::EnterCriticalSection(lock); |
| 597 | + return lock; |
| 598 | + }()}; |
| 599 | + |
| 600 | + if ( !peb->Ldr->Initialized ) |
| 601 | + return Ok(res); |
| 602 | + |
| 603 | + |
| 604 | + auto head = &(peb->Ldr->InLoadOrderModuleList); |
| 605 | + |
| 606 | + for ( auto cur = head; cur->Flink && cur->Flink != head; cur = cur->Flink ) |
| 607 | + { |
| 608 | + auto ptr = CONTAINING_RECORD(cur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); |
| 609 | + |
| 610 | + // HACK We copy for now because the module may have been unloaded by the time we access it |
| 611 | + LDR_DATA_TABLE_ENTRY entry {}; |
| 612 | + ::memcpy(&entry, ptr, sizeof(LDR_DATA_TABLE_ENTRY)); |
| 613 | + res.emplace_back(entry); |
| 614 | + } |
| 615 | + |
| 616 | + return Ok(res); |
| 617 | +} |
| 618 | + |
| 619 | +Result<std::vector<LDR_DATA_TABLE_ENTRY>> |
| 620 | +Process::EnumerateRemoteModules() |
| 621 | +{ |
| 622 | + std::vector<LDR_DATA_TABLE_ENTRY> res; |
| 623 | + auto ppeb = Peb(); |
| 624 | + auto mem = Memory(*this); |
| 625 | + auto peb_buf = Value(mem.Read((uptr)ppeb, sizeof(PEB))); |
| 626 | + auto peb = reinterpret_cast<PPEB>(peb_buf.data()); |
| 627 | + |
| 628 | + auto ldr_buf = Value(mem.Read((uptr)peb->Ldr, sizeof(PEB_LDR_DATA))); |
| 629 | + auto ldr = reinterpret_cast<PPEB_LDR_DATA>(ldr_buf.data()); |
| 630 | + auto head = &(ldr->InLoadOrderModuleList); |
| 631 | + |
| 632 | + for ( auto cur = head; cur->Flink && cur->Flink != head; cur = cur->Flink ) |
| 633 | + { |
| 634 | + LDR_DATA_TABLE_ENTRY entry {}; |
| 635 | + auto buf = Value(mem.Read( |
| 636 | + (uptr)CONTAINING_RECORD(cur, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks), |
| 637 | + sizeof(LDR_DATA_TABLE_ENTRY))); |
| 638 | + ::memcpy(&entry, buf.data(), sizeof(LDR_DATA_TABLE_ENTRY)); |
| 639 | + res.emplace_back(entry); |
| 640 | + } |
| 641 | + |
| 642 | + return Ok(res); |
| 643 | +} |
| 644 | + |
| 645 | + |
573 | 646 | #pragma endregion Process |
574 | 647 |
|
575 | 648 |
|
@@ -633,7 +706,6 @@ AppContainer::AppContainer( |
633 | 706 | throw std::runtime_error("Failed to get SID"); |
634 | 707 | } |
635 | 708 |
|
636 | | - |
637 | 709 | dbg(L"sid={}", m_SidAsString.c_str()); |
638 | 710 |
|
639 | 711 | // |
|
0 commit comments