]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/whereami.c
1 // (‑●‑●)> released under the WTFPL v2 license, by Gregory Pakosz (@gpakosz)
2 // https://github.com/gpakosz/whereami
4 // in case you want to #include "whereami.c" in a larger compilation unit
5 #if !defined(WHEREAMI_H)
13 #define _DEFAULT_SOURCE
15 #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
19 #if !defined(WAI_MALLOC)
20 #define WAI_MALLOC(size) malloc(size)
23 #if !defined(WAI_FREE)
24 #define WAI_FREE(p) free(p)
27 #if !defined(WAI_REALLOC)
28 #define WAI_REALLOC(p, size) realloc(p, size)
33 #define WAI_NOINLINE __declspec(noinline)
34 #elif defined(__GNUC__)
35 #define WAI_NOINLINE __attribute__((noinline))
37 #error unsupported compiler
42 #define WAI_RETURN_ADDRESS() _ReturnAddress()
43 #elif defined(__GNUC__)
44 #define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0))
46 #error unsupported compiler
51 #define WIN32_LEAN_AND_MEAN
53 #pragma warning(push, 3)
60 static int WAI_PREFIX(getModulePath_
)(HMODULE module
, char* out
, int capacity
, int* dirname_length
)
62 wchar_t buffer1
[MAX_PATH
];
63 wchar_t buffer2
[MAX_PATH
];
70 int length_
, length__
;
72 size
= GetModuleFileNameW(module
, buffer1
, sizeof(buffer1
) / sizeof(buffer1
[0]));
76 else if (size
== (DWORD
)(sizeof(buffer1
) / sizeof(buffer1
[0])))
83 path_
= (wchar_t*)WAI_REALLOC(path
, sizeof(wchar_t) * size_
* 2);
88 size
= GetModuleFileNameW(module
, path
, size_
);
90 while (size
== size_
);
98 if (!_wfullpath(buffer2
, path
, MAX_PATH
))
100 length_
= (int)wcslen(buffer2
);
101 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, out
, capacity
, NULL
, NULL
);
104 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, NULL
, 0, NULL
, NULL
);
108 if (length__
<= capacity
&& dirname_length
)
112 for (i
= length__
- 1; i
>= 0; --i
)
135 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
137 return WAI_PREFIX(getModulePath_
)(NULL
, out
, capacity
, dirname_length
);
143 int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
148 #if defined(_MSC_VER)
149 #pragma warning(push)
150 #pragma warning(disable: 4054)
152 if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module))
153 #if defined(_MSC_VER)
157 length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length);
164 #elif defined(__linux__)
168 #include <linux/limits.h>
169 #ifndef __STDC_FORMAT_MACROS
170 #define __STDC_FORMAT_MACROS
172 #include <inttypes.h>
174 #if !defined(WAI_PROC_SELF_EXE)
175 #define WAI_PROC_SELF_EXE "/proc/self/exe"
179 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
181 char buffer
[PATH_MAX
];
182 char* resolved
= NULL
;
187 resolved
= realpath(WAI_PROC_SELF_EXE
, buffer
);
191 length
= (int)strlen(resolved
);
192 if (length
<= capacity
)
194 memcpy(out
, resolved
, length
);
200 for (i
= length
- 1; i
>= 0; --i
)
217 #if !defined(WAI_PROC_SELF_MAPS_RETRY)
218 #define WAI_PROC_SELF_MAPS_RETRY 5
221 #if !defined(WAI_PROC_SELF_MAPS)
222 #define WAI_PROC_SELF_MAPS "/proc/self/maps"
225 #if defined(__ANDROID__) || defined(ANDROID)
227 #include <sys/mman.h>
232 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
238 for (i
= 0; i
< WAI_PROC_SELF_MAPS_RETRY
; ++i
)
240 maps
= fopen(WAI_PROC_SELF_MAPS
, "r");
246 char buffer
[PATH_MAX
< 1024 ? 1024 : PATH_MAX
];
250 uint32_t major
, minor
;
254 if (!fgets(buffer
, sizeof(buffer
), maps
))
257 if (sscanf(buffer
, "%" PRIx64
"-%" PRIx64
" %s %" PRIx64
" %x:%x %u %s\n", &low
, &high
, perms
, &offset
, &major
, &minor
, &inode
, path
) == 8)
259 uint64_t addr
= (uint64_t)(uintptr_t)WAI_RETURN_ADDRESS();
260 if (low
<= addr
&& addr
<= high
)
264 resolved
= realpath(path
, buffer
);
268 length
= (int)strlen(resolved
);
269 #if defined(__ANDROID__) || defined(ANDROID)
271 &&buffer
[length
- 1] == 'k'
272 &&buffer
[length
- 2] == 'p'
273 &&buffer
[length
- 3] == 'a'
274 &&buffer
[length
- 4] == '.')
276 int fd
= open(path
, O_RDONLY
);
280 begin
= (char*)mmap(0, offset
, PROT_READ
, MAP_SHARED
, fd
, 0);
283 while (p
>= begin
) // scan backwards
285 if (*((uint32_t*)p
) == 0x04034b50UL
) // local file header found
287 uint16_t length_
= *((uint16_t*)(p
+ 26));
289 if (length
+ 2 + length_
< (int)sizeof(buffer
))
291 memcpy(&buffer
[length
], "!/", 2);
292 memcpy(&buffer
[length
+ 2], p
+ 30, length_
);
293 length
+= 2 + length_
;
302 munmap(begin
, offset
);
306 if (length
<= capacity
)
308 memcpy(out
, resolved
, length
);
314 for (i
= length
- 1; i
>= 0; --i
)
339 #elif defined(__APPLE__)
341 #define _DARWIN_BETTER_REALPATH
342 #include <mach-o/dyld.h>
349 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
351 char buffer1
[PATH_MAX
];
352 char buffer2
[PATH_MAX
];
353 char* path
= buffer1
;
354 char* resolved
= NULL
;
359 uint32_t size
= (uint32_t)sizeof(buffer1
);
360 if (_NSGetExecutablePath(path
, &size
) == -1)
362 path
= (char*)WAI_MALLOC(size
);
363 if (!_NSGetExecutablePath(path
, &size
))
367 resolved
= realpath(path
, buffer2
);
371 length
= (int)strlen(resolved
);
372 if (length
<= capacity
)
374 memcpy(out
, resolved
, length
);
380 for (i
= length
- 1; i
>= 0; --i
)
402 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
404 char buffer
[PATH_MAX
];
405 char* resolved
= NULL
;
412 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
414 resolved
= realpath(info
.dli_fname
, buffer
);
418 length
= (int)strlen(resolved
);
419 if (length
<= capacity
)
421 memcpy(out
, resolved
, length
);
427 for (i
= length
- 1; i
>= 0; --i
)
445 #elif defined(__QNXNTO__)
453 #if !defined(WAI_PROC_SELF_EXE)
454 #define WAI_PROC_SELF_EXE "/proc/self/exefile"
458 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
460 char buffer1
[PATH_MAX
];
461 char buffer2
[PATH_MAX
];
462 char* resolved
= NULL
;
463 FILE* self_exe
= NULL
;
468 self_exe
= fopen(WAI_PROC_SELF_EXE
, "r");
472 if (!fgets(buffer1
, sizeof(buffer1
), self_exe
))
475 resolved
= realpath(buffer1
, buffer2
);
479 length
= (int)strlen(resolved
);
480 if (length
<= capacity
)
482 memcpy(out
, resolved
, length
);
488 for (i
= length
- 1; i
>= 0; --i
)
508 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
510 char buffer
[PATH_MAX
];
511 char* resolved
= NULL
;
518 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
520 resolved
= realpath(info
.dli_fname
, buffer
);
524 length
= (int)strlen(resolved
);
525 if (length
<= capacity
)
527 memcpy(out
, resolved
, length
);
533 for (i
= length
- 1; i
>= 0; --i
)
551 #elif defined(__DragonFly__) || defined(__FreeBSD__) || \
552 defined(__FreeBSD_kernel__) || defined(__NetBSD__)
557 #include <sys/types.h>
558 #include <sys/sysctl.h>
562 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
564 char buffer1
[PATH_MAX
];
565 char buffer2
[PATH_MAX
];
566 char* path
= buffer1
;
567 char* resolved
= NULL
;
572 int mib
[4] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PATHNAME
, -1 };
573 size_t size
= sizeof(buffer1
);
575 if (sysctl(mib
, (u_int
)(sizeof(mib
) / sizeof(mib
[0])), path
, &size
, NULL
, 0) != 0)
578 resolved
= realpath(path
, buffer2
);
582 length
= (int)strlen(resolved
);
583 if (length
<= capacity
)
585 memcpy(out
, resolved
, length
);
591 for (i
= length
- 1; i
>= 0; --i
)
613 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
615 char buffer
[PATH_MAX
];
616 char* resolved
= NULL
;
623 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
625 resolved
= realpath(info
.dli_fname
, buffer
);
629 length
= (int)strlen(resolved
);
630 if (length
<= capacity
)
632 memcpy(out
, resolved
, length
);
638 for (i
= length
- 1; i
>= 0; --i
)
658 #error unsupported platform