private void SendCMDPacket(CMDS cmd, int length, params object[] fields) { CMDPacket packet = new CMDPacket { magic = CMD_PACKET_MAGIC, cmd = (uint)cmd, datalen = (uint)length }; byte[] data = null; if (length > 0) { MemoryStream rs = new MemoryStream(); foreach (object field in fields) { byte[] bytes = null; switch (field) { case char c: bytes = BitConverter.GetBytes(c); break; case byte b: bytes = BitConverter.GetBytes(b); break; case short s: bytes = BitConverter.GetBytes(s); break; case ushort us: bytes = BitConverter.GetBytes(us); break; case int i: bytes = BitConverter.GetBytes(i); break; case uint u: bytes = BitConverter.GetBytes(u); break; case long l: bytes = BitConverter.GetBytes(l); break; case ulong ul: bytes = BitConverter.GetBytes(ul); break; case byte[] ba: bytes = ba; break; } if (bytes != null) { rs.Write(bytes, 0, bytes.Length); } } data = rs.ToArray(); rs.Dispose(); } SendData(GetBytesFromObject(packet), CMD_PACKET_SIZE); if (data != null) { SendData(data, length); } }
/// <summary> /// Call function (returns rax) /// </summary> /// <param name="pid">Process ID</param> /// <param name="rpcstub">Stub address from InstallRPC</param> /// <param name="address">Address to call</param> /// <param name="args">Arguments array</param> /// <returns></returns> public ulong Call(int pid, ulong rpcstub, ulong address, params object[] args) { CheckConnected(); // need to do this in a custom format CMDPacket packet = new CMDPacket { magic = CMD_PACKET_MAGIC, cmd = (uint)CMDS.CMD_PROC_CALL, datalen = (uint)CMD_PROC_CALL_PACKET_SIZE }; SendData(GetBytesFromObject(packet), CMD_PACKET_SIZE); MemoryStream rs = new MemoryStream(); rs.Write(BitConverter.GetBytes(pid), 0, sizeof(int)); rs.Write(BitConverter.GetBytes(rpcstub), 0, sizeof(ulong)); rs.Write(BitConverter.GetBytes(address), 0, sizeof(ulong)); int num = 0; foreach (object arg in args) { byte[] bytes = new byte[8]; switch (arg) { case char c: { byte[] tmp = BitConverter.GetBytes(c); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(char)); byte[] pad = new byte[sizeof(ulong) - sizeof(char)]; Buffer.BlockCopy(pad, 0, bytes, sizeof(char), pad.Length); break; } case byte b: { byte[] tmp = BitConverter.GetBytes(b); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(byte)); byte[] pad = new byte[sizeof(ulong) - sizeof(byte)]; Buffer.BlockCopy(pad, 0, bytes, sizeof(byte), pad.Length); break; } case short s: { byte[] tmp = BitConverter.GetBytes(s); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(short)); byte[] pad = new byte[sizeof(ulong) - sizeof(short)]; Buffer.BlockCopy(pad, 0, bytes, sizeof(short), pad.Length); break; } case ushort us: { byte[] tmp = BitConverter.GetBytes(us); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(ushort)); byte[] pad = new byte[sizeof(ulong) - sizeof(ushort)]; Buffer.BlockCopy(pad, 0, bytes, sizeof(ushort), pad.Length); break; } case int i: { byte[] tmp = BitConverter.GetBytes(i); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(int)); byte[] pad = new byte[sizeof(ulong) - sizeof(int)]; Buffer.BlockCopy(pad, 0, bytes, sizeof(int), pad.Length); break; } case uint ui: { byte[] tmp = BitConverter.GetBytes(ui); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(uint)); byte[] pad = new byte[sizeof(ulong) - sizeof(uint)]; Buffer.BlockCopy(pad, 0, bytes, sizeof(uint), pad.Length); break; } case long l: { byte[] tmp = BitConverter.GetBytes(l); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(long)); break; } case ulong ul: { byte[] tmp = BitConverter.GetBytes(ul); Buffer.BlockCopy(tmp, 0, bytes, 0, sizeof(ulong)); break; } } rs.Write(bytes, 0, bytes.Length); num++; } if (num > 6) { throw new Exception("libdbg: too many arguments"); } if (num < 6) { for (int i = 0; i < (6 - num); i++) { rs.Write(BitConverter.GetBytes((ulong)0), 0, sizeof(ulong)); } } SendData(rs.ToArray(), CMD_PROC_CALL_PACKET_SIZE); rs.Dispose(); CheckStatus(); byte[] data = ReceiveData(PROC_CALL_SIZE); return(BitConverter.ToUInt64(data, 4)); }