in src/disasm.cpp [361:440]
PBYTE CDetourDis::CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
{
UINT nBytesFixed;
if (m_bVex || m_bEvex)
{
ASSERT(pEntry->nFlagBits == 0);
ASSERT(pEntry->nFixedSize == pEntry->nFixedSize16);
}
UINT const nModOffset = pEntry->nModOffset;
UINT const nFlagBits = pEntry->nFlagBits;
UINT const nFixedSize = pEntry->nFixedSize;
UINT const nFixedSize16 = pEntry->nFixedSize16;
if (nFlagBits & ADDRESS) {
nBytesFixed = m_bAddressOverride ? nFixedSize16 : nFixedSize;
}
#ifdef DETOURS_X64
// REX.W trumps 66
else if (m_bRaxOverride) {
nBytesFixed = nFixedSize + ((nFlagBits & RAX) ? 4 : 0);
}
#endif
else {
nBytesFixed = m_bOperandOverride ? nFixedSize16 : nFixedSize;
}
UINT nBytes = nBytesFixed;
UINT nRelOffset = pEntry->nRelOffset;
UINT cbTarget = nBytes - nRelOffset;
if (nModOffset > 0) {
ASSERT(nRelOffset == 0);
BYTE const bModRm = pbSrc[nModOffset];
BYTE const bFlags = s_rbModRm[bModRm];
nBytes += bFlags & NOTSIB;
if (bFlags & SIB) {
BYTE const bSib = pbSrc[nModOffset + 1];
if ((bSib & 0x07) == 0x05) {
if ((bModRm & 0xc0) == 0x00) {
nBytes += 4;
}
else if ((bModRm & 0xc0) == 0x40) {
nBytes += 1;
}
else if ((bModRm & 0xc0) == 0x80) {
nBytes += 4;
}
}
cbTarget = nBytes - nRelOffset;
}
#ifdef DETOURS_X64
else if (bFlags & RIP) {
nRelOffset = nModOffset + 1;
cbTarget = 4;
}
#endif
}
CopyMemory(pbDst, pbSrc, nBytes);
if (nRelOffset) {
*m_ppbTarget = AdjustTarget(pbDst, pbSrc, nBytes, nRelOffset, cbTarget);
#ifdef DETOURS_X64
if (pEntry->nRelOffset == 0) {
// This is a data target, not a code target, so we shouldn't return it.
*m_ppbTarget = NULL;
}
#endif
}
if (nFlagBits & NOENLARGE) {
*m_plExtra = -*m_plExtra;
}
if (nFlagBits & DYNAMIC) {
*m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
}
return pbSrc + nBytes;
}