[+] Initial attempt at parsing Linux VMA space

[*] Refactor old C++ enums into AUE derivative
This commit is contained in:
Reece Wilson 2022-04-21 00:34:08 +01:00
parent 52983989b5
commit 237d2d070c
9 changed files with 275 additions and 28 deletions

View File

@ -9,11 +9,11 @@
namespace Aurora::Crypto
{
enum class EHashType
{
AUE_DEFINE(EHashType,
(
eSHA1_20_160,
eTiger_24_192,
eSHA2_32_256,
eSHA2_64_512
};
));
}

View File

@ -9,9 +9,9 @@
namespace Aurora::Crypto
{
enum class EKeyType
{
AUE_DEFINE(EKeyType,
(
eKeyPublic,
eKeyPrivate
};
));
}

View File

@ -9,8 +9,8 @@
namespace Aurora::Crypto
{
enum class EPaddingType
{
AUE_DEFINE(EPaddingType,
(
ePaddingNone,
// For use with encryption
ePKCS_OAEP,
@ -20,5 +20,5 @@ namespace Aurora::Crypto
ePKCS_1_PSS,
// For use with signing
ePKCS_1_5_NA1
};
));
}

View File

@ -9,13 +9,13 @@
namespace Aurora::Crypto::RSA
{
enum class ERSAKeyType
{
AUE_DEFINE(ERSAKeyType,
(
/// pkcs1
eRsaKey,
/// pkcs8
eKey,
/// x509
eCert
};
));
}

View File

@ -9,12 +9,12 @@
namespace Aurora::Crypto::X509
{
enum class ESignatureAlgorithm
{
AUE_DEFINE(ESignatureAlgorithm,
(
eInvalidAlgorithm,
eMD5WithRSA,
eSHA1WithRSA,
eSHA256WithRSA,
eECDSAWithRSA
};
));
}

View File

@ -15,15 +15,11 @@ namespace Aurora::Time
/**
Converts milliseconds from the Aurora epoch to a civil timestamp structure
similar to or of std::tm
Range: 1900 -> 2001 +- 2^63-1 ms
*/
AUKN_SYM tm ToCivilTime(AuInt64 time, bool UTC = true);
/**
Converts civil time to milliseconds from the Aurora epoch
Range: 1900 -> 2001 +- 2^63-1 ms
*/
AUKN_SYM AuInt64 FromCivilTime(const tm &time, bool UTC = true);
@ -120,4 +116,4 @@ namespace Aurora::Time
Retrieves the freqency of jiffies per second
*/
AUKN_SYM AuUInt64 ClockJiffies();
}
}

View File

