2025-04-20 21:00:38 +08:00
|
|
|
|
#include "sandbox.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto Sandbox::InitializeLdrData() -> void {
|
2025-04-23 03:48:16 +08:00
|
|
|
|
if (m_peInfo->isX64) {
|
2025-04-20 21:00:38 +08:00
|
|
|
|
// ΪLDR_DATA<54><41><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
|
|
|
|
|
uint64_t ldrDataAddress = m_pebBase + sizeof(X64PEB);
|
|
|
|
|
|
m_pebEnd = ldrDataAddress + sizeof(X64_PEB_LDR_DATA);
|
|
|
|
|
|
m_peb64.Ldr = ldrDataAddress;
|
|
|
|
|
|
|
|
|
|
|
|
// ӳ<><D3B3>LDR<44><52><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
|
|
|
|
|
uc_mem_map(m_ucEngine, ldrDataAddress, sizeof(X64_PEB_LDR_DATA),
|
|
|
|
|
|
UC_PROT_ALL);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ʼ<EFBFBD><CABC>LDR_DATA<54>ṹ
|
|
|
|
|
|
X64_PEB_LDR_DATA ldrData = { 0 };
|
|
|
|
|
|
ldrData.Length = sizeof(X64_PEB_LDR_DATA);
|
|
|
|
|
|
ldrData.Initialized = 1;
|
|
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ - ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ָ<EFBFBD><D6B8><EFBFBD>Լ<EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
|
|
|
|
uint64_t inLoadOrderListHead = ldrDataAddress + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList);
|
|
|
|
|
|
uint64_t inMemoryOrderListHead = ldrDataAddress + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList);
|
|
|
|
|
|
uint64_t inInitOrderListHead = ldrDataAddress + offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Flink<6E><6B>Blink<6E><6B>ָ<EFBFBD><D6B8><EFBFBD>Լ<EFBFBD>
|
|
|
|
|
|
ldrData.InLoadOrderModuleList.Flink = (LIST_ENTRY*)inLoadOrderListHead;
|
|
|
|
|
|
ldrData.InLoadOrderModuleList.Blink = (LIST_ENTRY*)inLoadOrderListHead;
|
|
|
|
|
|
|
|
|
|
|
|
ldrData.InMemoryOrderModuleList.Flink = (LIST_ENTRY*)inMemoryOrderListHead;
|
|
|
|
|
|
ldrData.InMemoryOrderModuleList.Blink = (LIST_ENTRY*)inMemoryOrderListHead;
|
|
|
|
|
|
|
|
|
|
|
|
ldrData.InInitializationOrderModuleList.Flink = (LIST_ENTRY*)inInitOrderListHead;
|
|
|
|
|
|
ldrData.InInitializationOrderModuleList.Blink = (LIST_ENTRY*)inInitOrderListHead;
|
|
|
|
|
|
|
|
|
|
|
|
// д<><D0B4>LDR_DATA<54>ṹ<EFBFBD><E1B9B9><EFBFBD>ڴ<EFBFBD>
|
|
|
|
|
|
uc_mem_write(m_ucEngine, ldrDataAddress, &ldrData, sizeof(X64_PEB_LDR_DATA));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>PEB<45>е<EFBFBD>Ldrָ<72><D6B8>
|
|
|
|
|
|
uc_mem_write(m_ucEngine, m_pebBase, &m_peb64, sizeof(X64PEB));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
auto Sandbox::CreateLdrEntry(const std::shared_ptr<struct_moudle>& module,
|
|
|
|
|
|
uint64_t entryAddress, uint64_t fullNameAddress,
|
|
|
|
|
|
uint64_t baseNameAddress) -> LDR_DATA_TABLE_ENTRY {
|
2025-04-23 03:48:16 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>ȷ<EFBFBD><C8B7>ʼ<EFBFBD><CABC>
|
|
|
|
|
|
LDR_DATA_TABLE_ENTRY entry = {};
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ַ - <20><><EFBFBD><EFBFBD>nullָ<6C><D6B8>
|
|
|
|
|
|
if (module->base == 0) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD>棺ģ<EFBFBD><EFBFBD>'%s'<27>Ļ<EFBFBD>ַΪ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n", module->name);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-20 21:00:38 +08:00
|
|
|
|
entry.DllBase = reinterpret_cast<PVOID>(module->base);
|
|
|
|
|
|
entry.EntryPoint = reinterpret_cast<PVOID>(module->base + module->entry);
|
|
|
|
|
|
entry.SizeOfImages = static_cast<ULONG>(module->size);
|
|
|
|
|
|
// <><D7BC>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>Unicode<64>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
|
|
|
wchar_t nameBuffer[MAX_PATH] = { 0 };
|
2025-04-23 03:48:16 +08:00
|
|
|
|
size_t convertedChars = 0;
|
|
|
|
|
|
std::string fakeFullName = "c:\\windows\\system32\\" + std::string(module->name);
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// ʹ<>ø<EFBFBD><C3B8><EFBFBD>ȫ<EFBFBD><C8AB>mbstowcs_s<5F><73><EFBFBD><EFBFBD>
|
|
|
|
|
|
mbstowcs_s(&convertedChars, nameBuffer, MAX_PATH, fakeFullName.c_str(), fakeFullName.size());
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>֤ת<D6A4><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
size_t nameLen = wcslen(nameBuffer);
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
|
|
|
|
|
|
if (nameLen == 0 || nameLen >= MAX_PATH) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD>棺ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'%s'ת<><D7AA><EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD><E2A3AC><EFBFBD><EFBFBD>=%zu\n", module->name, nameLen);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
|
|
|
|
|
|
entry.FullDllName.Length = static_cast<USHORT>(nameLen * sizeof(wchar_t));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
entry.FullDllName.MaximumLength = MAX_PATH * sizeof(wchar_t);
|
|
|
|
|
|
entry.FullDllName.Buffer = reinterpret_cast<PWSTR>(fullNameAddress);
|
|
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
entry.BaseDllName.Length = static_cast<USHORT>(nameLen * sizeof(wchar_t));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
entry.BaseDllName.MaximumLength = MAX_PATH * sizeof(wchar_t);
|
|
|
|
|
|
entry.BaseDllName.Buffer = reinterpret_cast<PWSTR>(baseNameAddress);
|
2025-04-23 03:48:16 +08:00
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
printf("DEBUG: д<><D0B4>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD> '%s' <20><><EFBFBD><EFBFBD>ַ 0x%llx <20><> 0x%llx\n",
|
|
|
|
|
|
module->name, fullNameAddress, baseNameAddress);
|
|
|
|
|
|
}
|
|
|
|
|
|
uc_mem_write(m_ucEngine, fullNameAddress, nameBuffer, (nameLen + 1) * sizeof(wchar_t));
|
|
|
|
|
|
uc_mem_write(m_ucEngine, baseNameAddress, nameBuffer, (nameLen + 1) * sizeof(wchar_t));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ΪNULL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UpdateLdrLinks<6B><73><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
|
|
|
|
|
entry.InLoadOrderLinks.Flink = nullptr;
|
|
|
|
|
|
entry.InLoadOrderLinks.Blink = nullptr;
|
|
|
|
|
|
entry.InMemoryOrderLinks.Flink = nullptr;
|
|
|
|
|
|
entry.InMemoryOrderLinks.Blink = nullptr;
|
|
|
|
|
|
entry.InInitializationOrderLinks.Flink = nullptr;
|
|
|
|
|
|
entry.InInitializationOrderLinks.Blink = nullptr;
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
|
|
|
|
|
return entry;
|
|
|
|
|
|
}
|
|
|
|
|
|
auto Sandbox::UpdateLdrLinks(const LDR_DATA_TABLE_ENTRY& entry,
|
2025-04-23 03:48:16 +08:00
|
|
|
|
uint64_t entryAddress, X64_PEB_LDR_DATA& ldrData) -> void {
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ַ
|
|
|
|
|
|
uint64_t inLoadOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList);
|
|
|
|
|
|
uint64_t inMemoryOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList);
|
|
|
|
|
|
uint64_t inInitOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList);
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еĵ<D0B5>ַ
|
|
|
|
|
|
uint64_t entryInLoadOrder = entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
|
|
|
|
|
uint64_t entryInMemoryOrder = entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
|
|
|
|
|
|
uint64_t entryInInitOrder = entryAddress + offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks);
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
LIST_ENTRY listHead;
|
|
|
|
|
|
LIST_ENTRY entryLinks;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>InLoadOrderModuleList
|
|
|
|
|
|
uc_mem_read(m_ucEngine, inLoadOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>뵽<EFBFBD><EBB5BD><EFBFBD><EFBFBD>ͷ֮<CDB7><D6AE>)
|
|
|
|
|
|
entryLinks.Flink = listHead.Flink; // <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>Flink = ԭ<><D4AD>ͷ<EFBFBD><CDB7>Flink
|
|
|
|
|
|
entryLinks.Blink = (LIST_ENTRY*)inLoadOrderListHead; // <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF>Blink = ͷ
|
|
|
|
|
|
uc_mem_write(m_ucEngine, entryInLoadOrder, &entryLinks, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Flinkָ<6B><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
|
listHead.Flink = (LIST_ENTRY*)entryInLoadOrder;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, inLoadOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>Blink
|
|
|
|
|
|
if (entryLinks.Flink != (LIST_ENTRY*)inLoadOrderListHead) {
|
|
|
|
|
|
LIST_ENTRY nextEntry;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
nextEntry.Blink = (LIST_ENTRY*)entryInLoadOrder;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// ͬ<><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>InMemoryOrderModuleList
|
|
|
|
|
|
uc_mem_read(m_ucEngine, inMemoryOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
entryLinks.Flink = listHead.Flink;
|
|
|
|
|
|
entryLinks.Blink = (LIST_ENTRY*)inMemoryOrderListHead;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, entryInMemoryOrder, &entryLinks, sizeof(LIST_ENTRY));
|
|
|
|
|
|
listHead.Flink = (LIST_ENTRY*)entryInMemoryOrder;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, inMemoryOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
if (entryLinks.Flink != (LIST_ENTRY*)inMemoryOrderListHead) {
|
|
|
|
|
|
LIST_ENTRY nextEntry;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
nextEntry.Blink = (LIST_ENTRY*)entryInMemoryOrder;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>InInitializationOrderModuleList
|
|
|
|
|
|
uc_mem_read(m_ucEngine, inInitOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
entryLinks.Flink = listHead.Flink;
|
|
|
|
|
|
entryLinks.Blink = (LIST_ENTRY*)inInitOrderListHead;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, entryInInitOrder, &entryLinks, sizeof(LIST_ENTRY));
|
|
|
|
|
|
listHead.Flink = (LIST_ENTRY*)entryInInitOrder;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, inInitOrderListHead, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
if (entryLinks.Flink != (LIST_ENTRY*)inInitOrderListHead) {
|
|
|
|
|
|
LIST_ENTRY nextEntry;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
nextEntry.Blink = (LIST_ENTRY*)entryInInitOrder;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, (uint64_t)entryLinks.Flink, &nextEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
auto Sandbox::AddModuleToLdr(const std::shared_ptr<struct_moudle>& module) -> void {
|
|
|
|
|
|
if (!m_peInfo->isX64) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>: '%s', <20><>ַ: 0x%llx, <20><><EFBFBD>ڵ<EFBFBD>: 0x%llx, <20><>С: 0x%llx\n",
|
|
|
|
|
|
module->name, module->base, module->entry, module->size);
|
|
|
|
|
|
}
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
|
|
|
|
|
const size_t stringSectionSize = MAX_PATH * sizeof(wchar_t) * 2;
|
|
|
|
|
|
uint64_t entrySize = sizeof(LDR_DATA_TABLE_ENTRY) + stringSectionSize;
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// ȷ<><C8B7><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>뵽8<EBB5BD>ֽڱ߽磨<DFBD><E7A3A8><EFBFBD><EFBFBD>64λ<34>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>
|
|
|
|
|
|
uint64_t entryAddress = (m_pebEnd + 7) & ~7ULL;
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>LDR<EFBFBD><EFBFBD>Ŀ: <20><>ַ=0x%llx, <20><>С=0x%llx\n", entryAddress, entrySize);
|
|
|
|
|
|
}
|
2025-04-20 21:00:38 +08:00
|
|
|
|
// ӳ<><D3B3><EFBFBD>ڴ<EFBFBD>
|
2025-04-23 03:48:16 +08:00
|
|
|
|
const size_t pageSize = 4096;
|
|
|
|
|
|
size_t alignedSize = (entrySize + pageSize - 1) & ~(pageSize - 1);
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
uc_err err = uc_mem_map(m_ucEngine, entryAddress, alignedSize, UC_PROT_ALL);
|
|
|
|
|
|
if (err != UC_ERR_OK) {
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><EFBFBD>ӳ<EFBFBD><D3B3>LDR<44><52>Ŀ<EFBFBD>ڴ<EFBFBD> @ 0x%llx (<28><><EFBFBD><EFBFBD>=%d)\n", entryAddress, err);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>Unicode<64>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ȷ<EFBFBD><C8B7>8<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD>
|
|
|
|
|
|
uint64_t fullNameAddress = (entryAddress + sizeof(LDR_DATA_TABLE_ENTRY) + 7) & ~7ULL;
|
|
|
|
|
|
uint64_t baseNameAddress = (fullNameAddress + (MAX_PATH * sizeof(wchar_t)) + 7) & ~7ULL;
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
// <20><>֤<EFBFBD><D6A4>ַ<EFBFBD><D6B7>Χ
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ַ - FullName=0x%llx, BaseName=0x%llx\n",
|
|
|
|
|
|
fullNameAddress, baseNameAddress);
|
|
|
|
|
|
}
|
|
|
|
|
|
// ȷ<><C8B7><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ淶Χ
|
|
|
|
|
|
if (baseNameAddress + (MAX_PATH * sizeof(wchar_t)) > entryAddress + alignedSize) {
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ淶Χ!\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>LDR<44><52>Ŀ
|
|
|
|
|
|
auto entry = CreateLdrEntry(module, entryAddress, fullNameAddress, baseNameAddress);
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>֤DllBase<73><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ
|
|
|
|
|
|
if ((uint64_t)entry.DllBase != module->base) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: DllBase<73><65>ƥ<EFBFBD><C6A5> (<28><><EFBFBD><EFBFBD>=%llx, <20><><EFBFBD><EFBFBD>=%llx)\n",
|
|
|
|
|
|
(uint64_t)entry.DllBase, module->base);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-20 21:00:38 +08:00
|
|
|
|
// <20><>PEB<45><42>ȡ<EFBFBD><C8A1>ǰLDR_DATA<54>ṹ
|
|
|
|
|
|
X64_PEB_LDR_DATA ldrData;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, m_peb64.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA));
|
|
|
|
|
|
|
|
|
|
|
|
// д<><D0B4>LDR_DATA_TABLE_ENTRY<52>ṹ
|
2025-04-23 03:48:16 +08:00
|
|
|
|
uc_mem_write(m_ucEngine, entryAddress, &entry, sizeof(LDR_DATA_TABLE_ENTRY));
|
2025-04-20 21:00:38 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
UpdateLdrLinks(entry, entryAddress, ldrData);
|
|
|
|
|
|
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD>PEBβ<42><CEB2>λ<EFBFBD><CEBB>
|
|
|
|
|
|
m_pebEnd = entryAddress + alignedSize;
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
|
|
|
|
|
|
printf("<EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD> '%s' <20><>LDR<44><52><EFBFBD>ݱ<EFBFBD> @ 0x%llx\n", module->name, entryAddress);
|
|
|
|
|
|
}
|
2025-04-20 21:00:38 +08:00
|
|
|
|
}
|
2025-04-23 03:48:16 +08:00
|
|
|
|
auto Sandbox::TestLdrListTraversal() -> bool {
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
|
|
|
|
|
|
printf("\n============ LDR<44><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ============\n");
|
|
|
|
|
|
|
|
|
|
|
|
// 1. <20><>ȡPEB<45><42>ַ
|
|
|
|
|
|
uint64_t pebAddress = m_pebBase; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PEB<45><42>ַ
|
|
|
|
|
|
X64PEB peb;
|
|
|
|
|
|
if (uc_mem_read(m_ucEngine, pebAddress, &peb, sizeof(X64PEB)) != UC_ERR_OK) {
|
|
|
|
|
|
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡPEB<45>ṹ<EFBFBD><E1B9B9>\n");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
printf("PEBλ<EFBFBD><EFBFBD>: 0x%llx\n", pebAddress);
|
|
|
|
|
|
printf("PEB.Ldrָ<72><D6B8>: 0x%llx\n", peb.Ldr);
|
|
|
|
|
|
|
|
|
|
|
|
// 2. <20><>ȡLDR_DATA<54>ṹ
|
|
|
|
|
|
if (peb.Ldr == 0) {
|
|
|
|
|
|
printf("ERROR: PEB.LdrΪNULL<4C><4C>LDRδ<52><CEB4>ʼ<EFBFBD><CABC>\n");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
X64_PEB_LDR_DATA ldrData;
|
|
|
|
|
|
if (uc_mem_read(m_ucEngine, peb.Ldr, &ldrData, sizeof(X64_PEB_LDR_DATA)) != UC_ERR_OK) {
|
|
|
|
|
|
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡLDR_DATA<54>ṹ<EFBFBD><E1B9B9>\n");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
printf("LDR_DATA.Length: %u\n", ldrData.Length);
|
|
|
|
|
|
printf("LDR_DATA.Initialized: %u\n", ldrData.Initialized);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. <20><><EFBFBD>鲢<EFBFBD><E9B2A2>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
DumpLdrList("InLoadOrderModuleList", peb.Ldr,
|
|
|
|
|
|
offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList),
|
|
|
|
|
|
offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks));
|
|
|
|
|
|
|
|
|
|
|
|
DumpLdrList("InMemoryOrderModuleList", peb.Ldr,
|
|
|
|
|
|
offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList),
|
|
|
|
|
|
offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
|
|
|
|
|
|
|
|
|
|
|
|
DumpLdrList("InInitializationOrderModuleList", peb.Ldr,
|
|
|
|
|
|
offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList),
|
|
|
|
|
|
offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks));
|
|
|
|
|
|
|
|
|
|
|
|
printf("========================================\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2025-04-23 04:47:01 +08:00
|
|
|
|
auto Sandbox::FinalizeLdrLinks() -> void {
|
|
|
|
|
|
if (!m_peInfo->isX64) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ַ
|
|
|
|
|
|
uint64_t inLoadOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList);
|
|
|
|
|
|
uint64_t inMemoryOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList);
|
|
|
|
|
|
uint64_t inInitOrderListHead = m_peb64.Ldr + offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList);
|
|
|
|
|
|
|
|
|
|
|
|
// <20>պ<EFBFBD>InLoadOrderModuleList<73><74><EFBFBD><EFBFBD>
|
|
|
|
|
|
CloseLdrList(inLoadOrderListHead, offsetof(LDR_DATA_TABLE_ENTRY, InLoadOrderLinks));
|
|
|
|
|
|
|
|
|
|
|
|
// <20>պ<EFBFBD>InMemoryOrderModuleList<73><74><EFBFBD><EFBFBD>
|
|
|
|
|
|
CloseLdrList(inMemoryOrderListHead, offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
|
|
|
|
|
|
|
|
|
|
|
|
// <20>պ<EFBFBD>InInitializationOrderModuleList<73><74><EFBFBD><EFBFBD>
|
|
|
|
|
|
CloseLdrList(inInitOrderListHead, offsetof(LDR_DATA_TABLE_ENTRY, InInitializationOrderLinks));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto Sandbox::CloseLdrList(uint64_t listHeadAddr, size_t entryLinkOffset) -> void {
|
|
|
|
|
|
LIST_ENTRY listHead;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, listHeadAddr, &listHead, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD>账<EFBFBD><E8B4A6>
|
|
|
|
|
|
if (listHead.Flink == (LIST_ENTRY*)listHeadAddr) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ԫ<EFBFBD><D4AA>
|
|
|
|
|
|
uint64_t currentLink = (uint64_t)listHead.Flink;
|
|
|
|
|
|
uint64_t lastLink = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while (currentLink != listHeadAddr && currentLink != 0) {
|
|
|
|
|
|
LIST_ENTRY currentEntry;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, currentLink, ¤tEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>ջ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
|
if (currentEntry.Flink == nullptr ||
|
|
|
|
|
|
(uint64_t)currentEntry.Flink == currentLink ||
|
|
|
|
|
|
(uint64_t)currentEntry.Flink == 0) {
|
|
|
|
|
|
lastLink = currentLink;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>պ<EFBFBD>
|
|
|
|
|
|
if ((uint64_t)currentEntry.Flink == listHeadAddr) {
|
|
|
|
|
|
return; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>պϣ<D5BA><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lastLink = currentLink;
|
|
|
|
|
|
currentLink = (uint64_t)currentEntry.Flink;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if (lastLink != 0) {
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ԫ<EFBFBD><D4AA>
|
|
|
|
|
|
LIST_ENTRY lastEntry;
|
|
|
|
|
|
uc_mem_read(m_ucEngine, lastLink, &lastEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ԫ<EFBFBD>ص<EFBFBD>Flinkָ<6B><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
|
|
|
|
|
|
lastEntry.Flink = (LIST_ENTRY*)listHeadAddr;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, lastLink, &lastEntry, sizeof(LIST_ENTRY));
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>Blinkָ<6B><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>Ԫ<EFBFBD><D4AA>
|
|
|
|
|
|
listHead.Blink = (LIST_ENTRY*)lastLink;
|
|
|
|
|
|
uc_mem_write(m_ucEngine, listHeadAddr, &listHead, sizeof(LIST_ENTRY));
|
2025-04-23 03:48:16 +08:00
|
|
|
|
|
2025-04-23 04:47:01 +08:00
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ=0x%llx, <20><><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>=0x%llx\n",
|
|
|
|
|
|
listHeadAddr, lastLink);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-04-23 03:48:16 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӡָ<D3A1><D6B8><EFBFBD><EFBFBD>LDR<44><52><EFBFBD><EFBFBD>
|
|
|
|
|
|
auto Sandbox::DumpLdrList(const char* listName, uint64_t ldrDataBase, size_t listOffset, size_t entryLinkOffset) -> void {
|
|
|
|
|
|
if (LOG_LEVEL > 4) {
|
|
|
|
|
|
|
|
|
|
|
|
printf("\n--- %s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---\n", listName);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ַ
|
|
|
|
|
|
uint64_t listHeadAddr = ldrDataBase + listOffset;
|
|
|
|
|
|
LIST_ENTRY listHead;
|
|
|
|
|
|
if (uc_mem_read(m_ucEngine, listHeadAddr, &listHead, sizeof(LIST_ENTRY)) != UC_ERR_OK) {
|
|
|
|
|
|
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ @ 0x%llx\n", listHeadAddr);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
printf("<EFBFBD>б<EFBFBD>ͷ @ 0x%llx: Flink=0x%llx, Blink=0x%llx\n",
|
|
|
|
|
|
listHeadAddr, (uint64_t)listHead.Flink, (uint64_t)listHead.Blink);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>
|
|
|
|
|
|
if (listHead.Flink == (LIST_ENTRY*)listHeadAddr) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD> (Flinkָ<6B><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)\n");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
uint64_t currentLink = (uint64_t)listHead.Flink;
|
|
|
|
|
|
int entryCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while (currentLink != listHeadAddr && entryCount < 100) { // <20><>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
entryCount++;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>㵱ǰLDR_DATA_TABLE_ENTRY<52>ĵ<EFBFBD>ַ
|
|
|
|
|
|
uint64_t entryAddr = currentLink - entryLinkOffset;
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
|
LDR_DATA_TABLE_ENTRY entry;
|
|
|
|
|
|
if (uc_mem_read(m_ucEngine, entryAddr, &entry, sizeof(LDR_DATA_TABLE_ENTRY)) != UC_ERR_OK) {
|
|
|
|
|
|
printf("ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡ<EFBFBD><C8A1>Ŀ @ 0x%llx\n", entryAddr);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
printf("\n<EFBFBD><EFBFBD>Ŀ #%d @ 0x%llx:\n", entryCount, entryAddr);
|
|
|
|
|
|
printf(" DllBase: 0x%llx\n", (uint64_t)entry.DllBase);
|
|
|
|
|
|
printf(" EntryPoint: 0x%llx\n", (uint64_t)entry.EntryPoint);
|
|
|
|
|
|
printf(" SizeOfImage: 0x%x\n", entry.SizeOfImages);
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD>ʹ<EFBFBD>ӡģ<D3A1><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
if ((uint64_t)entry.FullDllName.Buffer != 0 && entry.FullDllName.Length > 0) {
|
|
|
|
|
|
size_t nameLen = entry.FullDllName.Length / sizeof(wchar_t);
|
|
|
|
|
|
wchar_t* nameBuffer = new wchar_t[nameLen + 1];
|
|
|
|
|
|
|
|
|
|
|
|
if (uc_mem_read(m_ucEngine, (uint64_t)entry.FullDllName.Buffer, nameBuffer, entry.FullDllName.Length) == UC_ERR_OK) {
|
|
|
|
|
|
nameBuffer[nameLen] = L'\0';
|
|
|
|
|
|
|
|
|
|
|
|
// ת<><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
char mbName[MAX_PATH * 2] = { 0 };
|
|
|
|
|
|
wcstombs(mbName, nameBuffer, sizeof(mbName) - 1);
|
|
|
|
|
|
printf(" FullDllName: %s\n", mbName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
printf(" ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡFullDllName @ 0x%llx (<28><><EFBFBD><EFBFBD>: %d)\n",
|
|
|
|
|
|
(uint64_t)entry.FullDllName.Buffer, entry.FullDllName.Length);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delete[] nameBuffer;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
printf(" FullDllName: <<3C>ջ<EFBFBD><D5BB><EFBFBD>Ч>\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ͬ<><CDAC><EFBFBD><EFBFBD>ӡBaseDllName
|
|
|
|
|
|
if ((uint64_t)entry.BaseDllName.Buffer != 0 && entry.BaseDllName.Length > 0) {
|
|
|
|
|
|
size_t nameLen = entry.BaseDllName.Length / sizeof(wchar_t);
|
|
|
|
|
|
wchar_t* nameBuffer = new wchar_t[nameLen + 1];
|
|
|
|
|
|
|
|
|
|
|
|
if (uc_mem_read(m_ucEngine, (uint64_t)entry.BaseDllName.Buffer, nameBuffer, entry.BaseDllName.Length) == UC_ERR_OK) {
|
|
|
|
|
|
nameBuffer[nameLen] = L'\0';
|
|
|
|
|
|
|
|
|
|
|
|
char mbName[MAX_PATH * 2] = { 0 };
|
|
|
|
|
|
wcstombs(mbName, nameBuffer, sizeof(mbName) - 1);
|
|
|
|
|
|
printf(" BaseDllName: %s\n", mbName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
printf(" ERROR: <20><EFBFBD><DEB7><EFBFBD>ȡBaseDllName @ 0x%llx (<28><><EFBFBD><EFBFBD>: %d)\n",
|
|
|
|
|
|
(uint64_t)entry.BaseDllName.Buffer, entry.BaseDllName.Length);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delete[] nameBuffer;
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
printf(" BaseDllName: <<3C>ջ<EFBFBD><D5BB><EFBFBD>Ч>\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>
|
|
|
|
|
|
printf(" <20><><EFBFBD><EFBFBD>: Flink=0x%llx, Blink=0x%llx\n",
|
|
|
|
|
|
(uint64_t)entry.InLoadOrderLinks.Flink, (uint64_t)entry.InLoadOrderLinks.Blink);
|
|
|
|
|
|
|
|
|
|
|
|
// <20>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ŀ
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>Flink<6E>ֶ<EFBFBD>
|
|
|
|
|
|
if (listOffset == offsetof(X64_PEB_LDR_DATA, InLoadOrderModuleList))
|
|
|
|
|
|
currentLink = (uint64_t)entry.InLoadOrderLinks.Flink;
|
|
|
|
|
|
else if (listOffset == offsetof(X64_PEB_LDR_DATA, InMemoryOrderModuleList))
|
|
|
|
|
|
currentLink = (uint64_t)entry.InMemoryOrderLinks.Flink;
|
|
|
|
|
|
else if (listOffset == offsetof(X64_PEB_LDR_DATA, InInitializationOrderModuleList))
|
|
|
|
|
|
currentLink = (uint64_t)entry.InInitializationOrderLinks.Flink;
|
|
|
|
|
|
|
|
|
|
|
|
// <20>ڴ<EFBFBD><DAB4><EFBFBD>֤ - <20><>ֹ<EFBFBD><D6B9>Чָ<D0A7><D6B8>
|
|
|
|
|
|
if (currentLink == 0 || currentLink == entryAddr) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD>Flinkָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (entryCount == 0) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD>棺û<EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷָʾ<EFBFBD>ǿ<EFBFBD>\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (entryCount >= 100) {
|
|
|
|
|
|
printf("<EFBFBD><EFBFBD><EFBFBD>棺<EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
printf("\n<EFBFBD>ܹ<EFBFBD><EFBFBD>ҵ<EFBFBD> %d <20><><EFBFBD><EFBFBD>Ŀ\n", entryCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|