private static void main_loop() { Console.WriteLine("Synchronizing with target..."); comm.gdb_send_message("?"); await.state s = await.get_state(); Console.WriteLine(s.ToString()); bool cont = true; string[] prev_cmd = null; while (cont) { Console.Write("(tydb) "); string orig_cmd_line = Console.ReadLine(); string[] cmd_line = orig_cmd_line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (cmd_line.Length == 0) { if (prev_cmd != null) { cmd_line = prev_cmd; } else { continue; } } string cmd = cmd_line[0]; if ((cmd == "q") || (cmd == "quit") || (cmd == "exit")) { cont = false; } else if ((cmd == "c") || (cmd == "cont") || (cmd == "continue")) { comm.gdb_send_message("c"); s = await.get_state(); Console.WriteLine(s.ToString()); } else if ((cmd == "si") || (cmd == "stepi")) { comm.gdb_send_message("s"); s = await.get_state(); Console.WriteLine(s.ToString()); } else if ((cmd == "s") || (cmd == "step")) { do { comm.gdb_send_message("s"); s = await.get_state(); } while (s.source == null); Console.WriteLine(s.ToString()); } else if ((cmd == "r") || (cmd == "regs") || (cmd == "registers")) { regs.dump_regs(); } else if ((cmd == "bp") || (cmd == "break") || (cmd == "breakpoint")) { string addr = cmd_line[1]; if (addr.StartsWith("0x")) { addr = addr.Substring(2); } ulong uaddr = ulong.Parse(addr, System.Globalization.NumberStyles.HexNumber); comm.gdb_send_message("Z0," + uaddr.ToString("X16") + ",1"); if (comm.gdb_read_message() == "OK") { Console.WriteLine("Breakpoint set"); } else { Console.WriteLine("Error setting breakpoint"); } } else if ((cmd == "x") || (cmd == "?")) { //ulong addr = ulong.Parse(cmd_line[1], System.Globalization.NumberStyles.HexNumber); //obj obj = obj.get_obj(addr); if (s.ty_f != null) { libtysila.tydb.VarArg va = s.ty_f.GetVarArg(cmd_line[1]); if (va != null) { if (va.Location.Type == libtysila.tydb.Location.LocationType.Register) { cmd_line[1] = va.Location.RegisterName; } else if (va.Location.Type == libtysila.tydb.Location.LocationType.ContentsOfLocation) { if (va.Location.ContentsOf.Type == libtysila.tydb.Location.LocationType.Register) { ulong?val = await.get_register(s, Program.arch.get_reg(va.Location.ContentsOf.RegisterName).id); if (val.HasValue) { ulong mem_loc = val.Value; if (va.Location.Offset >= 0) { mem_loc += (ulong)va.Location.Offset; } else { mem_loc -= (ulong)(-va.Location.Offset); } cmd_line[1] = "*" + mem_loc.ToString("x" + (Program.arch.address_size * 2).ToString()); } } } } } dbgarch.register r = arch.get_reg(cmd_line[1]); if (r != null) { ulong?val = await.get_register(new await.state(), r.id); Console.WriteLine(r.name + " = " + (val.HasValue ? val.Value.ToString("x" + (arch.data_size * 2).ToString()) : "unknown")); } else { obj obj = var.get_var(cmd_line[1]); if (obj == null) { Console.WriteLine("Syntax Error"); } else { Console.WriteLine(obj.addr.ToString("x" + (arch.address_size * 2).ToString()) + " = " + obj.ToString()); } } } else if (cmd == "set") { if (orig_cmd_line == "set") { foreach (KeyValuePair <string, obj> kvp in var.vars) { Console.WriteLine(kvp.Key + " = " + kvp.Value.ToString()); } continue; } int eq_pos = orig_cmd_line.IndexOf('='); if (eq_pos == -1) { Console.WriteLine("Syntax Error"); continue; } string var_n = orig_cmd_line.Substring(4, eq_pos - 4).Trim(); string arg = orig_cmd_line.Substring(eq_pos + 1).Trim(); if (var_n.Contains(" ") || arg.Contains(" ")) { Console.WriteLine("Syntax Error"); continue; } obj o = var.get_var(arg); if (o == null) { Console.WriteLine("Syntax Error"); } else { var.vars[var_n] = o; } } else { Console.WriteLine("Unrecognized command: " + cmd); prev_cmd = null; continue; } prev_cmd = cmd_line; } }
internal static obj get_obj(ulong address) { bool is_obj = false; ulong vtbl_address; ulong ti_address = 0; // try and get a vtable at the contents of this address vtbl_address = mem.get_mem(address); ulong offset; string vtbl_name = mem.get_symbol(vtbl_address, out offset); if (vtbl_name.EndsWith("TI")) { // try and get a typeinfo at the contents of the vtbl ti_address = mem.get_mem(vtbl_address); string ti_name = mem.get_symbol(ti_address, out offset); if ((offset == 0) && (ti_name.EndsWith("TI"))) { is_obj = true; } } if (is_obj) { // if an object try and interpret its typeinfo obj obj = new obj(); libtysila.Layout ti_l = Program.arch.ass.GetTysosTypeLayout(); libtysila.Layout fi_l = Program.arch.ass.GetTysosFieldLayout(); string full_name = get_type_fullname(ti_address); string extends_name = get_type_fullname(mem.get_mem(ti_address + (ulong)ti_l.InstanceFieldOffsets["libsupcs.TysosType Extends"])); if (((extends_name == "[mscorlib]System.ValueType") && (full_name != "[mscorlib]System.Enum")) || (extends_name == "[mscorlib]System.EnumType")) { obj.is_vt = true; } else { obj.is_vt = false; } obj.type = full_name; obj.addr = address; if (full_name == "[mscorlib]System.String") { obj.value = get_string(address); } else { obj.value = get_fields(ti_address, address); /*ulong field_pointer = mem.get_mem(ti_address + (ulong)ti_l.InstanceFieldOffsets["IntPtr Fields"]); * * if (field_pointer != 0) * { * List<obj.field> fields = new List<field>(); * * ulong cur_field = mem.get_mem(field_pointer); * * while (cur_field != 0) * { * string field_name = get_string(mem.get_mem(cur_field + (ulong)fi_l.InstanceFieldOffsets["String _Name"])); * int flags = (int)mem.get_mem(cur_field + (ulong)fi_l.InstanceFieldOffsets["Int32 Flags"], 4); * int f_offset = (int)mem.get_mem(cur_field + (ulong)fi_l.InstanceFieldOffsets["Int32 offset"], 4); * string field_type = get_type_fullname(mem.get_mem(cur_field + (ulong)fi_l.InstanceFieldOffsets["tysos.TysosType _FieldType"])); * ulong field_ti = mem.get_mem(cur_field + (ulong)fi_l.InstanceFieldOffsets["tysos.TysosType _FieldType"]); * * if ((flags & 0x10) == 0x0) * { * // is an instance field * int len = get_data_length(field_type); * ulong val = mem.get_mem(address + (ulong)f_offset, len); * bool is_vt = false; * * string field_extends_name = get_type_fullname(mem.get_mem(field_ti + (ulong)ti_l.InstanceFieldOffsets["tysos.TysosType Extends"])); * if (((field_extends_name == "[mscorlib]System.ValueType") && (field_type != "[mscorlib]System.Enum")) || * (field_extends_name == "[mscorlib]System.EnumType")) * is_vt = true; * * fields.Add(new field { name = field_name, type = field_type, value = val, is_vt = is_vt, ti_addr = field_ti }); * } * * field_pointer += (ulong)Program.arch.address_size; * cur_field = mem.get_mem(field_pointer); * } * * obj.value = fields.ToArray(); * } */ } return(obj); } else { // if not an object, then interpret it as an unsigned integer in the native // byte length ulong val = mem.get_mem(address, Program.arch.data_size); obj obj = new obj(); obj.addr = address; switch (Program.arch.data_size) { case 4: obj.type = "[mscorlib]System.UInt32"; obj.value = (uint)val; break; case 8: default: obj.type = "[mscorlib]System.UInt64"; obj.value = (ulong)val; break; } obj.is_vt = true; return(obj); } }
internal static obj get_var(string name) { if (name.Contains(".")) { // Composite value string[] names = name.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); obj o = get_var(names[0]); if (o == null) { return(null); } for (int i = 1; i < names.Length; i++) { obj.field found = null; if (o.value is obj.field[]) { obj.field[] fs = o.value as obj.field[]; foreach (obj.field f in fs) { if (f.name == names[i]) { found = f; break; } } } if (found == null) { Console.WriteLine(o.type + " does not contain field " + names[i]); return(null); } if (found.is_vt) { obj new_o = new obj(); new_o.addr = o.addr + (ulong)found.offset; new_o.is_vt = true; new_o.type = found.type; new_o.value = mem.get_mem(new_o.addr, (int)found.size); o = new_o; } else { o = obj.get_obj((ulong)found.value); } } return(o); } if (vars.ContainsKey(name)) { vars[name] = obj.get_obj(vars[name].addr); return(vars[name]); } if (name.StartsWith("[") && name.EndsWith("]")) { string reg_name = name.Substring(1, name.Length - 2); dbgarch.register r = Program.arch.get_reg(reg_name); if (r == null) { return(null); } ulong?r_val = await.get_register(new await.state(), r.id); if (r_val.HasValue) { return(obj.get_obj(r_val.Value)); } else { return(null); } } if (name.StartsWith("*")) { string mem_addr = name.Substring(1); if (mem_addr.StartsWith("0x")) { mem_addr = mem_addr.Substring(2); } try { ulong m_addr_u = ulong.Parse(mem_addr, System.Globalization.NumberStyles.HexNumber); return(obj.get_obj(m_addr_u)); } catch (Exception) { return(null); } } return(null); }