in src/disasm.cpp [496:574]
PBYTE CDetourDis::AdjustTarget(PBYTE pbDst, PBYTE pbSrc, UINT cbOp,
UINT cbTargetOffset, UINT cbTargetSize)
{
PBYTE pbTarget = NULL;
#if 1 // fault injection to test test code
#if defined(DETOURS_X64)
typedef LONGLONG T;
#else
typedef LONG T;
#endif
T nOldOffset;
T nNewOffset;
PVOID pvTargetAddr = &pbDst[cbTargetOffset];
switch (cbTargetSize) {
case 1:
nOldOffset = *(signed char*&)pvTargetAddr;
break;
case 2:
nOldOffset = *(UNALIGNED SHORT*&)pvTargetAddr;
break;
case 4:
nOldOffset = *(UNALIGNED LONG*&)pvTargetAddr;
break;
#if defined(DETOURS_X64)
case 8:
nOldOffset = *(UNALIGNED LONGLONG*&)pvTargetAddr;
break;
#endif
default:
ASSERT(!"cbTargetSize is invalid.");
nOldOffset = 0;
break;
}
pbTarget = pbSrc + cbOp + nOldOffset;
nNewOffset = nOldOffset - (T)(pbDst - pbSrc);
switch (cbTargetSize) {
case 1:
*(CHAR*&)pvTargetAddr = (CHAR)nNewOffset;
if (nNewOffset < SCHAR_MIN || nNewOffset > SCHAR_MAX) {
*m_plExtra = sizeof(ULONG) - 1;
}
break;
case 2:
*(UNALIGNED SHORT*&)pvTargetAddr = (SHORT)nNewOffset;
if (nNewOffset < SHRT_MIN || nNewOffset > SHRT_MAX) {
*m_plExtra = sizeof(ULONG) - 2;
}
break;
case 4:
*(UNALIGNED LONG*&)pvTargetAddr = (LONG)nNewOffset;
if (nNewOffset < LONG_MIN || nNewOffset > LONG_MAX) {
*m_plExtra = sizeof(ULONG) - 4;
}
break;
#if defined(DETOURS_X64)
case 8:
*(UNALIGNED LONGLONG*&)pvTargetAddr = nNewOffset;
break;
#endif
}
#ifdef DETOURS_X64
// When we are only computing size, source and dest can be
// far apart, distance not encodable in 32bits. Ok.
// At least still check the lower 32bits.
if (pbDst >= m_rbScratchDst && pbDst < (sizeof(m_rbScratchDst) + m_rbScratchDst)) {
ASSERT((((size_t)pbDst + cbOp + nNewOffset) & 0xFFFFFFFF) == (((size_t)pbTarget) & 0xFFFFFFFF));
}
else
#endif
{
ASSERT(pbDst + cbOp + nNewOffset == pbTarget);
}
#endif
return pbTarget;
}