第零章 WebKit 霸氣修改

js容錯(cuò)機(jī)制修改

JITExceptions.cpp:

//未修改前代碼
void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
{
    RELEASE_ASSERT(exceptionValue);
    HandlerInfo* handler = vm->interpreter->unwind(callFrame, exceptionValue); // This may update callFrame.

    void* catchRoutine;
    Instruction* catchPCForInterpreter = 0;
    if (handler) {
        catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
#if ENABLE(JIT)
        catchRoutine = handler->nativeCode.executableAddress();
#else
        catchRoutine = catchPCForInterpreter->u.pointer;
#endif
    } else
        catchRoutine = LLInt::getCodePtr(returnFromJavaScript);
    
    vm->callFrameForThrow = callFrame;
    vm->targetMachinePCForThrow = catchRoutine;
    vm->targetInterpreterPCForThrow = catchPCForInterpreter;
    
    RELEASE_ASSERT(catchRoutine);
}
//修改之后代碼
void genericUnwind(VM* vm, ExecState* callFrame, JSValue exceptionValue)
{
    RELEASE_ASSERT(exceptionValue);
    ExecState* saveCallFrame = callFrame;
    HandlerInfo* handler = vm->interpreter->unwind(callFrame, exceptionValue); // This may update callFrame.

    void* catchRoutine;
    Instruction* catchPCForInterpreter = 0;
    if (handler) {
        catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
#if ENABLE(JIT)
        catchRoutine = handler->nativeCode.executableAddress();
#else
        catchRoutine = catchPCForInterpreter->u.pointer;
#endif
    }
    else{
#ifndef USE_UTSTARCOM
        catchRoutine = LLInt::getCodePtr(returnFromJavaScript);
#else
        Instruction* vpc = saveCallFrame->currentVPC() - 1;
        unsigned int line = 0, column = 0;
        if (vm->exceptionStack().size() > 0) {
            String file = vm->exceptionStack()[0].friendlySourceURL();
            ULOG("[JS] catch js exception file:%s(%d)", file.ascii().data(), vm->exceptionStack()[0].lineOffset + vm->exceptionStack()[0].firstLineColumnOffset);
        }
        ULOG("[JS] catch js exception op len:%d", opcodeLength(vm->interpreter->getOpcodeID(vpc->u.opcode)));
        if (opcodeLength(vm->interpreter->getOpcodeID(vpc->u.opcode)) == 0){
            catchRoutine = LLInt::getCodePtr(returnFromJavaScript);
            goto END;
        }
        catchPCForInterpreter = vpc + opcodeLength(vm->interpreter->getOpcodeID(vpc->u.opcode));
#if ENABLE(JIT)
        catchRoutine = handler->nativeCode.executableAddress();
#else
        catchRoutine = catchPCForInterpreter->u.pointer;
#endif
        ULOG("[JS] catch js exception 2");
        vm->clearException();
        vm->clearExceptionStack();
#endif
    }

    END:
    vm->callFrameForThrow = callFrame;
    vm->targetMachinePCForThrow = catchRoutine;
    vm->targetInterpreterPCForThrow = catchPCForInterpreter;
    
    RELEASE_ASSERT(catchRoutine);
}

LLIntSlowPaths.cpp:

//未修改前代碼
LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
{
    LLINT_BEGIN_NO_SET_PC();
    ASSERT(vm.exception());
    genericUnwind(&vm, exec, vm.exception());
    LLINT_END_IMPL();
}
//修改之后代碼
LLINT_SLOW_PATH_DECL(slow_path_handle_exception)
{
    LLINT_BEGIN_NO_SET_PC();
    ASSERT(vm.exception());
    genericUnwind(&vm, exec, vm.exception());
#ifdef USE_UTSTARCOM
    if (vm.exception() == JSValue()){
        Instruction* vpc = exec->currentVPC() - 1;
        if (opcodeLength(exec->interpreter()->getOpcodeID(vpc->u.opcode)) == 0){
            goto END;
        }
        pc = vpc + opcodeLength(exec->interpreter()->getOpcodeID(vpc->u.opcode));
    }
    END:
#endif
    LLINT_END_IMPL();
}
//修改之前代碼
LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
{
    LLINT_BEGIN();
    const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
    JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
    ResolveModeAndType modeAndType(pc[4].u.operand);

    PropertySlot slot(scope);
    if (!scope->getPropertySlot(exec, ident, slot)) {
        if (modeAndType.mode() == ThrowIfNotFound)
            LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
        LLINT_RETURN(jsUndefined());
    }

    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
    if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
        if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
            CodeBlock* codeBlock = exec->codeBlock();
            ConcurrentJITLocker locker(codeBlock->m_lock);
            pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
            pc[6].u.pointer = reinterpret_cast<void*>(slot.cachedOffset());
        }
    }

    LLINT_RETURN(slot.getValue(exec, ident));
}
//修改之后代碼
LLINT_SLOW_PATH_DECL(slow_path_get_from_scope)
{
    LLINT_BEGIN();
    const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
    JSObject* scope = jsCast<JSObject*>(LLINT_OP(2).jsValue());
    ResolveModeAndType modeAndType(pc[4].u.operand);

    PropertySlot slot(scope);
    if (!scope->getPropertySlot(exec, ident, slot)) {
#ifndef USE_UTSTARCOM
        if (modeAndType.mode() == ThrowIfNotFound)
            LLINT_RETURN(exec->vm().throwException(exec, createUndefinedVariableError(exec, ident)));
#endif
        LLINT_RETURN(jsUndefined());
    }

    // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
    if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
        if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
            CodeBlock* codeBlock = exec->codeBlock();
            ConcurrentJITLocker locker(codeBlock->m_lock);
            pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
            pc[6].u.pointer = reinterpret_cast<void*>(slot.cachedOffset());
        }
    }

    LLINT_RETURN(slot.getValue(exec, ident));
}

