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:
22
loader.cpp
22
loader.cpp
@@ -116,7 +116,13 @@ wibo::Executable::~Executable() {
|
||||
}
|
||||
}
|
||||
|
||||
bool wibo::Executable::loadPE(FILE *file) {
|
||||
/**
|
||||
* Load a PE file into memory.
|
||||
*
|
||||
* @param file The file to load.
|
||||
* @param exec Whether to make the loaded image executable.
|
||||
*/
|
||||
bool wibo::Executable::loadPE(FILE *file, bool exec) {
|
||||
// Skip to PE header
|
||||
fseek(file, 0x3C, SEEK_SET);
|
||||
uint32_t offsetToPE = read32(file);
|
||||
@@ -145,7 +151,12 @@ bool wibo::Executable::loadPE(FILE *file) {
|
||||
|
||||
// Build buffer
|
||||
imageSize = header32.sizeOfImage;
|
||||
imageBuffer = mmap((void *) header32.imageBase, header32.sizeOfImage, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, -1, 0);
|
||||
if (exec) {
|
||||
imageBuffer = mmap((void *)header32.imageBase, header32.sizeOfImage, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1, 0);
|
||||
} else {
|
||||
imageBuffer = mmap(nullptr, header32.sizeOfImage, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
}
|
||||
memset(imageBuffer, 0, header32.sizeOfImage);
|
||||
if (imageBuffer == MAP_FAILED) {
|
||||
perror("Image mapping failed!");
|
||||
@@ -165,7 +176,7 @@ bool wibo::Executable::loadPE(FILE *file) {
|
||||
name[8] = 0;
|
||||
DEBUG_LOG("Section %d: name=%s addr=%x size=%x (raw=%x) ptr=%x\n", i, name, section.virtualAddress, section.virtualSize, section.sizeOfRawData, section.pointerToRawData);
|
||||
|
||||
void *sectionBase = (void *) (header32.imageBase + section.virtualAddress);
|
||||
void *sectionBase = (void *) ((uintptr_t) imageBuffer + section.virtualAddress);
|
||||
if (section.pointerToRawData > 0 && section.sizeOfRawData > 0) {
|
||||
// Grab this data
|
||||
long savePos = ftell(file);
|
||||
@@ -179,6 +190,11 @@ bool wibo::Executable::loadPE(FILE *file) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!exec) {
|
||||
// No need to resolve imports
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle imports
|
||||
PEImportDirectoryEntry *dir = fromRVA<PEImportDirectoryEntry>(header32.importTable.virtualAddress);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user