private void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP) { if (debugRecords != null) { InstructionInfoFactory factory = new InstructionInfoFactory(); InstructionInfo info = factory.GetInfo(instr); ulong codeOffset = instr.IP - baseInstrIP; debugRecords.Update(codeOffset); Variable variable = null; foreach (UsedMemory usedMemInfo in info.GetUsedMemory()) { string baseRegister = usedMemInfo.Base.ToString(); int displacement; unchecked { displacement = (int)usedMemInfo.Displacement; } Dictionary <int, Variable> offsetToVariableMap; if (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap)) { if (offsetToVariableMap.TryGetValue(displacement, out variable)) { output.Write($"; [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}"); } } } foreach (UsedRegister usedMemInfo in info.GetUsedRegisters()) { if (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variable)) { output.Write($"; {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}"); } } } }
void VATests(VirtualAddressTestCase tc) { var decoder = Decoder.Create(tc.Bitness, new ByteArrayCodeReader(tc.HexBytes), tc.DecoderOptions); decoder.IP = tc.Bitness switch { 16 => DecoderConstants.DEFAULT_IP16, 32 => DecoderConstants.DEFAULT_IP32, 64 => DecoderConstants.DEFAULT_IP64, _ => throw new InvalidOperationException(), }; var instruction = decoder.Decode(); var getRegValue = new VARegisterValueProviderImpl(tc.RegisterValues); var getRegValueFail = new VARegisterValueProviderImpl(Array.Empty <(Register register, int elementIndex, int elementSize, ulong value)>()); var factory = new InstructionInfoFactory(); var info = factory.GetInfo(instruction); var usedMem = info.GetUsedMemory().Skip(tc.UsedMemIndex).First(); bool b1 = usedMem.TryGetVirtualAddress(tc.ElementIndex, getRegValue, out ulong value1); Assert.True(b1); Assert.Equal(tc.ExpectedValue, value1); bool b2 = usedMem.TryGetVirtualAddress(tc.ElementIndex, out ulong value2, (Register register, int elementIndex, int elementSize, out ulong value) => getRegValue.TryGetRegisterValue(register, elementIndex, elementSize, out value)); Assert.True(b2); Assert.Equal(tc.ExpectedValue, value2); ulong value3 = usedMem.GetVirtualAddress(tc.ElementIndex, getRegValue); Assert.Equal(tc.ExpectedValue, value3); ulong value4 = usedMem.GetVirtualAddress(tc.ElementIndex, (register, elementIndex2, elementSize) => getRegValue.GetRegisterValue(register, elementIndex2, elementSize)); Assert.Equal(tc.ExpectedValue, value4); Assert.False(usedMem.TryGetVirtualAddress(tc.ElementIndex, out ulong value5, (Register register, int elementIndex, int elementSize, out ulong value) => { value = 0; return(false); })); Assert.Equal(0UL, value5); Assert.False(usedMem.TryGetVirtualAddress(tc.ElementIndex, getRegValueFail, out ulong value6)); Assert.Equal(0UL, value6); }
private void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP) { if (debugRecords != null) { HashSet <Variable> variables; InstructionInfoFactory factory = new InstructionInfoFactory(); InstructionInfo info = factory.GetInfo(instr); ulong codeOffset = instr.IP - baseInstrIP; debugRecords.Update(codeOffset); foreach (UsedMemory usedMemInfo in info.GetUsedMemory()) { string baseRegister = usedMemInfo.Base.ToString(); int displacement; unchecked { displacement = (int)usedMemInfo.Displacement; } Dictionary <int, HashSet <Variable> > offsetToVariableMap; if (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap)) { if (offsetToVariableMap.TryGetValue(displacement, out variables)) { output.Write($";"); foreach (Variable variable in variables) { output.Write($" [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}"); } } } } foreach (UsedRegister usedMemInfo in info.GetUsedRegisters()) { // TODO, if the code is accessing EAX but the debug info maps to RAX, then this match is going to fail. if (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variables)) { output.Write($";"); foreach (Variable variable in variables) { output.Write($" {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}"); } } } } }