From 82c05df74ea5609f94292736df8b20d7d868e49d Mon Sep 17 00:00:00 2001 From: Simon Lindholm Date: Wed, 29 Jun 2022 01:07:04 +0200 Subject: [PATCH] more --- advapi32.cpp | 2 +- kernel32.cpp | 86 ++++++++++++++++++++++++++++++++++++---------------- lmgr11.cpp | 24 +++++++++++++++ loader.cpp | 14 ++++----- main.cpp | 22 +++++++++++--- user32.cpp | 2 +- version.cpp | 2 +- 7 files changed, 111 insertions(+), 41 deletions(-) create mode 100644 lmgr11.cpp diff --git a/advapi32.cpp b/advapi32.cpp index 74908c8..00b8c3f 100644 --- a/advapi32.cpp +++ b/advapi32.cpp @@ -2,7 +2,7 @@ namespace advapi32 { unsigned int WIN_FUNC RegOpenKeyExA(void *hKey, const char *lpSubKey, unsigned int ulOptions, void *samDesired, void **phkResult) { - printf("RegOpenKeyExA(key=%p, subkey=%s, ...)\n", hKey, lpSubKey); + DEBUG_LOG("RegOpenKeyExA(key=%p, subkey=%s, ...)\n", hKey, lpSubKey); return 1; // screw them for now } } diff --git a/kernel32.cpp b/kernel32.cpp index c66598a..7b7e2a4 100644 --- a/kernel32.cpp +++ b/kernel32.cpp @@ -13,17 +13,21 @@ namespace kernel32 { return (void *) 0xFFFFFFFF; } + void WIN_FUNC ExitProcess(unsigned int uExitCode) { + exit(uExitCode); + } + void WIN_FUNC InitializeCriticalSection(void *param) { - // printf("InitializeCriticalSection(...)\n"); + // DEBUG_LOG("InitializeCriticalSection(...)\n"); } void WIN_FUNC DeleteCriticalSection(void *param) { - // printf("DeleteCriticalSection(...)\n"); + // DEBUG_LOG("DeleteCriticalSection(...)\n"); } void WIN_FUNC EnterCriticalSection(void *param) { - // printf("EnterCriticalSection(...)\n"); + // DEBUG_LOG("EnterCriticalSection(...)\n"); } void WIN_FUNC LeaveCriticalSection(void *param) { - // printf("LeaveCriticalSection(...)\n"); + // DEBUG_LOG("LeaveCriticalSection(...)\n"); } /* @@ -33,20 +37,20 @@ namespace kernel32 { static bool tlsValuesUsed[MAX_TLS_VALUES] = { false }; static void *tlsValues[MAX_TLS_VALUES]; unsigned int WIN_FUNC TlsAlloc() { - printf("TlsAlloc()\n"); + DEBUG_LOG("TlsAlloc()\n"); for (int i = 0; i < MAX_TLS_VALUES; i++) { if (tlsValuesUsed[i] == false) { tlsValuesUsed[i] = true; tlsValues[i] = 0; - printf("...returning %d\n", i); + DEBUG_LOG("...returning %d\n", i); return i; } } - printf("...returning nothing\n"); + DEBUG_LOG("...returning nothing\n"); return 0xFFFFFFFF; } unsigned int WIN_FUNC TlsFree(unsigned int dwTlsIndex) { - printf("TlsFree(%u)\n", dwTlsIndex); + DEBUG_LOG("TlsFree(%u)\n", dwTlsIndex); if (dwTlsIndex >= 0 && dwTlsIndex < MAX_TLS_VALUES && tlsValuesUsed[dwTlsIndex]) { tlsValuesUsed[dwTlsIndex] = false; return 1; @@ -55,14 +59,14 @@ namespace kernel32 { } } void *WIN_FUNC TlsGetValue(unsigned int dwTlsIndex) { - // printf("TlsGetValue(%u)\n", dwTlsIndex); + // DEBUG_LOG("TlsGetValue(%u)\n", dwTlsIndex); if (dwTlsIndex >= 0 && dwTlsIndex < MAX_TLS_VALUES && tlsValuesUsed[dwTlsIndex]) return tlsValues[dwTlsIndex]; else return 0; } unsigned int WIN_FUNC TlsSetValue(unsigned int dwTlsIndex, void *lpTlsValue) { - // printf("TlsSetValue(%u, %p)\n", dwTlsIndex, lpTlsValue); + // DEBUG_LOG("TlsSetValue(%u, %p)\n", dwTlsIndex, lpTlsValue); if (dwTlsIndex >= 0 && dwTlsIndex < MAX_TLS_VALUES && tlsValuesUsed[dwTlsIndex]) { tlsValues[dwTlsIndex] = lpTlsValue; return 1; @@ -75,12 +79,15 @@ namespace kernel32 { * Memory */ void *WIN_FUNC GlobalAlloc(uint32_t uFlags, size_t dwBytes) { - printf("GlobalAlloc(flags=%x, size=%x)\n", uFlags, dwBytes); + DEBUG_LOG("GlobalAlloc(flags=%x, size=%x)\n", uFlags, dwBytes); if (uFlags & 2) { // GMEM_MOVEABLE - not implemented rn return 0; } else { // GMEM_FIXED - this is simpler + if (dwBytes == 0) + dwBytes = 1; + assert(dwBytes > 0); void *buffer = malloc(dwBytes); if (buffer && (uFlags & 0x40)) { // GMEM_ZEROINT @@ -94,6 +101,25 @@ namespace kernel32 { return 0; } + void *WIN_FUNC GlobalReAlloc(void *hMem, size_t dwBytes, uint32_t uFlags) { + if (uFlags & 0x80) { // GMEM_MODIFY + assert(0); + } else { + if (dwBytes == 0) + dwBytes = 1; + void *buffer = realloc(hMem, dwBytes); + if (buffer && (uFlags & 0x40)) { + // GMEM_ZEROINT + memset(buffer, 0, dwBytes); + } + return buffer; + } + } + + unsigned int WIN_FUNC GlobalFlags(void *hMem) { + return 0; + } + /* * Environment */ @@ -158,10 +184,14 @@ namespace kernel32 { } // This probably won't come up - printf("Unhandled DuplicateHandle(source=%p)\n", hSourceHandle); + DEBUG_LOG("Unhandled DuplicateHandle(source=%p)\n", hSourceHandle); return 0; } + int WIN_FUNC CloseHandle(void *hObject) { + return 1; + } + std::filesystem::path pathFromWindows(const char *inStr) { // Convert to forward slashes std::string str = inStr; @@ -187,10 +217,10 @@ namespace kernel32 { } unsigned int WIN_FUNC GetFullPathNameA(const char *lpFileName, unsigned int nBufferLength, char *lpBuffer, char **lpFilePart) { - printf("GetFullPathNameA(%s)...\n", lpFileName); + DEBUG_LOG("GetFullPathNameA(%s)...\n", lpFileName); std::filesystem::path absPath = std::filesystem::absolute(pathFromWindows(lpFileName)); std::string absStr = pathToWindows(absPath); - printf("AbsPath: %s - %s\n", absPath.c_str(), absStr.c_str()); + DEBUG_LOG("AbsPath: %s - %s\n", absPath.c_str(), absStr.c_str()); // Enough space? if ((absStr.size() + 1) <= nBufferLength) { @@ -214,20 +244,20 @@ namespace kernel32 { unsigned int WIN_FUNC GetFileAttributesA(const char *lpFileName) { auto path = pathFromWindows(lpFileName); - printf("GetFileAttributesA(%s)... (%s)\n", lpFileName, path.c_str()); + DEBUG_LOG("GetFileAttributesA(%s)... (%s)\n", lpFileName, path.c_str()); auto status = std::filesystem::status(path); wibo::lastError = 0; switch (status.type()) { case std::filesystem::file_type::regular: - printf("File exists\n"); + DEBUG_LOG("File exists\n"); return 0x80; // FILE_ATTRIBUTE_NORMAL case std::filesystem::file_type::directory: return 0x10; // FILE_ATTRIBUTE_DIRECTORY case std::filesystem::file_type::not_found: default: - printf("File does not exist\n"); + DEBUG_LOG("File does not exist\n"); wibo::lastError = 2; // ERROR_FILE_NOT_FOUND return 0xFFFFFFFF; // INVALID_FILE_ATTRIBUTES } @@ -293,7 +323,7 @@ namespace kernel32 { } unsigned int WIN_FUNC GetCurrentDirectoryA(unsigned int uSize, char *lpBuffer) { - printf("GetCurrentDirectoryA\n"); + DEBUG_LOG("GetCurrentDirectoryA\n"); std::filesystem::path cwd = std::filesystem::current_path(); std::string path = pathToWindows(cwd); @@ -305,44 +335,44 @@ namespace kernel32 { } void* WIN_FUNC GetModuleHandleA(const char* lpModuleName) { - printf("GetModuleHandleA %s\n", lpModuleName); + DEBUG_LOG("GetModuleHandleA %s\n", lpModuleName); // wibo::lastError = 0; return (void*)1; } unsigned int WIN_FUNC GetModuleFileNameA(void* hModule, char* lpFilename, unsigned int nSize) { - printf("GetModuleFileNameA %p\n", hModule); + DEBUG_LOG("GetModuleFileNameA %p\n", hModule); wibo::lastError = 0; return 0; } void* WIN_FUNC FindResourceA(void* hModule, const char* lpName, const char* lpType) { - printf("FindResourceA %p %s %s\n", hModule, lpName, lpType); + DEBUG_LOG("FindResourceA %p %s %s\n", hModule, lpName, lpType); return (void*)2; } void* WIN_FUNC LoadResource(void* hModule, void* res) { - printf("LoadResource %p %p\n", hModule, res); + DEBUG_LOG("LoadResource %p %p\n", hModule, res); return (void*)3; } void* WIN_FUNC LockResource(void* res) { - printf("LockResource %p\n", res); + DEBUG_LOG("LockResource %p\n", res); return (void*)4; } unsigned int WIN_FUNC SizeofResource(void* hModule, void* res) { - printf("SizeofResource %p %p\n", hModule, res); + DEBUG_LOG("SizeofResource %p %p\n", hModule, res); return 0; } void* WIN_FUNC LoadLibraryA(const char* lpLibFileName) { - printf("LoadLibraryA %s\n", lpLibFileName); + DEBUG_LOG("LoadLibraryA %s\n", lpLibFileName); return (void*)5; } int WIN_FUNC FreeLibrary(void* hLibModule) { - printf("FreeLibrary %p\n", hLibModule); + DEBUG_LOG("FreeLibrary %p\n", hLibModule); return 1; } } @@ -350,12 +380,15 @@ namespace kernel32 { void *wibo::resolveKernel32(const char *name) { if (strcmp(name, "GetLastError") == 0) return (void *) kernel32::GetLastError; if (strcmp(name, "GetCurrentProcess") == 0) return (void *) kernel32::GetCurrentProcess; + if (strcmp(name, "ExitProcess") == 0) return (void *) kernel32::ExitProcess; if (strcmp(name, "InitializeCriticalSection") == 0) return (void *) kernel32::InitializeCriticalSection; if (strcmp(name, "DeleteCriticalSection") == 0) return (void *) kernel32::DeleteCriticalSection; if (strcmp(name, "EnterCriticalSection") == 0) return (void *) kernel32::EnterCriticalSection; if (strcmp(name, "LeaveCriticalSection") == 0) return (void *) kernel32::LeaveCriticalSection; if (strcmp(name, "GlobalAlloc") == 0) return (void *) kernel32::GlobalAlloc; + if (strcmp(name, "GlobalReAlloc") == 0) return (void *) kernel32::GlobalReAlloc; if (strcmp(name, "GlobalFree") == 0) return (void *) kernel32::GlobalFree; + if (strcmp(name, "GlobalFlags") == 0) return (void *) kernel32::GlobalFlags; if (strcmp(name, "TlsAlloc") == 0) return (void *) kernel32::TlsAlloc; if (strcmp(name, "TlsFree") == 0) return (void *) kernel32::TlsFree; if (strcmp(name, "TlsGetValue") == 0) return (void *) kernel32::TlsGetValue; @@ -365,6 +398,7 @@ void *wibo::resolveKernel32(const char *name) { if (strcmp(name, "FreeEnvironmentStringsA") == 0) return (void *) kernel32::FreeEnvironmentStringsA; if (strcmp(name, "GetStdHandle") == 0) return (void *) kernel32::GetStdHandle; if (strcmp(name, "DuplicateHandle") == 0) return (void *) kernel32::DuplicateHandle; + if (strcmp(name, "CloseHandle") == 0) return (void *) kernel32::CloseHandle; if (strcmp(name, "GetFullPathNameA") == 0) return (void *) kernel32::GetFullPathNameA; if (strcmp(name, "GetFileAttributesA") == 0) return (void *) kernel32::GetFileAttributesA; if (strcmp(name, "WriteFile") == 0) return (void *) kernel32::WriteFile; diff --git a/lmgr11.cpp b/lmgr11.cpp new file mode 100644 index 0000000..ad93671 --- /dev/null +++ b/lmgr11.cpp @@ -0,0 +1,24 @@ +#include "common.h" + +namespace lmgr11 { + int lp_checkout(int a, int b, const char* c, const char* d, int e, const char* f, int* out) { + DEBUG_LOG("lp_checkout %d %d %s %s %d %s\n", a, b, c, d, e, f); + *out = 1234; + return 0; + } + + int lp_checkin() { + DEBUG_LOG("lp_checkin\n"); + return 0; + } +} + +void *wibo::resolveLmgr11(uint16_t ordinal) { + switch (ordinal) { + case 189: + return (void*)lmgr11::lp_checkin; + case 190: + return (void*)lmgr11::lp_checkout; + } + return 0; +} diff --git a/loader.cpp b/loader.cpp index 4e30f5d..8f94404 100644 --- a/loader.cpp +++ b/loader.cpp @@ -128,7 +128,7 @@ bool wibo::Executable::loadPE(FILE *file) { if (header.machine != 0x14C) // i386 return false; - printf("Sections: %d / Size of optional header: %x\n", header.numberOfSections, header.sizeOfOptionalHeader); + DEBUG_LOG("Sections: %d / Size of optional header: %x\n", header.numberOfSections, header.sizeOfOptionalHeader); PE32Header header32; memset(&header32, 0, sizeof header32); @@ -136,10 +136,10 @@ bool wibo::Executable::loadPE(FILE *file) { if (header32.magic != 0x10B) return false; - printf("Image Base: %x / Size: %x\n", header32.imageBase, header32.sizeOfImage); + DEBUG_LOG("Image Base: %x / Size: %x\n", header32.imageBase, header32.sizeOfImage); long pageSize = sysconf(_SC_PAGE_SIZE); - printf("Page size: %x\n", (unsigned int)pageSize); + DEBUG_LOG("Page size: %x\n", (unsigned int)pageSize); // Build buffer imageSize = header32.sizeOfImage; @@ -160,7 +160,7 @@ bool wibo::Executable::loadPE(FILE *file) { char name[9]; memcpy(name, section.name, 8); name[8] = 0; - printf("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); if (section.sizeOfRawData > 0) { // Grab this data @@ -177,7 +177,7 @@ bool wibo::Executable::loadPE(FILE *file) { while (dir->name) { char *name = fromRVA(dir->name); - printf("DLL Name: %s\n", name); + DEBUG_LOG("DLL Name: %s\n", name); uint32_t *lookupTable = fromRVA(dir->importLookupTable); uint32_t *addressTable = fromRVA(dir->importAddressTable); @@ -186,12 +186,12 @@ bool wibo::Executable::loadPE(FILE *file) { if (lookup & 0x80000000) { // Import by ordinal uint16_t ordinal = lookup & 0xFFFF; - printf(" Ordinal: %d\n", ordinal); + DEBUG_LOG(" Ordinal: %d\n", ordinal); *addressTable = (uint32_t) resolveStubByOrdinal(name, ordinal); } else { // Import by name PEHintNameTableEntry *hintName = fromRVA(lookup); - printf(" Name: %s\n", hintName->name); + DEBUG_LOG(" Name: %s\n", hintName->name); *addressTable = (uint32_t) resolveStubByName(name, hintName->name); } ++lookupTable; diff --git a/main.cpp b/main.cpp index 41a75d0..3940b43 100644 --- a/main.cpp +++ b/main.cpp @@ -4,10 +4,18 @@ #include #include #include +#include uint32_t wibo::lastError = 0; char *wibo::commandLine; +void wibo::debug_log(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + static int stubIndex = 0; static char stubDlls[0x100][0x100]; static char stubFuncNames[0x100][0x100]; @@ -15,7 +23,7 @@ static char stubFuncNames[0x100][0x100]; static void stubBase(int index) { // should go through all the functions imported by mwcceppc.exe // and create template stubs for them, at least... - printf("Unhandled function %s (%s)\n", stubFuncNames[index], stubDlls[index]); + DEBUG_LOG("Unhandled function %s (%s)\n", stubFuncNames[index], stubDlls[index]); exit(0); } @@ -35,7 +43,7 @@ DEFINE_STUBS(3, 0) DEFINE_STUBS(3, 1) DEFINE_STUBS(3, 2) DEFINE_STUBS(3, 3) #undef DEFINE_STUBS uint32_t __attribute__((stdcall)) CoInitialize(void *pvReserved) { - printf("CoInitialize(...)\n"); + DEBUG_LOG("CoInitialize(...)\n"); return 0; // S_OK I think? } @@ -64,7 +72,7 @@ void *wibo::resolveStubByName(const char *dllName, const char *funcName) { if (strcmp(funcName, "CoInitialize") == 0) return (void *) CoInitialize; } - printf("Missing function: %s (%s)\n", dllName, funcName); + DEBUG_LOG("Missing function: %s (%s)\n", dllName, funcName); assert(stubIndex < 0x100); assert(strlen(dllName) < 0x100); assert(strlen(funcName) < 0x100); @@ -74,7 +82,11 @@ void *wibo::resolveStubByName(const char *dllName, const char *funcName) { } void *wibo::resolveStubByOrdinal(const char *dllName, uint16_t ordinal) { - // printf("Missing function: %s (%x)\n", dllName, ordinal); + if (strcmp(dllName, "LMGR11.dll") == 0) { + void* func = wibo::resolveLmgr11(ordinal); + if (func) + return func; + } assert(stubIndex < 0x100); assert(strlen(dllName) < 0x100); sprintf(stubFuncNames[stubIndex], "%d", ordinal); @@ -130,7 +142,7 @@ int main(int argc, char **argv) { : : "r"(tibSegment), "r"(exec.entryPoint) ); - printf("We came back\n"); + DEBUG_LOG("We came back\n"); return 0; } diff --git a/user32.cpp b/user32.cpp index 4f1d95e..400d058 100644 --- a/user32.cpp +++ b/user32.cpp @@ -2,7 +2,7 @@ namespace user32 { int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) { - printf("LoadStringA %p %d %d\n", hInstance, uID, cchBufferMax); + DEBUG_LOG("LoadStringA %p %d %d\n", hInstance, uID, cchBufferMax); strcpy(lpBuffer, "hello"); return 5; } diff --git a/version.cpp b/version.cpp index 1182785..38e620b 100644 --- a/version.cpp +++ b/version.cpp @@ -2,7 +2,7 @@ namespace version { unsigned int WIN_FUNC GetFileVersionInfoSizeA(const char* lptstrFilename, unsigned int* outZero) { - printf("GetFileVersionInfoSizeA %s\n", lptstrFilename); + DEBUG_LOG("GetFileVersionInfoSizeA %s\n", lptstrFilename); *outZero = 0; // stub: signal an error wibo::lastError = 0;