mirror of https://github.com/decompals/wibo.git
resources
This commit is contained in:
parent
e6dc3b4ffd
commit
1a9d5d5a86
7
common.h
7
common.h
|
@ -6,8 +6,8 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define WIN_FUNC __attribute__((stdcall))
|
#define WIN_FUNC __attribute__((stdcall))
|
||||||
#define DEBUG_LOG(...) /* nothing */
|
// inline void DEBUG_LOG(const char *fmt, ...) {}
|
||||||
// #define DEBUG_LOG(...) wibo::debug_log(__VA_ARGS__)
|
#define DEBUG_LOG(...) wibo::debug_log(__VA_ARGS__)
|
||||||
|
|
||||||
namespace wibo {
|
namespace wibo {
|
||||||
extern uint32_t lastError;
|
extern uint32_t lastError;
|
||||||
|
@ -31,6 +31,7 @@ namespace wibo {
|
||||||
void *imageBuffer;
|
void *imageBuffer;
|
||||||
size_t imageSize;
|
size_t imageSize;
|
||||||
void *entryPoint;
|
void *entryPoint;
|
||||||
|
void *rsrcBase;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *fromRVA(uint32_t rva) {
|
T *fromRVA(uint32_t rva) {
|
||||||
|
@ -42,4 +43,6 @@ namespace wibo {
|
||||||
return fromRVA<T>((uint32_t) rva);
|
return fromRVA<T>((uint32_t) rva);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Executable *mainModule;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,9 +79,10 @@ namespace kernel32 {
|
||||||
* Memory
|
* Memory
|
||||||
*/
|
*/
|
||||||
void *WIN_FUNC GlobalAlloc(uint32_t uFlags, size_t dwBytes) {
|
void *WIN_FUNC GlobalAlloc(uint32_t uFlags, size_t dwBytes) {
|
||||||
DEBUG_LOG("GlobalAlloc(flags=%x, size=%x)\n", uFlags, dwBytes);
|
// DEBUG_LOG("GlobalAlloc(flags=%x, size=%x)\n", uFlags, dwBytes);
|
||||||
if (uFlags & 2) {
|
if (uFlags & 2) {
|
||||||
// GMEM_MOVEABLE - not implemented rn
|
// GMEM_MOVEABLE - not implemented rn
|
||||||
|
assert(0);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
// GMEM_FIXED - this is simpler
|
// GMEM_FIXED - this is simpler
|
||||||
|
|
|
@ -106,6 +106,7 @@ uint32_t read32(FILE *file) {
|
||||||
wibo::Executable::Executable() {
|
wibo::Executable::Executable() {
|
||||||
imageBuffer = nullptr;
|
imageBuffer = nullptr;
|
||||||
imageSize = 0;
|
imageSize = 0;
|
||||||
|
rsrcBase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wibo::Executable::~Executable() {
|
wibo::Executable::~Executable() {
|
||||||
|
@ -162,14 +163,18 @@ bool wibo::Executable::loadPE(FILE *file) {
|
||||||
name[8] = 0;
|
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);
|
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);
|
||||||
if (section.sizeOfRawData > 0) {
|
if (section.sizeOfRawData > 0) {
|
||||||
// Grab this data
|
// Grab this data
|
||||||
long savePos = ftell(file);
|
long savePos = ftell(file);
|
||||||
fseek(file, section.pointerToRawData, SEEK_SET);
|
fseek(file, section.pointerToRawData, SEEK_SET);
|
||||||
void *sectionBase = (void *) (header32.imageBase + section.virtualAddress);
|
|
||||||
fread(sectionBase, section.virtualSize, 1, file);
|
fread(sectionBase, section.virtualSize, 1, file);
|
||||||
fseek(file, savePos, SEEK_SET);
|
fseek(file, savePos, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcmp(name, ".rsrc") == 0) {
|
||||||
|
rsrcBase = sectionBase;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle imports
|
// Handle imports
|
||||||
|
|
2
main.cpp
2
main.cpp
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
uint32_t wibo::lastError = 0;
|
uint32_t wibo::lastError = 0;
|
||||||
char *wibo::commandLine;
|
char *wibo::commandLine;
|
||||||
|
wibo::Executable *wibo::mainModule = 0;
|
||||||
|
|
||||||
void wibo::debug_log(const char *fmt, ...) {
|
void wibo::debug_log(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@ -168,6 +169,7 @@ int main(int argc, char **argv) {
|
||||||
DEBUG_LOG("Command line: %s\n", wibo::commandLine);
|
DEBUG_LOG("Command line: %s\n", wibo::commandLine);
|
||||||
|
|
||||||
wibo::Executable exec;
|
wibo::Executable exec;
|
||||||
|
wibo::mainModule = &exec;
|
||||||
|
|
||||||
FILE *f = fopen(argv[1], "rb");
|
FILE *f = fopen(argv[1], "rb");
|
||||||
exec.loadPE(f);
|
exec.loadPE(f);
|
||||||
|
|
95
user32.cpp
95
user32.cpp
|
@ -1,10 +1,101 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
namespace user32 {
|
namespace user32 {
|
||||||
|
struct Resource {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ResourceTable {
|
||||||
|
char pad[12];
|
||||||
|
uint16_t nameEntryCount;
|
||||||
|
uint16_t idEntryCount;
|
||||||
|
Resource resources[];
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int searchResourceTableByID(const char *tableAddr, unsigned int id) {
|
||||||
|
ResourceTable* table = (ResourceTable*)tableAddr;
|
||||||
|
for (int i = 0; i < table->idEntryCount; i++) {
|
||||||
|
const Resource& r = table->resources[table->nameEntryCount + i];
|
||||||
|
if (r.id == id) {
|
||||||
|
return r.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int* getResourceByID(wibo::Executable *mod, unsigned int typeID, unsigned int nameID, unsigned int languageID) {
|
||||||
|
const char *rsrcBase = (const char *)mod->rsrcBase;
|
||||||
|
|
||||||
|
if (rsrcBase == 0) {
|
||||||
|
DEBUG_LOG("getResourceByID: no .rsrc section\n");
|
||||||
|
wibo::lastError = 1812; // ERROR_RESOURCE_DATA_NOT_FOUND
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int typeTable = searchResourceTableByID(rsrcBase, typeID) & 0x7FFFFFFFu;
|
||||||
|
if (typeTable == 0) {
|
||||||
|
DEBUG_LOG("getResourceByID: no type table with id = %s\n", typeID);
|
||||||
|
wibo::lastError = 1813; // ERROR_RESOURCE_TYPE_NOT_FOUND
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int nameTable = searchResourceTableByID(rsrcBase + typeTable, nameID) & 0x7FFFFFFFu;
|
||||||
|
if (nameTable == 0) {
|
||||||
|
DEBUG_LOG("getResourceByID: no name table with id = %s\n", nameID);
|
||||||
|
wibo::lastError = 1814; // ERROR_RESOURCE_NAME_NOT_FOUND
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int langEntry = searchResourceTableByID(rsrcBase + nameTable, languageID);
|
||||||
|
if (langEntry == 0) {
|
||||||
|
DEBUG_LOG("getResourceByID: no lang entry with id = %s\n", languageID);
|
||||||
|
wibo::lastError = 1814; // ERROR_RESOURCE_NAME_NOT_FOUND
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned int*)(rsrcBase + langEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *getStringFromTable(unsigned int uID) {
|
||||||
|
wibo::Executable *mod = wibo::mainModule;
|
||||||
|
unsigned int tableID = (uID >> 4) + 1;
|
||||||
|
unsigned int entryID = uID & 15;
|
||||||
|
unsigned int* stringTable = getResourceByID(mod, 6, tableID, 1033);
|
||||||
|
if (stringTable == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// what's in here?
|
||||||
|
const char *str = mod->fromRVA<const char>(stringTable[0]);
|
||||||
|
unsigned int size = stringTable[1];
|
||||||
|
assert(entryID < size);
|
||||||
|
|
||||||
|
// skip over strings to get to the one we want
|
||||||
|
for (unsigned int i = 0; i < entryID; i++) {
|
||||||
|
int stringSize = *(uint16_t*)str;
|
||||||
|
str += 2;
|
||||||
|
str += stringSize * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) {
|
int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) {
|
||||||
DEBUG_LOG("LoadStringA %p %d %d\n", hInstance, uID, cchBufferMax);
|
DEBUG_LOG("LoadStringA %p %d %d\n", hInstance, uID, cchBufferMax);
|
||||||
strcpy(lpBuffer, "hello");
|
const char* s = getStringFromTable(uID);
|
||||||
return 5;
|
if (!s) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int len = *(int16_t*)s;
|
||||||
|
s += 2;
|
||||||
|
assert(cchBufferMax != 0);
|
||||||
|
len = (len < cchBufferMax - 1 ? len : cchBufferMax - 1);
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
lpBuffer[i] = s[i * 2];
|
||||||
|
}
|
||||||
|
lpBuffer[len] = 0;
|
||||||
|
DEBUG_LOG("returning: %s\n", lpBuffer);
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue