VirtualBox

vbox的更動 66794 路徑 trunk/src/VBox/HostDrivers


忽略:
時間撮記:
2017-5-4 下午01:09:36 (8 年 以前)
作者:
vboxsync
訊息:

Support: Implement strategy for relative call instructions when hooking the dlopen()++ interface

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp

    r66632 r66794  
    342342     */
    343343    uint32_t cRipRelMovs = 0;
     344    uint32_t cRelCalls = 0;
    344345
    345346    /* Just use the disassembler to skip 12 bytes or more, we might need to
     
    350351        int rc = DISInstr(pbTarget + offJmpBack, DISCPUMODE_64BIT, &Dis, &cbInstr);
    351352        if (   RT_FAILURE(rc)
    352             || (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW)
     353            || (   Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW
     354                && Dis.pCurInstr->uOpcode != OP_CALL)
    353355            || (   Dis.ModRM.Bits.Mod == 0
    354356                && Dis.ModRM.Bits.Rm  == 5 /* wrt RIP */
     
    358360        if (Dis.ModRM.Bits.Mod == 0 && Dis.ModRM.Bits.Rm == 5 /* wrt RIP */)
    359361            cRipRelMovs++;
     362        if (   Dis.pCurInstr->uOpcode == OP_CALL
     363            && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
     364            cRelCalls++;
    360365
    361366        offJmpBack += cbInstr;
     
    363368    }
    364369
     370    /*
     371     * Each relative call requires 7 extra bytes as it is converted to an absolute one
     372     * using two instructions (mov raw, qword + call rax). */
     373    cbPatchMem += cRelCalls * 7;
    365374    cbPatchMem += 14; /* jmp qword [$+8 wrt RIP] + 8 byte address to jump to. */
    366375    cbPatchMem = RT_ALIGN_32(cbPatchMem, 8);
    367376
    368     /* Allocate suitable exectuable memory available. */
     377    /* Allocate suitable executable memory available. */
    369378    bool fConvRipRelMovs = false;
    370379    uint8_t *pbPatchMem = supR3HardenedMainPosixExecMemAlloc(cbPatchMem, pbTarget, cRipRelMovs > 0);
     
    397406        int rc = DISInstr(pbTarget + offInsn, DISCPUMODE_64BIT, &Dis, &cbInstr);
    398407        if (   RT_FAILURE(rc)
    399             || (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW))
     408            || (   Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW
     409                && Dis.pCurInstr->uOpcode != OP_CALL))
    400410            return VERR_SUPLIB_UNEXPECTED_INSTRUCTION;
    401411
     
    439449                pbPatchMem   += sizeof(int32_t);
    440450            }
     451        }
     452        else if (   Dis.pCurInstr->uOpcode == OP_CALL
     453                 && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
     454        {
     455            /* Convert to absolute call. */
     456            uintptr_t uAddr = (uintptr_t)&pbTarget[offInsn + cbInstr] + (intptr_t)Dis.Param1.uValue;
     457
     458            *pbPatchMem++ = 0x48;
     459            *pbPatchMem++ = 0xb8;
     460            *(uint64_t *)pbPatchMem = uAddr;
     461            pbPatchMem   += sizeof(uint64_t);
     462
     463            *pbPatchMem++ = 0xff; /* call rax */
     464            *pbPatchMem++ = 0xd0;
    441465        }
    442466        else
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette