You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
5.6 KiB
C
306 lines
5.6 KiB
C
4 years ago
|
#ifndef HLAPI_H
|
||
|
#define HLAPI_H
|
||
|
|
||
|
/* A high level C++ wrapper for various memory functions */
|
||
|
|
||
|
#include "../wintools.h"
|
||
|
#include "../mem.h"
|
||
|
|
||
|
#include <stdexcept>
|
||
|
#include <string.h>
|
||
|
#include <vector>
|
||
|
#include <algorithm>
|
||
|
|
||
|
class VMException : public std::exception
|
||
|
{
|
||
|
public:
|
||
|
VMException(int status)
|
||
|
{
|
||
|
value = status;
|
||
|
}
|
||
|
|
||
|
int value;
|
||
|
};
|
||
|
|
||
|
template<typename T>
|
||
|
class WinListIterator
|
||
|
{
|
||
|
public:
|
||
|
WinListIterator(T* l)
|
||
|
{
|
||
|
list = l;
|
||
|
count = 0;
|
||
|
}
|
||
|
|
||
|
WinListIterator(T* l, size_t c)
|
||
|
{
|
||
|
list = l;
|
||
|
count = c;
|
||
|
}
|
||
|
|
||
|
auto& operator*()
|
||
|
{
|
||
|
return list->list[count];
|
||
|
}
|
||
|
|
||
|
WinListIterator& operator++(int c)
|
||
|
{
|
||
|
count += c;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
WinListIterator& operator++()
|
||
|
{
|
||
|
return operator++(1);
|
||
|
}
|
||
|
WinListIterator& operator--(int c)
|
||
|
{
|
||
|
count -= c;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
WinListIterator& operator--()
|
||
|
{
|
||
|
return operator--(1);
|
||
|
}
|
||
|
|
||
|
bool operator==(WinListIterator& rhs)
|
||
|
{
|
||
|
return count == rhs.count && list == rhs.list;
|
||
|
}
|
||
|
|
||
|
bool operator!=(WinListIterator& rhs)
|
||
|
{
|
||
|
return !operator==(rhs);
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
size_t count;
|
||
|
private:
|
||
|
T* list;
|
||
|
};
|
||
|
|
||
|
class WinExportIteratableList
|
||
|
{
|
||
|
public:
|
||
|
using iterator = WinListIterator<WinExportList>;
|
||
|
iterator begin();
|
||
|
iterator end();
|
||
|
size_t getSize();
|
||
|
private:
|
||
|
friend class WinListIterator<WinExportList>;
|
||
|
friend class WinDll;
|
||
|
class WinDll* windll;
|
||
|
|
||
|
WinExportList list;
|
||
|
};
|
||
|
|
||
|
class WinDll
|
||
|
{
|
||
|
public:
|
||
|
uint64_t GetProcAddress(const char* procName);
|
||
|
WinDll();
|
||
|
WinDll(const class WinProcess* p, WinModule& i);
|
||
|
WinDll(WinDll&& rhs);
|
||
|
WinDll(WinDll& rhs) = delete;
|
||
|
~WinDll();
|
||
|
|
||
|
auto& operator=(WinDll&& rhs)
|
||
|
{
|
||
|
info = rhs.info;
|
||
|
std::swap(exports.list, rhs.exports.list);
|
||
|
process = rhs.process;
|
||
|
proc = rhs.proc;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
WinModule info;
|
||
|
WinExportIteratableList exports;
|
||
|
const class WinProcess* process;
|
||
|
private:
|
||
|
WinProc proc;
|
||
|
friend class WinExportIteratableList;
|
||
|
void VerifyExportList();
|
||
|
};
|
||
|
|
||
|
class ModuleIteratableList
|
||
|
{
|
||
|
public:
|
||
|
using iterator = WinListIterator<ModuleIteratableList>;
|
||
|
ModuleIteratableList(bool k = false);
|
||
|
ModuleIteratableList(class WinProcess* p, bool k = false);
|
||
|
ModuleIteratableList(ModuleIteratableList&& rhs);
|
||
|
ModuleIteratableList(ModuleIteratableList& rhs) = delete;
|
||
|
~ModuleIteratableList();
|
||
|
ModuleIteratableList& operator=(ModuleIteratableList&& rhs) = default;
|
||
|
iterator begin();
|
||
|
iterator end();
|
||
|
size_t getSize();
|
||
|
void Verify();
|
||
|
void InvalidateList();
|
||
|
WinDll* GetModuleInfo(const char* moduleName);
|
||
|
private:
|
||
|
friend class WinListIterator<ModuleIteratableList>;
|
||
|
friend class WinProcess;
|
||
|
friend class WinProcessList;
|
||
|
class WinProcess* process;
|
||
|
bool kernel;
|
||
|
WinDll* list;
|
||
|
size_t size;
|
||
|
};
|
||
|
|
||
|
class WriteList
|
||
|
{
|
||
|
public:
|
||
|
WriteList(const WinProcess*);
|
||
|
~WriteList();
|
||
|
void Commit();
|
||
|
|
||
|
template<typename T>
|
||
|
void Write(uint64_t address, T& value)
|
||
|
{
|
||
|
writeList.push_back({(uint64_t)buffer.size(), address, sizeof(T)});
|
||
|
buffer.reserve(sizeof(T));
|
||
|
std::copy((char*)&value, (char*)&value + sizeof(T), std::back_inserter(buffer));
|
||
|
}
|
||
|
|
||
|
const WinCtx* ctx;
|
||
|
const WinProc* proc;
|
||
|
private:
|
||
|
std::vector<RWInfo> writeList;
|
||
|
std::vector<char> buffer;
|
||
|
};
|
||
|
|
||
|
class WinProcess
|
||
|
{
|
||
|
public:
|
||
|
[[deprecated("Please use ModuleIteratableList::GetModuleInfo")]]
|
||
|
WinDll* GetModuleInfo(const char* moduleName);
|
||
|
PEB GetPeb();
|
||
|
WinProcess();
|
||
|
WinProcess(const WinProc& p, const WinCtx* c);
|
||
|
WinProcess(WinProcess&& rhs);
|
||
|
WinProcess(WinProcess& rhs) = delete;
|
||
|
void UpdateKernelModuleProcess(const WinProc& p);
|
||
|
WinProcess& operator=(WinProcess&& rhs) noexcept;
|
||
|
|
||
|
ssize_t Read(uint64_t address, void* buffer, size_t sz);
|
||
|
ssize_t Write(uint64_t address, void* buffer, size_t sz);
|
||
|
|
||
|
void ReadMem(uint64_t address, uint64_t remote, int len)
|
||
|
{
|
||
|
VMemRead(&ctx->process, proc.dirBase, remote, address, len);
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
T Read(uint64_t address)
|
||
|
{
|
||
|
T ret;
|
||
|
VMemRead(&ctx->process, proc.dirBase, (uint64_t)&ret, address, sizeof(T));
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
void Write(uint64_t address, const T& value)
|
||
|
{
|
||
|
VMemWrite(&ctx->process, proc.dirBase, (uint64_t)&value, address, sizeof(T));
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
void WriteMem(uint64_t address, T value[], int len)
|
||
|
{
|
||
|
VMemWrite(&ctx->process, proc.dirBase, (uint64_t)value, address, len);
|
||
|
}
|
||
|
|
||
|
WinProc proc;
|
||
|
const WinCtx* ctx;
|
||
|
ModuleIteratableList modules;
|
||
|
protected:
|
||
|
friend class ModuleIteratableList;
|
||
|
friend class WriteList;
|
||
|
};
|
||
|
|
||
|
class WinProcessList
|
||
|
{
|
||
|
public:
|
||
|
using iterator = WinListIterator<WinProcessList>;
|
||
|
void Refresh();
|
||
|
WinProcess* FindProc(const char* name);
|
||
|
iterator begin();
|
||
|
iterator end();
|
||
|
WinProcessList();
|
||
|
WinProcessList(const WinCtx* pctx);
|
||
|
WinProcessList(WinProcessList&& rhs);
|
||
|
WinProcessList(WinProcessList& rhs) = delete;
|
||
|
~WinProcessList();
|
||
|
|
||
|
auto& operator=(WinProcessList rhs)
|
||
|
{
|
||
|
std::swap(plist, rhs.plist);
|
||
|
std::swap(list, rhs.list);
|
||
|
ctx = rhs.ctx;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
const WinCtx* ctx;
|
||
|
protected:
|
||
|
friend iterator;
|
||
|
WinProcList plist;
|
||
|
WinProcess* list;
|
||
|
void FreeProcessList();
|
||
|
};
|
||
|
|
||
|
class SystemModuleList
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
ModuleIteratableList& Get(WinProcess* p)
|
||
|
{
|
||
|
proc.UpdateKernelModuleProcess(p ? p->proc : proc.ctx->initialProcess);
|
||
|
return proc.modules;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
friend class WinContext;
|
||
|
WinProcess proc;
|
||
|
};
|
||
|
|
||
|
class WinContext
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
template<typename T>
|
||
|
T Read(uint64_t address)
|
||
|
{
|
||
|
T ret;
|
||
|
MemRead(&ctx.process, (uint64_t)&ret, address, sizeof(T));
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
template<typename T>
|
||
|
void Write(uint64_t address, T& value)
|
||
|
{
|
||
|
MemWrite(&ctx.process, (uint64_t)&value, address, sizeof(T));
|
||
|
}
|
||
|
|
||
|
WinContext(pid_t pid)
|
||
|
{
|
||
|
int ret = InitializeContext(&ctx, pid);
|
||
|
if (ret)
|
||
|
throw VMException(ret);
|
||
|
processList = WinProcessList(&ctx);
|
||
|
systemModuleList.proc.ctx = &ctx;
|
||
|
}
|
||
|
|
||
|
~WinContext()
|
||
|
{
|
||
|
FreeContext(&ctx);
|
||
|
}
|
||
|
|
||
|
WinProcessList processList;
|
||
|
SystemModuleList systemModuleList;
|
||
|
WinCtx ctx;
|
||
|
};
|
||
|
|
||
|
#endif
|