]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/whereami.c
48e87c7fad35fd5547eccac857dc4b37f08a0627
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 #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
17 #if !defined(WAI_MALLOC)
18 #define WAI_MALLOC(size) malloc(size)
21 #if !defined(WAI_FREE)
22 #define WAI_FREE(p) free(p)
25 #if !defined(WAI_REALLOC)
26 #define WAI_REALLOC(p, size) realloc(p, size)
31 #define WAI_NOINLINE __declspec(noinline)
32 #elif defined(__GNUC__)
33 #define WAI_NOINLINE __attribute__((noinline))
35 #error unsupported compiler
40 #define WAI_RETURN_ADDRESS() _ReturnAddress()
41 #elif defined(__GNUC__)
42 #define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0))
44 #error unsupported compiler
49 #define WIN32_LEAN_AND_MEAN
51 #pragma warning(push, 3)
58 static int WAI_PREFIX(getModulePath_
)(HMODULE module
, char* out
, int capacity
, int* dirname_length
)
60 wchar_t buffer1
[MAX_PATH
];
61 wchar_t buffer2
[MAX_PATH
];
68 int length_
, length__
;
70 size
= GetModuleFileNameW(module
, buffer1
, sizeof(buffer1
) / sizeof(buffer1
[0]));
74 else if (size
== (DWORD
)(sizeof(buffer1
) / sizeof(buffer1
[0])))
81 path_
= (wchar_t*)WAI_REALLOC(path
, sizeof(wchar_t) * size_
* 2);
86 size
= GetModuleFileNameW(module
, path
, size_
);
88 while (size
== size_
);
96 if (!_wfullpath(buffer2
, path
, MAX_PATH
))
98 length_
= (int)wcslen(buffer2
);
99 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, out
, capacity
, NULL
, NULL
);
102 length__
= WideCharToMultiByte(CP_UTF8
, 0, buffer2
, length_
, NULL
, 0, NULL
, NULL
);
106 if (length__
<= capacity
&& dirname_length
)
110 for (i
= length__
- 1; i
>= 0; --i
)
133 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
135 return WAI_PREFIX(getModulePath_
)(NULL
, out
, capacity
, dirname_length
);
141 int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
146 #if defined(_MSC_VER)
147 #pragma warning(push)
148 #pragma warning(disable: 4054)
150 if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module))
151 #if defined(_MSC_VER)
155 length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length);
162 #elif defined(__linux__)
163 #define _DEFAULT_SOURCE
167 #include <linux/limits.h>
168 #ifndef __STDC_FORMAT_MACROS
169 #define __STDC_FORMAT_MACROS
171 #include <inttypes.h>
173 #if !defined(WAI_PROC_SELF_EXE)
174 #define WAI_PROC_SELF_EXE "/proc/self/exe"
178 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
180 char buffer
[PATH_MAX
];
181 char* resolved
= NULL
;
186 resolved
= realpath(WAI_PROC_SELF_EXE
, buffer
);
190 length
= (int)strlen(resolved
);
191 if (length
<= capacity
)
193 memcpy(out
, resolved
, length
);
199 for (i
= length
- 1; i
>= 0; --i
)
216 #if !defined(WAI_PROC_SELF_MAPS_RETRY)
217 #define WAI_PROC_SELF_MAPS_RETRY 5
220 #if !defined(WAI_PROC_SELF_MAPS)
221 #define WAI_PROC_SELF_MAPS "/proc/self/maps"
224 #if defined(__ANDROID__) || defined(ANDROID)
226 #include <sys/mman.h>
231 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
237 for (i
= 0; i
< WAI_PROC_SELF_MAPS_RETRY
; ++i
)
239 maps
= fopen(WAI_PROC_SELF_MAPS
, "r");
245 char buffer
[PATH_MAX
< 1024 ? 1024 : PATH_MAX
];
249 uint32_t major
, minor
;
253 if (!fgets(buffer
, sizeof(buffer
), maps
))
256 if (sscanf(buffer
, "%" PRIx64
"-%" PRIx64
" %s %" PRIx64
" %x:%x %u %s\n", &low
, &high
, perms
, &offset
, &major
, &minor
, &inode
, path
) == 8)
258 uint64_t addr
= (uint64_t)(uintptr_t)WAI_RETURN_ADDRESS();
259 if (low
<= addr
&& addr
<= high
)
263 resolved
= realpath(path
, buffer
);
267 length
= (int)strlen(resolved
);
268 #if defined(__ANDROID__) || defined(ANDROID)
270 &&buffer
[length
- 1] == 'k'
271 &&buffer
[length
- 2] == 'p'
272 &&buffer
[length
- 3] == 'a'
273 &&buffer
[length
- 4] == '.')
275 int fd
= open(path
, O_RDONLY
);
279 begin
= (char*)mmap(0, offset
, PROT_READ
, MAP_SHARED
, fd
, 0);
282 while (p
>= begin
) // scan backwards
284 if (*((uint32_t*)p
) == 0x04034b50UL
) // local file header found
286 uint16_t length_
= *((uint16_t*)(p
+ 26));
288 if (length
+ 2 + length_
< (int)sizeof(buffer
))
290 memcpy(&buffer
[length
], "!/", 2);
291 memcpy(&buffer
[length
+ 2], p
+ 30, length_
);
292 length
+= 2 + length_
;
301 munmap(begin
, offset
);
305 if (length
<= capacity
)
307 memcpy(out
, resolved
, length
);
313 for (i
= length
- 1; i
>= 0; --i
)
338 #elif defined(__APPLE__)
340 #define _DARWIN_BETTER_REALPATH
341 #include <mach-o/dyld.h>
348 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
350 char buffer1
[PATH_MAX
];
351 char buffer2
[PATH_MAX
];
352 char* path
= buffer1
;
353 char* resolved
= NULL
;
358 uint32_t size
= (uint32_t)sizeof(buffer1
);
359 if (_NSGetExecutablePath(path
, &size
) == -1)
361 path
= (char*)WAI_MALLOC(size
);
362 if (!_NSGetExecutablePath(path
, &size
))
366 resolved
= realpath(path
, buffer2
);
370 length
= (int)strlen(resolved
);
371 if (length
<= capacity
)
373 memcpy(out
, resolved
, length
);
379 for (i
= length
- 1; i
>= 0; --i
)
401 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
403 char buffer
[PATH_MAX
];
404 char* resolved
= NULL
;
411 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
413 resolved
= realpath(info
.dli_fname
, buffer
);
417 length
= (int)strlen(resolved
);
418 if (length
<= capacity
)
420 memcpy(out
, resolved
, length
);
426 for (i
= length
- 1; i
>= 0; --i
)
444 #elif defined(__QNXNTO__)
452 #if !defined(WAI_PROC_SELF_EXE)
453 #define WAI_PROC_SELF_EXE "/proc/self/exefile"
457 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
459 char buffer1
[PATH_MAX
];
460 char buffer2
[PATH_MAX
];
461 char* resolved
= NULL
;
462 FILE* self_exe
= NULL
;
467 self_exe
= fopen(WAI_PROC_SELF_EXE
, "r");
471 if (!fgets(buffer1
, sizeof(buffer1
), self_exe
))
474 resolved
= realpath(buffer1
, buffer2
);
478 length
= (int)strlen(resolved
);
479 if (length
<= capacity
)
481 memcpy(out
, resolved
, length
);
487 for (i
= length
- 1; i
>= 0; --i
)
507 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
509 char buffer
[PATH_MAX
];
510 char* resolved
= NULL
;
517 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
519 resolved
= realpath(info
.dli_fname
, buffer
);
523 length
= (int)strlen(resolved
);
524 if (length
<= capacity
)
526 memcpy(out
, resolved
, length
);
532 for (i
= length
- 1; i
>= 0; --i
)
550 #elif defined(__DragonFly__) || defined(__FreeBSD__) || \
551 defined(__FreeBSD_kernel__) || defined(__NetBSD__)
556 #include <sys/types.h>
557 #include <sys/sysctl.h>
561 int WAI_PREFIX(getExecutablePath
)(char* out
, int capacity
, int* dirname_length
)
563 char buffer1
[PATH_MAX
];
564 char buffer2
[PATH_MAX
];
565 char* path
= buffer1
;
566 char* resolved
= NULL
;
571 int mib
[4] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PATHNAME
, -1 };
572 size_t size
= sizeof(buffer1
);
574 if (sysctl(mib
, (u_int
)(sizeof(mib
) / sizeof(mib
[0])), path
, &size
, NULL
, 0) != 0)
577 resolved
= realpath(path
, buffer2
);
581 length
= (int)strlen(resolved
);
582 if (length
<= capacity
)
584 memcpy(out
, resolved
, length
);
590 for (i
= length
- 1; i
>= 0; --i
)
612 int WAI_PREFIX(getModulePath
)(char* out
, int capacity
, int* dirname_length
)
614 char buffer
[PATH_MAX
];
615 char* resolved
= NULL
;
622 if (dladdr(WAI_RETURN_ADDRESS(), &info
))
624 resolved
= realpath(info
.dli_fname
, buffer
);
628 length
= (int)strlen(resolved
);
629 if (length
<= capacity
)
631 memcpy(out
, resolved
, length
);
637 for (i
= length
- 1; i
>= 0; --i
)
657 #error unsupported platform