qiling icon indicating copy to clipboard operation
qiling copied to clipboard

Remote GDB debugging X8664_Linux occurs warning: Invalid remote reply:

Open Leshyan opened this issue 2 years ago • 6 comments

*Describe the bug When qiling runs the x8664_linux program and enables default GDB remote debugging, two n/si instructions issued by GDB will trigger warning: Invalid remote reply, causing debugging to fail. But the breakpoint-based c instruction is normal.

Sample Code

import sys
from qiling import *
from qiling.extensions import pipe
from qiling.const import QL_VERBOSE

def test_gdb(path, rootfs):
    ql = Qiling(path, rootfs, verbose=QL_VERBOSE.DEBUG,log_file="./output")
    ql.debugger = True
    ql.run()  

if __name__ == "__main__":
    test_gdb(["../tool/qiling/examples/rootfs/x8664_linux/bin/pwn1"], "../tool/qiling/examples/rootfs/x8664_linux")

Expected behavior Remote gdb can debug normally without restriction.

Screenshots CleanShot 2023-08-30 at 22 05 42

Additional context Part of the log.

[+] 	getpkt ("qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+;xmlRegisters=i386");
[+] 	putpkt ("+");
[+] 	[sent ack]
[+] 	putpkt ("BreakpointCommands+;ConditionalBreakpoints+;ConditionalTracepoints+;DisconnectedTracing+;EnableDisableTracepoints+;InstallInTrace+;QAgent+;QCatchSyscalls+;QDisableRandomization+;QNonStop+;QPassSignals+;QProgramSignals+;QStartNoAckMode+;QStartupWithShell+;QTBuffer:size+;StaticTracepoints+;TraceStateVariables+;TracepointSource+;exec-events+;fork-events+;hwbreak+;multiprocess+;no-resumed+;qXfer:features:read+;qXfer:siginfo:read+;qXfer:siginfo:write+;qXfer:statictrace:read+;qXfer:traceframe-info:read+;swbreak+;tracenz+;vfork-events+;PacketSize=3fff;qXfer:spu:read+;qXfer:spu:write+;QEnvironmentHexEncoded+;QEnvironmentReset+;QEnvironmentUnset+;QSetWorkingDir+;qXfer:auxv:read+;qXfer:exec-file:read+;qXfer:threads:read+");
[+] 	getpkt ("vMustReplyEmpty");
[+] 	putpkt ("+");
[+] 	[sent ack]
[+] 	putpkt ("");
[+] 	getpkt ("QStartNoAckMode");
[+] 	putpkt ("+");
[+] 	[sent ack]
[+] 	[noack mode enabled]
[+] 	putpkt ("OK");
[+] 	getpkt ("QProgramSignals:0;1;3;4;6;7;8;9;a;b;c;d;e;f;10;11;12;13;14;15;16;17;18;19;1a;1b;1c;1d;1e;1f;20;21;22;23;24;25;26;27;28;29;2a;2b;2c;2d;2e;2f;30;31;32;33;34;35;36;37;38;39;3a;3b;3c;3d;3e;3f;40;41;42;43;44;45;46;47;48;49;4a;4b;4c;4d;4e;4f;50;51;52;53;54;55;56;57;58;59;5a;5b;5c;5d;5e;5f;60;61;62;63;64;65;66;67;68;69;6a;6b;6c;6d;6e;6f;70;71;72;73;74;75;76;77;78;79;7a;7b;7c;7d;7e;7f;80;81;82;83;84;85;86;87;88;89;8a;8b;8c;8d;8e;8f;90;91;92;93;94;95;96;97;");
[+] 	putpkt ("OK");
[+] 	getpkt ("Hgp0.0");
[+] 	putpkt ("OK");
[+] 	getpkt ("qXfer:features:read:target.xml:0,1000");
[+] 	putpkt ("m<?xml version='1.0' encoding='utf-8'?>
<target>
 * <architecture>i386:x86-64</architecture>
 * <osabi>GNU/Linux</osabi>

 * <feature name="org.gnu.gdb.i386.core">
  <flags id="i386_eflags" size="4">
 * <field name="CF" start="0" end="0" />
 * <field name="" start="1" end="1" />
 * <field name="PF" start="2" end="2" />
 * <field name="AF" start="4" end="4" />
 * <field name="ZF" start="6" end="6" />
 * <field name="SF" start="7" end="7" />
 * <field name="TF" start="8" end="8" />
 * <field name="IF" start="9" end="9" />
 * <field name="DF" start="10" end="10" />
 * <field name="OF" start="11" end="11" />
 * <field name="NT" start="14" end="14" />
 * <field name="RF" start="16" end="16" />
 * <field name="VM" start="17" end="17" />
 * <field name="AC" start="18" end="18" />
 * <field name="VIF" start="19" end="19" />
 * <field name="VIP" start="20" end="20" />
 * <field name="ID" start="21" end="21" />
  </flags>

  <reg name="rax" bitsize="64" type="int64" />
  <reg name="rbx" bitsize="64" type="int64" />
  <reg name="rcx" bitsize="64" type="int64" />
  <reg name="rdx" bitsize="64" type="int64" />
  <reg name="rsi" bitsize="64" type="int64" />
  <reg name="rdi" bitsize="64" type="int64" />
  <reg name="rbp" bitsize="64" type="data_ptr" />
  <reg name="rsp" bitsize="64" type="data_ptr" />
  <reg name="r8" bitsize="64" type="int64" />
  <reg name="r9" bitsize="64" type="int64" />
  <reg name="r10" bitsize="64" type="int64" />
  <reg name="r11" bitsize="64" type="int64" />
  <reg name="r12" bitsize="64" type="int64" />
  <reg name="r13" bitsize="64" type="int64" />
  <reg name="r14" bitsize="64" type="int64" />
  <reg name="r15" bitsize="64" type="int64" />

  <reg name="rip" bitsize="64" type="code_ptr" />
  <reg name="eflags" bitsize="32" type="i386_eflags" />
  <reg name="cs" bitsize="32" type="int32" />
  <reg name="ss" bitsize="32" type="int32" />
  <reg name="ds" bitsize="32" type="int32" />
  <reg name="es" bitsize="32" type="int32" />
  <reg name="fs" bitsize="32" type="int32" />
  <reg name="gs" bitsize="32" type="int32" />

  <reg name="st0" bitsize="80" type="i387_ext" />
  <reg name="st1" bitsize="80" type="i387_ext" />
  <reg name="st2" bitsize="80" type="i387_ext" />
  <reg name="st3" bitsize="80" type="i387_ext" />
  <reg name="st4" bitsize="80" type="i387_ext" />
  <reg name="st5" bitsize="80" type="i387_ext" />
  <reg name="st6" bitsize="80" type="i387_ext" />
  <reg name="st7" bitsize="80" type="i387_ext" />

  <reg name="fctrl" bitsize="32" type="int" group="float" />
  <reg name="fstat" bitsize="32" type="int" group="float" />
  <reg name="ftag" bitsize="32" type="int" group="float" />
  <reg name="fiseg" bitsize="32" type="int" group="float" />
  <reg name="fioff" bitsize="32" type="int" group="float" />
  <reg name="foseg" bitsize="32" type="int" group="float" />
  <reg name="fooff" bitsize="32" type="int" group="float" />
  <reg name="fop" bitsize="32" type="int" group="float" />
</feature>
 * <feature name="org.gnu.gdb.i386.sse">
  <vector id="v4f" type="ieee_single" count="4" />
  <vector id="v2d" type="ieee_double" count="2" />
  <vector id="v16i8" type="int8" count="16" />
  <vector id="v8i16" type="int16" count="8" />
  <vector id="v4i32" type="int32" count="4" />
  <vector id="v2i64" type="int64" count="2" />
  <union id="vec128">
 * <field name="v4_float" type="v4f" />
 * <field name="v2_double" type="v2d" />
 * <field name="v16_int8" type="v16i8" />
 * <field name="v8_int16" type="v8i16" />
 * <field name="v4_int32" type="v4i32" />
 * <field name="v2_int64" type="v2i64" />
 * <field name="uint128" type="uint128" />
  </union>
  <flags id="i386_mxcsr" size="4">
 * <field name="IE" start="0" end="0" />
 * <field name="DE" start="1" end="1" />
 * <field name="ZE" start="2" end="2" />
 * <field name="OE" start="3" end="3" />
 * <field name="UE" start="4" end="4" />
 * <field name="PE" start="5" end="5" />
 * <field name="DAZ" start="6" end="6" />
 * <field name="IM" start="7" end="7" />
 * <field name="DM" start="8" end="8" />
 * <field name="ZM" start="9" end=");
[+] 	getpkt ("qXfer:features:read:target.xml:1000,1000");
[+] 	putpkt ("l"9" />
 * <field name="OM" start="10" end="10" />
 * <field name="UM" start="11" end="11" />
 * <field name="PM" start="12" end="12" />
 * <field name="FZ" start="15" end="15" />
  </flags>

  <reg name="xmm0" bitsize="128" type="vec128" regnum="40" />
  <reg name="xmm1" bitsize="128" type="vec128" />
  <reg name="xmm2" bitsize="128" type="vec128" />
  <reg name="xmm3" bitsize="128" type="vec128" />
  <reg name="xmm4" bitsize="128" type="vec128" />
  <reg name="xmm5" bitsize="128" type="vec128" />
  <reg name="xmm6" bitsize="128" type="vec128" />
  <reg name="xmm7" bitsize="128" type="vec128" />
  <reg name="xmm8" bitsize="128" type="vec128" />
  <reg name="xmm9" bitsize="128" type="vec128" />
  <reg name="xmm10" bitsize="128" type="vec128" />
  <reg name="xmm11" bitsize="128" type="vec128" />
  <reg name="xmm12" bitsize="128" type="vec128" />
  <reg name="xmm13" bitsize="128" type="vec128" />
  <reg name="xmm14" bitsize="128" type="vec128" />
  <reg name="xmm15" bitsize="128" type="vec128" />

  <reg name="mxcsr" bitsize="32" type="i386_mxcsr" group="vector" />
</feature>
 * <feature name="org.gnu.gdb.i386.linux">
  <reg name="orig_rax" bitsize="64" type="int" regnum="57" />
</feature>
 * <feature name="org.gnu.gdb.i386.segments">
  <reg name="fs_base" bitsize="64" type="int" />
  <reg name="gs_base" bitsize="64" type="int" />
</feature>
 * <feature name="org.gnu.gdb.i386.avx">
  <reg name="ymm0h" bitsize="128" type="uint128" />
  <reg name="ymm1h" bitsize="128" type="uint128" />
  <reg name="ymm2h" bitsize="128" type="uint128" />
  <reg name="ymm3h" bitsize="128" type="uint128" />
  <reg name="ymm4h" bitsize="128" type="uint128" />
  <reg name="ymm5h" bitsize="128" type="uint128" />
  <reg name="ymm6h" bitsize="128" type="uint128" />
  <reg name="ymm7h" bitsize="128" type="uint128" />
  <reg name="ymm8h" bitsize="128" type="uint128" />
  <reg name="ymm9h" bitsize="128" type="uint128" />
  <reg name="ymm10h" bitsize="128" type="uint128" />
  <reg name="ymm11h" bitsize="128" type="uint128" />
  <reg name="ymm12h" bitsize="128" type="uint128" />
  <reg name="ymm13h" bitsize="128" type="uint128" />
  <reg name="ymm14h" bitsize="128" type="uint128" />
  <reg name="ymm15h" bitsize="128" type="uint128" />
</feature>
 * <feature name="org.gnu.gdb.i386.mpx">
  <struct id="br128">
 * <field name="lbound" type="uint64" />
 * <field name="ubound_raw" type="uint64" />
  </struct>

  <struct id="_bndstatus" size="8">
 * <field name="bde" start="2" end="63" />
 * <field name="error" start="0" end="1" />
  </struct>

  <union id="status">
 * <field name="raw" type="data_ptr" />
 * <field name="status" type="_bndstatus" />
  </union>

  <struct id="_bndcfgu" size="8">
 * <field name="base" start="12" end="63" />
 * <field name="reserved" start="2" end="11" />
 * 
 * <field name="preserved" start="1" end="1" type="uint64" />
 * <field name="enabled" start="0" end="0" type="uint64" />
  </struct>

   <union id="cfgu">
 * <field name="raw" type="data_ptr" />
 * <field name="config" type="_bndcfgu" />
  </union>

  <reg name="bnd0raw" bitsize="128" type="br128" />
  <reg name="bnd1raw" bitsize="128" type="br128" />
  <reg name="bnd2raw" bitsize="128" type="br128" />
  <reg name="bnd3raw" bitsize="128" type="br128" />
  <reg name="bndcfgu" bitsize="64" type="cfgu" />
  <reg name="bndstatus" bitsize="64" type="status" />
</feature>
</target>");
[+] 	getpkt ("qXfer:auxv:read::0,1000");
[+] 	putpkt ("l");
[+] 	getpkt ("QNonStop:0");
[+] 	putpkt ("OK");
[+] 	getpkt ("qTStatus");
[+] 	putpkt ("T0;tnotrun:0;tframes:0;tcreated:0;tfree:0* 50*';tsize:0* 50*';circular:0;disconn:0;starttime:0;stoptime:0;username:;notes::");
[+] 	getpkt ("qTfV");
[+] 	putpkt ("l");
[+] 	getpkt ("?");
[+] 	putpkt ("T0506:0*,;07:20de0*"80*!;10:601040*';");
[+] 	getpkt ("qXfer:threads:read::0,1000");
[+] 	putpkt ("l<threads>
<thread id="1996" core="1" name="pwn1"/>
</threads>");
[+] 	getpkt ("qAttached:a410");
[+] 	putpkt ("");
[+] 	getpkt ("qXfer:exec-file:read:a410:0,1000");
[+] 	putpkt ("l/bin/pwn1");
[+] 	getpkt ("vFile:setfs:0");
[+] 	putpkt ("");
[+] 	getpkt ("vFile:open:6a7573742070726f62696e67,0,1c0");
[+] 	gdb> target host path: /home/also/tool/qiling/examples/rootfs/x8664_linux/just probing
[+] 	putpkt ("F-1");
[+] 	getpkt ("vFile:open:2f62696e2f70776e31,0,0");
[+] 	gdb> target host path: /home/also/tool/qiling/examples/rootfs/x8664_linux/bin/pwn1
[+] 	putpkt ("F6");
[+] 	getpkt ("vFile:pread:6,3fff,0");
[+] 	putpkt ("F3fff;ELF");
[+] 	getpkt ("vFile:fstat:6");
[+] 	putpkt ("");
[+] 	getpkt ("vFile:pread:6,3fff,4058");
[+] 	putpkt ("F40;

Leshyan avatar Aug 30 '23 14:08 Leshyan

The last incoming command is vCont;S0f:pa410.1996;c:pa410.-1. Since vCont support is limited, Qiling doesn't know how to handle the S0f command and fails. We should fix that.

elicn avatar Sep 02 '23 18:09 elicn

Thank you for your reply

Leshyan avatar Sep 05 '23 02:09 Leshyan

I'm also experiencing this issue. Is there any fix or workaround for it? Would running on a compatible VM or using a different debugger solve the issue, and if so, what do you suggest to try?

Here is the last bit of my log - seems to break on the same command:

[=]     gdb> breakpoint added at 0x7ffff7de5590
[+]     putpkt ("OK");
[+]     getpkt ("QPassSignals:e;10;14;17;1a;1b;1c;21;24;25;2c;4c;97;");
[+]     putpkt ("OK");
[+]     getpkt ("vCont;S0f:pa410.1996;c:pa410.-1");
[+]     putpkt ("");

bstee615 avatar Nov 21 '23 18:11 bstee615

Same issue here, usually if I try to do anything (step, continue, etc) after hitting a breakpoint I get a SIGTERM disconnect.

GreaterGoodest avatar May 24 '24 15:05 GreaterGoodest