public static IntPtr FindLastRcxReadAddressBeforeCallTo(IntPtr codeStart, IntPtr callTarget) { var decoder = XrefScanner.DecoderForAddress(codeStart); IntPtr lastRcxRead = IntPtr.Zero; while (true) { decoder.Decode(out var instruction); if (decoder.LastError == DecoderError.NoMoreBytes) { return(IntPtr.Zero); } if (instruction.FlowControl == FlowControl.Return) { return(IntPtr.Zero); } if (instruction.FlowControl == FlowControl.UnconditionalBranch) { continue; } if (instruction.Mnemonic == Mnemonic.Int || instruction.Mnemonic == Mnemonic.Int1) { return(IntPtr.Zero); } if (instruction.Mnemonic == Mnemonic.Call) { var target = ExtractTargetAddress(instruction); if ((IntPtr)target == callTarget) { return(lastRcxRead); } } if (instruction.Mnemonic == Mnemonic.Mov) { if (instruction.Op0Kind == OpKind.Register && instruction.Op0Register == Register.ECX && instruction.Op1Kind == OpKind.Memory && instruction.IsIPRelativeMemoryOperand) { var movTarget = (IntPtr)instruction.IPRelativeMemoryAddress; if (instruction.MemorySize != MemorySize.UInt32 && instruction.MemorySize != MemorySize.Int32) { continue; } lastRcxRead = movTarget; } } } }
public static IntPtr FindByteWriteTargetRightAfterCallTo(IntPtr codeStart, IntPtr callTarget) { var decoder = XrefScanner.DecoderForAddress(codeStart); var seenCall = false; while (true) { decoder.Decode(out var instruction); if (decoder.LastError == DecoderError.NoMoreBytes) { return(IntPtr.Zero); } if (instruction.FlowControl == FlowControl.Return) { return(IntPtr.Zero); } if (instruction.FlowControl == FlowControl.UnconditionalBranch) { continue; } if (instruction.Mnemonic == Mnemonic.Int || instruction.Mnemonic == Mnemonic.Int1) { return(IntPtr.Zero); } if (instruction.Mnemonic == Mnemonic.Call) { var target = ExtractTargetAddress(instruction); if ((IntPtr)target == callTarget) { seenCall = true; } } if (instruction.Mnemonic == Mnemonic.Mov && seenCall) { if (instruction.Op0Kind == OpKind.Memory && (instruction.MemorySize == MemorySize.Int8 || instruction.MemorySize == MemorySize.UInt8)) { return((IntPtr)instruction.IPRelativeMemoryAddress); } } } }
private static IEnumerable <IntPtr> CallAndIndirectTargetsImpl(Decoder decoder) { while (true) { decoder.Decode(out var instruction); if (decoder.InvalidNoMoreBytes) { yield break; } if (instruction.FlowControl == FlowControl.Return) { yield break; } if (instruction.Mnemonic == Mnemonic.Int || instruction.Mnemonic == Mnemonic.Int1) { yield break; } if (instruction.Mnemonic == Mnemonic.Call || instruction.Mnemonic == Mnemonic.Jmp) { var targetAddress = XrefScanner.ExtractTargetAddress(instruction); if (targetAddress != 0) { yield return((IntPtr)targetAddress); } continue; } if (instruction.Mnemonic == Mnemonic.Lea) { if (instruction.MemoryBase == Register.RIP) { var targetAddress = instruction.IPRelativeMemoryAddress; if (targetAddress != 0) { yield return((IntPtr)targetAddress); } } } } }
public static IEnumerable <IntPtr> JumpTargets(IntPtr codeStart) { return(JumpTargetsImpl(XrefScanner.DecoderForAddress(codeStart))); }
public static IEnumerable <IntPtr> CallAndIndirectTargets(IntPtr pointer) => CallAndIndirectTargetsImpl(XrefScanner.DecoderForAddress(pointer, 1024 * 1024));