mirror of https://github.com/decompals/wibo.git
wip
This commit is contained in:
parent
d1a4fd35a7
commit
3fd1f6a30c
|
@ -4,7 +4,7 @@ An experiment to try and write a minimal, low-fuss wrapper that can run really s
|
||||||
|
|
||||||
Don't run this on any untrusted executables, I implore you. (Or probably just don't run it at all... :p)
|
Don't run this on any untrusted executables, I implore you. (Or probably just don't run it at all... :p)
|
||||||
|
|
||||||
g++ -g -m32 -std=c++20 -lstdc++ main.cpp kernel32.cpp advapi32.cpp loader.cpp
|
g++ -g -m32 -std=c++20 -lstdc++ main.cpp version.cpp user32.cpp kernel32.cpp advapi32.cpp loader.cpp
|
||||||
|
|
||||||
If you need something like this project (but more mature), you might find [taviso/loadlibrary](https://github.com/taviso/loadlibrary) more interesting.
|
If you need something like this project (but more mature), you might find [taviso/loadlibrary](https://github.com/taviso/loadlibrary) more interesting.
|
||||||
|
|
||||||
|
|
3
common.h
3
common.h
|
@ -3,6 +3,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#define WIN_FUNC __attribute__((stdcall))
|
#define WIN_FUNC __attribute__((stdcall))
|
||||||
|
|
||||||
|
@ -10,7 +11,9 @@ namespace wibo {
|
||||||
extern uint32_t lastError;
|
extern uint32_t lastError;
|
||||||
extern char *commandLine;
|
extern char *commandLine;
|
||||||
|
|
||||||
|
void *resolveVersion(const char *name);
|
||||||
void *resolveKernel32(const char *name);
|
void *resolveKernel32(const char *name);
|
||||||
|
void *resolveUser32(const char *name);
|
||||||
void *resolveAdvApi32(const char *name);
|
void *resolveAdvApi32(const char *name);
|
||||||
void *resolveStubByName(const char *dllName, const char *funcName);
|
void *resolveStubByName(const char *dllName, const char *funcName);
|
||||||
void *resolveStubByOrdinal(const char *dllName, uint16_t ordinal);
|
void *resolveStubByOrdinal(const char *dllName, uint16_t ordinal);
|
||||||
|
|
63
kernel32.cpp
63
kernel32.cpp
|
@ -291,6 +291,60 @@ namespace kernel32 {
|
||||||
strcpy(lpBuffer, "C:\\Windows");
|
strcpy(lpBuffer, "C:\\Windows");
|
||||||
return strlen(lpBuffer);
|
return strlen(lpBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int WIN_FUNC GetCurrentDirectoryA(unsigned int uSize, char *lpBuffer) {
|
||||||
|
printf("GetCurrentDirectoryA\n");
|
||||||
|
|
||||||
|
std::filesystem::path cwd = std::filesystem::current_path();
|
||||||
|
std::string path = pathToWindows(cwd);
|
||||||
|
|
||||||
|
assert(path.size() < uSize);
|
||||||
|
|
||||||
|
strcpy(lpBuffer, path.c_str());
|
||||||
|
return path.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void* WIN_FUNC GetModuleHandleA(const char* lpModuleName) {
|
||||||
|
printf("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);
|
||||||
|
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);
|
||||||
|
return (void*)2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* WIN_FUNC LoadResource(void* hModule, void* res) {
|
||||||
|
printf("LoadResource %p %p\n", hModule, res);
|
||||||
|
return (void*)3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* WIN_FUNC LockResource(void* res) {
|
||||||
|
printf("LockResource %p\n", res);
|
||||||
|
return (void*)4;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int WIN_FUNC SizeofResource(void* hModule, void* res) {
|
||||||
|
printf("SizeofResource %p %p\n", hModule, res);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* WIN_FUNC LoadLibraryA(const char* lpLibFileName) {
|
||||||
|
printf("LoadLibraryA %s\n", lpLibFileName);
|
||||||
|
return (void*)5;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WIN_FUNC FreeLibrary(void* hLibModule) {
|
||||||
|
printf("FreeLibrary %p\n", hLibModule);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *wibo::resolveKernel32(const char *name) {
|
void *wibo::resolveKernel32(const char *name) {
|
||||||
|
@ -318,5 +372,14 @@ void *wibo::resolveKernel32(const char *name) {
|
||||||
if (strcmp(name, "GetConsoleScreenBufferInfo") == 0) return (void *) kernel32::GetConsoleScreenBufferInfo;
|
if (strcmp(name, "GetConsoleScreenBufferInfo") == 0) return (void *) kernel32::GetConsoleScreenBufferInfo;
|
||||||
if (strcmp(name, "GetSystemDirectoryA") == 0) return (void *) kernel32::GetSystemDirectoryA;
|
if (strcmp(name, "GetSystemDirectoryA") == 0) return (void *) kernel32::GetSystemDirectoryA;
|
||||||
if (strcmp(name, "GetWindowsDirectoryA") == 0) return (void *) kernel32::GetWindowsDirectoryA;
|
if (strcmp(name, "GetWindowsDirectoryA") == 0) return (void *) kernel32::GetWindowsDirectoryA;
|
||||||
|
if (strcmp(name, "GetCurrentDirectoryA") == 0) return (void *) kernel32::GetCurrentDirectoryA;
|
||||||
|
if (strcmp(name, "GetModuleHandleA") == 0) return (void *) kernel32::GetModuleHandleA;
|
||||||
|
if (strcmp(name, "GetModuleFileNameA") == 0) return (void *) kernel32::GetModuleFileNameA;
|
||||||
|
if (strcmp(name, "FindResourceA") == 0) return (void *) kernel32::FindResourceA;
|
||||||
|
if (strcmp(name, "LoadResource") == 0) return (void *) kernel32::LoadResource;
|
||||||
|
if (strcmp(name, "LockResource") == 0) return (void *) kernel32::LockResource;
|
||||||
|
if (strcmp(name, "SizeofResource") == 0) return (void *) kernel32::SizeofResource;
|
||||||
|
if (strcmp(name, "LoadLibraryA") == 0) return (void *) kernel32::LoadLibraryA;
|
||||||
|
if (strcmp(name, "FreeLibrary") == 0) return (void *) kernel32::FreeLibrary;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ bool wibo::Executable::loadPE(FILE *file) {
|
||||||
printf("Image Base: %x / Size: %x\n", header32.imageBase, header32.sizeOfImage);
|
printf("Image Base: %x / Size: %x\n", header32.imageBase, header32.sizeOfImage);
|
||||||
|
|
||||||
long pageSize = sysconf(_SC_PAGE_SIZE);
|
long pageSize = sysconf(_SC_PAGE_SIZE);
|
||||||
printf("Page size: %x\n", pageSize);
|
printf("Page size: %x\n", (unsigned int)pageSize);
|
||||||
|
|
||||||
// Build buffer
|
// Build buffer
|
||||||
imageSize = header32.sizeOfImage;
|
imageSize = header32.sizeOfImage;
|
||||||
|
|
47
main.cpp
47
main.cpp
|
@ -8,13 +8,32 @@
|
||||||
uint32_t wibo::lastError = 0;
|
uint32_t wibo::lastError = 0;
|
||||||
char *wibo::commandLine;
|
char *wibo::commandLine;
|
||||||
|
|
||||||
void stub() {
|
static int stubIndex = 0;
|
||||||
|
static char stubDlls[0x100][0x100];
|
||||||
|
static char stubFuncNames[0x100][0x100];
|
||||||
|
|
||||||
|
static void stubBase(int index) {
|
||||||
// should go through all the functions imported by mwcceppc.exe
|
// should go through all the functions imported by mwcceppc.exe
|
||||||
// and create template stubs for them, at least...
|
// and create template stubs for them, at least...
|
||||||
printf("Unhandled function\n");
|
printf("Unhandled function %s (%s)\n", stubFuncNames[index], stubDlls[index]);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void (*stubFuncs[0x100])(void) = {
|
||||||
|
#define DEFINE_STUB(a, b, c, d) []() { stubBase(a << 6 | b << 4 | c << 2 | d); },
|
||||||
|
#define DEFINE_STUBS(a, b) \
|
||||||
|
DEFINE_STUB(a, b, 0, 0) DEFINE_STUB(a, b, 0, 1) DEFINE_STUB(a, b, 0, 2) DEFINE_STUB(a, b, 0, 3) \
|
||||||
|
DEFINE_STUB(a, b, 1, 0) DEFINE_STUB(a, b, 1, 1) DEFINE_STUB(a, b, 1, 2) DEFINE_STUB(a, b, 1, 3) \
|
||||||
|
DEFINE_STUB(a, b, 2, 0) DEFINE_STUB(a, b, 2, 1) DEFINE_STUB(a, b, 2, 2) DEFINE_STUB(a, b, 2, 3) \
|
||||||
|
DEFINE_STUB(a, b, 3, 0) DEFINE_STUB(a, b, 3, 1) DEFINE_STUB(a, b, 3, 2) DEFINE_STUB(a, b, 3, 3)
|
||||||
|
DEFINE_STUBS(0, 0) DEFINE_STUBS(0, 1) DEFINE_STUBS(0, 2) DEFINE_STUBS(0, 3)
|
||||||
|
DEFINE_STUBS(1, 0) DEFINE_STUBS(1, 1) DEFINE_STUBS(1, 2) DEFINE_STUBS(1, 3)
|
||||||
|
DEFINE_STUBS(2, 0) DEFINE_STUBS(2, 1) DEFINE_STUBS(2, 2) DEFINE_STUBS(2, 3)
|
||||||
|
DEFINE_STUBS(3, 0) DEFINE_STUBS(3, 1) DEFINE_STUBS(3, 2) DEFINE_STUBS(3, 3)
|
||||||
|
};
|
||||||
|
#undef DEFINE_STUB
|
||||||
|
#undef DEFINE_STUBS
|
||||||
|
|
||||||
uint32_t __attribute__((stdcall)) CoInitialize(void *pvReserved) {
|
uint32_t __attribute__((stdcall)) CoInitialize(void *pvReserved) {
|
||||||
printf("CoInitialize(...)\n");
|
printf("CoInitialize(...)\n");
|
||||||
return 0; // S_OK I think?
|
return 0; // S_OK I think?
|
||||||
|
@ -26,21 +45,41 @@ void *wibo::resolveStubByName(const char *dllName, const char *funcName) {
|
||||||
if (func)
|
if (func)
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
if (strcmp(dllName, "USER32.dll") == 0) {
|
||||||
|
void *func = wibo::resolveUser32(funcName);
|
||||||
|
if (func)
|
||||||
|
return func;
|
||||||
|
}
|
||||||
if (strcmp(dllName, "ADVAPI32.dll") == 0) {
|
if (strcmp(dllName, "ADVAPI32.dll") == 0) {
|
||||||
void *func = wibo::resolveAdvApi32(funcName);
|
void *func = wibo::resolveAdvApi32(funcName);
|
||||||
if (func)
|
if (func)
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
if (strcmp(dllName, "VERSION.dll") == 0) {
|
||||||
|
void *func = wibo::resolveVersion(funcName);
|
||||||
|
if (func)
|
||||||
|
return func;
|
||||||
|
}
|
||||||
if (strcmp(dllName, "ole32.dll") == 0) {
|
if (strcmp(dllName, "ole32.dll") == 0) {
|
||||||
if (strcmp(funcName, "CoInitialize") == 0) return (void *) CoInitialize;
|
if (strcmp(funcName, "CoInitialize") == 0) return (void *) CoInitialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Missing function: %s (%s)\n", dllName, funcName);
|
printf("Missing function: %s (%s)\n", dllName, funcName);
|
||||||
return (void *) stub;
|
assert(stubIndex < 0x100);
|
||||||
|
assert(strlen(dllName) < 0x100);
|
||||||
|
assert(strlen(funcName) < 0x100);
|
||||||
|
strcpy(stubFuncNames[stubIndex], funcName);
|
||||||
|
strcpy(stubDlls[stubIndex], dllName);
|
||||||
|
return (void *) stubFuncs[stubIndex++];
|
||||||
}
|
}
|
||||||
|
|
||||||
void *wibo::resolveStubByOrdinal(const char *dllName, uint16_t ordinal) {
|
void *wibo::resolveStubByOrdinal(const char *dllName, uint16_t ordinal) {
|
||||||
return (void *) stub;
|
// printf("Missing function: %s (%x)\n", dllName, ordinal);
|
||||||
|
assert(stubIndex < 0x100);
|
||||||
|
assert(strlen(dllName) < 0x100);
|
||||||
|
sprintf(stubFuncNames[stubIndex], "%d", ordinal);
|
||||||
|
strcpy(stubDlls[stubIndex], dllName);
|
||||||
|
return (void *) stubFuncs[stubIndex++];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows Thread Information Block
|
// Windows Thread Information Block
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
namespace user32 {
|
||||||
|
int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) {
|
||||||
|
printf("LoadStringA %p %d %d\n", hInstance, uID, cchBufferMax);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *wibo::resolveUser32(const char *name) {
|
||||||
|
if (strcmp(name, "LoadStringA") == 0) return (void *) user32::LoadStringA;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
namespace version {
|
||||||
|
unsigned int WIN_FUNC GetFileVersionInfoSizeA(const char* lptstrFilename, unsigned int* outZero) {
|
||||||
|
printf("GetFileVersionInfoSizeA %s\n", lptstrFilename);
|
||||||
|
*outZero = 0;
|
||||||
|
// stub: signal an error
|
||||||
|
wibo::lastError = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *wibo::resolveVersion(const char *name) {
|
||||||
|
if (strcmp(name, "GetFileVersionInfoSizeA") == 0) return (void *) version::GetFileVersionInfoSizeA;
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue