@@ -140,12 +140,35 @@ public static FunctionHook Create(CodeManager manager, void* target, void* hook,
140140 var low = baseAddr + int . MinValue ;
141141
142142 if ( low > baseAddr )
143- low = null ; // Underflow, i.e. the bottom of the address space is reachable.
143+ low = ( byte * ) nuint . MinValue ; // Underflow, i.e. the bottom of the address space is reachable.
144144
145145 var high = baseAddr + int . MaxValue ;
146146
147147 if ( high < baseAddr )
148- high = ( byte * ) null - 1 ; // Overflow, i.e. the top of the address space is reachable.
148+ high = ( byte * ) nuint . MaxValue ; // Overflow, i.e. the top of the address space is reachable.
149+
150+ // We need to factor in any IP-relative memory addresses in the prologue code. If we do not do this, the
151+ // relocated instructions may fail to assemble due to range issues.
152+ foreach ( var insn in prologue )
153+ {
154+ if ( ! insn . IsIPRelativeMemoryOperand )
155+ continue ;
156+
157+ var dispAddr = ( byte * ) insn . IPRelativeMemoryAddress + insn . Length ;
158+
159+ var dispLow = dispAddr + int . MinValue ;
160+
161+ if ( dispLow > dispAddr )
162+ dispLow = ( byte * ) nuint . MinValue ; // Underflow, i.e. the bottom of the address space is reachable.
163+
164+ var dispHigh = dispAddr + int . MaxValue ;
165+
166+ if ( dispHigh < dispAddr )
167+ dispHigh = ( byte * ) nuint . MaxValue ; // Overflow, i.e. the top of the address space is reachable.
168+
169+ low = ( byte * ) nuint . Max ( ( nuint ) low , ( nuint ) dispLow ) ;
170+ high = ( byte * ) nuint . Min ( ( nuint ) high , ( nuint ) dispHigh ) ;
171+ }
149172
150173 placement = CodePlacement . Range ( low , high ) ;
151174 }
0 commit comments