From: misomosi Date: Tue, 7 May 2024 01:54:50 +0000 (-0400) Subject: Add POSIX implementation X-Git-Url: http://git.misomosispi.com/?a=commitdiff_plain;h=c2dd6d300469bdcdf975ac80926189aeaf4dc53c;p=pldh.git Add POSIX implementation --- diff --git a/README.md b/README.md index 9a52158..f11cef5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # pld.h Functions and logging generally useful for preloads + + diff --git a/examples/printf.c b/examples/printf.c new file mode 100644 index 0000000..7cdb93d --- /dev/null +++ b/examples/printf.c @@ -0,0 +1,8 @@ +#include "../pld.h" +#include +PLD("libc.so.6"); +int main(void) +{ + PFN(printf)("Hello World! %d\n", 2); + return 0; +} diff --git a/examples/writefile.c b/examples/writefile.c index 3528609..5f6e4b3 100644 --- a/examples/writefile.c +++ b/examples/writefile.c @@ -1,6 +1,6 @@ #include "../pld.h" -PLD(KERNEL32.DLL) +PLD("KERNEL32.DLL") int main(void) { DWORD dummy; PFN(WriteFile)(GetStdHandle(STD_OUTPUT_HANDLE), "Hello World!\n", 13, &dummy, NULL); diff --git a/pld.h b/pld.h index dd67f04..7c50c95 100644 --- a/pld.h +++ b/pld.h @@ -15,11 +15,12 @@ static int PLD_Private_strlen(const char *s) return len - 1; } -static void PLD_Private_Log(const char *, const char *, int); #ifdef _WIN32 #include +typedef DWORD PLD_ErrCode; +static void PLD_Private_Log(const char *, const char *, PLD_ErrCode); static void PLD_Private_WriteString(const char *s) { @@ -27,7 +28,7 @@ static void PLD_Private_WriteString(const char *s) WriteFile(GetStdHandle(STD_ERROR_HANDLE), s, PLD_Private_strlen(s), &dummy, NULL); } -static void PLD_Private_FormatError(int code, char *s, int len) +static void PLD_Private_FormatError(DWORD code, char *s, int len) { DWORD_PTR arg = (DWORD_PTR)s; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, @@ -42,12 +43,13 @@ static void PLD_Private_FormatError(int code, char *s, int len) static HMODULE PLD_Private_LoadLibrary_wrapper(LPCSTR lpLibFileName) { HMODULE hModule = GetModuleHandleA(lpLibFileName); - if (hModule != NULL) + if (hModule == NULL) hModule = LoadLibraryA(lpLibFileName); if (hModule == NULL) PLD_Private_Log("Failed to load library!", lpLibFileName, GetLastError()); return hModule; } + static FARPROC PLD_Private_GetProcAddress_wrapper(HMODULE hModule, LPCSTR lpProcName) { FARPROC lpProc = GetProcAddress(hModule, lpProcName); @@ -59,17 +61,66 @@ static FARPROC PLD_Private_GetProcAddress_wrapper(HMODULE hModule, LPCSTR lpProc #define PLD(name) \ static HMODULE PLDH(void) { \ static HMODULE hModule = NULL; \ - if (hModule == NULL) hModule = PLD_Private_LoadLibrary_wrapper(#name); \ + if (hModule == NULL) hModule = PLD_Private_LoadLibrary_wrapper(name); \ return hModule; \ } \ -#define PFN(name) ((PLDTYPEOF(name))PLD_Private_GetProcAddress_wrapper(PLDH(), #name)) +#define PFN(name) ((PLDTYPEOF(&name))PLD_Private_GetProcAddress_wrapper(PLDH(), #name)) #else -#error POSIX Unimplemented! + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +typedef intptr_t PLD_ErrCode; +static void PLD_Private_Log(const char *, const char *, PLD_ErrCode); + +static void PLD_Private_WriteString(const char *s) +{ + write(2, s, PLD_Private_strlen(s)); +} + +static void PLD_Private_FormatError(intptr_t code, char *s, int len) +{ + *s = 0; + strncat(s, (const char *)code, len); +} + +static void *PLD_Private_dlopen_wrapper(const char *name) +{ + if (name == NULL) + return (void *)RTLD_NEXT; + void *handle = dlopen(name, RTLD_NOLOAD); + if (handle == NULL) + handle = dlopen(name, RTLD_LAZY); + if (handle == NULL) + PLD_Private_Log("Failed to load library!", name, (intptr_t)dlerror()); + return handle; +} + +static void *PLD_Private_dlsym_wrapper(void *handle, const char *name) +{ + void *sym = dlsym(handle, name); + if (sym == NULL) + PLD_Private_Log("Failed to load procedure!", name, (intptr_t)dlerror()); + return sym; +} + +#define PLD(name) \ + static void *PLDH(void) { \ + static void *handle = NULL; \ + if (handle == NULL) handle = PLD_Private_dlopen_wrapper(name); \ + return handle; \ + } \ + +#define PFN(name) ((PLDTYPEOF(&name))PLD_Private_dlsym_wrapper(PLDH(), #name)) + #endif -static void PLD_Private_Log(const char *message, const char *name, int err) +static void PLD_Private_Log(const char *message, const char *name, PLD_ErrCode err) { PLD_Private_WriteString(message); PLD_Private_WriteString(" "); @@ -82,6 +133,11 @@ static void PLD_Private_Log(const char *message, const char *name, int err) char errtext[256]; PLD_Private_FormatError(err, errtext, sizeof(errtext)); PLD_Private_WriteString(errtext); + + // An extra newline because dlerror doesn't append one +#ifndef _WIN32 + PLD_Private_WriteString("\n"); +#endif } #ifndef PLDLOG