From b804b9cdb8dbf43e41d9372e450433e39fe534f4 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 24 Feb 2017 14:59:38 +0100 Subject: [PATCH] ADD: @pivipw 's changes "making lua paths". ref:: https://github.com/Proxmark/proxmark3/commit/4197a3f6ff9420673cc2eeaeb3eeedeb4a9c0dc9 This contains a ugly hardcoded hack to solve the issue: https://github.com/Proxmark/proxmark3/issues/217 where GetModuleHandleEx doesn't exist in mingw (old proxspace 2013 environment). Use the docker container or linux... --- client/Makefile | 1 + client/cmdscript.c | 31 ++- client/proxmark3.h | 3 + client/scripting.c | 8 +- client/scripting.h | 5 + client/whereami.c | 662 +++++++++++++++++++++++++++++++++++++++++++++ client/whereami.h | 65 +++++ 7 files changed, 762 insertions(+), 13 deletions(-) create mode 100644 client/whereami.c create mode 100644 client/whereami.h diff --git a/client/Makefile b/client/Makefile index 7e002488..3c7a33fd 100644 --- a/client/Makefile +++ b/client/Makefile @@ -97,6 +97,7 @@ CMDSRCS = mifarehost.c \ loclass/ikeys.c \ loclass/elite_crack.c \ loclass/fileutils.c \ + whereami.c \ parity.c \ crc.c \ crc16.c \ diff --git a/client/cmdscript.c b/client/cmdscript.c index 87544a99..760d74e1 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -30,7 +30,6 @@ #include #include - static int CmdHelp(const char *Cmd); static int CmdList(const char *Cmd); static int CmdRun(const char *Cmd); @@ -64,7 +63,7 @@ int str_ends_with(const char * str, const char * suffix) { */ int CmdHelp(const char * Cmd) { - PrintAndLog("This is a feature to run Lua-scripts. You can place lua-scripts within the ´client/scripts/´ folder."); + PrintAndLog("This is a feature to run Lua-scripts. You can place lua-scripts within the scripts/-folder. "); return 0; } @@ -76,19 +75,24 @@ int CmdHelp(const char * Cmd) */ int CmdList(const char *Cmd) { + DIR *dp; struct dirent *ep; - DIR *dp = opendir ("./scripts/"); - if ( dp == NULL ) { - PrintAndLog ("Couldn't open the scripts-directory"); - return 1; - } + char script_directory_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + 1]; + strcpy(script_directory_path, get_my_executable_directory()); + strcat(script_directory_path, LUA_SCRIPTS_DIRECTORY); + dp = opendir(script_directory_path); + if (dp != NULL) + { while ((ep = readdir (dp)) != NULL) { if(str_ends_with(ep->d_name, ".lua")) PrintAndLog("%-21s %s", ep->d_name, "A script file"); } (void) closedir (dp); + } + else + PrintAndLog ("Couldn't open the scripts-directory"); return 0; } @@ -150,14 +154,19 @@ int CmdRun(const char *Cmd) suffix = ".lua"; } - char buf[256]; - snprintf(buf, sizeof buf, "./scripts/%s%s", script_name, suffix); + char script_path[strlen(get_my_executable_directory()) + strlen(LUA_SCRIPTS_DIRECTORY) + strlen(script_name) + strlen(suffix) + 1]; + strcpy(script_path, get_my_executable_directory()); + strcat(script_path, LUA_SCRIPTS_DIRECTORY); + strcat(script_path, script_name); + strcat(script_path, suffix); + + printf("--- Executing: %s%s, args '%s'\n", script_name, suffix, arguments); + - printf("--- Executing: %s, args'%s'\n", buf, arguments); // run the Lua script - int error = luaL_loadfile(lua_state, buf); + int error = luaL_loadfile(lua_state, script_path); if(!error) { lua_pushstring(lua_state, arguments); diff --git a/client/proxmark3.h b/client/proxmark3.h index d8887197..15049ee3 100644 --- a/client/proxmark3.h +++ b/client/proxmark3.h @@ -30,4 +30,7 @@ #define PROXPROMPT "pm3 --> " void SendCommand(UsbCommand *c); +const char const *get_my_executable_path(void); +const char const *get_my_executable_directory(void); + #endif \ No newline at end of file diff --git a/client/scripting.c b/client/scripting.c index f35707fe..d04c88ea 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -221,10 +221,10 @@ static int l_iso14443b_crc(lua_State *L) unsigned char *TransmitFirst, unsigned char *TransmitSecond) */ + unsigned char buf[USB_CMD_DATA_SIZE] = {0x00}; size_t size = 0; const char *data = luaL_checklstring(L, 1, &size); - unsigned char buf[USB_CMD_DATA_SIZE] = {0x00}; for (int i = 0; i < size; i += 2) sscanf(&data[i], "%02x", (unsigned int *)&buf[i / 2]); @@ -605,7 +605,11 @@ int set_pm3_libraries(lua_State *L) //-- Last but not least, add to the LUA_PATH (package.path in lua) // so we can load libraries from the ./lualib/ - directory - setLuaPath(L,"./lualibs/?.lua"); + char libraries_path[strlen(get_my_executable_directory()) + strlen(LUA_LIBRARIES_DIRECTORY) + strlen(LUA_LIBRARIES_WILDCARD) + 1]; + strcpy(libraries_path, get_my_executable_directory()); + strcat(libraries_path, LUA_LIBRARIES_DIRECTORY); + strcat(libraries_path, LUA_LIBRARIES_WILDCARD); + setLuaPath(L, libraries_path); return 1; } diff --git a/client/scripting.h b/client/scripting.h index fadb81f5..5b286760 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -28,6 +28,11 @@ #include "cmdcrc.h" #include "cmdhfmfhard.h" + +#define LUA_LIBRARIES_DIRECTORY "lualibs/" +#define LUA_SCRIPTS_DIRECTORY "scripts/" +#define LUA_LIBRARIES_WILDCARD "?.lua" + /** * @brief set_libraries loads the core components of pm3 into the 'pm3' * namespace within the given lua_State diff --git a/client/whereami.c b/client/whereami.c new file mode 100644 index 00000000..05f58e25 --- /dev/null +++ b/client/whereami.c @@ -0,0 +1,662 @@ +// (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz) +// https://github.com/gpakosz/whereami + +// in case you want to #include "whereami.c" in a larger compilation unit +#if !defined(WHEREAMI_H) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC) +#include +#endif + +#if !defined(WAI_MALLOC) +#define WAI_MALLOC(size) malloc(size) +#endif + +#if !defined(WAI_FREE) +#define WAI_FREE(p) free(p) +#endif + +#if !defined(WAI_REALLOC) +#define WAI_REALLOC(p, size) realloc(p, size) +#endif + +#ifndef WAI_NOINLINE +#if defined(_MSC_VER) +#define WAI_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) +#define WAI_NOINLINE __attribute__((noinline)) +#else +#error unsupported compiler +#endif +#endif + +#if defined(_MSC_VER) +#define WAI_RETURN_ADDRESS() _ReturnAddress() +#elif defined(__GNUC__) +#define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0)) +#else +#error unsupported compiler +#endif + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#if defined(_MSC_VER) +#pragma warning(push, 3) +#endif +#include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length) +{ + wchar_t buffer1[MAX_PATH]; + wchar_t buffer2[MAX_PATH]; + wchar_t* path = NULL; + int length = -1; + + for (;;) + { + DWORD size; + int length_, length__; + + size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0])); + + if (size == 0) + break; + else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0]))) + { + DWORD size_ = size; + do + { + wchar_t* path_; + + path_ = (wchar_t*)WAI_REALLOC(path, sizeof(wchar_t) * size_ * 2); + if (!path_) + break; + size_ *= 2; + path = path_; + size = GetModuleFileNameW(module, path, size_); + } + while (size == size_); + + if (size == size_) + break; + } + else + path = buffer1; + + if (!_wfullpath(buffer2, path, MAX_PATH)) + break; + length_ = (int)wcslen(buffer2); + length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_ , out, capacity, NULL, NULL); + + if (length__ == 0) + length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, NULL, 0, NULL, NULL); + if (length__ == 0) + break; + + if (length__ <= capacity && dirname_length) + { + int i; + + for (i = length__ - 1; i >= 0; --i) + { + if (out[i] == '\\') + { + *dirname_length = i; + break; + } + } + } + + length = length__; + + break; + } + + if (path != buffer1) + WAI_FREE(path); + + return length; +} + +WAI_NOINLINE +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + return WAI_PREFIX(getModulePath_)(NULL, out, capacity, dirname_length); +} + +WAI_NOINLINE +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) +{ + HMODULE module; + int length = -1; + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable: 4054) +#endif +// if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module)) + module = GetModuleHandle("proxmark3.exe"); +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + { + length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length); + } + + return length; +} + +#elif defined(__linux__) + +#include +#include +#include +#include +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#include + +#if !defined(WAI_PROC_SELF_EXE) +#define WAI_PROC_SELF_EXE "/proc/self/exe" +#endif + +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + char buffer[PATH_MAX]; + char* resolved = NULL; + int length = -1; + + for (;;) + { + resolved = realpath(WAI_PROC_SELF_EXE, buffer); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + + break; + } + + return length; +} + +#if !defined(WAI_PROC_SELF_MAPS_RETRY) +#define WAI_PROC_SELF_MAPS_RETRY 5 +#endif + +#if !defined(WAI_PROC_SELF_MAPS) +#define WAI_PROC_SELF_MAPS "/proc/self/maps" +#endif + +#if defined(__ANDROID__) || defined(ANDROID) +#include +#include +#endif + +WAI_NOINLINE +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) +{ + int length = -1; + FILE* maps = NULL; + int i; + + for (i = 0; i < WAI_PROC_SELF_MAPS_RETRY; ++i) + { + maps = fopen(WAI_PROC_SELF_MAPS, "r"); + if (!maps) + break; + + for (;;) + { + char buffer[PATH_MAX < 1024 ? 1024 : PATH_MAX]; + uint64_t low, high; + char perms[5]; + uint64_t offset; + uint32_t major, minor; + char path[PATH_MAX]; + uint32_t inode; + + if (!fgets(buffer, sizeof(buffer), maps)) + break; + + if (sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8) + { + uint64_t addr = (uint64_t)(uintptr_t)WAI_RETURN_ADDRESS(); + if (low <= addr && addr <= high) + { + char* resolved; + + resolved = realpath(path, buffer); + if (!resolved) + break; + + length = (int)strlen(resolved); +#if defined(__ANDROID__) || defined(ANDROID) + if (length > 4 + &&buffer[length - 1] == 'k' + &&buffer[length - 2] == 'p' + &&buffer[length - 3] == 'a' + &&buffer[length - 4] == '.') + { + int fd = open(path, O_RDONLY); + char* begin; + char* p; + + begin = (char*)mmap(0, offset, PROT_READ, MAP_SHARED, fd, 0); + p = begin + offset; + + while (p >= begin) // scan backwards + { + if (*((uint32_t*)p) == 0x04034b50UL) // local file header found + { + uint16_t length_ = *((uint16_t*)(p + 26)); + + if (length + 2 + length_ < (int)sizeof(buffer)) + { + memcpy(&buffer[length], "!/", 2); + memcpy(&buffer[length + 2], p + 30, length_); + length += 2 + length_; + } + + break; + } + + p -= 4; + } + + munmap(begin, offset); + close(fd); + } +#endif + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + + break; + } + } + } + + fclose(maps); + + if (length != -1) + break; + } + + return length; +} + +#elif defined(__APPLE__) + +#define _DARWIN_BETTER_REALPATH +#include +#include +#include +#include +#include + +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + char buffer1[PATH_MAX]; + char buffer2[PATH_MAX]; + char* path = buffer1; + char* resolved = NULL; + int length = -1; + + for (;;) + { + uint32_t size = (uint32_t)sizeof(buffer1); + if (_NSGetExecutablePath(path, &size) == -1) + { + path = (char*)WAI_MALLOC(size); + if (!_NSGetExecutablePath(path, &size)) + break; + } + + resolved = realpath(path, buffer2); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + + break; + } + + if (path != buffer1) + WAI_FREE(path); + + return length; +} + +WAI_NOINLINE +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) +{ + char buffer[PATH_MAX]; + char* resolved = NULL; + int length = -1; + + for(;;) + { + Dl_info info; + + if (dladdr(WAI_RETURN_ADDRESS(), &info)) + { + resolved = realpath(info.dli_fname, buffer); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + } + + break; + } + + return length; +} + +#elif defined(__QNXNTO__) + +#include +#include +#include +#include +#include + +#if !defined(WAI_PROC_SELF_EXE) +#define WAI_PROC_SELF_EXE "/proc/self/exefile" +#endif + +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + char buffer1[PATH_MAX]; + char buffer2[PATH_MAX]; + char* resolved = NULL; + FILE* self_exe = NULL; + int length = -1; + + for (;;) + { + self_exe = fopen(WAI_PROC_SELF_EXE, "r"); + if (!self_exe) + break; + + if (!fgets(buffer1, sizeof(buffer1), self_exe)) + break; + + resolved = realpath(buffer1, buffer2); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + + break; + } + + fclose(self_exe); + + return length; +} + +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) +{ + char buffer[PATH_MAX]; + char* resolved = NULL; + int length = -1; + + for(;;) + { + Dl_info info; + + if (dladdr(WAI_RETURN_ADDRESS(), &info)) + { + resolved = realpath(info.dli_fname, buffer); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + } + + break; + } + + return length; +} + +#elif defined(__DragonFly__) || defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__NetBSD__) + +#include +#include +#include +#include +#include +#include + +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length) +{ + char buffer1[PATH_MAX]; + char buffer2[PATH_MAX]; + char* path = buffer1; + char* resolved = NULL; + int length = -1; + + for (;;) + { + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + size_t size = sizeof(buffer1); + + if (sysctl(mib, (u_int)(sizeof(mib) / sizeof(mib[0])), path, &size, NULL, 0) != 0) + break; + + resolved = realpath(path, buffer2); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + + break; + } + + if (path != buffer1) + WAI_FREE(path); + + return length; +} + +WAI_NOINLINE +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length) +{ + char buffer[PATH_MAX]; + char* resolved = NULL; + int length = -1; + + for(;;) + { + Dl_info info; + + if (dladdr(WAI_RETURN_ADDRESS(), &info)) + { + resolved = realpath(info.dli_fname, buffer); + if (!resolved) + break; + + length = (int)strlen(resolved); + if (length <= capacity) + { + memcpy(out, resolved, length); + + if (dirname_length) + { + int i; + + for (i = length - 1; i >= 0; --i) + { + if (out[i] == '/') + { + *dirname_length = i; + break; + } + } + } + } + } + + break; + } + + return length; +} + +#else + +#error unsupported platform + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/client/whereami.h b/client/whereami.h new file mode 100644 index 00000000..6c81af81 --- /dev/null +++ b/client/whereami.h @@ -0,0 +1,65 @@ +// (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz) +// https://github.com/gpakosz/whereami + +#ifndef WHEREAMI_H +#define WHEREAMI_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WAI_FUNCSPEC + #define WAI_FUNCSPEC +#endif +#ifndef WAI_PREFIX +#define WAI_PREFIX(function) wai_##function +#endif + +/** + * Returns the path to the current executable. + * + * Usage: + * - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to + * retrieve the length of the path + * - allocate the destination buffer with `path = (char*)malloc(length + 1);` + * - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the + * path + * - add a terminal NUL character with `path[length] = '\0';` + * + * @param out destination buffer, optional + * @param capacity destination buffer capacity + * @param dirname_length optional recipient for the length of the dirname part + * of the path. + * + * @return the length of the executable path on success (without a terminal NUL + * character), otherwise `-1` + */ +WAI_FUNCSPEC +int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length); + +/** + * Returns the path to the current module + * + * Usage: + * - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve + * the length of the path + * - allocate the destination buffer with `path = (char*)malloc(length + 1);` + * - call `wai_getModulePath(path, length, NULL)` again to retrieve the path + * - add a terminal NUL character with `path[length] = '\0';` + * + * @param out destination buffer, optional + * @param capacity destination buffer capacity + * @param dirname_length optional recipient for the length of the dirname part + * of the path. + * + * @return the length of the module path on success (without a terminal NUL + * character), otherwise `-1` + */ +WAI_FUNCSPEC +int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length); + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef WHEREAMI_H -- 2.39.2