From 8ce30b96b93a31b76113d84b92f3497df7ea85e1 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Mon, 1 Jun 2015 15:53:20 -0700 Subject: [PATCH] Split WebCycript functionality to its own package. --- .gitignore | 1 + LockScreen.mm | 849 +-------------------- WebCycript.h | 30 + WebCycript.mm | 904 +++++++++++++++++++++++ WebCycript.plist | 24 + Info.plist => WebCycriptLockScreen.plist | 0 control.in => cydget.in | 2 +- makefile | 43 +- webcycript.in | 12 + 9 files changed, 1020 insertions(+), 845 deletions(-) create mode 100644 WebCycript.h create mode 100644 WebCycript.mm create mode 100644 WebCycript.plist rename Info.plist => WebCycriptLockScreen.plist (100%) rename control.in => cydget.in (59%) create mode 100644 webcycript.in diff --git a/.gitignore b/.gitignore index 70b9e85..42ef5ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ CydgetLoader.dylib CydgetSettings +WebCycript WebCycriptLockScreen *.deb package diff --git a/LockScreen.mm b/LockScreen.mm index 826999c..abbef7e 100644 --- a/LockScreen.mm +++ b/LockScreen.mm @@ -22,7 +22,6 @@ #include #include -#include #include #include @@ -31,7 +30,7 @@ #include #include -#include "yieldToSelector.h" +#include #ifdef USE_ICU_REGEX #include @@ -39,9 +38,6 @@ #include #endif -#define _transient -#define _forever for (;;) - _disused static unsigned trace_; #define _trace() do { \ @@ -50,39 +46,14 @@ _disused static unsigned trace_; ); \ } while (false) -#define _assert(test) do \ - if (!(test)) { \ - NSLog(@"_assert(%d:%s)@%s:%u[%s]\n", errno, #test, __FILE__, __LINE__, __FUNCTION__); \ - exit(-1); \ - } \ -while (false) - -#define _syscall(expr) \ - do if ((long) (expr) != -1) \ - break; \ - else switch (errno) { \ - case EINTR: \ - continue; \ - default: \ - _assert(false); \ - } while (true) - -extern "C" UIImage *_UIImageWithName(NSString *name); - typedef uint16_t UChar; @interface TPBottomLockBar - (CGFloat) defaultHeight; @end -@interface UIApplication (Apple) -- (void) applicationOpenURL:(NSURL *)url; -@end - @interface UIScroller : UIView -- (CGSize) contentSize; - (void) setDirectionalScrolling:(BOOL)directional; -- (void) setOffset:(CGPoint)offset; - (void) setScrollDecelerationFactor:(CGFloat)factor; - (void) setScrollHysteresis:(CGFloat)hysteresis; - (void) setThumbDetectionEnabled:(BOOL)enabled; @@ -154,37 +125,7 @@ typedef uint16_t UChar; static Class $CydgetController(objc_getClass("CydgetController")); -static bool iOS32, iOS4; - -@interface NSString (UIKit) -- (NSString *) stringByAddingPercentEscapes; -@end - -@implementation UIWebDocumentView (WebCycript) - -- (void) _setScrollerOffset:(CGPoint)offset { - UIScroller *scroller([self _scroller]); - - CGSize size([scroller contentSize]); - CGSize bounds([scroller bounds].size); - - CGPoint max; - max.x = size.width - bounds.width; - max.y = size.height - bounds.height; - - // wtf Apple?! - if (max.x < 0) - max.x = 0; - if (max.y < 0) - max.y = 0; - - offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x; - offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y; - - [scroller setOffset:offset]; -} - -@end +MSClassHook(SBLockScreenManager) #ifdef USE_ICU_REGEX /* ICU Regular Expression {{{ */ @@ -212,9 +153,11 @@ class RegEx { bool operator ()(const UChar *data, size_t size) { UErrorCode status(U_ZERO_ERROR); uregex_setText(regex_, data, size, &status); - _assert(U_SUCCESS(status)); + if (!U_SUCCESS(status)) + return false; bool matches(uregex_matches(regex_, 0, &status)); - _assert(U_SUCCESS(status)); + if (!U_SUCCESS(status)) + return false; return matches; } }; @@ -262,25 +205,8 @@ class RegEx { /* }}} */ #endif -@interface DOMCSSStyleSheet : NSObject -- (int) addRule:(NSString *)rule style:(NSString *)style index:(unsigned)index; -- (void) deleteRule:(unsigned)index; -@end - -@interface DOMStyleSheetList : NSObject -- (DOMCSSStyleSheet *) item:(unsigned)index; -@end - -@interface DOMDocument : NSObject -- (DOMStyleSheetList *) styleSheets; -@end - static float CYScrollViewDecelerationRateNormal; -@interface NSURL (Apple) -- (BOOL) isSpringboardHandledURL; -@end - @interface UIScrollView (Apple) - (void) setDecelerationRate:(CGFloat)value; - (void) setScrollingEnabled:(BOOL)enabled; @@ -309,37 +235,15 @@ static float CYScrollViewDecelerationRateNormal; @class UIWebViewWebViewDelegate; -@interface CydgetWebView : UIWebView { -} - +@interface UIWebView (WebCycript) - (void) updateStyles; - @end -MSClassHook(UIApplication) -MSClassHook(SBLockScreenManager) - -MSInstanceMessageHook1(void, UIApplication, openURL, NSURL *, url) { - [self applicationOpenURL:url]; -} - -@implementation NSURL (Cydget) - -- (NSNumber *) cydget$isSpringboardHandledURL { - return [NSNumber numberWithBool:[self isSpringboardHandledURL]]; +@interface CydgetWebView : UIWebView { } @end -MSClassHook(NSURL) - -MSInstanceMessageHook0(BOOL, NSURL, isSpringboardHandledURL) { - if (![NSThread isMainThread]) - return MSOldCall(); - - return [[self cydget$yieldToSelector:@selector(cydget$isSpringboardHandledURL)] boolValue]; -} - @implementation CydgetWebView - (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { @@ -357,12 +261,6 @@ MSInstanceMessageHook0(BOOL, NSURL, isSpringboardHandledURL) { [super webView:view addMessageToConsole:message]; } -- (void) updateStyles { - DOMCSSStyleSheet *sheet([[[[[[self _documentView] webView] mainFrame] DOMDocument] styleSheets] item:0]); - [sheet addRule:@"cydget" style:@"color: black" index:0]; - [sheet deleteRule:0]; -} - @end @interface WebCydgetLockScreenView : UIView { @@ -520,16 +418,7 @@ MSInstanceMessageHook0(BOOL, NSURL, isSpringboardHandledURL) { if (cycript_ != nil) if (NSString *href = [[[[frame dataSource] request] URL] absoluteString]) if (RegEx([cycript_ UTF8String])(href)) - if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) - if (void (*CYSetupContext)(JSGlobalContextRef) = reinterpret_cast(dlsym(handle, "CydgetSetupContext"))) { - WebFrame *frame([webview mainFrame]); - JSGlobalContextRef context([frame globalContext]); - @try { - CYSetupContext(context); - } @catch (NSException *e) { - NSLog(@"*** CydgetSetupContext => %@", e); - } - } + WebCycriptSetupView(webview); } - (void) updateStyles { @@ -549,581 +438,17 @@ MSInstanceMessageHook0(BOOL, NSURL, isSpringboardHandledURL) { @end -#include - -struct State { - unsigned state; -}; - -namespace JSC { - class JSGlobalData; - class UString; -} - -namespace WebCore { - class KURL; -} - -namespace WebCore { -struct String { - void *impl_; -}; } - -namespace JSC { -struct SourceCode { - void *provider_; - int start_; - int end_; - int line_; -}; } - -namespace JSC { -union ScriptSourceCode { - struct { - JSC::SourceCode source_; - } Old; - struct { - void *provider_; - JSC::SourceCode source_; - } New; -}; } - -class CFStringStruct { - private: - CFStringRef value_; - - public: - CFStringStruct() : - value_(NULL) - { - } - - CFStringStruct(const CFStringStruct &value) : - value_((CFStringRef) CFRetain(value.value_)) - { - } - - ~CFStringStruct() { - [*this autorelease]; - } - - operator CFStringRef() const { - return value_; - } - - operator NSString *() const { - return (NSString *) value_; - } -}; - -// String Helpers {{{ -static const UChar *(*_ZNK7WebCore6String10charactersEv)(const WebCore::String *); -static const UChar *(*_ZN7WebCore6String29charactersWithNullTerminationEv)(const WebCore::String *); -static CFStringStruct (*_ZNK3WTF6String14createCFStringEv)(const WebCore::String *); -static unsigned (*_ZNK7WebCore6String6lengthEv)(const WebCore::String *); - -static bool StringGet(const WebCore::String &string, const UChar *&data, size_t &length) { - bool terminated; - - if (false) { - } else if (_ZNK7WebCore6String10charactersEv != NULL) { - data = (*_ZNK7WebCore6String10charactersEv)(&string); - terminated = false; - } else if (_ZN7WebCore6String29charactersWithNullTerminationEv != NULL) { - data = (*_ZN7WebCore6String29charactersWithNullTerminationEv)(&string); - terminated = true; - } else if (_ZNK3WTF6String14createCFStringEv != NULL) { - CFStringStruct cf((*_ZNK3WTF6String14createCFStringEv)(&string)); - data = (const UChar *) [cf cStringUsingEncoding:NSUTF16StringEncoding]; - length = CFStringGetLength(cf); - return true; - } else return false; - - if (data == NULL) - return false; - - if (_ZNK7WebCore6String6lengthEv != NULL) - length = (*_ZNK7WebCore6String6lengthEv)(&string); - else if (terminated) - for (length = 0; data[length] != 0; ++length); - else return false; - - return true; -} - -static bool StringEquals(const WebCore::String &string, const char *value) { - const UChar *data; - size_t size; - if (!StringGet(string, data, size)) - return false; - - size_t length(strlen(value)); - if (size != length) - return false; - - for (size_t index(0); index != length; ++index) - if (data[index] != value[index]) - return false; - - return true; -} -// }}} -// State Machine {{{ -static bool cycript_; - -MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, const WebCore::String &mime) { - if (!StringEquals(mime, "text/cycript")) { - cycript_ = false; - return __ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE(mime); - } - - static void *handle(dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)); - if (handle == NULL) - return false; - - cycript_ = true; - return true; -} -// }}} -// Script Compiler {{{ -static void Log(const WebCore::String &string) { -#if 0 - const UChar *data; - size_t length; - if (!StringGet(string, data, length)) - return; - - UChar terminated[length + 1]; - terminated[length] = 0; - memcpy(terminated, data, length * 2); - NSLog(@"wtf %p:%zu:%S:", &string, length, terminated); -#endif -} - -static bool Cycriptify(const uint16_t *&data, size_t &size) { - cycript_ = false; - - if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) - if (void (*CydgetMemoryParse)(const uint16_t **, size_t *) = reinterpret_cast(dlsym(handle, "CydgetMemoryParse"))) @try { - CydgetMemoryParse(&data, &size); - return true; - } @catch (NSException *e) { - NSLog(@"*** CydgetMemoryParse => %@", e); - } - return false; -} - -static void (*_ZN7WebCore6String6appendEPKtj)(WebCore::String *, const UChar *, unsigned); -static void (*_ZN7WebCore6String8truncateEj)(WebCore::String *, unsigned); - -static void Cycriptify(const WebCore::String &source, int *psize = NULL) { - if (!cycript_) - return; - cycript_ = false; - - const UChar *data; - size_t length; - if (!StringGet(source, data, length)) - return; - - size_t size(length); - if (!Cycriptify(data, size)) - return; - - WebCore::String &script(const_cast(source)); - _ZN7WebCore6String8truncateEj(&script, 0); - _ZN7WebCore6String6appendEPKtj(&script, data, size); - - if (psize != NULL) - *psize = size; - - free((void *) data); - - Log(source); -} -// }}} - -static WebCore::String *string; - -// iOS 2.x -MSHook(State, _ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i, void *_this, const WebCore::String &string, State state, const WebCore::String &url, int line) { - Cycriptify(string); - return __ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i(_this, string, state, url, line); -} - -// iOS 3.x -MSHook(void, _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, JSC::SourceCode **_this, JSC::JSGlobalData *global, int *line, JSC::UString *message) { - /*if (cycript_) { - JSC::SourceCode *source(_this[iOS32 ? 6 : 0]); - const uint16_t *data(source->data()); - size_t size(source->length()); - - if (Cycriptify(data, size)) { - source->~SourceCode(); - // XXX: I actually don't have the original URL here: pants - new (source) JSC::SourceCode(JSC::UStringSourceProvider::create(JSC::UString(data, size), "cycript://"), 1); - free((void *) data); - } - }*/ - - return __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, global, line, message); -} - -// iOS 3.x cdata -MSHook(const WebCore::String &, _ZNK7WebCore4Node11textContentEb, void *_this, bool convert) { - const WebCore::String &code(__ZNK7WebCore4Node11textContentEb(_this, convert)); - string = const_cast(&code); - Cycriptify(code); - return code; -} - -// iOS 4.x cdata -MSHook(void, _ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi, void *_this, const WebCore::String &source, const WebCore::KURL &url, int line) { - Cycriptify(source); - return __ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi(_this, source, url, line); -} - -// iOS 4.x+5.0 @src= -MSHook(const WebCore::String &, _ZN7WebCore12CachedScript6scriptEv, void *_this) { - const WebCore::String &script(__ZN7WebCore12CachedScript6scriptEv(_this)); - string = const_cast(&script); - return script; -} - -// iOS 4.x @src= -MSHook(State, _ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE, void *_this, JSC::ScriptSourceCode &script, State state) { - if (string != NULL) { - JSC::SourceCode *source(iOS4 ? &script.New.source_ : &script.Old.source_); - Cycriptify(*string, &source->end_); - string = NULL; - } - - return __ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE(_this, script, state); -} - -// iOS 5.0 cdata -MSHook(void, _ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE, void *_this, const WebCore::String &source, const WebCore::KURL &url, void *position) { - Cycriptify(source); - return __ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE(_this, source, url, position); -} - -// iOS 5.0 @src= -MSHook(void, _ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE, void *_this, void *position, int legacy) { - string = NULL; - return __ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE(_this, position, legacy); -} - -void (*$_ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE)(void *_this, int legacy); - -// iOS 5.0 @src= -MSHook(void, _ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE, void *_this, JSC::ScriptSourceCode &script) { - if (string != NULL) { - JSC::SourceCode *source(&script.New.source_); - $_ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE(_this, 0); - Cycriptify(*string, &source->end_); - string = NULL; - } - - return __ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE(_this, script); -} - -// iOS 6.0 cdata -MSHook(void, _ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, void *_this, const WebCore::String &source, const WebCore::KURL &url, void *position) { - Cycriptify(source); - return __ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE(_this, source, url, position); -} - -// iOS 6.0 @src= -MSHook(void, _ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE, void *_this, void *position, int legacy) { - string = NULL; - return __ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE(_this, position, legacy); -} - -/* Cydget:// Protocol {{{ */ -@interface CydgetURLProtocol : NSURLProtocol { -} - -@end - -@implementation CydgetURLProtocol - -+ (BOOL) canInitWithRequest:(NSURLRequest *)request { - NSURL *url([request URL]); - if (url == nil) - return NO; - NSString *scheme([[url scheme] lowercaseString]); - if (scheme == nil || ![scheme isEqualToString:@"cydget"]) - return NO; - return YES; -} - -+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request { - return request; -} - -- (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request { - id client([self client]); - if (icon == nil) - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]]; - else { - NSData *data(UIImagePNGRepresentation(icon)); - - NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]); - [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - [client URLProtocol:self didLoadData:data]; - [client URLProtocolDidFinishLoading:self]; - } -} - -- (void) startLoading { - id client([self client]); - NSURLRequest *request([self request]); - - NSURL *url([request URL]); - NSString *href([url absoluteString]); - - NSString *path([href substringFromIndex:9]); - NSRange slash([path rangeOfString:@"/"]); - - NSString *command; - if (slash.location == NSNotFound) { - command = path; - path = nil; - } else { - command = [path substringToIndex:slash.location]; - path = [path substringFromIndex:(slash.location + 1)]; - } - - if ([command isEqualToString:@"_UIImageWithName"]) { - if (path == nil) - goto fail; - path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - UIImage *icon(_UIImageWithName(path)); - [self _returnPNGWithImage:icon forRequest:request]; - } else fail: { - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; - } -} - -- (void) stopLoading { -} - -@end -/* }}} */ -/* Cydget-CGI:// Protocol {{{ */ -@interface CydgetCGIURLProtocol : NSURLProtocol { - pid_t pid_; - CFHTTPMessageRef http_; - NSFileHandle *handle_; -} - -@end - -@implementation CydgetCGIURLProtocol - -+ (BOOL) canInitWithRequest:(NSURLRequest *)request { - NSURL *url([request URL]); - if (url == nil) - return NO; - NSString *scheme([[url scheme] lowercaseString]); - if (scheme == nil || ![scheme isEqualToString:@"cydget-cgi"]) - return NO; - return YES; -} - -+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request { - return request; -} - -- (id) initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)response client:(id)client { - if ((self = [super initWithRequest:request cachedResponse:response client:client]) != nil) { - pid_ = -1; - } return self; -} - -- (void) startLoading { - id client([self client]); - NSURLRequest *request([self request]); - NSURL *url([request URL]); - - NSString *path([url path]); - if (path == nil) { - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; - return; - } - - NSFileManager *manager([NSFileManager defaultManager]); - if (![manager fileExistsAtPath:path]) { - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]]; - return; - } - - int fds[2]; - _assert(pipe(fds) != -1); - - _assert(pid_ == -1); - pid_ = fork(); - if (pid_ == -1) { - _assert(close(fds[0]) != -1); - _assert(close(fds[1]) != -1); - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; - return; - } - - if (pid_ == 0) { - const char *script([path UTF8String]); - - setenv("GATEWAY_INTERFACE", "CGI/1.1", true); - setenv("SCRIPT_FILENAME", script, true); - NSString *query([url query]); - if (query != nil) - setenv("QUERY_STRING", [query UTF8String], true); - - _assert(dup2(fds[1], 1) != -1); - _assert(close(fds[0]) != -1); - _assert(close(fds[1]) != -1); - - execl(script, script, NULL); - exit(1); - _assert(false); - } - - _assert(close(fds[1]) != -1); - - _assert(http_ == NULL); - http_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, FALSE); - CFHTTPMessageAppendBytes(http_, (const uint8_t *) "HTTP/1.1 200 OK\r\n", 17); - - _assert(handle_ == nil); - handle_ = [[NSFileHandle alloc] initWithFileDescriptor:fds[0] closeOnDealloc:YES]; - - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(onRead:) - name:@"NSFileHandleReadCompletionNotification" - object:handle_ - ]; - - [handle_ readInBackgroundAndNotify]; -} - -- (void) onRead:(NSNotification *)notification { - NSFileHandle *handle([notification object]); - - NSData *data([[notification userInfo] objectForKey:NSFileHandleNotificationDataItem]); - - if (size_t length = [data length]) { - CFHTTPMessageAppendBytes(http_, reinterpret_cast([data bytes]), length); - [handle readInBackgroundAndNotify]; - } else { - id client([self client]); - - CFStringRef mime(CFHTTPMessageCopyHeaderFieldValue(http_, CFSTR("Content-type"))); - if (mime == NULL) - [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadServerResponse userInfo:nil]]; - else { - NSURLRequest *request([self request]); - - NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:(NSString *)mime expectedContentLength:-1 textEncodingName:nil] autorelease]); - CFRelease(mime); - - [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - - CFDataRef body(CFHTTPMessageCopyBody(http_)); - [client URLProtocol:self didLoadData:(NSData *)body]; - CFRelease(body); - - [client URLProtocolDidFinishLoading:self]; - } - - CFRelease(http_); - http_ = NULL; - } -} - - //[client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nil]]; - -- (void) stopLoading_ { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - if (handle_ != nil) { - [handle_ release]; - handle_ = nil; - } - - if (pid_ != -1) { - kill(pid_, SIGTERM); - int status; - _syscall(waitpid(pid_, &status, 0)); - pid_ = -1; - } -} - -- (void) stopLoading { - [self - performSelectorOnMainThread:@selector(stopLoading_) - withObject:nil - waitUntilDone:NO - ]; -} - -@end -/* }}} */ - -namespace WebCore { - class MediaQueryEvaluator; - class CSSParserValueList; -} - -namespace WebCore { -struct MediaQueryExp { - String feature_; - void *value_; - bool valid_; - String cache_; -}; } - -bool CYHaveMediaControls() { +static BOOL CYHaveMediaControls() { SBLockScreenView *view([[[$SBLockScreenManager sharedInstance] lockScreenViewController] lockScreenView]); return view != nil && ![view mediaControlsHidden]; //return [[[$SBLockScreenManager sharedInstance] lockScreenViewController] isShowingMediaControls]; } -bool CYHaveNotificationList() { +static BOOL CYHaveNotificationList() { SBLockScreenNotificationListController *controller([[[$SBLockScreenManager sharedInstance] lockScreenViewController] _notificationController]); return controller != nil && [controller hasAnyContent]; } -MSHook(bool, _ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE, WebCore::MediaQueryEvaluator *_this, WebCore::String &query) { - Log(query); if (false); - else if (kCFCoreFoundationVersionNumber >= 800 && StringEquals(query, "-cydget-media-controls")) - return CYHaveMediaControls(); - else if (kCFCoreFoundationVersionNumber >= 800 && StringEquals(query, "-cydget-notification-list")) - return CYHaveNotificationList(); - else - return __ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE(_this, query); -} - -MSHook(void *, _ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE, WebCore::MediaQueryExp *_this, WebCore::String &query, WebCore::CSSParserValueList *values) { - Log(query); - void *value(__ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE(_this, query, values)); - if (!_this->valid_) if ( - StringEquals(query, "-cydget-media-controls") || - StringEquals(query, "-cydget-notification-list") || - false) _this->valid_ = true; - return value; -} - -template -static void dlset(Type_ &function, const char *name) { - function = reinterpret_cast(dlsym(RTLD_DEFAULT, name)); -} - -#define msset(function, handle) \ - MSHookSymbol(function, "_" #function, handle) - -@implementation WebCycriptLockScreenController - static void $UIWebViewWebViewDelegate$webView$addMessageToConsole$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSDictionary *message) { UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); if ([uiWebView respondsToSelector:@selector(webView:addMessageToConsole:)]) @@ -1136,7 +461,7 @@ static void $UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$(UIW [uiWebView webView:view didClearWindowObject:window forFrame:frame]; } -+ (void) initialize { +MSInitialize { if (Class $UIWebViewWebViewDelegate = objc_getClass("UIWebViewWebViewDelegate")) { class_addMethod($UIWebViewWebViewDelegate, @selector(webView:addMessageToConsole:), (IMP) &$UIWebViewWebViewDelegate$webView$addMessageToConsole$, "v16@0:4@8@12"); class_addMethod($UIWebViewWebViewDelegate, @selector(webView:didClearWindowObject:forFrame:), (IMP) &$UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$, "v20@0:4@8@12@16"); @@ -1147,144 +472,14 @@ static void $UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$(UIW else // XXX: this actually might be fast on some older systems: we should look into this CYScrollViewDecelerationRateNormal = 0.998; - iOS4 = kCFCoreFoundationVersionNumber >= 550.32; - iOS32 = !iOS4 && kCFCoreFoundationVersionNumber >= 478.61; - - int maxproc; - size_t size(sizeof(maxproc)); - if (sysctlbyname("kern.maxproc", &maxproc, &size, NULL, 0) == -1) - NSLog(@"sysctlbyname(\"kern.maxproc\", ?)"); - else if (maxproc < 72) { - maxproc = 72; - if (sysctlbyname("kern.maxproc", NULL, NULL, &maxproc, sizeof(maxproc)) == -1) - NSLog(@"sysctlbyname(\"kern.maxproc\", #)"); - } - - [NSURLProtocol registerClass:[CydgetURLProtocol class]]; - [WebView registerURLSchemeAsLocal:@"cydget"]; - - [NSURLProtocol registerClass:[CydgetCGIURLProtocol class]]; - [WebView registerURLSchemeAsLocal:@"cydget-cgi"]; - - MSImageRef JavaScriptCore(NULL); - if (JavaScriptCore == NULL) - JavaScriptCore = MSGetImageByName("/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore"); - if (JavaScriptCore == NULL) - JavaScriptCore = MSGetImageByName("/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore"); - - MSImageRef WebCore(MSGetImageByName("/System/Library/PrivateFrameworks/WebCore.framework/WebCore")); - - if (!iOS4) { - void (*_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE)(JSC::SourceCode **, JSC::JSGlobalData *, int *, JSC::UString *); - dlset(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, "_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE"); - if (_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE != NULL) - MSHookFunction(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, MSHake(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE)); - } - - bool (*_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE)(const WebCore::String &) = NULL; - if (_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE == NULL) - MSHookSymbol(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, "__ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE", WebCore); - if (_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE == NULL) - MSHookSymbol(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, "__ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKN3WTF6StringE", WebCore); - if (_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE != NULL) - MSHookFunction(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, MSHake(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE)); - - void (*_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi)(void *, const WebCore::String &, const WebCore::KURL &, int) = NULL; - if (_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi == NULL) - MSHookSymbol(_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi, "__ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi", WebCore); - if (_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi != NULL) - MSHookFunction(_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi, MSHake(_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi)); - - if (!iOS4) { - const WebCore::String &(*_ZNK7WebCore4Node11textContentEb)(void *, bool) = NULL; - if (_ZNK7WebCore4Node11textContentEb == NULL) - MSHookSymbol(_ZNK7WebCore4Node11textContentEb, "__ZNK7WebCore4Node11textContentEb", WebCore); - if (_ZNK7WebCore4Node11textContentEb != NULL) - MSHookFunction(_ZNK7WebCore4Node11textContentEb, MSHake(_ZNK7WebCore4Node11textContentEb)); + if (kCFCoreFoundationVersionNumber >= 800) { + WebCycriptRegisterStyle("-cydget-media-controls", &CYHaveMediaControls); + WebCycriptRegisterStyle("-cydget-notification-list", &CYHaveNotificationList); } - - const WebCore::String &(*_ZN7WebCore12CachedScript6scriptEv)(void *) = NULL; - if (_ZN7WebCore12CachedScript6scriptEv == NULL) - MSHookSymbol(_ZN7WebCore12CachedScript6scriptEv, "__ZN7WebCore12CachedScript6scriptEv", WebCore); - if (_ZN7WebCore12CachedScript6scriptEv != NULL) - MSHookFunction(_ZN7WebCore12CachedScript6scriptEv, MSHake(_ZN7WebCore12CachedScript6scriptEv)); - - State (*_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i)(void *, const WebCore::String &, State, const WebCore::String &, int) = NULL; - if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i == NULL) - MSHookSymbol(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i, "__ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i", WebCore); - if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i != NULL) - MSHookFunction(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i, MSHake(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i)); - - State (*_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE)(void *, JSC::ScriptSourceCode &, State) = NULL; - if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE == NULL) - MSHookSymbol(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE, "__ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE", WebCore); - if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE != NULL) - MSHookFunction(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE, MSHake(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE)); - - void (*_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE)(void *, const WebCore::String &, const WebCore::KURL &, void *); - msset(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE, WebCore); - if (_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE != NULL) - MSHookFunction(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE, MSHake(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE)); - - void (*_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE)(void *, const WebCore::String &, const WebCore::KURL &, void *); - msset(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, WebCore); - if (_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE == NULL) - MSHookSymbol(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, "__ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_3URLERKNS1_12TextPositionE", WebCore); - if (_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE != NULL) - MSHookFunction(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, MSHake(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE)); - - void (*_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE)(void *, void *, int); - msset(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE, WebCore); - if (_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE != NULL) - MSHookFunction(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE, MSHake(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE)); - - void (*_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE)(void *, void *, int); - msset(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE, WebCore); - if (_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE != NULL) - MSHookFunction(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE, MSHake(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE)); - - MSHookSymbol($_ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE, "__ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE", WebCore); - - void (*_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE)(void *, JSC::ScriptSourceCode &); - msset(_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE, WebCore); - if (_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE != NULL) - MSHookFunction(_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE, MSHake(_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE)); - - if (_ZN7WebCore6String6appendEPKtj == NULL) - MSHookSymbol(_ZN7WebCore6String6appendEPKtj, "__ZN7WebCore6String6appendEPKtj", WebCore); - if (_ZN7WebCore6String6appendEPKtj == NULL) - msset(_ZN7WebCore6String6appendEPKtj, JavaScriptCore); - if (_ZN7WebCore6String6appendEPKtj == NULL) - MSHookSymbol(_ZN7WebCore6String6appendEPKtj, "__ZN3WTF6String6appendEPKtj", JavaScriptCore); - - if (_ZN7WebCore6String8truncateEj == NULL) - MSHookSymbol(_ZN7WebCore6String8truncateEj, "__ZN7WebCore6String8truncateEj", WebCore); - if (_ZN7WebCore6String8truncateEj == NULL) - msset(_ZN7WebCore6String8truncateEj, JavaScriptCore); - if (_ZN7WebCore6String8truncateEj == NULL) - MSHookSymbol(_ZN7WebCore6String8truncateEj, "__ZN3WTF6String8truncateEj", JavaScriptCore); - - msset(_ZNK7WebCore6String10charactersEv, WebCore); - - msset(_ZN7WebCore6String29charactersWithNullTerminationEv, JavaScriptCore); - if (_ZN7WebCore6String29charactersWithNullTerminationEv == NULL) - MSHookSymbol(_ZN7WebCore6String29charactersWithNullTerminationEv, "__ZN3WTF6String29charactersWithNullTerminationEv", JavaScriptCore); - - msset(_ZNK3WTF6String14createCFStringEv, JavaScriptCore); - - msset(_ZNK7WebCore6String6lengthEv, WebCore); - - bool (*_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE)(WebCore::MediaQueryEvaluator *, WebCore::String &); - msset(_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE, WebCore); - if (_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE != NULL) - MSHookFunction(_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE, MSHake(_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE)); - - void *(*_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE)(WebCore::MediaQueryExp *, WebCore::String &, WebCore::CSSParserValueList *); - msset(_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE, WebCore); - if (_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE != NULL) - MSHookFunction(_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE, MSHake(_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE)); } +@implementation WebCycriptLockScreenController + + (id) rootViewController { return [[[self alloc] init] autorelease]; } @@ -1431,13 +626,3 @@ static void $UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$(UIW } @end - -MSClassHook(WebView) -MSMetaClassHook(WebView) - -MSClassMessageHook0(void, WebView, enableWebThread) { - if (kCFCoreFoundationVersionNumber >= 478.61) - return MSOldCall(); - - NSLog(@"-[WebView enableWebThread]"); -} diff --git a/WebCycript.h b/WebCycript.h new file mode 100644 index 0000000..7354671 --- /dev/null +++ b/WebCycript.h @@ -0,0 +1,30 @@ +/* Cydget - open-source AwayView plugin multiplexer + * Copyright (C) 2009-2015 Jay Freeman (saurik) +*/ + +/* GNU General Public License, Version 3 {{{ */ +/* + * Cydia is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Cydia is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cydia. If not, see . +**/ +/* }}} */ + +#ifndef WEBCYCRIPT_H +#define WEBCYCRIPT_H + +@class WebView; + +extern "C" void WebCycriptSetupView(WebView *webview); +extern "C" void WebCycriptRegisterStyle(const char *name, BOOL (*code)()); + +#endif//WEBCYCRIPT_H diff --git a/WebCycript.mm b/WebCycript.mm new file mode 100644 index 0000000..37c5d65 --- /dev/null +++ b/WebCycript.mm @@ -0,0 +1,904 @@ +/* Cydget - open-source AwayView plugin multiplexer + * Copyright (C) 2009-2014 Jay Freeman (saurik) +*/ + +/* GNU General Public License, Version 3 {{{ */ +/* + * Cydia is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, + * or (at your option) any later version. + * + * Cydia is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cydia. If not, see . +**/ +/* }}} */ + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "yieldToSelector.h" + +_disused static unsigned trace_; + +#define _trace() do { \ + NSLog(@"_trace(%u)@%s:%u[%s](%p)\n", \ + trace_++, __FILE__, __LINE__, __FUNCTION__, pthread_self() \ + ); \ +} while (false) + +#define _assert(test) do \ + if (!(test)) { \ + NSLog(@"_assert(%d:%s)@%s:%u[%s]\n", errno, #test, __FILE__, __LINE__, __FUNCTION__); \ + exit(-1); \ + } \ +while (false) + +#define _syscall(expr) \ + do if ((long) (expr) != -1) \ + break; \ + else switch (errno) { \ + case EINTR: \ + continue; \ + default: \ + _assert(false); \ + } while (true) + +extern "C" UIImage *_UIImageWithName(NSString *name); + +typedef uint16_t UChar; + +@interface UIApplication (Apple) +- (void) applicationOpenURL:(NSURL *)url; +@end + +@interface UIScroller : UIView +- (CGSize) contentSize; +- (void) setOffset:(CGPoint)offset; +@end + +@interface UIWebDocumentView : UIView +- (WebView *) webView; +@end + +@interface UIView (Apple) +- (UIScroller *) _scroller; +@end + +static bool iOS32, iOS4; + +@interface NSString (UIKit) +- (NSString *) stringByAddingPercentEscapes; +@end + +@implementation UIWebDocumentView (WebCycript) + +- (void) _setScrollerOffset:(CGPoint)offset { + UIScroller *scroller([self _scroller]); + + CGSize size([scroller contentSize]); + CGSize bounds([scroller bounds].size); + + CGPoint max; + max.x = size.width - bounds.width; + max.y = size.height - bounds.height; + + // wtf Apple?! + if (max.x < 0) + max.x = 0; + if (max.y < 0) + max.y = 0; + + offset.x = offset.x < 0 ? 0 : offset.x > max.x ? max.x : offset.x; + offset.y = offset.y < 0 ? 0 : offset.y > max.y ? max.y : offset.y; + + [scroller setOffset:offset]; +} + +@end + +@interface DOMCSSStyleSheet : NSObject +- (int) addRule:(NSString *)rule style:(NSString *)style index:(unsigned)index; +- (void) deleteRule:(unsigned)index; +@end + +@interface DOMStyleSheetList : NSObject +- (DOMCSSStyleSheet *) item:(unsigned)index; +@end + +@interface DOMDocument : NSObject +- (DOMStyleSheetList *) styleSheets; +@end + +@interface NSURL (Apple) +- (BOOL) isSpringboardHandledURL; +@end + +@interface UIWebView (Apple) +- (UIWebDocumentView *) _documentView; +- (void) setDataDetectorTypes:(NSInteger)types; +- (void) _setDrawInWebThread:(BOOL)draw; +- (UIScrollView *) _scrollView; +- (UIScroller *) _scroller; +- (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message; +- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; +@end + +@protocol CydgetWebViewDelegate +- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; +@end + +MSClassHook(UIApplication) + +MSInstanceMessageHook1(void, UIApplication, openURL, NSURL *, url) { + [self applicationOpenURL:url]; +} + +@implementation NSURL (Cydget) + +- (NSNumber *) cydget$isSpringboardHandledURL { + return [NSNumber numberWithBool:[self isSpringboardHandledURL]]; +} + +@end + +MSClassHook(NSURL) + +MSInstanceMessageHook0(BOOL, NSURL, isSpringboardHandledURL) { + if (![NSThread isMainThread]) + return MSOldCall(); + + return [[self cydget$yieldToSelector:@selector(cydget$isSpringboardHandledURL)] boolValue]; +} + +@implementation UIWebView (WebCycript) + +- (void) updateStyles { + DOMCSSStyleSheet *sheet([[[[[[self _documentView] webView] mainFrame] DOMDocument] styleSheets] item:0]); + [sheet addRule:@"cydget" style:@"color: black" index:0]; + [sheet deleteRule:0]; +} + +@end + +extern "C" void WebCycriptSetupView(WebView *webview) { + if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) + if (void (*CYSetupContext)(JSGlobalContextRef) = reinterpret_cast(dlsym(handle, "CydgetSetupContext"))) { + WebFrame *frame([webview mainFrame]); + JSGlobalContextRef context([frame globalContext]); + @try { + CYSetupContext(context); + } @catch (NSException *e) { + NSLog(@"*** CydgetSetupContext => %@", e); + } + } +} + +#include + +struct State { + unsigned state; +}; + +namespace JSC { + class JSGlobalData; + class UString; +} + +namespace WebCore { + class KURL; +} + +namespace WebCore { +struct String { + void *impl_; +}; } + +namespace JSC { +struct SourceCode { + void *provider_; + int start_; + int end_; + int line_; +}; } + +namespace JSC { +union ScriptSourceCode { + struct { + JSC::SourceCode source_; + } Old; + struct { + void *provider_; + JSC::SourceCode source_; + } New; +}; } + +class CFStringStruct { + private: + CFStringRef value_; + + public: + CFStringStruct() : + value_(NULL) + { + } + + CFStringStruct(const CFStringStruct &value) : + value_((CFStringRef) CFRetain(value.value_)) + { + } + + ~CFStringStruct() { + [*this autorelease]; + } + + operator CFStringRef() const { + return value_; + } + + operator NSString *() const { + return (NSString *) value_; + } +}; + +// String Helpers {{{ +static const UChar *(*_ZNK7WebCore6String10charactersEv)(const WebCore::String *); +static const UChar *(*_ZN7WebCore6String29charactersWithNullTerminationEv)(const WebCore::String *); +static CFStringStruct (*_ZNK3WTF6String14createCFStringEv)(const WebCore::String *); +static unsigned (*_ZNK7WebCore6String6lengthEv)(const WebCore::String *); + +static bool StringGet(const WebCore::String &string, const UChar *&data, size_t &length) { + bool terminated; + + if (false) { + } else if (_ZNK7WebCore6String10charactersEv != NULL) { + data = (*_ZNK7WebCore6String10charactersEv)(&string); + terminated = false; + } else if (_ZN7WebCore6String29charactersWithNullTerminationEv != NULL) { + data = (*_ZN7WebCore6String29charactersWithNullTerminationEv)(&string); + terminated = true; + } else if (_ZNK3WTF6String14createCFStringEv != NULL) { + CFStringStruct cf((*_ZNK3WTF6String14createCFStringEv)(&string)); + data = (const UChar *) [cf cStringUsingEncoding:NSUTF16StringEncoding]; + length = CFStringGetLength(cf); + return true; + } else return false; + + if (data == NULL) + return false; + + if (_ZNK7WebCore6String6lengthEv != NULL) + length = (*_ZNK7WebCore6String6lengthEv)(&string); + else if (terminated) + for (length = 0; data[length] != 0; ++length); + else return false; + + return true; +} + +static bool StringEquals(const WebCore::String &string, const char *value) { + const UChar *data; + size_t size; + if (!StringGet(string, data, size)) + return false; + + size_t length(strlen(value)); + if (size != length) + return false; + + for (size_t index(0); index != length; ++index) + if (data[index] != value[index]) + return false; + + return true; +} +// }}} +// State Machine {{{ +static bool cycript_; + +MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, const WebCore::String &mime) { + if (!StringEquals(mime, "text/cycript")) { + cycript_ = false; + return __ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE(mime); + } + + static void *handle(dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)); + if (handle == NULL) + return false; + + cycript_ = true; + return true; +} +// }}} +// Script Compiler {{{ +static void Log(const WebCore::String &string) { +#if 0 + const UChar *data; + size_t length; + if (!StringGet(string, data, length)) + return; + + UChar terminated[length + 1]; + terminated[length] = 0; + memcpy(terminated, data, length * 2); + NSLog(@"wtf %p:%zu:%S:", &string, length, terminated); +#endif +} + +static bool Cycriptify(const uint16_t *&data, size_t &size) { + cycript_ = false; + + if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) + if (void (*CydgetMemoryParse)(const uint16_t **, size_t *) = reinterpret_cast(dlsym(handle, "CydgetMemoryParse"))) @try { + CydgetMemoryParse(&data, &size); + return true; + } @catch (NSException *e) { + NSLog(@"*** CydgetMemoryParse => %@", e); + } + return false; +} + +static void (*_ZN7WebCore6String6appendEPKtj)(WebCore::String *, const UChar *, unsigned); +static void (*_ZN7WebCore6String8truncateEj)(WebCore::String *, unsigned); + +static void Cycriptify(const WebCore::String &source, int *psize = NULL) { + if (!cycript_) + return; + cycript_ = false; + + const UChar *data; + size_t length; + if (!StringGet(source, data, length)) + return; + + size_t size(length); + if (!Cycriptify(data, size)) + return; + + WebCore::String &script(const_cast(source)); + _ZN7WebCore6String8truncateEj(&script, 0); + _ZN7WebCore6String6appendEPKtj(&script, data, size); + + if (psize != NULL) + *psize = size; + + free((void *) data); + + Log(source); +} +// }}} + +static WebCore::String *string; + +// iOS 2.x +MSHook(State, _ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i, void *_this, const WebCore::String &string, State state, const WebCore::String &url, int line) { + Cycriptify(string); + return __ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i(_this, string, state, url, line); +} + +// iOS 3.x +MSHook(void, _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, JSC::SourceCode **_this, JSC::JSGlobalData *global, int *line, JSC::UString *message) { + /*if (cycript_) { + JSC::SourceCode *source(_this[iOS32 ? 6 : 0]); + const uint16_t *data(source->data()); + size_t size(source->length()); + + if (Cycriptify(data, size)) { + source->~SourceCode(); + // XXX: I actually don't have the original URL here: pants + new (source) JSC::SourceCode(JSC::UStringSourceProvider::create(JSC::UString(data, size), "cycript://"), 1); + free((void *) data); + } + }*/ + + return __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, global, line, message); +} + +// iOS 3.x cdata +MSHook(const WebCore::String &, _ZNK7WebCore4Node11textContentEb, void *_this, bool convert) { + const WebCore::String &code(__ZNK7WebCore4Node11textContentEb(_this, convert)); + string = const_cast(&code); + Cycriptify(code); + return code; +} + +// iOS 4.x cdata +MSHook(void, _ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi, void *_this, const WebCore::String &source, const WebCore::KURL &url, int line) { + Cycriptify(source); + return __ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi(_this, source, url, line); +} + +// iOS 4.x+5.0 @src= +MSHook(const WebCore::String &, _ZN7WebCore12CachedScript6scriptEv, void *_this) { + const WebCore::String &script(__ZN7WebCore12CachedScript6scriptEv(_this)); + string = const_cast(&script); + return script; +} + +// iOS 4.x @src= +MSHook(State, _ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE, void *_this, JSC::ScriptSourceCode &script, State state) { + if (string != NULL) { + JSC::SourceCode *source(iOS4 ? &script.New.source_ : &script.Old.source_); + Cycriptify(*string, &source->end_); + string = NULL; + } + + return __ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE(_this, script, state); +} + +// iOS 5.0 cdata +MSHook(void, _ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE, void *_this, const WebCore::String &source, const WebCore::KURL &url, void *position) { + Cycriptify(source); + return __ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE(_this, source, url, position); +} + +// iOS 5.0 @src= +MSHook(void, _ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE, void *_this, void *position, int legacy) { + string = NULL; + return __ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE(_this, position, legacy); +} + +void (*$_ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE)(void *_this, int legacy); + +// iOS 5.0 @src= +MSHook(void, _ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE, void *_this, JSC::ScriptSourceCode &script) { + if (string != NULL) { + JSC::SourceCode *source(&script.New.source_); + $_ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE(_this, 0); + Cycriptify(*string, &source->end_); + string = NULL; + } + + return __ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE(_this, script); +} + +// iOS 6.0 cdata +MSHook(void, _ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, void *_this, const WebCore::String &source, const WebCore::KURL &url, void *position) { + Cycriptify(source); + return __ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE(_this, source, url, position); +} + +// iOS 6.0 @src= +MSHook(void, _ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE, void *_this, void *position, int legacy) { + string = NULL; + return __ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE(_this, position, legacy); +} + +/* Cydget:// Protocol {{{ */ +@interface CydgetURLProtocol : NSURLProtocol { +} + +@end + +@implementation CydgetURLProtocol + ++ (BOOL) canInitWithRequest:(NSURLRequest *)request { + NSURL *url([request URL]); + if (url == nil) + return NO; + NSString *scheme([[url scheme] lowercaseString]); + if (scheme == nil || ![scheme isEqualToString:@"cydget"]) + return NO; + return YES; +} + ++ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request { + return request; +} + +- (void) _returnPNGWithImage:(UIImage *)icon forRequest:(NSURLRequest *)request { + id client([self client]); + if (icon == nil) + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]]; + else { + NSData *data(UIImagePNGRepresentation(icon)); + + NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:@"image/png" expectedContentLength:-1 textEncodingName:nil] autorelease]); + [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; + [client URLProtocol:self didLoadData:data]; + [client URLProtocolDidFinishLoading:self]; + } +} + +- (void) startLoading { + id client([self client]); + NSURLRequest *request([self request]); + + NSURL *url([request URL]); + NSString *href([url absoluteString]); + + NSString *path([href substringFromIndex:9]); + NSRange slash([path rangeOfString:@"/"]); + + NSString *command; + if (slash.location == NSNotFound) { + command = path; + path = nil; + } else { + command = [path substringToIndex:slash.location]; + path = [path substringFromIndex:(slash.location + 1)]; + } + + if ([command isEqualToString:@"_UIImageWithName"]) { + if (path == nil) + goto fail; + path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + UIImage *icon(_UIImageWithName(path)); + [self _returnPNGWithImage:icon forRequest:request]; + } else fail: { + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; + } +} + +- (void) stopLoading { +} + +@end +/* }}} */ +/* Cydget-CGI:// Protocol {{{ */ +@interface CydgetCGIURLProtocol : NSURLProtocol { + pid_t pid_; + CFHTTPMessageRef http_; + NSFileHandle *handle_; +} + +@end + +@implementation CydgetCGIURLProtocol + ++ (BOOL) canInitWithRequest:(NSURLRequest *)request { + NSURL *url([request URL]); + if (url == nil) + return NO; + NSString *scheme([[url scheme] lowercaseString]); + if (scheme == nil || ![scheme isEqualToString:@"cydget-cgi"]) + return NO; + return YES; +} + ++ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request { + return request; +} + +- (id) initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)response client:(id)client { + if ((self = [super initWithRequest:request cachedResponse:response client:client]) != nil) { + pid_ = -1; + } return self; +} + +- (void) startLoading { + id client([self client]); + NSURLRequest *request([self request]); + NSURL *url([request URL]); + + NSString *path([url path]); + if (path == nil) { + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; + return; + } + + NSFileManager *manager([NSFileManager defaultManager]); + if (![manager fileExistsAtPath:path]) { + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]]; + return; + } + + int fds[2]; + _assert(pipe(fds) != -1); + + _assert(pid_ == -1); + pid_ = fork(); + if (pid_ == -1) { + _assert(close(fds[0]) != -1); + _assert(close(fds[1]) != -1); + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil]]; + return; + } + + if (pid_ == 0) { + const char *script([path UTF8String]); + + setenv("GATEWAY_INTERFACE", "CGI/1.1", true); + setenv("SCRIPT_FILENAME", script, true); + NSString *query([url query]); + if (query != nil) + setenv("QUERY_STRING", [query UTF8String], true); + + _assert(dup2(fds[1], 1) != -1); + _assert(close(fds[0]) != -1); + _assert(close(fds[1]) != -1); + + execl(script, script, NULL); + exit(1); + _assert(false); + } + + _assert(close(fds[1]) != -1); + + _assert(http_ == NULL); + http_ = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, FALSE); + CFHTTPMessageAppendBytes(http_, (const uint8_t *) "HTTP/1.1 200 OK\r\n", 17); + + _assert(handle_ == nil); + handle_ = [[NSFileHandle alloc] initWithFileDescriptor:fds[0] closeOnDealloc:YES]; + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(onRead:) + name:@"NSFileHandleReadCompletionNotification" + object:handle_ + ]; + + [handle_ readInBackgroundAndNotify]; +} + +- (void) onRead:(NSNotification *)notification { + NSFileHandle *handle([notification object]); + + NSData *data([[notification userInfo] objectForKey:NSFileHandleNotificationDataItem]); + + if (size_t length = [data length]) { + CFHTTPMessageAppendBytes(http_, reinterpret_cast([data bytes]), length); + [handle readInBackgroundAndNotify]; + } else { + id client([self client]); + + CFStringRef mime(CFHTTPMessageCopyHeaderFieldValue(http_, CFSTR("Content-type"))); + if (mime == NULL) + [client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadServerResponse userInfo:nil]]; + else { + NSURLRequest *request([self request]); + + NSURLResponse *response([[[NSURLResponse alloc] initWithURL:[request URL] MIMEType:(NSString *)mime expectedContentLength:-1 textEncodingName:nil] autorelease]); + CFRelease(mime); + + [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; + + CFDataRef body(CFHTTPMessageCopyBody(http_)); + [client URLProtocol:self didLoadData:(NSData *)body]; + CFRelease(body); + + [client URLProtocolDidFinishLoading:self]; + } + + CFRelease(http_); + http_ = NULL; + } +} + + //[client URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nil]]; + +- (void) stopLoading_ { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + if (handle_ != nil) { + [handle_ release]; + handle_ = nil; + } + + if (pid_ != -1) { + kill(pid_, SIGTERM); + int status; + _syscall(waitpid(pid_, &status, 0)); + pid_ = -1; + } +} + +- (void) stopLoading { + [self + performSelectorOnMainThread:@selector(stopLoading_) + withObject:nil + waitUntilDone:NO + ]; +} + +@end +/* }}} */ + +namespace WebCore { + class MediaQueryEvaluator; + class CSSParserValueList; +} + +namespace WebCore { +struct MediaQueryExp { + String feature_; + void *value_; + bool valid_; + String cache_; +}; } + +typedef std::map StyleMap_; +static StyleMap_ styles_; + +extern "C" void WebCycriptRegisterStyle(const char *name, BOOL (*code)()) { + styles_.insert(std::make_pair(name, code)); +} + +MSHook(bool, _ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE, WebCore::MediaQueryEvaluator *_this, WebCore::String &query) { + Log(query); + for (StyleMap_::const_iterator style(styles_.begin()); style != styles_.end(); ++style) + if (StringEquals(query, style->first.c_str())) + return style->second(); + return __ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE(_this, query); +} + +MSHook(void *, _ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE, WebCore::MediaQueryExp *_this, WebCore::String &query, WebCore::CSSParserValueList *values) { + Log(query); + void *value(__ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE(_this, query, values)); + if (!_this->valid_) + for (StyleMap_::const_iterator style(styles_.begin()); style != styles_.end(); ++style) + if (StringEquals(query, style->first.c_str())) + _this->valid_ = true; + return value; +} + +template +static void dlset(Type_ &function, const char *name) { + function = reinterpret_cast(dlsym(RTLD_DEFAULT, name)); +} + +#define msset(function, handle) \ + MSHookSymbol(function, "_" #function, handle) + +MSInitialize { + iOS4 = kCFCoreFoundationVersionNumber >= 550.32; + iOS32 = !iOS4 && kCFCoreFoundationVersionNumber >= 478.61; + + int maxproc; + size_t size(sizeof(maxproc)); + if (sysctlbyname("kern.maxproc", &maxproc, &size, NULL, 0) == -1) + NSLog(@"sysctlbyname(\"kern.maxproc\", ?)"); + else if (maxproc < 72) { + maxproc = 72; + if (sysctlbyname("kern.maxproc", NULL, NULL, &maxproc, sizeof(maxproc)) == -1) + NSLog(@"sysctlbyname(\"kern.maxproc\", #)"); + } + + [NSURLProtocol registerClass:[CydgetURLProtocol class]]; + [WebView registerURLSchemeAsLocal:@"cydget"]; + + [NSURLProtocol registerClass:[CydgetCGIURLProtocol class]]; + [WebView registerURLSchemeAsLocal:@"cydget-cgi"]; + + MSImageRef JavaScriptCore(NULL); + if (JavaScriptCore == NULL) + JavaScriptCore = MSGetImageByName("/System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore"); + if (JavaScriptCore == NULL) + JavaScriptCore = MSGetImageByName("/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore"); + + MSImageRef WebCore(MSGetImageByName("/System/Library/PrivateFrameworks/WebCore.framework/WebCore")); + + if (!iOS4) { + void (*_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE)(JSC::SourceCode **, JSC::JSGlobalData *, int *, JSC::UString *); + dlset(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, "_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE"); + if (_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE != NULL) + MSHookFunction(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, MSHake(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE)); + } + + bool (*_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE)(const WebCore::String &) = NULL; + if (_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE == NULL) + MSHookSymbol(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, "__ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE", WebCore); + if (_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE == NULL) + MSHookSymbol(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, "__ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKN3WTF6StringE", WebCore); + if (_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE != NULL) + MSHookFunction(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, MSHake(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE)); + + void (*_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi)(void *, const WebCore::String &, const WebCore::KURL &, int) = NULL; + if (_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi == NULL) + MSHookSymbol(_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi, "__ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi", WebCore); + if (_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi != NULL) + MSHookFunction(_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi, MSHake(_ZN7WebCore16ScriptSourceCodeC2ERKNS_6StringERKNS_4KURLEi)); + + if (!iOS4) { + const WebCore::String &(*_ZNK7WebCore4Node11textContentEb)(void *, bool) = NULL; + if (_ZNK7WebCore4Node11textContentEb == NULL) + MSHookSymbol(_ZNK7WebCore4Node11textContentEb, "__ZNK7WebCore4Node11textContentEb", WebCore); + if (_ZNK7WebCore4Node11textContentEb != NULL) + MSHookFunction(_ZNK7WebCore4Node11textContentEb, MSHake(_ZNK7WebCore4Node11textContentEb)); + } + + const WebCore::String &(*_ZN7WebCore12CachedScript6scriptEv)(void *) = NULL; + if (_ZN7WebCore12CachedScript6scriptEv == NULL) + MSHookSymbol(_ZN7WebCore12CachedScript6scriptEv, "__ZN7WebCore12CachedScript6scriptEv", WebCore); + if (_ZN7WebCore12CachedScript6scriptEv != NULL) + MSHookFunction(_ZN7WebCore12CachedScript6scriptEv, MSHake(_ZN7WebCore12CachedScript6scriptEv)); + + State (*_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i)(void *, const WebCore::String &, State, const WebCore::String &, int) = NULL; + if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i == NULL) + MSHookSymbol(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i, "__ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i", WebCore); + if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i != NULL) + MSHookFunction(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i, MSHake(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_6StringENS0_5StateES3_i)); + + State (*_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE)(void *, JSC::ScriptSourceCode &, State) = NULL; + if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE == NULL) + MSHookSymbol(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE, "__ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE", WebCore); + if (_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE != NULL) + MSHookFunction(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE, MSHake(_ZN7WebCore13HTMLTokenizer15scriptExecutionERKNS_16ScriptSourceCodeENS0_5StateE)); + + void (*_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE)(void *, const WebCore::String &, const WebCore::KURL &, void *); + msset(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE, WebCore); + if (_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE != NULL) + MSHookFunction(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE, MSHake(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionINS1_14OneBasedNumberEEE)); + + void (*_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE)(void *, const WebCore::String &, const WebCore::KURL &, void *); + msset(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, WebCore); + if (_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE == NULL) + MSHookSymbol(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, "__ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_3URLERKNS1_12TextPositionE", WebCore); + if (_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE != NULL) + MSHookFunction(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE, MSHake(_ZN7WebCore16ScriptSourceCodeC2ERKN3WTF6StringERKNS_4KURLERKNS1_12TextPositionE)); + + void (*_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE)(void *, void *, int); + msset(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE, WebCore); + if (_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE != NULL) + MSHookFunction(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE, MSHake(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionINS1_14OneBasedNumberEEENS0_17LegacyTypeSupportE)); + + void (*_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE)(void *, void *, int); + msset(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE, WebCore); + if (_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE != NULL) + MSHookFunction(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE, MSHake(_ZN7WebCore13ScriptElement13prepareScriptERKN3WTF12TextPositionENS0_17LegacyTypeSupportE)); + + MSHookSymbol($_ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE, "__ZNK7WebCore13ScriptElement21isScriptTypeSupportedENS0_17LegacyTypeSupportE", WebCore); + + void (*_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE)(void *, JSC::ScriptSourceCode &); + msset(_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE, WebCore); + if (_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE != NULL) + MSHookFunction(_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE, MSHake(_ZN7WebCore13ScriptElement13executeScriptERKNS_16ScriptSourceCodeE)); + + if (_ZN7WebCore6String6appendEPKtj == NULL) + MSHookSymbol(_ZN7WebCore6String6appendEPKtj, "__ZN7WebCore6String6appendEPKtj", WebCore); + if (_ZN7WebCore6String6appendEPKtj == NULL) + msset(_ZN7WebCore6String6appendEPKtj, JavaScriptCore); + if (_ZN7WebCore6String6appendEPKtj == NULL) + MSHookSymbol(_ZN7WebCore6String6appendEPKtj, "__ZN3WTF6String6appendEPKtj", JavaScriptCore); + + if (_ZN7WebCore6String8truncateEj == NULL) + MSHookSymbol(_ZN7WebCore6String8truncateEj, "__ZN7WebCore6String8truncateEj", WebCore); + if (_ZN7WebCore6String8truncateEj == NULL) + msset(_ZN7WebCore6String8truncateEj, JavaScriptCore); + if (_ZN7WebCore6String8truncateEj == NULL) + MSHookSymbol(_ZN7WebCore6String8truncateEj, "__ZN3WTF6String8truncateEj", JavaScriptCore); + + msset(_ZNK7WebCore6String10charactersEv, WebCore); + + msset(_ZN7WebCore6String29charactersWithNullTerminationEv, JavaScriptCore); + if (_ZN7WebCore6String29charactersWithNullTerminationEv == NULL) + MSHookSymbol(_ZN7WebCore6String29charactersWithNullTerminationEv, "__ZN3WTF6String29charactersWithNullTerminationEv", JavaScriptCore); + + msset(_ZNK3WTF6String14createCFStringEv, JavaScriptCore); + + msset(_ZNK7WebCore6String6lengthEv, WebCore); + + bool (*_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE)(WebCore::MediaQueryEvaluator *, WebCore::String &); + msset(_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE, WebCore); + if (_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE != NULL) + MSHookFunction(_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE, MSHake(_ZNK7WebCore19MediaQueryEvaluator4evalEPKNS_13MediaQueryExpE)); + + void *(*_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE)(WebCore::MediaQueryExp *, WebCore::String &, WebCore::CSSParserValueList *); + msset(_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE, WebCore); + if (_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE != NULL) + MSHookFunction(_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE, MSHake(_ZN7WebCore13MediaQueryExpC2ERKN3WTF12AtomicStringEPNS_18CSSParserValueListE)); +} + +MSClassHook(WebView) +MSMetaClassHook(WebView) + +MSClassMessageHook0(void, WebView, enableWebThread) { + if (kCFCoreFoundationVersionNumber >= 478.61) + return MSOldCall(); + + NSLog(@"-[WebView enableWebThread]"); +} diff --git a/WebCycript.plist b/WebCycript.plist new file mode 100644 index 0000000..732a411 --- /dev/null +++ b/WebCycript.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + WebCycript + CFBundleIdentifier + com.saurik.WebCycript + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + DTPlatformName + iphoneos + MinimumOSVersion + 2.1 + + diff --git a/Info.plist b/WebCycriptLockScreen.plist similarity index 100% rename from Info.plist rename to WebCycriptLockScreen.plist diff --git a/control.in b/cydget.in similarity index 59% rename from control.in rename to cydget.in index 65c0840..276c65c 100644 --- a/control.in +++ b/cydget.in @@ -6,7 +6,7 @@ Architecture: iphoneos-arm Version: % Description: framework for managing lock screen plugins Name: Cydget -Depends: mobilesubstrate (>= 0.9.3366-1), firmware (<< 6.0) | mobilesubstrate (>= 0.9.4000), firmware (<< 7.0) | mobilesubstrate (>= 0.9.5001), firmware (>= 2.2), firmware (<< 8.2), preferenceloader, cy+cpu.arm64 | pcre (>= 8.30), cycript (>= 0.9.500~b1) +Depends: mobilesubstrate, firmware (>= 2.2), firmware (<< 8.2), preferenceloader, cy+cpu.arm64 | pcre (>= 8.30), com.saurik.webcycript Replaces: cydialer (<< 0.9.17) Author: Jay Freeman (saurik) Depiction: http://cydia.saurik.com/info/cydget/ diff --git a/makefile b/makefile index 94af192..8e3ec48 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ jscore := JavaScriptCore-521 cycc = cycc -i2.0 -o$@ -- $(filter %.mm,$^) -Xarch_armv6 -marm -g0 -O2 -I. -F/System/Library/PrivateFrameworks -all: CydgetLoader.dylib WebCycriptLockScreen CydgetSettings +all: CydgetLoader.dylib WebCycript WebCycriptLockScreen CydgetSettings clean:: rm -f CydgetLoader.dylib CydgetSettings WebCycriptLockScreen @@ -14,28 +14,45 @@ CydgetLoader.dylib: CydgetLoader.mm makefile CydgetSettings: CydgetSettings.mm makefile $(cycc) -dynamiclib -framework Foundation -framework UIKit -framework Preferences -WebCycriptLockScreen: LockScreen.mm yieldToSelector.mm makefile - $(cycc) -bundle -isystem sysroot/usr/include \ - -I$(jscore) -iquote$(jscore)/{parser,runtime} \ +WebCycript: WebCycript.mm yieldToSelector.mm makefile + $(cycc) -dynamiclib -isystem sysroot/usr/include \ + -install_name /Library/Frameworks/WebCycript.framework/WebCycript \ -framework Foundation -framework UIKit \ -framework CydiaSubstrate -framework CFNetwork \ -framework JavaScriptCore -framework WebKit \ - -framework TelephonyUI -framework SpringBoardUI \ - -Xarch_armv6 -Lsysroot/usr/lib -Xarch_armv6 -lpcre \ - -Xarch_arm64 -DUSE_ICU_REGEX -Xarch_arm64 -licucore \ -Wl,-U,__ZN3JSC7UString3Rep7destroyEv \ -Wl,-U,__ZN3JSC7UStringC1EPKc \ -Wl,-U,__ZN3JSC7UStringC1EPKti \ - -Wl,-U,__ZNK3JSC7UString6substrEii \ - -Wno-mismatched-tags -Wno-tautological-constant-out-of-range-compare + -Wl,-U,__ZNK3JSC7UString6substrEii install_name_tool -change /System/Library/{,Private}Frameworks/JavaScriptCore.framework/JavaScriptCore $@ ldid -S $@ -deb: all +WebCycriptLockScreen: WebCycript LockScreen.mm makefile + $(cycc) -bundle -isystem sysroot/usr/include \ + -framework Foundation -framework UIKit \ + -framework CydiaSubstrate WebCycript \ + -framework TelephonyUI -framework SpringBoardUI \ + -Xarch_armv6 -Lsysroot/usr/lib -Xarch_armv6 -lpcre \ + -Xarch_arm64 -DUSE_ICU_REGEX -Xarch_arm64 -licucore + +webcycript-deb: all sudo rm -rf package mkdir -p package/DEBIAN mkdir -p package/Library/MobileSubstrate/DynamicLibraries - sed -e 's/%/$(shell cycc -V)/' control.in >package/DEBIAN/control + sed -e 's/%/$(shell cycc -V)/' webcycript.in >package/DEBIAN/control + mkdir -p package/Library/Frameworks/WebCycript.framework/Headers + cp -a WebCycript.plist package/Library/Frameworks/WebCycript.framework/Info.plist + cp -a WebCycript package/Library/Frameworks/WebCycript.framework + cp -a WebCycript.h package/Library/Frameworks/WebCycript.framework/Headers + sudo chown -R 0 package + sudo chgrp -R 0 package + deb=$$(grep ^Package: package/DEBIAN/control | cut -d ' ' -f 2-)_$$(grep ^Version: package/DEBIAN/control | cut -d ' ' -f 2)_iphoneos-arm.deb; dpkg-deb -b package "$$deb"; ln -sfv "$$deb" webcycript.deb + +cydget-deb: all + sudo rm -rf package + mkdir -p package/DEBIAN + mkdir -p package/Library/MobileSubstrate/DynamicLibraries + sed -e 's/%/$(shell cycc -V)/' cydget.in >package/DEBIAN/control cp -a preinst package/DEBIAN mkdir -p package/Library/PreferenceLoader/Preferences; cp -a CydgetLoader.{dylib,plist} package/Library/MobileSubstrate/DynamicLibraries @@ -45,7 +62,7 @@ deb: all cp -a PhotoExample.cydget package/System/Library/LockCydgets/PhotoExample.cydget cp -a PhotoExamplePlus.cydget package/System/Library/LockCydgets/PhotoExamplePlus.cydget mkdir -p package/System/Library/SpringBoardPlugins/WebCycriptLockScreen.bundle - cp -a Info.plist package/System/Library/SpringBoardPlugins/WebCycriptLockScreen.bundle + cp -a WebCycriptLockScreen.plist package/System/Library/SpringBoardPlugins/WebCycriptLockScreen.bundle/Info.plist cp -a WebCycriptLockScreen package/System/Library/SpringBoardPlugins/WebCycriptLockScreen.bundle mkdir -p package/Library/PreferenceLoader/Preferences mkdir -p package/System/Library/PreferenceBundles @@ -56,3 +73,5 @@ deb: all sudo chown -R 0 package sudo chgrp -R 0 package deb=$$(grep ^Package: package/DEBIAN/control | cut -d ' ' -f 2-)_$$(grep ^Version: package/DEBIAN/control | cut -d ' ' -f 2)_iphoneos-arm.deb; dpkg-deb -b package "$$deb"; ln -sfv "$$deb" cydget.deb + +deb: webcycript-deb cydget-deb diff --git a/webcycript.in b/webcycript.in new file mode 100644 index 0000000..a8e3eab --- /dev/null +++ b/webcycript.in @@ -0,0 +1,12 @@ +Package: com.saurik.webcycript +Priority: optional +Section: System +Maintainer: Jay Freeman (saurik) +Architecture: iphoneos-arm +Version: % +Description: library support for Cycript in a UIWebView +Name: WebCycript +Depends: mobilesubstrate (>= 0.9.3366-1), firmware (<< 6.0) | mobilesubstrate (>= 0.9.4000), firmware (<< 7.0) | mobilesubstrate (>= 0.9.5001), firmware (>= 2.2), firmware (<< 8.2), cycript (>= 0.9.500~b1) +Author: Jay Freeman (saurik) +Depiction: http://cydia.saurik.com/info/com.saurik.webcycript/ +Tag: purpose::library, role::enduser -- 2.45.2