diff options
author | evgeny <me@ch1p.com> | 2018-12-30 02:20:27 +0300 |
---|---|---|
committer | evgeny <me@ch1p.com> | 2018-12-30 02:20:27 +0300 |
commit | 4e289e0292edbb5146b79e190c67ef16eced069e (patch) | |
tree | f6fe9484ed91baf297f8d4247beebed45b027c56 |
add files
-rw-r--r-- | Makefile | 7 | ||||
-rwxr-xr-x | sketch.sh | 5 | ||||
-rw-r--r-- | sketchtrial.c | 99 |
3 files changed, 111 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9c717ea --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +CFLAGS = -dynamiclib -lpthread + +all: + $(CC) $(CFLAGS) sketchtrial.c -o libsketchtrial.dylib + +clean: + rm -rf *.o libsketchtrial.dylib diff --git a/sketch.sh b/sketch.sh new file mode 100755 index 0000000..73dcdfc --- /dev/null +++ b/sketch.sh @@ -0,0 +1,5 @@ +#!/bin/bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export DYLD_FORCE_FLAT_NAMESPACE=1 +export DYLD_INSERT_LIBRARIES=$DIR/libsketchtrial.dylib +/Applications/Sketch.app/Contents/MacOS/Sketch diff --git a/sketchtrial.c b/sketchtrial.c new file mode 100644 index 0000000..85354c9 --- /dev/null +++ b/sketchtrial.c @@ -0,0 +1,99 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> +#include <execinfo.h> +#include <dlfcn.h> +#include <pthread.h> + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +static int nstime_calls_left = 3; +static bool done = false; +static char buf[32]; +static long days = -5000; + +// pointer to the original function +int (*orig_gettimeofday) (struct timeval *restrict tp, void *restrict tzp) = NULL; + +void parse_bt_source(char* src, char* dst, int len) { + int pos = 0; + int state = 0; + for (char *c = src; *c != '\0' && pos < len-1; c++) { + if (!state) { + if (*c == ' ') { + state = 1; + } + continue; + } + if (state == 1) { + if (*c != ' ') { + state = 2; + } + } + if (state == 2) { + if (*c != ' ') { + dst[pos++] = *c; + } else { + dst[pos] = '\0'; + break; + } + } + } +} + +int gettimeofday(struct timeval *restrict tp, void *restrict tzp) { + if (!orig_gettimeofday) { + orig_gettimeofday = dlsym(RTLD_NEXT, "gettimeofday"); + } + + int result = orig_gettimeofday(tp, tzp); + if (result == 0 && !done) { + pthread_mutex_lock(&mutex); + if (nstime_calls_left > 0) { + void *callstack[128]; + int frames = backtrace(callstack, 128); + char **strs = backtrace_symbols(callstack, frames); + + bool is_sketch = false, is_nstime = false, is_cfnet = false, is_nt = false; + int i; + + for (i = 0; i < frames; ++i) { + parse_bt_source(strs[i], buf, 32); + if (!is_nstime && strstr(strs[i], "NSDate") != NULL) { + is_nstime = true; + } + if (!is_nt && strstr(strs[i], "NSNotification") != NULL) { + is_nt = true; + } + if (!is_sketch && !strcmp(buf, "Sketch")) { + is_sketch = true; + } + if (!is_cfnet && !strcmp(buf, "CFNetwork")) { + is_cfnet = true; + } + } + + if (is_sketch && is_nstime && !is_cfnet && !is_nt) { + tp->tv_sec += days * 86400; + tp->tv_usec = tp->tv_sec * 1000000; + nstime_calls_left--; + + printf("spoofed time on call stack:\n"); + for (i = 0; i < frames; i++) { + printf(" %s\n", strs[i]); + } + printf("\n"); + } + + free(strs); + if (!nstime_calls_left) { + done = true; + } + } + pthread_mutex_unlock(&mutex); + } + + return result; +} |