跨域修改

SecurityOrigin.cpp:

修改1

修改2

一種js注入邏輯(通過讀取xml形式)

int WebFrame_js_css_inject(void* handle, const char* filename)
{
    int ret = 0;
    WebView* view = (WebView*)handle;

    if (!handle)
        return -1;
    
    if (!filename)
        return -1;

    URL url = URL(ParsedURLString, "JsCssInject");
    Vector<String> whitelist;
    Vector<String> blacklist;
    int isJS = 1;
    int itemChildNum = 0;
    JsCssInjectTime injectTime = JsCssInjectAtTop;
    
    xmlDocPtr doc;
    xmlNodePtr rootNode = NULL;
    xmlNodePtr childNode = NULL;
    xmlNodePtr itemNodePtr = NULL;
    xmlNodePtr itemChildPtr = NULL;
    xmlNodePtr urlNodePtr = NULL;

    xmlKeepBlanksDefault(0);
        
    doc = xmlReadFile(filename, "UTF8", XML_PARSE_RECOVER); //讀取xml文件

    if (doc==NULL){
        fprintf(stderr,"Document not parsed successfully.\n");
        return -1;
    }

    rootNode = xmlDocGetRootElement(doc); //獲取根部節(jié)點(diǎn)
    if (NULL == rootNode){
        fprintf(stderr,"empty document\n");
        xmlFreeDoc(doc);
        return -1;
    } 

    if (xmlStrcmp(rootNode->name, BAD_CAST "resource")) {
        fprintf(stderr,"document of the wrong type, root node != InjectFile");
        xmlFreeDoc(doc);
        return -1;
    }

    childNode = rootNode->children;

    while (childNode != NULL) {
        if (!xmlStrcmp(childNode->name, BAD_CAST "item"))
            itemNodePtr = childNode;

        if (itemNodePtr != NULL) {
            /* 清除黑白名單url*/
            whitelist.clear();
            blacklist.clear();
            char *source = NULL;
            itemChildNum = 0;
            
            itemChildPtr = itemNodePtr->children;
            while (itemChildPtr != NULL) {
                if (!xmlStrcmp(itemChildPtr->name, BAD_CAST "whitelist")) {
                    urlNodePtr = itemChildPtr->children;
                    while (urlNodePtr != NULL) {
                        if (!xmlStrcmp(urlNodePtr->name, BAD_CAST "url")) {
                            char *value = (char*)xmlNodeGetContent(urlNodePtr);
                            whitelist.append(value);
                            xmlFree(value);
                        }
                        urlNodePtr = urlNodePtr->next;
                    }
                    itemChildNum++;
                } else if (!xmlStrcmp(itemChildPtr->name, BAD_CAST "blacklist")) {
                    urlNodePtr = itemChildPtr->children;
                    while (urlNodePtr != NULL) {
                        if (!xmlStrcmp(urlNodePtr->name, BAD_CAST "url")) {
                            char *value = (char*)xmlNodeGetContent(urlNodePtr);
                            blacklist.append(value);
                            xmlFree(value);
                        }
                        urlNodePtr = urlNodePtr->next;
                    }
                    itemChildNum++;
                } else if ((!xmlStrcmp(itemChildPtr->name, BAD_CAST "type"))) {
                    xmlChar *value = xmlNodeGetContent(itemChildPtr);
                    if(!xmlStrcasecmp(value, BAD_CAST "css"))
                        isJS = 0;
                    else if (!xmlStrcasecmp(value, BAD_CAST "js"))
                        isJS = 1;
                    else {
                        xmlFree(value);
                        break;
                    }
                    itemChildNum++;
                    xmlFree(value);
                } else if ((!xmlStrcmp(itemChildPtr->name, BAD_CAST "position"))) {
                    xmlChar *value = xmlNodeGetContent(itemChildPtr);
                    if (!xmlStrcasecmp(value, BAD_CAST "top"))
                        injectTime = JsCssInjectAtTop;
                    else if (!xmlStrcasecmp(value, BAD_CAST "bottom"))
                        injectTime = JsCssInjectAtBottom;
                    else {
                        xmlFree(value);
                        break;
                    }
                    itemChildNum++;
                    xmlFree(value);
                } else if ((!xmlStrcmp(itemChildPtr->name, BAD_CAST "file"))) {
                    char* value = (char*)xmlNodeGetContent(itemChildPtr);
                    if (!common_fileExists(value)) {
                        xmlFree(value);
                        break;
                    }

                    PlatformFileHandle fileHandle;
                    fileHandle = common_openFile(value, 0);
                    if (fileHandle == invalidPlatformFileHandle) {
                        xmlFree(value);
                        break;
                    }

                    long long filesize;
                    if (!common_getFileSize(value, filesize)) {
                        xmlFree(value);
                        break;
                    }

                    source = (char *)malloc((filesize + 1) * sizeof(char));
                    memset(source, 0, (filesize + 1) * sizeof(char));
                    
                    if (!common_readFromFile(fileHandle, source, filesize)) {
                        xmlFree(value);
                        break;
                    }

                    itemChildNum++;
                    xmlFree(value);
                }       
                itemChildPtr = itemChildPtr->next;
            }

            if (itemChildNum == 5) {
                if (isJS)
                    view->addUserScript(String(source), url, whitelist, blacklist, injectTime);
                else
                    view->addUserStyleSheet(String(source), url, whitelist, blacklist, injectTime);
            }
            if (source)
                free(source);
        }
        itemNodePtr = NULL;
        childNode = childNode->next;
    }

    
    xmlFreeDoc(doc);
    xmlCleanupParser();
    return ret ? 0 : -1;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末着帽,一起剝皮案震驚了整個(gè)濱河市瓶盛,隨后出現(xiàn)的幾起案子聚至,更是在濱河造成了極大的恐慌凉泄,老刑警劉巖秦叛,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轰豆,死亡現(xiàn)場離奇詭異迷殿,居然都是意外死亡乱顾,警方通過查閱死者的電腦和手機(jī)盟戏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門绪妹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人柿究,你說我怎么就攤上這事邮旷。” “怎么了蝇摸?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵婶肩,是天一觀的道長。 經(jīng)常有香客問我貌夕,道長律歼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任啡专,我火速辦了婚禮险毁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘们童。我一直安慰自己畔况,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布慧库。 她就那樣靜靜地躺著跷跪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪齐板。 梳的紋絲不亂的頭發(fā)上吵瞻,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音甘磨,去河邊找鬼听皿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宽档,可吹牛的內(nèi)容都是我干的尉姨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼吗冤,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼又厉!你這毒婦竟也來了九府?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤覆致,失蹤者是張志新(化名)和其女友劉穎侄旬,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煌妈,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡儡羔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了璧诵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汰蜘。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖之宿,靈堂內(nèi)的尸體忽然破棺而出族操,到底是詐尸還是另有隱情,我是刑警寧澤比被,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布色难,位于F島的核電站,受9級(jí)特大地震影響等缀,放射性物質(zhì)發(fā)生泄漏枷莉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一尺迂、第九天 我趴在偏房一處隱蔽的房頂上張望依沮。 院中可真熱鬧,春花似錦枪狂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至皇拣,卻和暖如春严蓖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背氧急。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工颗胡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吩坝。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓毒姨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钉寝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子弧呐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,774評(píng)論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法闸迷,類相關(guān)的語法,內(nèi)部類的語法俘枫,繼承相關(guān)的語法腥沽,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評(píng)論 18 399
  • 【轉(zhuǎn)載】CSDN - 張林blog http://blog.csdn.net/XIAOZHUXMEN/articl...
    竿牘閱讀 3,481評(píng)論 1 14
  • 找到真我 成為它 成就它 才是真正的愛自已啊 什么是真我呢 就是真實(shí)的自已啊 如何找到真我呢 那就去了解自...
    雪莉詩話閱讀 339評(píng)論 0 1
  • 人要是能在世上活得好鸠蚪,活得幸福今阳,不會(huì)尋找神的,正因?yàn)槿嘶畹貌缓妹┬牛詫ふ叶苌唷R驗(yàn)椴恢阑畹貌缓玫脑蚓褪呛蜕穹珠_,所...
    MO若耶閱讀 232評(píng)論 0 2