diff --git a/core/relinker/codegen/src/x86/X64InstructionRewriter.cpp b/core/relinker/codegen/src/x86/X64InstructionRewriter.cpp index 82990dd9ac..e17dde61e9 100644 --- a/core/relinker/codegen/src/x86/X64InstructionRewriter.cpp +++ b/core/relinker/codegen/src/x86/X64InstructionRewriter.cpp @@ -54,6 +54,12 @@ std::int64_t X64InstructionRewriter::AdjustedDelta( std::int64_t sliceSize, std::int64_t delta ) { + const bool targetInsideCut = targetPosition > cutStart && targetPosition < cutEnd; + + if (targetInsideCut) { + throw CodegenException("Branch target inside rewritten instruction", static_cast(instrPosition)); + } + const bool instrShifts = instrPosition >= cutEnd && instrPosition < sliceSize; const bool targetShifts = targetPosition >= cutEnd && targetPosition < sliceSize; diff --git a/core/relinker/codegen/tests/RewriteBoundaryTests.cpp b/core/relinker/codegen/tests/RewriteBoundaryTests.cpp index dd1bd9a185..66a6ed2fc6 100644 --- a/core/relinker/codegen/tests/RewriteBoundaryTests.cpp +++ b/core/relinker/codegen/tests/RewriteBoundaryTests.cpp @@ -54,6 +54,16 @@ int main() { Require(result.Bytes == std::vector{ 0x90, 0x90, 0x90, 0xC3}); + bool targetInsideCutRejected = false; + try { + (void)rewriter.Rewrite( + {0xEB, 0x01, 0xB8, 0x11, 0x22, 0x33, 0x44, 0xC3}, + {2, {0x90}}); + } catch (const std::exception&) { + targetInsideCutRejected = true; + } + Require(targetInsideCutRejected); + for (const auto& code : { std::vector{ 0x66, 0xEB, 0x01, 0x90, 0xC3}, @@ -107,7 +117,7 @@ int main() { } RequireTruncatedBranchRejected(backwardWraparoundRejected); - std::cout << "21 rewrite boundary cases passed\n"; + std::cout << "22 rewrite boundary cases passed\n"; } catch (const std::exception& error) { std::cerr << error.what() << '\n'; return 1;