Remote GDB debugging X8664_Linux occurs warning: Invalid remote reply:
*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
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;
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.
Thank you for your reply
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 ("");
Same issue here, usually if I try to do anything (step, continue, etc) after hitting a breakpoint I get a SIGTERM disconnect.