mirror of
https://github.com/decompals/wibo.git
synced 2025-10-16 07:05:11 +00:00
130 lines
4.2 KiB
C++
130 lines
4.2 KiB
C++
#pragma once
|
|
|
|
#include "common.h"
|
|
|
|
#include <optional>
|
|
#include <unordered_map>
|
|
|
|
namespace wibo {
|
|
|
|
using ResolveByName = void *(*)(const char *);
|
|
using ResolveByOrdinal = void *(*)(uint16_t);
|
|
|
|
struct ResourceIdentifier;
|
|
struct ResourceLocation;
|
|
|
|
struct ModuleStub {
|
|
const char **names;
|
|
ResolveByName byName;
|
|
ResolveByOrdinal byOrdinal;
|
|
};
|
|
|
|
class Executable {
|
|
public:
|
|
struct SectionInfo {
|
|
uintptr_t base = 0;
|
|
size_t size = 0;
|
|
DWORD protect = PAGE_NOACCESS;
|
|
DWORD characteristics = 0;
|
|
};
|
|
|
|
Executable() = default;
|
|
~Executable();
|
|
|
|
bool loadPE(FILE *file, bool exec);
|
|
bool resolveImports();
|
|
bool findResource(const ResourceIdentifier &type, const ResourceIdentifier &name, std::optional<uint16_t> language,
|
|
ResourceLocation &out) const;
|
|
|
|
template <typename T> T *fromRVA(uintptr_t rva) const { return (T *)(rva + (uint8_t *)imageBase); }
|
|
template <typename T> T *fromRVA(T *rva) const { return fromRVA<T>((uintptr_t)rva); }
|
|
|
|
void *imageBase = nullptr;
|
|
size_t imageSize = 0;
|
|
void *entryPoint = nullptr;
|
|
void *rsrcBase = nullptr;
|
|
uint32_t rsrcSize = 0;
|
|
uintptr_t preferredImageBase = 0;
|
|
intptr_t relocationDelta = 0;
|
|
uint32_t exportDirectoryRVA = 0;
|
|
uint32_t exportDirectorySize = 0;
|
|
uint32_t relocationDirectoryRVA = 0;
|
|
uint32_t relocationDirectorySize = 0;
|
|
uint32_t importDirectoryRVA = 0;
|
|
uint32_t importDirectorySize = 0;
|
|
uint32_t delayImportDirectoryRVA = 0;
|
|
uint32_t delayImportDirectorySize = 0;
|
|
bool execMapped = false;
|
|
bool importsResolved = false;
|
|
bool importsResolving = false;
|
|
std::vector<SectionInfo> sections;
|
|
};
|
|
|
|
struct ModuleInfo {
|
|
// Windows-style handle to the module. For the main module, this is the image base.
|
|
// For other modules, this is a pointer to the ModuleInfo structure.
|
|
HMODULE handle;
|
|
// Original name used to load the module
|
|
std::string originalName;
|
|
// Normalized module name
|
|
std::string normalizedName;
|
|
// Full path to the loaded module
|
|
std::filesystem::path resolvedPath;
|
|
// Pointer to the built-in module, nullptr if loaded from file
|
|
const wibo::ModuleStub *moduleStub = nullptr;
|
|
// Loaded PE executable
|
|
std::unique_ptr<wibo::Executable> executable;
|
|
// Reference count, or UINT_MAX for built-in modules
|
|
unsigned int refCount = 0;
|
|
bool processAttachCalled = false;
|
|
bool processAttachSucceeded = false;
|
|
bool threadNotificationsEnabled = true;
|
|
uint32_t exportOrdinalBase = 0;
|
|
std::vector<void *> exportsByOrdinal;
|
|
std::unordered_map<std::string, uint16_t> exportNameToOrdinal;
|
|
bool exportsInitialized = false;
|
|
std::vector<void *> onExitFunctions;
|
|
};
|
|
extern ModuleInfo *mainModule;
|
|
|
|
using ModulePtr = std::shared_ptr<wibo::ModuleInfo>;
|
|
|
|
void initializeModuleRegistry();
|
|
void shutdownModuleRegistry();
|
|
ModuleInfo *moduleInfoFromHandle(HMODULE module);
|
|
void setDllDirectoryOverride(const std::filesystem::path &path);
|
|
void clearDllDirectoryOverride();
|
|
std::optional<std::filesystem::path> dllDirectoryOverride();
|
|
ModuleInfo *findLoadedModule(const char *name);
|
|
void registerOnExitTable(void *table);
|
|
void addOnExitFunction(void *table, void (*func)());
|
|
void executeOnExitTable(void *table);
|
|
void runPendingOnExit(ModuleInfo &info);
|
|
void notifyDllThreadAttach();
|
|
void notifyDllThreadDetach();
|
|
BOOL disableThreadNotifications(ModuleInfo *info);
|
|
std::unordered_map<std::string, ModulePtr> allLoadedModules();
|
|
|
|
ModuleInfo *loadModule(const char *name);
|
|
void freeModule(ModuleInfo *info);
|
|
void *resolveFuncByName(ModuleInfo *info, const char *funcName);
|
|
void *resolveFuncByOrdinal(ModuleInfo *info, uint16_t ordinal);
|
|
void *resolveMissingImportByName(const char *dllName, const char *funcName);
|
|
void *resolveMissingImportByOrdinal(const char *dllName, uint16_t ordinal);
|
|
|
|
ModuleInfo *registerProcessModule(std::unique_ptr<Executable> executable, std::filesystem::path resolvedPath,
|
|
std::string originalName);
|
|
Executable *executableFromModule(HMODULE module);
|
|
ModuleInfo *moduleInfoFromAddress(void *addr);
|
|
|
|
/**
|
|
* HMODULE will be `nullptr` or `mainModule->imageBase` if it's the main module,
|
|
* otherwise it will be a pointer to a `wibo::ModuleInfo`.
|
|
*/
|
|
inline bool isMainModule(HMODULE hModule) {
|
|
return hModule == nullptr || hModule == reinterpret_cast<HMODULE>(mainModule) ||
|
|
(mainModule && mainModule->executable && hModule == mainModule->executable->imageBase);
|
|
}
|
|
|
|
} // namespace wibo
|