mirror of
https://github.com/decompals/wibo.git
synced 2025-12-16 08:27:07 +00:00
Fix TlsGetValue & more (#48)
`TlsGetValue` disambiguates 0 and an error by relying on `GetLastError`. Depending on the program state, `GetLastError` could be non-0, even though `TlsGetValue` succeeded. Resolve this by always setting `wibo::lastError`. This matches the behavior described by the documentation. Additionally, when reading resources, later versions of mwcc and mwld call `GetModuleHandleA` with the program path, and then call `LoadStringA` on that handle. Support this behavior by _actually_ loading the PE at the path passed in to `GetModuleHandleA`, instead of assuming it's the current program. (This is especially useful because sjiswrap relies on overriding `GetModuleFileNameA`, so the wrapped program reads its own resources, rather than sjiswrap's.) Other small changes: - Add ms-win-crt `exit` & run atexit funcs - Implements vcruntime `memmove` - Implements kernel32 `GetModuleFileNameA`
This commit is contained in:
35
main.cpp
35
main.cpp
@@ -31,7 +31,7 @@ void wibo::debug_log(const char *fmt, ...) {
|
||||
|
||||
vfprintf(stderr, fmt, args);
|
||||
}
|
||||
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
@@ -110,11 +110,6 @@ const wibo::Module * wibo::modules[] = {
|
||||
nullptr,
|
||||
};
|
||||
|
||||
struct ModuleInfo {
|
||||
std::string name;
|
||||
const wibo::Module* module = nullptr;
|
||||
};
|
||||
|
||||
HMODULE wibo::loadModule(const char *dllName) {
|
||||
auto *result = new ModuleInfo;
|
||||
result->name = dllName;
|
||||
@@ -151,6 +146,32 @@ void *wibo::resolveFuncByOrdinal(HMODULE module, uint16_t ordinal) {
|
||||
return resolveMissingFuncOrdinal(info->name.c_str(), ordinal);
|
||||
}
|
||||
|
||||
wibo::Executable *wibo::executableFromModule(HMODULE module) {
|
||||
if (wibo::isMainModule(module)) {
|
||||
return wibo::mainModule;
|
||||
}
|
||||
|
||||
auto info = static_cast<wibo::ModuleInfo *>(module);
|
||||
if (!info->executable) {
|
||||
DEBUG_LOG("wibo::executableFromModule: loading %s\n", info->name.c_str());
|
||||
auto executable = std::make_unique<wibo::Executable>();
|
||||
const auto path = files::pathFromWindows(info->name.c_str());
|
||||
FILE *f = fopen(path.c_str(), "rb");
|
||||
if (!f) {
|
||||
perror("wibo::executableFromModule");
|
||||
return nullptr;
|
||||
}
|
||||
bool result = executable->loadPE(f, false);
|
||||
fclose(f);
|
||||
if (!result) {
|
||||
DEBUG_LOG("wibo::executableFromModule: failed to load %s\n", path.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
info->executable = std::move(executable);
|
||||
}
|
||||
return info->executable.get();
|
||||
}
|
||||
|
||||
struct UNICODE_STRING {
|
||||
unsigned short Length;
|
||||
unsigned short MaximumLength;
|
||||
@@ -295,7 +316,7 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
exec.loadPE(f);
|
||||
exec.loadPE(f, true);
|
||||
fclose(f);
|
||||
|
||||
// 32-bit windows only reserves the lowest 2GB of memory for use by a process (https://www.tenouk.com/WinVirtualAddressSpace.html)
|
||||
|
||||
Reference in New Issue
Block a user