Everything needed to run simple Rust programs (#40)

* Everything needed to run simple Rust programs

* Add IsDBCSLeadByte implementation

* Address PR comments
This commit is contained in:
2023-09-09 23:07:23 -04:00
committed by GitHub
parent 6e18120410
commit 94b44fd697
18 changed files with 1106 additions and 151 deletions

112
main.cpp
View File

@@ -8,9 +8,11 @@
#include <sys/syscall.h>
#include <stdarg.h>
#include <iostream>
#include <fstream>
#include <fstream>
uint32_t wibo::lastError = 0;
char** wibo::argv;
int wibo::argc;
char *wibo::commandLine;
wibo::Executable *wibo::mainModule = 0;
bool wibo::debugEnabled = false;
@@ -54,48 +56,85 @@ FOR_256
#undef FOR_256_2
#undef FOR_256
static void *resolveMissingFunc(const char *dllName, const char *funcName) {
static void *resolveMissingFuncName(const char *dllName, const char *funcName) {
DEBUG_LOG("Missing function: %s (%s)\n", dllName, funcName);
assert(stubIndex < 0x100);
assert(strlen(dllName) < 0x100);
assert(strlen(funcName) < 0x100);
strcpy(stubFuncNames[stubIndex], funcName);
strcpy(stubDlls[stubIndex], dllName);
return (void *) stubFuncs[stubIndex++];
return (void *)stubFuncs[stubIndex++];
}
void *wibo::resolveFuncByName(const char *dllName, const char *funcName) {
void *func = nullptr;
if (strcasecmp(dllName, "KERNEL32.dll") == 0) {
func = wibo::resolveKernel32(funcName);
} else if (strcasecmp(dllName, "USER32.dll") == 0) {
func = wibo::resolveUser32(funcName);
} else if (strcasecmp(dllName, "ADVAPI32.dll") == 0) {
func = wibo::resolveAdvApi32(funcName);
} else if (strcasecmp(dllName, "VERSION.dll") == 0) {
func = wibo::resolveVersion(funcName);
} else if (strcasecmp(dllName, "OLE32.dll") == 0) {
func = wibo::resolveOle32(funcName);
}
if (func)
return func;
return resolveMissingFunc(dllName, funcName);
}
void *wibo::resolveFuncByOrdinal(const char *dllName, uint16_t ordinal) {
void *func;
if (strcmp(dllName, "LMGR11.dll") == 0 ||
strcmp(dllName, "LMGR326B.dll") == 0 ||
strcmp(dllName, "LMGR8C.dll") == 0) {
func = wibo::resolveLmgr(ordinal);
}
if (func)
return func;
static void *resolveMissingFuncOrdinal(const char *dllName, uint16_t ordinal) {
char buf[16];
sprintf(buf, "%d", ordinal);
return resolveMissingFunc(dllName, buf);
return resolveMissingFuncName(dllName, buf);
}
extern const wibo::Module lib_advapi32;
extern const wibo::Module lib_bcrypt;
extern const wibo::Module lib_crt;
extern const wibo::Module lib_kernel32;
extern const wibo::Module lib_lmgr;
extern const wibo::Module lib_ntdll;
extern const wibo::Module lib_ole32;
extern const wibo::Module lib_user32;
extern const wibo::Module lib_vcruntime;
extern const wibo::Module lib_version;
const wibo::Module * wibo::modules[] = {
&lib_advapi32,
&lib_bcrypt,
&lib_crt,
&lib_kernel32,
&lib_lmgr,
&lib_ntdll,
&lib_ole32,
&lib_user32,
&lib_vcruntime,
&lib_version,
nullptr,
};
struct ModuleInfo {
std::string name;
const wibo::Module* module = nullptr;
};
HMODULE wibo::loadModule(const char *dllName) {
auto *result = new ModuleInfo;
result->name = dllName;
for (int i = 0; modules[i]; i++) {
for (int j = 0; modules[i]->names[j]; j++) {
if (strcasecmp(dllName, modules[i]->names[j]) == 0) {
result->module = modules[i];
return result;
}
}
}
return result;
}
void wibo::freeModule(HMODULE module) { delete static_cast<ModuleInfo *>(module); }
void *wibo::resolveFuncByName(HMODULE module, const char *funcName) {
auto *info = static_cast<ModuleInfo *>(module);
if (info && info->module && info->module->byName) {
void *func = info->module->byName(funcName);
if (func)
return func;
}
return resolveMissingFuncName(info->name.c_str(), funcName);
}
void *wibo::resolveFuncByOrdinal(HMODULE module, uint16_t ordinal) {
auto *info = static_cast<ModuleInfo *>(module);
if (info && info->module && info->module->byOrdinal) {
void *func = info->module->byOrdinal(ordinal);
if (func)
return func;
}
return resolveMissingFuncOrdinal(info->name.c_str(), ordinal);
}
struct UNICODE_STRING {
@@ -221,6 +260,9 @@ int main(int argc, char **argv) {
wibo::commandLine = cmdLine.data();
DEBUG_LOG("Command line: %s\n", wibo::commandLine);
wibo::argv = argv + 1;
wibo::argc = argc - 1;
wibo::Executable exec;
wibo::mainModule = &exec;
@@ -259,13 +301,13 @@ int main(int argc, char **argv) {
holdingMapStart = std::max(holdingMapStart, FILL_MEMORY_ABOVE);
void* holdingMap = mmap((void*) holdingMapStart, holdingMapEnd - holdingMapStart, PROT_READ, MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0);
if (holdingMap == MAP_FAILED) {
perror("Failed to create holding map");
return 1;
}
}
lastMapEnd = mapEnd;
}