VirtualBox

Ignore:
Timestamp:
Mar 24, 2025 11:02:34 AM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168129
Message:

HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp: We don't support 32-bit x86 hosts anymore, so drop the dead code, bugref:10391 [revert as our 32bit buildboxes are unhappy, even though the code is never run, no time to fix this]

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/posix/SUPR3HardenedMain-posix.cpp

    r108711 r108712  
    510510
    511511#else  /* !RT_ARCH_AMD64 */
    512 # error "Port me"
     512    /*
     513     * Patch 32-bit hosts.
     514     */
     515    /* Just use the disassembler to skip 5 bytes or more. */
     516    while (offJmpBack < 5)
     517    {
     518        cbInstr = 1;
     519        int rc = DISInstr(pbTarget + offJmpBack, DISCPUMODE_32BIT, &Dis, &cbInstr);
     520        if (   RT_FAILURE(rc)
     521            || (   (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW)
     522                && Dis.pCurInstr->uOpcode != OP_CALL))
     523            return VERR_SUPLIB_UNEXPECTED_INSTRUCTION;
     524
     525        if (   Dis.pCurInstr->uOpcode == OP_CALL
     526            && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
     527            cbPatchMem += 10; /* push imm32 + jmp rel32 */
     528        else
     529            cbPatchMem += cbInstr;
     530
     531        offJmpBack += cbInstr;
     532    }
     533
     534    /* Allocate suitable exectuable memory available. */
     535    uint8_t *pbPatchMem = supR3HardenedMainPosixExecMemAlloc(cbPatchMem, pbTarget, false /* fRipRelAddr */);
     536    if (!pbPatchMem)
     537        return VERR_NO_MEMORY;
     538
     539    /* Assemble the code for resuming the call.*/
     540    *ppfnReal = (uintptr_t)pbPatchMem;
     541
     542    /* Go through the instructions to patch and fixup any relative call instructions. */
     543    uint32_t offInsn = 0;
     544    while (offInsn < offJmpBack)
     545    {
     546        cbInstr = 1;
     547        int rc = DISInstr(pbTarget + offInsn, DISCPUMODE_32BIT, &Dis, &cbInstr);
     548        if (   RT_FAILURE(rc)
     549            || (   (Dis.pCurInstr->fOpType & DISOPTYPE_CONTROLFLOW)
     550                && Dis.pCurInstr->uOpcode != OP_CALL))
     551            return VERR_SUPLIB_UNEXPECTED_INSTRUCTION;
     552
     553        if (   Dis.pCurInstr->uOpcode == OP_CALL
     554            && (Dis.pCurInstr->fOpType & DISOPTYPE_RELATIVE_CONTROLFLOW))
     555        {
     556            /*
     557             * Don't use a call instruction directly but push the original return address
     558             * onto the stack and use a relative jump to the call target.
     559             * The reason here is that on Linux the called method saves the return
     560             * address from the stack which will be different from the original because
     561             * the code is executed from our patch memory.
     562             *
     563             * Luckily the call instruction is 5 bytes long which means it is always the
     564             * last instruction to patch and we don't need to return from the call
     565             * to patch memory anyway but can use this method to resume the original call.
     566             */
     567            AssertReturn(offInsn + cbInstr >= offJmpBack, VERR_SUPLIB_UNEXPECTED_INSTRUCTION); /* Must be last instruction! */
     568
     569            /* push return address */
     570            uint32_t const uAddrReturn = (uintptr_t)&pbTarget[offInsn + cbInstr]; /* The return address to push to the stack. */
     571
     572            *pbPatchMem++           = 0x68; /* push dword */
     573            *(uint32_t *)pbPatchMem = uAddrReturn;
     574            pbPatchMem             += sizeof(uint32_t);
     575
     576            /* jmp rel32 to the call target */
     577            uintptr_t const uAddr      = uAddrReturn + (int32_t)Dis.aParams[0].uValue;
     578            int32_t   const i32DispNew = uAddr - (uintptr_t)&pbPatchMem[5];
     579
     580            *pbPatchMem++          = 0xe9; /* jmp rel32 */
     581            *(int32_t *)pbPatchMem = i32DispNew;
     582            pbPatchMem            += sizeof(int32_t);
     583        }
     584        else
     585        {
     586            memcpy(pbPatchMem, pbTarget + offInsn, cbInstr);
     587            pbPatchMem += cbInstr;
     588        }
     589
     590        offInsn += cbInstr;
     591    }
     592
     593    *pbPatchMem++ = 0xe9; /* jmp rel32 */
     594    *(uint32_t *)pbPatchMem = (uintptr_t)&pbTarget[offJmpBack] - ((uintptr_t)pbPatchMem + 4);
     595
     596    /* Assemble the patch. */
     597    Assert(offJmpBack >= 5);
     598    pbTarget[0] = 0xe9;
     599    *(uint32_t *)&pbTarget[1] = (uintptr_t)pfnHook - (uintptr_t)&pbTarget[1+4];
    513600#endif /* !RT_ARCH_AMD64 */
    514601
Note: See TracChangeset for help on using the changeset viewer.

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