This commit is contained in:
Simon Lindholm 2022-06-28 23:08:23 +02:00
parent d1a4fd35a7
commit 3fd1f6a30c
7 changed files with 140 additions and 6 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -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

13
user32.cpp Normal file
View File

@ -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;
}

16
version.cpp Normal file
View File

@ -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;
}