天天看點

iOS Safari閱讀模式分析過程

1. Break on evaluate

  b JSC::evaluate(JSC::ExecState*, JSC::ScopeChainNode*, JSC::SourceCode const&, JSC::JSValue, JSC::JSValue*)

  dump the source content from JSC::SourceCode

iOS Safari閱讀模式分析過程

Printing description of source.m_provider.m_ptr->m_url:

(WTF::String) m_url = { length = 0, contents = '' } {

  m_impl = {

    m_ptr = 0x0000000000000000 { length = 0, is8bit = 0, contents = '' }

  }

}

Printing description of source.m_provider.m_ptr->m_source:

(WTF::String) m_source = { length = 66370, contents = '/*

 * Copyright © 2010 Apple Inc. All rights reserved.

 */

 ……

2. Call Stack

iOS Safari閱讀模式分析過程

3. (lldb) image list

[  0] 396DF4E9-18D6-3C39-B1FB-E783D7F9B947 0x00001000 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk/Applications/MobileSafari.app/MobileSafari 

-> JSEvaluateScript

0x70224(0x702a5) -> 

0x6fdc8(0x6fe19) -> 

0x6fd9a(0x6fdb5) -> XREF:-[ReaderTestProcessor _processReaderTestResult:tabDocument:] & -[ReaderContext isReaderAvailable] 

0x6eac5(0x6eae5) -> -[ReaderContext isReaderAvailable] 

0xa3d84(0xa3dd3) -> XREF:-[TabDocument _detectReaderAvailabilityOnWebThread]

HandleRunSource

i. 查找起點

iOS Safari閱讀模式分析過程

  3483 -> 0xa3d15  -[TabDocument _detectReaderAvailabilityOnWebThread]

  3490 -> 0xa3f56(0xa404b)  -[TabDocument _detectReaderAvailabilityNow]

ii. 誰發起了_detectReaderAvailabilityNow

-[BrowserController stopFromAddressView:] 

-[TabDocument _progressDidStall]

-[TabDocument webView:didFinishLoadForFrame:]  

    ->   -[TabDocument detectReaderAvailabilitySoon] 

iOS Safari閱讀模式分析過程

  3496->0xa4279  -[TabDocument detectReaderAvailabilitySoon] 

  3274-> 0x9c16b (0x9c1ad) -[TabDocument webView:didFinishLoadForFrame:] 

4. (FAILED)

b -[UIView setHidden:]

(lldb) showParameters 3

$56 = 0x09a43aa0 <ReaderButtonView: 0x1a39ca50; baseClass = UIButton; frame = (276 2; 49 27); alpha = 0; opaque = NO; layer = <CALayer: 0x1a398610>>

0x08d60840: "setHidden:"

5. 

b -[UIView setFrame:]

$26 = 0x0a984730 <ReaderButtonView: 0x9af39d0; baseClass = UIButton; frame = (276 2; 49 27); alpha = 0; opaque = NO; layer = <CALayer: 0x9a6fb60>>

0x07b37881: "setFrame:"

0x07b3788b: "addSubview:"

iOS Safari閱讀模式分析過程

96 -> 0x6d38 (0x6f9d):  -[AddressView _layoutReloadButtonForProgressViewFrame:forEditing:textField:showInactiveFieldWhileEditing:]

257 -> 0x126a4 (0x1288a): -[AddressView layoutReaderButton]

3482 -> 0xa3927 (0xa3caf): -[TabDocument _didDetectReaderAvailability:]

3485 -> 0xa3e3f (0xa3e6b): (MEM:didDetectReaderAvailability)

-[AddressViewaccessibility(SafeCategory) layoutReaderButton]

6. (FAILED)

根據WebKit Objective-C Programming Guide, 擷取JS資料需要先擷取window對象:

    id win =  [webview windowScriptObject];

前且所有的JS對象是使用WebScriptObject包裝起來的。

Summary: WebCore`-[WebScriptObject valueForKey:]        Address: WebCore[0x00d35b30] (WebCore.__TEXT.__text + 13843984)

(lldb) b WebCore`-[WebScriptObject valueForKey:]

Breakpoint 14: where = WebCore`-[WebScriptObject valueForKey:], address = 0x03581700

7. 

TabDocument::- (void)_detectReaderAvailabilityNow;     // IMP=0x000a3f56- (void)_detectReaderAvailabilityOnWebThread;     // IMP=0x000a3d15

- (void)_didDetectReaderAvailability:(BOOL)arg1;     // IMP=0x000a3927

8.

  var ReaderArticleFinderJS = new ReaderArticleFinder(document);

iOS Safari閱讀模式分析過程

6fdc8(6fe24) -> 1b3ba(1b3d6) -> isReaderModeAvailable

9. break at JSObjectGetProperty

(lldb) p/x `*(int*)($ebp+16)`

(int) $33 = 0x000debdf

(lldb) mem read `$33`

0x000debdf: 69 73 52 65 61 64 65 72 4d 6f 64 65 41 76 61 69  isReaderModeAvai

0x000debef: 6c 61 62 6c 65 00 70 72 65 70 61 72 65 54 6f 54  lable.prepareToT

10. 還需要再擷取對象

iOS Safari閱讀模式分析過程

450 -> 0x1b774(0x1b777) ->  return ReaderArticleFinderJS

1656 -> 0x5a70c (0x5a76e) ->

2193 -> 0x70224 (0x70315) ->

2186 -> 0x6fdc8 (0x6fe19) ->

2185 ->0x6fd9a(0x6fdb5) -> XREF:-[ReaderTestProcessor _processReaderTestResult:tabDocument:] & -[ReaderContext isReaderAvailable] 

2125 ->0x6eac5(0x6eae5) -> -[ReaderContext isReaderAvailable] 

3484 -> 0xa3d84(0xa3dd3) -> XREF:-[TabDocument _detectReaderAvailabilityOnWebThread] 

11. click the "Reader" button

0.

a.再次确認Reader Mode

iOS Safari閱讀模式分析過程

2193->0x70224 (0x702a5)

2186->0x6fdc8(0x6fe19)

2195->0x70372(0x70387) WebThreadLock, call 6fdc8.

2146->0x6f3cd(0x6f3f1) -> -[ReaderContext createArticleFinder]

978-> 0x38445(0x384f5) [BrowserController setShowingReader:animated]

122 -> 0x995c(0x99bc) ->

        bShowing = [[BrowserController sharedBrowserController] isShowingReader];

        [[BrowserController sharedBrowserController] setShowingReader:bShowing animated:YES]

b. 顯示出内容

i.加載html檔案

iOS Safari閱讀模式分析過程

-> loadRequest (Reader~ipad.html)

2132 ->0x6ee1e (0x6ee96) [ReaderContext loadReaderDocument]

2118 ->0x6e85b (0x6e959) [ReaderContext createWebViewIfNeeded]

3491->0xa4053 (0xa4097) [TabDocument createBrowserReaderViewIfNeeded]

979 ->0x38549 (0x38610) [BrowserController showReaderForTabDocument]

978-> 0x38445(0x38526)  [BrowserController setShowingReader:animated]

122 ->0x995c(0x99bc)

     bShowing = [[BrowserController sharedBrowserController] isShowingReader];

        [[BrowserController sharedBrowserController] setShowingReader:bShowing animated:YES] 

ii. 在WebView允許修改window object時,執行閱讀模式處理腳本

iOS Safari閱讀模式分析過程

 2205 -> 0x705ce (0x7066f)

 2127 -> 0x6eb17 (0x6eb62) -[ReaderContext initReaderJSController:] 

1296 -> 0x4952c (0x49588) [BrowserReaderView uiWebView:didClearWindowObject:forFrame]

iii. 頁面加載後會執行JS:

     <body class="preloading" onload="ReaderJS.loaded();" onscroll="articleHasScrolled();">  

繼續閱讀