private string ReadMemory(GDBPacket packet) { var parameters = packet.GetCommandParameters(); if (parameters.Length < 2) { return(GetErrorAnswer(Errno.EPERM)); } var arg1 = Convert.ToUInt32(parameters[0], 16); var arg2 = Convert.ToUInt32(parameters[1], 16); if (arg1 > ushort.MaxValue || arg2 > ushort.MaxValue) { return(GetErrorAnswer(Errno.EPERM)); } var addr = (ushort)arg1; var length = (ushort)arg2; var result = string.Empty; for (var i = 0; i < length; i++) { var hex = _target.CPU.RDMEM((ushort)(addr + i)) .ToLowEndianHexString(); result += hex; } return(result); }
private string GeneralQueryResponse(GDBPacket packet) { string command = packet.GetCommandParameters()[0]; if (command.StartsWith("Supported")) { return("PacketSize=4000"); } if (command.StartsWith("C")) { return(StandartAnswers.Empty); } if (command.StartsWith("Attached")) { return("1"); } if (command.StartsWith("TStatus")) { return(StandartAnswers.Empty); } if (command.StartsWith("Offset")) { return(StandartAnswers.Error); } return(StandartAnswers.OK); }
private string WriteMemory(GDBPacket packet) { var parameters = packet.GetCommandParameters(); if (parameters.Length < 3) { return(GetErrorAnswer(Errno.ENOENT)); } var arg1 = Convert.ToUInt32(parameters[0], 16); var arg2 = Convert.ToUInt32(parameters[1], 16); if (arg1 > ushort.MaxValue || arg2 > ushort.MaxValue) { return(GetErrorAnswer(Errno.ENOENT)); } var addr = (ushort)arg1; var length = (ushort)arg2; for (var i = 0; i < length; i++) { var hex = parameters[2].Substring(i * 2, 2); var value = Convert.ToByte(hex, 16); _target.CPU.WRMEM((ushort)(addr + i), value); } return(StandartAnswers.OK); }
private string ReadRegisters(GDBPacket packet) { var values = Enumerable.Range(0, RegistersCount - 1) .Select(i => GetRegisterAsHex(i)) .ToArray(); return(String.Join("", values)); }
private string ReadRegisters(GDBPacket packet) { string[] values = new string[17]; for (int i = 0; i < values.Length; i++) { values[i] = GetRegisterAsHex(i); } return(String.Join("", values)); }
private string RemoveBreakpoint(GDBPacket packet) { string[] parameters = packet.GetCommandParameters(); Breakpoint.BreakpointType type = Breakpoint.GetBreakpointType(int.Parse(parameters[0])); ushort addr = Convert.ToUInt16(parameters[1], 16); _target.RemoveBreakpoint(type, addr); return(StandartAnswers.OK); }
private string WriteRegisters(GDBPacket packet) { var regsData = packet.GetCommandParameters()[0]; for (int i = 0, pos = 0; i < RegistersCount; i++) { int currentRegisterLength = GetRegisterSize(i) == RegisterSize.Word ? 4 : 2; SetRegister(i, regsData.Substring(pos, currentRegisterLength)); pos += currentRegisterLength; } return(StandartAnswers.OK); }
private string ExecutionRequest(GDBPacket packet) { string command = packet.GetCommandParameters()[0]; if (command.StartsWith("Cont?")) { return(""); } if (command.StartsWith("Cont")) { } return(StandartAnswers.Empty); }
private string SetRegister(GDBPacket packet) { var parameters = packet.GetCommandParameters()[0].Split(new char[] { '=' }); if (SetRegister(Convert.ToInt32(parameters[0], 16), parameters[1])) { return(StandartAnswers.OK); } else { return(StandartAnswers.Error); } }
private string WriteRegisters(GDBPacket packet) { /* * var regsData = packet.GetCommandParameters()[0]; * for (int i = 0, pos = 0; i < RegistersCount; i++) * { * int currentRegisterLength = 8; * SetRegister(i, regsData.Substring(pos, currentRegisterLength)); * pos += currentRegisterLength; * } */ return(StandartAnswers.OK); }
private string ReadMemory(GDBPacket packet) { var parameters = packet.GetCommandParameters(); if (parameters.Length < 2) { return(GetErrorAnswer(Errno.EPERM)); } var arg1 = Convert.ToUInt32(parameters[0], 16); var arg2 = Convert.ToUInt32(parameters[1], 16); if (arg1 > uint.MaxValue || arg2 > uint.MaxValue) { return(GetErrorAnswer(Errno.EPERM)); } var addr = (uint)arg1; var length = (uint)arg2; var result = string.Empty; for (uint i = 0; i < length;) { uint remain = length - i; if (remain > 64) { remain = 64; } byte[] get = _target.RDMEM((uint)(addr + i), (uint)remain); for (int j = 0; j < get.Length; j++) { var hex = get[j].ToLowEndianHexString().ToLower(); result += hex; } if ((get.Length == 0) && (i == 0)) { return(GetErrorAnswer(Errno.EFAULT)); } else if (get.Length != remain) { return(result); } i += remain; } return(result); }
private string WriteMemory(GDBPacket packet) { var parameters = packet.GetCommandParameters(); if (parameters.Length < 3) { return(GetErrorAnswer(Errno.ENOENT)); } var arg1 = Convert.ToUInt32(parameters[0], 16); var arg2 = Convert.ToUInt32(parameters[1], 16); if (arg1 > uint.MaxValue || arg2 > uint.MaxValue) { return(GetErrorAnswer(Errno.ENOENT)); } uint addr = (uint)arg1; uint length = (uint)arg2; byte[] data = new byte[length]; for (uint i = 0; i < length; i++) { var hex = parameters[2].Substring((int)i * 2, 2); var value = Convert.ToByte(hex, 16); data[i] = value; } for (uint i = 0; i < length;) { uint remain = length - i; if (remain > 64) { remain = 64; } byte[] toSend = new byte[remain]; for (int j = 0; j < remain; j++) { toSend[j] = data[i + j]; } _target.WRMEM((uint)(addr + i), toSend); i += remain; } return(StandartAnswers.OK); }
private string GetTargetHaltedReason(GDBPacket packet) { return(StandartAnswers.HaltedReason); }
private string GetRegister(GDBPacket packet) { return(GetRegisterAsHex(Convert.ToInt32(packet.GetCommandParameters()[0], 16))); }
public static string FormatResponse(string response, bool ack) { return(((ack)?"+$":"$") + response + "#" + GDBPacket.CalculateCRC(response)); }
private async Task ProcessGdbClient(TcpClient tcpClient) { NetworkStream clientStream = tcpClient.GetStream(); GDBSession session = new GDBSession(_target); byte[] message = new byte[0x1000]; int bytesRead; _target.DoStop(); while (true) { try { bytesRead = await clientStream.ReadAsync(message, 0, 4096); } catch (IOException iex) { var sex = iex.InnerException as SocketException; if (sex == null || sex.SocketErrorCode != SocketError.Interrupted) { _target.LogException?.Invoke(sex); } break; } catch (SocketException sex) { if (sex.SocketErrorCode != SocketError.Interrupted) { _target.LogException?.Invoke(sex); } break; } catch (Exception ex) { _target.LogException?.Invoke(ex); break; } if (bytesRead == 0) { //the client has disconnected from the server break; } if (bytesRead > 0) { GDBPacket packet = new GDBPacket(message, bytesRead); _target.Log?.Invoke($"--> {packet}"); bool isSignal; string response = session.ParseRequest(packet, out isSignal); if (response != null) { if (isSignal) { await SendGlobal(response); } else { await SendResponse(clientStream, response); } } } } tcpClient.Client.Shutdown(SocketShutdown.Both); }
public string ParseRequest(GDBPacket packet, out bool isSignal) { var result = StandartAnswers.Empty; isSignal = false; // ctrl+c is SIGINT if (packet.GetBytes()[0] == 0x03) { _target.DoStop(); result = StandartAnswers.Interrupt; isSignal = true; } try { switch (packet.CommandName) { case '\0': // Command is empty ("+" in 99.99% cases) return(null); case 'q': result = GeneralQueryResponse(packet); break; case 'Q': result = GeneralQueryResponse(packet); break; case '?': result = GetTargetHaltedReason(packet); break; case '!': // extended connection break; case 'g': // read registers result = ReadRegisters(packet); break; case 'G': // write registers result = WriteRegisters(packet); break; case 'm': // read memory result = ReadMemory(packet); break; case 'M': // write memory result = WriteMemory(packet); break; case 'X': // write memory binary // Not implemented yet, client shoul use M instead //result = StandartAnswers.OK; break; case 'p': // get single register result = GetRegister(packet); break; case 'P': // set single register result = SetRegister(packet); break; case 'v': // some requests, mainly vCont result = ExecutionRequest(packet); break; case 's': //stepi _target.CPU.ExecCycle(); result = "T05"; break; case 'z': // remove bp result = RemoveBreakpoint(packet); break; case 'Z': // insert bp result = SetBreakpoint(packet); break; case 'k': // Kill the target break; case 'H': // set thread result = StandartAnswers.OK; // we do not have threads, so ignoring this command is OK break; case 'c': // continue _target.DoRun(); result = null; break; case 'D': // Detach from client _target.DoRun(); result = StandartAnswers.OK; break; } } catch (Exception ex) { _target.LogException?.Invoke(ex); result = GetErrorAnswer(Errno.EPERM); } if (result == null) { return("+"); } else { return(FormatResponse(result)); } }
public static string FormatResponse(string response) { return("+$" + response + "#" + GDBPacket.CalculateCRC(response)); }