@ -68,15 +68,15 @@ namespace Aurora::IO::FS
auto len = file->GetLength();
// NOTE: Linux file systems are such a cluster fuck of unimplemented interface
// It's not unusual for these sockets to be unstreamable across NIX-like oses
// NOTE: Linux filesystems are such a cluster fuck of unimplemented interfaces and half-assed drivers
// It's not unusual for these "files" to not support the required seek operations across NIX-like oses.
if (len == 0)
{
if (AuStartsWith(path, "/proc/") ||
AuStartsWith(path, "/sys/") ||
AuStartsWith(path, "/dev/"))
{
len = 4096;
len = 4096 * 10;
}
else
{

View File

@ -8,22 +8,267 @@
#include <Source/RuntimeInternal.hpp>
#include "ProcessMap.Linux.hpp"
#include "ProcessMap.hpp"
#include <link.h>
#if defined(AURORA_IS_64BIT)
using Elf_Ehdr = Elf64_Ehdr;
using Elf_Shdr = Elf64_Shdr;
#else
using Elf_Ehdr = Elf32_Ehdr;
using Elf_Shdr = Elf32_Shdr;
#endif
namespace Aurora::Process
{
void InitProcessMapLinux()
{
//puts("InitProcessMapLinux");
}
void DeinitProcessMapLinux()
{
//puts("DeinitProcessMapLinux");
}
static AuHashMap<AuUInt, AuTuple<AuString, AuList<AuTuple<AuUInt, AuUInt, AuUInt, AuUInt>>>> gModuleMap;
static int LdDlIIterateCallback(struct dl_phdr_info *info,
size_t size,
void *data)
{
#if 0
auto index = file.find_last_of(".so");
if (index != AuString::npos)
{
file = file.substr(0, index);
}
#endif
AuString fileName = info->dlpi_name[0] ? info->dlpi_name : AuString{};
if (fileName.empty())
{
GetProcFullPath(fileName);
}
if (!AuIOFS::FileExists(fileName))
{
//printf("drop: %s\n", fileName.c_str());
return 0;
}
AuList<AuTuple<AuUInt, AuUInt, AuUInt, AuUInt>> sections;
for (int j = 0; j < info->dlpi_phnum; j++)
{
AuTryInsert(sections, AuMakeTuple((AuUInt)info->dlpi_phdr[j].p_vaddr, (AuUInt)info->dlpi_phdr[j].p_offset, (AuUInt)info->dlpi_phdr[j].p_memsz, (AuUInt)info->dlpi_phdr[j].p_flags));
}
AuTryInsert(gModuleMap, info->dlpi_addr, AuMakeTuple(fileName, sections));
return 0;
}
static void PassOneScanLd()
{
::dl_iterate_phdr(LdDlIIterateCallback, NULL);
}
static void PassTwoScanMaps()
{
AuString map;
if (!AuIOFS::ReadString("/proc/self/maps", map))
{
return;
}
AuParse::SplitNewlines(map, [&](const AuString &line)
{
char *endPtr;
auto base = strtoll(line.c_str(), &endPtr, 16);
if (errno == ERANGE) return;
if (*endPtr != '-') return;
auto end = strtoll(endPtr + 1, &endPtr, 16);
if (errno == ERANGE) return;
if (*endPtr != ' ') return;
auto A = line.find_first_of(':');
if (A == AuString::npos) return;
A += 4;
auto gross = line.substr(A);
AuString name;
auto B = gross.find_first_of(' ');
if (B != AuString::npos)
{
auto C = gross.find_first_not_of(' ', B);
if (C != AuString::npos)
{
name = gross.substr(C);
}
}
if (name == "[stack]")
{
name = kSectionNameStack;
}
else if (name == "[heap]")
{
name = kSectionNameHeap;
}
else if (name == "[vdso]")
{
name = kSectionNameFile;
}
if (name.size())
{
bool bIsFile = AuIOFS::FileExists(name);
if (bIsFile)
{
return;
}
}
// TODO:
//printf("%llx %llx %s\n", base, end, name.c_str());
}, false);
}
static void PassThreeGatherMissingProgNames()
{
for (const auto & [baseAddress, pair] : gModuleMap)
{
auto & [path, sections] = pair;
AuString file;
AuIOFS::GetFileFromPath(file, path);
auto object = AuIOFS::OpenReadUnique(path);
if (!object)
{
SysPushErrorIO();
continue;
}
Elf_Ehdr header;
AuUInt read;
if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(&header, sizeof(header)), read)))
{
SysPushErrorIO();
}
AuList<Elf_Shdr> elfSections;
if (!AuTryResize(elfSections, header.e_shnum))
{
SysPushErrorMem();
continue;
}
object->SetOffset(header.e_shoff);
if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(elfSections.data(),
elfSections.size() * sizeof(Elf_Shdr)
),
read)))
{
SysPushErrorIO();
continue;
}
auto &strtab = elfSections[header.e_shstrndx];
AuList<AuUInt8> strHeap;
if (!AuTryResize(strHeap, strtab.sh_size))
{
SysPushErrorMem();
continue;
}
object->SetOffset(strtab.sh_offset);
if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(strHeap.data(),
strHeap.size()
),
read)))
{
SysPushErrorIO();
continue;
}
Sections modSections;
for (const auto & section : elfSections)
{
auto len = strnlen((const char *)strHeap.data() + section.sh_name, strHeap.size() - section.sh_name);
AuString sectionName((const char *)strHeap.data() + section.sh_name, len);
AuUInt fileOffset = section.sh_offset;
AuUInt programOffset = section.sh_addr;
Section sect {};
sect.origVa = section.sh_addr;
sect.baseVa = 0;
for (const auto & [base, offset, size, flags] : sections)
{
if ((offset <= fileOffset) &&
((offset + size) > fileOffset) && fileOffset && offset)
{
sect.pt.readable = section.sh_addr ? (section.sh_flags & SHF_ALLOC) : false;//?
auto baseOfMap = baseAddress;
auto offsetInMap = fileOffset - offset;
sect.baseVa = (baseOfMap + base) + offsetInMap;
}
}
sect.size = section.sh_size;
sect.fsOff = fileOffset;
sect.pt.NX = !(section.sh_flags & SHF_EXECINSTR);
sect.pt.writable = section.sh_flags & SHF_WRITE;
if (!sect.pt.readable)
{
sect.baseVa = 0;
}
sect.name = sectionName;
AuTryInsert(modSections, sect);
}
auto pub = AuMakeShared<PublicModule>();
if (!pub) return;
pub->moduleMeta = AuMakeShared<ModuleMeta>();
if (!pub->moduleMeta) return;
pub->moduleMeta->moduleBase = baseAddress;
pub->moduleMeta->moduleName = AuMove(file);
pub->moduleMeta->modulePath = AuMove(path);
pub->moduleMeta->origVa = 0;
pub->sections = AuMove(modSections);
// TODO: ...
InsertModuleCache(ModuleBasePair{pub->moduleMeta->moduleName, baseAddress + AuGet<0>(sections[0])}, pub);
}
}
static void PassFourAdd()
{
// TODO: ?
}
void RescanMaps()
{
PassOneScanLd();
PassTwoScanMaps();
PassThreeGatherMissingProgNames();
PassFourAdd();
}
}

View File

@ -104,10 +104,15 @@ namespace Aurora::Process
AU_LOCK_GUARD(gMutexUnique);
section.moduleMeta = mod;
if (!section.baseVa)
{
continue;
}
for (AuUInt i = section.baseVa; i < section.baseVa + section.size; i += (kMinPageAlignment * kPageBufferPad))
{
ModuleLookup a(section);
gModulePtrMap[i] = a;
gModulePtrMap[ToLowestPageAlignment(i)] = a;
}
}
@ -128,7 +133,7 @@ namespace Aurora::Process
{
for (AuUInt i = section.baseVa; i < section.baseVa + section.size; i += (kMinPageAlignment * kPageBufferPad))
{
auto itr = gModulePtrMap.find(i);
auto itr = gModulePtrMap.find(ToLowestPageAlignment(i));
if (itr != gModulePtrMap.end())
{
gModulePtrMap.erase(itr);
@ -150,6 +155,7 @@ namespace Aurora::Process
static AuOptional<Section> FindInCache(AuUInt pointer)
{
auto curPtr = ToLowestPageAlignment(pointer);
auto temp = GetSectionCache(curPtr);
if (temp.has_value()) return temp;