mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 951827 - Part 3: Give trampolines some structure. r=ehsan
This commit is contained in:
parent
bc116ff55b
commit
4a4492190f
@ -236,7 +236,8 @@ public:
|
||||
#else
|
||||
#error "Unknown processor type"
|
||||
#endif
|
||||
byteptr_t origBytes = *((byteptr_t *)p);
|
||||
Trampoline *tramp = (Trampoline*)p;
|
||||
byteptr_t origBytes = (byteptr_t)tramp->origFunction;
|
||||
|
||||
// If CreateTrampoline failed, we may have an empty trampoline.
|
||||
if (!origBytes) {
|
||||
@ -264,7 +265,7 @@ public:
|
||||
}
|
||||
// Remove the hook by making the original function jump directly
|
||||
// in the trampoline.
|
||||
intptr_t dest = (intptr_t)(p + sizeof(void *));
|
||||
intptr_t dest = (intptr_t)(&tramp->code[0]);
|
||||
#if defined(_M_IX86)
|
||||
*((intptr_t*)(origBytes+1)) = dest - (intptr_t)(origBytes+5); // target displacement
|
||||
#elif defined(_M_X64)
|
||||
@ -344,6 +345,7 @@ public:
|
||||
protected:
|
||||
const static int kPageSize = 4096;
|
||||
const static int kHookSize = 128;
|
||||
const static int kCodeSize = 100;
|
||||
|
||||
const static uint8_t opTrampolineRelativeJump = 0xe9;
|
||||
const static uint16_t opTrampolineRegLoad = 0xbb49;
|
||||
@ -353,13 +355,21 @@ protected:
|
||||
int mMaxHooks;
|
||||
int mCurHooks;
|
||||
|
||||
struct Trampoline
|
||||
{
|
||||
void *origFunction;
|
||||
uint8_t code[kCodeSize];
|
||||
};
|
||||
|
||||
static_assert(sizeof(Trampoline) <= kHookSize, "Trampolines too big");
|
||||
|
||||
void CreateTrampoline(void *origFunction,
|
||||
intptr_t dest,
|
||||
void **outTramp)
|
||||
{
|
||||
*outTramp = nullptr;
|
||||
|
||||
byteptr_t tramp = FindTrampolineSpace();
|
||||
Trampoline *tramp = FindTrampolineSpace();
|
||||
if (!tramp)
|
||||
return;
|
||||
|
||||
@ -580,17 +590,16 @@ protected:
|
||||
#error "Unknown processor type"
|
||||
#endif
|
||||
|
||||
if (nBytes > 100) {
|
||||
if (nBytes > kCodeSize) {
|
||||
//printf ("Too big!");
|
||||
return;
|
||||
}
|
||||
|
||||
// We keep the address of the original function in the first bytes of
|
||||
// the trampoline buffer
|
||||
*((void **)tramp) = origFunction;
|
||||
tramp += sizeof(void *);
|
||||
tramp->origFunction = origFunction;
|
||||
|
||||
memcpy(tramp, origFunction, nBytes);
|
||||
memcpy(&tramp->code[0], origFunction, nBytes);
|
||||
|
||||
// OrigFunction+N, the target of the trampoline
|
||||
byteptr_t trampDest = origBytes + nBytes;
|
||||
@ -600,36 +609,36 @@ protected:
|
||||
// Jump directly to the original target of the jump instead of jumping to the
|
||||
// original function.
|
||||
// Adjust jump target displacement to jump location in the trampoline.
|
||||
*((intptr_t*)(tramp+pJmp32+1)) += origBytes - tramp;
|
||||
*((intptr_t*)(&tramp->code[pJmp32+1])) += origBytes - &tramp->code[0];
|
||||
} else {
|
||||
tramp[nBytes] = opTrampolineRelativeJump; // jmp
|
||||
*((intptr_t*)(tramp+nBytes+1)) = (intptr_t)trampDest - (intptr_t)(tramp+nBytes+5); // target displacement
|
||||
tramp->code[nBytes] = opTrampolineRelativeJump; // jmp
|
||||
*((intptr_t*)(&tramp->code[nBytes+1])) = (intptr_t)trampDest - (intptr_t)(&tramp->code[nBytes+5]); // target displacement
|
||||
}
|
||||
#elif defined(_M_X64)
|
||||
// If JMP32 opcode found, we don't insert to trampoline jump
|
||||
if (pJmp32 >= 0) {
|
||||
// mov r11, address
|
||||
*((uint16_t*)(tramp+pJmp32)) = opTrampolineRegLoad;
|
||||
*((intptr_t*)(tramp+pJmp32+2)) = (intptr_t)directJmpAddr;
|
||||
*((uint16_t*)(&tramp->code[pJmp32])) = opTrampolineRegLoad;
|
||||
*((intptr_t*)(&tramp->code[pJmp32+2])) = (intptr_t)directJmpAddr;
|
||||
|
||||
// jmp r11
|
||||
tramp[pJmp32+10] = 0x41;
|
||||
tramp[pJmp32+11] = 0xff;
|
||||
tramp[pJmp32+12] = 0xe3;
|
||||
tramp->code[pJmp32+10] = 0x41;
|
||||
tramp->code[pJmp32+11] = 0xff;
|
||||
tramp->code[pJmp32+12] = 0xe3;
|
||||
} else {
|
||||
// mov r11, address
|
||||
*((uint16_t*)(tramp+nBytes)) = opTrampolineRegLoad;
|
||||
*((intptr_t*)(tramp+nBytes+2)) = (intptr_t)trampDest;
|
||||
*((uint16_t*)(&tramp->code[nBytes])) = opTrampolineRegLoad;
|
||||
*((intptr_t*)(&tramp->code[nBytes+2])) = (intptr_t)trampDest;
|
||||
|
||||
// jmp r11
|
||||
tramp[nBytes+10] = 0x41;
|
||||
tramp[nBytes+11] = 0xff;
|
||||
tramp[nBytes+12] = 0xe3;
|
||||
tramp->code[nBytes+10] = 0x41;
|
||||
tramp->code[nBytes+11] = 0xff;
|
||||
tramp->code[nBytes+12] = 0xe3;
|
||||
}
|
||||
#endif
|
||||
|
||||
// The trampoline is now valid.
|
||||
*outTramp = tramp;
|
||||
*outTramp = &tramp->code[0];
|
||||
|
||||
// ensure we can modify the original code
|
||||
DWORD op;
|
||||
@ -657,16 +666,16 @@ protected:
|
||||
VirtualProtectEx(GetCurrentProcess(), origFunction, nBytes, op, &op);
|
||||
}
|
||||
|
||||
byteptr_t FindTrampolineSpace()
|
||||
Trampoline* FindTrampolineSpace()
|
||||
{
|
||||
if (mCurHooks >= mMaxHooks)
|
||||
return 0;
|
||||
return nullptr;
|
||||
|
||||
byteptr_t p = mHookPage + mCurHooks*kHookSize;
|
||||
|
||||
mCurHooks++;
|
||||
|
||||
return p;
|
||||
return (Trampoline*)p;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user