From 4e8fa43bd9b2c4738aaec9c9df6a67aa1d02c540 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Sun, 8 Nov 2009 14:13:14 +0000 Subject: [PATCH] Finished implementing text/cycript. --- LockScreen.mm | 170 ++++++++++++++++++++++++++++++++++++++++++++------ Welcome.html | 14 ++++- control | 4 +- make.sh | 2 +- makefile | 2 +- 5 files changed, 168 insertions(+), 24 deletions(-) diff --git a/LockScreen.mm b/LockScreen.mm index f1963e7..06a6d4f 100644 --- a/LockScreen.mm +++ b/LockScreen.mm @@ -69,8 +69,10 @@ extern NSString * const kCAFilterNearest; #include #include -//#include "Parser.h" #include "JSGlobalData.h" +#include "SourceCode.h" + +#include @interface WebView (UICaboodle) - (void) setScriptDebugDelegate:(id)delegate; @@ -95,8 +97,6 @@ _disused static unsigned trace_; - (NSDictionary *) currentConfiguration; @end -static void (*CYSetupContext)(JSGlobalContextRef); - static Class $CydgetController(objc_getClass("CydgetController")); @interface NSString (UIKit) @@ -296,6 +296,7 @@ static Class $CydgetController(objc_getClass("CydgetController")); [scroller_ release]; [indicator_ release]; + [loading_ release]; [super dealloc]; } @@ -358,6 +359,8 @@ static Class $CydgetController(objc_getClass("CydgetController")); frame.size.height -= GSDefaultStatusBarHeight(); if ((self = [super initWithFrame:frame]) != nil) { + loading_ = [[NSMutableSet alloc] initWithCapacity:3]; + struct CGRect bounds([self bounds]); scroller_ = [[UIScroller alloc] initWithFrame:bounds]; @@ -592,12 +595,14 @@ static Class $CydgetController(objc_getClass("CydgetController")); } - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { - if (cycript_ && CYSetupContext != NULL) { - WebView *webview([document_ webView]); - WebFrame *frame([webview mainFrame]); - JSGlobalContextRef context([frame globalContext]); - CYSetupContext(context); - } + if (cycript_) + if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) + if (void (*CYSetupContext)(JSGlobalContextRef) = reinterpret_cast(dlsym(handle, "CYSetupContext"))) { + WebView *webview([document_ webView]); + WebFrame *frame([webview mainFrame]); + JSGlobalContextRef context([frame globalContext]); + CYSetupContext(context); + } } - (bool) isLoading { @@ -605,10 +610,13 @@ static Class $CydgetController(objc_getClass("CydgetController")); } - (void) reloadButtons { - if ([self isLoading]) + if ([self isLoading]) { + [UIApp setNetworkActivityIndicatorVisible:YES]; [indicator_ startAnimation]; - else + } else { + [UIApp setNetworkActivityIndicatorVisible:NO]; [indicator_ stopAnimation]; + } } - (void) _finishLoading { @@ -712,10 +720,94 @@ static Class $CydgetController(objc_getClass("CydgetController")); @end -/*extern "C" void _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(JSC::Parser *, JSC::JSGlobalData *, int *, JSC::UString *); -MSHook(void, _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, JSC::Parser *_this, JSC::JSGlobalData *data, int *line, JSC::UString *message) { - return __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, data, line, message); -}*/ +#include + +static bool cycript_; +static bool jscript_; + +static void SetParser(bool cycript, bool jscript) { + cycript_ = cycript; + jscript_ = jscript; +} + +static bool GetParser0() { + return cycript_; +} + +static bool GetParser1() { + return jscript_; +} + +static void Cycriptify(apr_pool_t *pool, const uint16_t *&data, size_t &size) { + if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) + if (void (*CYParseUChar)(apr_pool_t *, const uint16_t **, size_t *) = reinterpret_cast(dlsym(handle, "CYParseWebCore"))) + CYParseUChar(pool, &data, &size); +} + +MSHook(void, _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, JSC::SourceCode **_this, JSC::JSGlobalData *global, int *line, JSC::UString *message) { + if (!GetParser0()) + return __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, global, line, message); + else { + SetParser(false, true); + JSC::SourceCode *source(*_this); + const uint16_t *data(source->data()); + size_t size(source->length()); + apr_pool_t *pool; + apr_pool_create(&pool, NULL); + Cycriptify(pool, data, size); + std::string stuff(data, data + size); + JSC::SourceCode code(JSC::makeSource(JSC::UString(data, size))); + *_this = &code; + __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE(_this, global, line, message); + apr_pool_destroy(pool); + *_this = source; + } +} + +MSHook(void, _ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE, void *_this, int start, const UChar *code, unsigned length, int *source, int *line, JSC::UString *message) { + if (!GetParser0()) + return __ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE(_this, start, code, length, source, line, message); + else { + const uint16_t *data(code); + size_t size(length); + apr_pool_t *pool; + apr_pool_create(&pool, NULL); + Cycriptify(pool, data, size); + __ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE(_this, start, data, size, source, line, message); + apr_pool_destroy(pool); + } +} + +struct State { + unsigned state; +}; + +MSHook(State, _ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE, State state) { + SetParser(false, true); + state = __ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE(state); + SetParser(false, false); + return state; +} + +MSHook(void, _ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE, void *resource) { + SetParser(false, true); + __ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE(resource); + SetParser(false, false); +} + +MSHook(bool, _ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, const WebCore::String &mime) { + bool jscript; + + if (!GetParser1()) through: + jscript = __ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE(mime); + else if (mime == "text/cycript") { + SetParser(true, true); + jscript = true; + } else + goto through; + + return jscript; +} /* Cydget:// Protocol {{{ */ @interface CydgetURLProtocol : NSURLProtocol { @@ -789,13 +881,55 @@ MSHook(void, _ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, JSC::Parse @end /* }}} */ +template +static void nlset(Type_ &function, struct nlist *nl, size_t index) { + struct nlist &name(nl[index]); + uintptr_t value(name.n_value); + if ((name.n_desc & N_ARM_THUMB_DEF) != 0) + value |= 0x00000001; + function = reinterpret_cast(value); +} + +template +static void dlset(Type_ &function, const char *name) { + function = reinterpret_cast(dlsym(RTLD_DEFAULT, name)); +} + @implementation WebCycriptLockScreenController + (void) initialize { + apr_initialize(); + [NSURLProtocol registerClass:[CydgetURLProtocol class]]; - //MSHookFunction(&_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE, MSHake(_ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE)); - if (void *handle = dlopen("/usr/lib/libcycript.dylib", RTLD_LAZY | RTLD_GLOBAL)) - CYSetupContext = reinterpret_cast(dlsym(handle, "CYSetupContext")); + + 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)); + + void (*_ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE)(void *, int, const UChar *, unsigned, int *, int *, JSC::UString *); + dlset(_ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE, "_ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE"); + if (_ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE != NULL) + MSHookFunction(_ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE, MSHake(_ZN3KJS6Parser5parseEiPKNS_5UCharEjPiS4_PNS_7UStringE)); + + struct nlist nl[4]; + memset(nl, 0, sizeof(nl)); + nl[0].n_un.n_name = (char *) "__ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE"; + nl[1].n_un.n_name = (char *) "__ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE"; + nl[2].n_un.n_name = (char *) "__ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE"; + nlist("/System/Library/PrivateFrameworks/WebCore.framework/WebCore", nl); + + State (*_ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE)(State); + nlset(_ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE, nl, 0); + MSHookFunction(_ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE, MSHake(_ZN7WebCore13HTMLTokenizer13scriptHandlerENS0_5StateE)); + + void (*_ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE)(void *); + nlset(_ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE, nl, 1); + MSHookFunction(_ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE, MSHake(_ZN7WebCore13HTMLTokenizer14notifyFinishedEPNS_14CachedResourceE)); + + bool (*_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE)(const WebCore::String &); + nlset(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, nl, 2); + MSHookFunction(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE, MSHake(_ZN7WebCore16MIMETypeRegistry29isSupportedJavaScriptMIMETypeERKNS_6StringE)); } + (id) rootViewController { diff --git a/Welcome.html b/Welcome.html index 0863bb7..724f319 100644 --- a/Welcome.html +++ b/Welcome.html @@ -72,18 +72,28 @@ }
-

 

+

+

Welcome to Cydget!

Cydgettm is a very simple SBAwayViewPlugin multiplexer, allowing both developers and web designers to extend the capabilities of the lock screen by tapping into the existing mechanism Apple is already using for VoiceRecorder and Nike+. The WebCycript Cydget framework is designed to be a powerful replacement for the Lock Widget feature from WinterBoard, which it hereby supercedes.

+ Home

You can switch between Cydgets (your original SpringBoard away view is next in the rotation) using the Home/Menu button, and you can re-order them using Settings under "Cydget".

-