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)
|
||||
|
||||
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.
|
||||
|
||||
|
|
3
common.h
3
common.h
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define WIN_FUNC __attribute__((stdcall))
|
||||
|
||||
|
@ -10,7 +11,9 @@ namespace wibo {
|
|||
extern uint32_t lastError;
|
||||
extern char *commandLine;
|
||||
|
||||
void *resolveVersion(const char *name);
|
||||
void *resolveKernel32(const char *name);
|
||||
void *resolveUser32(const char *name);
|
||||
void *resolveAdvApi32(const char *name);
|
||||
void *resolveStubByName(const char *dllName, const char *funcName);
|
||||
void *resolveStubByOrdinal(const char *dllName, uint16_t ordinal);
|
||||
|
|
63
kernel32.cpp
63
kernel32.cpp
|
@ -291,6 +291,60 @@ namespace kernel32 {
|
|||
strcpy(lpBuffer, "C:\\Windows");
|
||||
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) {
|
||||
|
@ -318,5 +372,14 @@ void *wibo::resolveKernel32(const char *name) {
|
|||
if (strcmp(name, "GetConsoleScreenBufferInfo") == 0) return (void *) kernel32::GetConsoleScreenBufferInfo;
|
||||
if (strcmp(name, "GetSystemDirectoryA") == 0) return (void *) kernel32::GetSystemDirectoryA;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ bool wibo::Executable::loadPE(FILE *file) {
|
|||
printf("Image Base: %x / Size: %x\n", header32.imageBase, header32.sizeOfImage);
|
||||
|
||||
long pageSize = sysconf(_SC_PAGE_SIZE);
|
||||
printf("Page size: %x\n", pageSize);
|
||||
printf("Page size: %x\n", (unsigned int)pageSize);
|
||||
|
||||
// Build buffer
|
||||
imageSize = header32.sizeOfImage;
|
||||
|
|
47
main.cpp
47
main.cpp
|
@ -8,13 +8,32 @@
|
|||
uint32_t wibo::lastError = 0;
|
||||
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
|
||||
// and create template stubs for them, at least...
|
||||
printf("Unhandled function\n");
|
||||
printf("Unhandled function %s (%s)\n", stubFuncNames[index], stubDlls[index]);
|
||||
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) {
|
||||
printf("CoInitialize(...)\n");
|
||||
return 0; // S_OK I think?
|
||||
|
@ -26,21 +45,41 @@ void *wibo::resolveStubByName(const char *dllName, const char *funcName) {
|
|||
if (func)
|
||||
return func;
|
||||
}
|
||||
if (strcmp(dllName, "USER32.dll") == 0) {
|
||||
void *func = wibo::resolveUser32(funcName);
|
||||
if (func)
|
||||
return func;
|
||||
}
|
||||
if (strcmp(dllName, "ADVAPI32.dll") == 0) {
|
||||
void *func = wibo::resolveAdvApi32(funcName);
|
||||
if (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(funcName, "CoInitialize") == 0) return (void *) CoInitialize;
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
|
|
|
@ -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