summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevgeny <me@ch1p.com>2018-12-30 02:20:27 +0300
committerevgeny <me@ch1p.com>2018-12-30 02:20:27 +0300
commit4e289e0292edbb5146b79e190c67ef16eced069e (patch)
treef6fe9484ed91baf297f8d4247beebed45b027c56
add files
-rw-r--r--Makefile7
-rwxr-xr-xsketch.sh5
-rw-r--r--sketchtrial.c99
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;
+}