diff options
author | Evgeny Zinoviev <me@ch1p.io> | 2019-06-16 18:22:01 +0300 |
---|---|---|
committer | Evgeny Zinoviev <me@ch1p.io> | 2019-06-16 18:22:01 +0300 |
commit | d3c5951bb4552185b5a0766a38cc30ffbf857036 (patch) | |
tree | 659b54956e51c696280454ef7fcde8d5f5a4e165 | |
parent | e22e14ddb18f52014004336047d8191d09030d5a (diff) |
rewrite
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rwxr-xr-x | sketch.sh | 1 | ||||
-rw-r--r-- | sketchtrial.c | 103 | ||||
-rw-r--r-- | sketchtrial.m | 28 |
5 files changed, 33 insertions, 107 deletions
@@ -1,7 +1,7 @@ -CFLAGS = -dynamiclib -lpthread +CFLAGS = -dynamiclib -framework AppKit -framework Foundation all: - $(CC) $(CFLAGS) sketchtrial.c -o libsketchtrial.dylib + $(CC) $(CFLAGS) sketchtrial.m -o libsketchtrial.dylib clean: rm -rf *.o libsketchtrial.dylib @@ -1,6 +1,8 @@ # sketchtrial -To bypass Sketch trial verification process you just need to spoof a couple of NSDate calls when the app starts. This repository contains a shared library code that can be inserted (using `DYLD_INSERT_LIBRARIES`) to the Sketch process that spoofs the right `gettimeofday` calls. +This is a shared library that spoofs some ObjC method calls to disable Sketch license verification. + +Tested on Sketch 55.2. ## Building ``` @@ -1,5 +1,4 @@ #!/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 deleted file mode 100644 index 388f8ab..0000000 --- a/sketchtrial.c +++ /dev/null @@ -1,103 +0,0 @@ -#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 calls_left = 9; -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) { - return result; - } - - pthread_mutex_lock(&mutex); - if (!calls_left) { - goto end; - } - - void *callstack[128]; - int frames = backtrace(callstack, 128); - char **strs = backtrace_symbols(callstack, frames); - int i; - bool call_sketch = false; - bool call_nsdate = false; - - for (i = 0; i < frames; ++i) { - parse_bt_source(strs[i], buf, 32); - if (strstr(strs[i], "NSNotification") != NULL || !strcmp(buf, "CFNetwork")) { - call_sketch = false; - break; - } - if (!call_nsdate && strstr(strs[i], "NSDate") != NULL) { - call_nsdate = true; - } - if (!call_sketch && !strcmp(buf, "Sketch")) { - call_sketch = true; - } - } - - if (call_sketch && call_nsdate) { - tp->tv_sec += days * 86400; - tp->tv_usec = tp->tv_sec * 1000000; - 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 (!calls_left) { - done = true; - } - -end: - pthread_mutex_unlock(&mutex); - - return result; -} diff --git a/sketchtrial.m b/sketchtrial.m new file mode 100644 index 0000000..26875d6 --- /dev/null +++ b/sketchtrial.m @@ -0,0 +1,28 @@ +#import <objc/runtime.h> +#import <Foundation/Foundation.h> +#include <AppKit/AppKit.h> + + +// +// BCRegularLicense +// + +@interface BCRegularLicensePatched : NSObject +- (bool)isExpired; +@end + +@implementation BCRegularLicensePatched + ++(void)load { +Class origClass = NSClassFromString(@"BCRegularLicense"); + Method origMethod = class_getInstanceMethod(origClass, @selector(isExpired)); + Method replMethod = class_getInstanceMethod(NSClassFromString(@"BCRegularLicensePatched"), @selector(isExpired)); + + method_exchangeImplementations(origMethod, replMethod); +} + +-(bool)isExpired { + return false; +} + +@end |