This commit is contained in:
Evgeny Zinoviev 2019-06-16 18:22:01 +03:00
parent e22e14ddb1
commit d3c5951bb4
5 changed files with 33 additions and 107 deletions

View File

@ -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

View File

@ -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
```

View File

@ -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

View File

@ -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;
}

28
sketchtrial.m Normal file
View File

@ -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