2023-09-10 03:07:23 +00:00
|
|
|
#include <cassert>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
#include <string>
|
2022-07-06 02:26:24 +00:00
|
|
|
#include <sys/stat.h>
|
2022-06-13 00:20:18 +00:00
|
|
|
#include <unistd.h>
|
2023-09-22 00:13:56 +00:00
|
|
|
#include <vector>
|
2023-10-02 03:56:35 +00:00
|
|
|
#include <memory>
|
2022-06-13 00:20:18 +00:00
|
|
|
|
2023-01-23 15:36:14 +00:00
|
|
|
// On Windows, the incoming stack is aligned to a 4 byte boundary.
|
|
|
|
// force_align_arg_pointer will realign the stack to match GCC's 16 byte alignment.
|
2023-01-23 20:22:50 +00:00
|
|
|
#define WIN_ENTRY __attribute__((force_align_arg_pointer, callee_pop_aggregate_return(0)))
|
2023-01-23 15:36:14 +00:00
|
|
|
#define WIN_FUNC WIN_ENTRY __attribute__((stdcall))
|
2022-06-29 11:19:45 +00:00
|
|
|
#define DEBUG_LOG(...) wibo::debug_log(__VA_ARGS__)
|
2022-06-13 00:20:18 +00:00
|
|
|
|
2023-09-10 03:07:23 +00:00
|
|
|
typedef void *HANDLE;
|
|
|
|
typedef void *HMODULE;
|
|
|
|
typedef void *PVOID;
|
|
|
|
typedef void *LPVOID;
|
|
|
|
typedef void *FARPROC;
|
|
|
|
typedef uint32_t DWORD;
|
|
|
|
typedef DWORD *PDWORD;
|
|
|
|
typedef DWORD *LPDWORD;
|
|
|
|
typedef int32_t LONG;
|
|
|
|
typedef LONG *PLONG;
|
|
|
|
typedef uint32_t ULONG;
|
|
|
|
typedef ULONG *PULONG;
|
|
|
|
typedef int64_t LARGE_INTEGER;
|
|
|
|
typedef LARGE_INTEGER *PLARGE_INTEGER;
|
|
|
|
typedef uintptr_t ULONG_PTR;
|
|
|
|
typedef char *LPSTR;
|
|
|
|
typedef const char *LPCSTR;
|
|
|
|
typedef uint16_t *LPWSTR;
|
|
|
|
typedef const uint16_t *LPCWSTR;
|
|
|
|
typedef int BOOL;
|
|
|
|
typedef BOOL *PBOOL;
|
|
|
|
typedef unsigned char UCHAR;
|
|
|
|
typedef UCHAR *PUCHAR;
|
|
|
|
typedef size_t SIZE_T;
|
|
|
|
typedef SIZE_T *PSIZE_T;
|
|
|
|
typedef unsigned char BYTE;
|
|
|
|
|
|
|
|
#define TRUE 1
|
|
|
|
#define FALSE 0
|
|
|
|
|
|
|
|
#define ERROR_SUCCESS 0
|
|
|
|
#define ERROR_FILE_NOT_FOUND 2
|
|
|
|
#define ERROR_PATH_NOT_FOUND 3
|
|
|
|
#define ERROR_ACCESS_DENIED 5
|
|
|
|
#define ERROR_INVALID_HANDLE 6
|
2023-10-08 17:08:53 +00:00
|
|
|
#define ERROR_NO_MORE_FILES 18
|
2023-09-10 03:07:23 +00:00
|
|
|
#define ERROR_READ_FAULT 30
|
|
|
|
#define ERROR_HANDLE_EOF 38
|
|
|
|
#define ERROR_NOT_SUPPORTED 50
|
|
|
|
#define ERROR_INVALID_PARAMETER 87
|
2023-10-02 03:56:35 +00:00
|
|
|
#define ERROR_INSUFFICIENT_BUFFER 122
|
2023-09-10 03:07:23 +00:00
|
|
|
#define ERROR_NEGATIVE_SEEK 131
|
|
|
|
#define ERROR_ALREADY_EXISTS 183
|
|
|
|
|
|
|
|
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
|
|
|
|
#define INVALID_HANDLE_VALUE ((HANDLE)-1)
|
|
|
|
|
|
|
|
typedef int NTSTATUS;
|
|
|
|
#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
|
|
|
|
#define STATUS_INVALID_HANDLE ((NTSTATUS)0xC0000008)
|
|
|
|
#define STATUS_END_OF_FILE ((NTSTATUS)0xC0000011)
|
|
|
|
#define STATUS_NOT_SUPPORTED ((NTSTATUS)0xC00000BB)
|
|
|
|
#define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS)0xC00000E9)
|
|
|
|
|
|
|
|
typedef int HRESULT;
|
|
|
|
#define S_OK ((HRESULT)0x00000000)
|
2022-07-27 10:28:29 +00:00
|
|
|
|
2022-06-13 00:20:18 +00:00
|
|
|
namespace wibo {
|
|
|
|
extern uint32_t lastError;
|
2023-09-10 03:07:23 +00:00
|
|
|
extern char **argv;
|
|
|
|
extern int argc;
|
2023-09-18 06:05:47 +00:00
|
|
|
extern char *executableName;
|
2022-06-13 00:20:18 +00:00
|
|
|
extern char *commandLine;
|
2023-09-22 00:13:56 +00:00
|
|
|
extern std::vector<uint16_t> commandLineW;
|
2022-06-29 13:24:58 +00:00
|
|
|
extern bool debugEnabled;
|
2023-09-18 06:05:47 +00:00
|
|
|
extern unsigned int debugIndent;
|
2022-06-13 00:20:18 +00:00
|
|
|
|
2022-06-28 23:29:26 +00:00
|
|
|
void debug_log(const char *fmt, ...);
|
|
|
|
|
2023-09-10 03:07:23 +00:00
|
|
|
using ResolveByName = void *(*)(const char *);
|
|
|
|
using ResolveByOrdinal = void *(*)(uint16_t);
|
|
|
|
struct Module {
|
|
|
|
const char** names;
|
|
|
|
ResolveByName byName;
|
|
|
|
ResolveByOrdinal byOrdinal;
|
|
|
|
};
|
|
|
|
extern const Module *modules[];
|
|
|
|
|
|
|
|
HMODULE loadModule(const char *name);
|
|
|
|
void freeModule(HMODULE module);
|
|
|
|
void *resolveFuncByName(HMODULE module, const char *funcName);
|
|
|
|
void *resolveFuncByOrdinal(HMODULE module, uint16_t ordinal);
|
2022-06-13 00:20:18 +00:00
|
|
|
|
|
|
|
struct Executable {
|
|
|
|
Executable();
|
|
|
|
~Executable();
|
2023-10-02 03:56:35 +00:00
|
|
|
bool loadPE(FILE *file, bool exec);
|
2022-06-13 00:20:18 +00:00
|
|
|
|
|
|
|
void *imageBuffer;
|
|
|
|
size_t imageSize;
|
|
|
|
void *entryPoint;
|
2022-06-29 11:19:45 +00:00
|
|
|
void *rsrcBase;
|
2022-06-13 00:20:18 +00:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T *fromRVA(uint32_t rva) {
|
|
|
|
return (T *) (rva + (uint8_t *) imageBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T *fromRVA(T *rva) {
|
|
|
|
return fromRVA<T>((uint32_t) rva);
|
|
|
|
}
|
|
|
|
};
|
2023-10-02 03:56:35 +00:00
|
|
|
struct ModuleInfo {
|
|
|
|
std::string name;
|
|
|
|
const wibo::Module* module = nullptr;
|
|
|
|
std::unique_ptr<wibo::Executable> executable;
|
|
|
|
};
|
2022-06-29 11:19:45 +00:00
|
|
|
|
|
|
|
extern Executable *mainModule;
|
2023-10-02 03:56:35 +00:00
|
|
|
Executable *executableFromModule(HMODULE module);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* HMODULE will be `nullptr` or `mainModule->imageBuffer` if it's the main module,
|
|
|
|
* otherwise it will be a pointer to a `wibo::ModuleInfo`.
|
|
|
|
*/
|
|
|
|
inline bool isMainModule(HMODULE hModule) {
|
|
|
|
return hModule == nullptr || hModule == mainModule->imageBuffer;
|
|
|
|
}
|
|
|
|
} // namespace wibo
|