Remote GDB Debugger issues

There are several issues in IDA related to GDB remote debugging. The following concerns debugging windows programs.

IDA does not show correct destination of logical addresses involving fs or gs overrides, for example:

mov eax, fs:18h    ;clicking on this goes to an address 0x18 instead of fs_base + 0x18
mov eax, gs:30h    ;same here, goes to 0x30 instead of gs_base + 0x30

At the same time, GDB stub provides fs_base and gs_base registers. Here is a tcpdump of the interaction with GDB stub:

>> from IDA to remote stub
qXfer:features:read:64bit-segments.xml:0,1023

<< from remote stub to IDA
l<?xml version="1.0"?>
<!-- Copyright (C) 2016-2018 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.segments">
  <reg name="fs_base" bitsize="64" type="int"/>
  <reg name="gs_base" bitsize="64" type="int"/>
</feature>

IDA is supposed to show thread names in Threads debugging window. Instead it shows only FFFFFFFFFFFFFFFF regardless of thread names

an example conversation shows that names are set:

<< from IDA
qXfer:threads:read::0,1023

>> to IDA
l<threads>
<thread id="1" core="0" name="main thread" />
<thread id="2" core="0" name="thread #1" />
<thread id="3" core="0" name="thread #2" />
</threads>

But all the names are FFFFFFFFFFFFFFFF in Threads window.

Choose process to attach to window does not show process name

IDA can make a request qXfer:exec-file:read to read the name of the program. When attaching to the remote process a window Choose process to attach to appears. It has two fields: Id and Name. Name is always <attach to the process started on target> regardless of the process name, that can be obtained through qXfer:exec-file:read request.

Duplicated program name in Modules window

As I noticed, IDA makes qXfer:exec-file:read to get the name of the running program. Let’s assume that the process name is c:\test.exe. This name is shown in Modules window without base address (ok, it’s not known by default). But if GDB stub provides program’s name in the loaded libraries like this:

<< from IDA
qXfer:libraries:read::0,1023

>> to IDA
l<library-list>
    <library name="c:\windows\system32\win32u.dll"><segment address="0x100001000"/></library>
    <library name="c:\test.exe"><segment address="0x140001000"/></library>
    <library name="c:\windows\system32\ntdll.dll"><segment address="0x180001000"/></library>
</library-list>

then Modules window will contain duplicated entry for the program name:

Path                            Base                Size
c:\windows\system32\win32u.dll	0000000100000000	0000000000022000
c:\test.exe	                    0000000140000000	0000000000009000
c:\windows\system32\ntdll.dll	0000000180000000	00000000001F8000
c:\test.exe

Some symbols disappear when using Load debug symbols in Modules window

Attach to a program. Load ntdll.dll symbols. Go to LdrLoadDll and find this line in its prolog:

mov     rax, cs:__security_cookie

Then load symbols for another module. Look at LdrLoadDll’s prolog again and notice a missed name:

mov     rax, cs:off_180184510

WOW64 debugging problems

When debugging WOW64 processes we have a mix of 64/32-bit modules. IDA does not respect module bitness. It loads all the modules as 64-bit. Moreover, if I manually set segment bitness (Alt-S) for such a module to 32-bit, IDA can revert it back to 64-bit during program execution (I think it depends on other module loading).

Hi @lvm,
Thank you for the extensive report!
A few more details would likely help us to investigate it further. Would you be able to share with us:

  • The exact GDB server you are using
  • Your IDA version and your system version
  • Sample idb (you can add it via our support channel)

Hi @teresa_hexrays,

The exact GDP server you are using

The GDB server is from the windows emulator.
Unfortunately the release version is not suitable for thorough checking. Currently I’m working on enhancing the GDB support and I didn’t yet make a PR with all the stuff.

So, I uploaded my build here, it is a 7-zip archive with password emulator. Below are the setup instructions.

  1. Use a virtual machine with Windows 10 installed.
  2. Download an archive and unpack it to a directory, e.g. c:\test
  3. Create an emulation root (run under elevated command prompt):
> cd /d c:\test
> create-root.bat
> dump-apiset.exe
> move api-set.bin root
  1. Run the emulator
    analyzer.exe -d -e c:\test\root -p c:\test.exe some_sample.exe c:\test.exe

Substitute some_sample.exe with the path to a sample. You can use threads-64.exe or threads-32.exe from the archive to test thread names.

At first, you can omit -d (Enable GDB debugging mode) to test that everything is ok.

  1. GDB stub listens on 127.0.0.1:28960 and is ready to work

Your IDA version and your system version

9.2, Windows 10 22H2

Sample idb (you can add it via our support channel)

I don’t load any sample to the database initially. I use an empty (“Work on your own”) database.
Then I set up the debugger:

Go to DebuggerAttachRemote GDB Debugger and set

Hostname: localhost
Port: 28960

Configuration: Intel x64 (this is by default)

I forgot to mention another issue. This is not yet implemented in my build but I want to implement it.

The original gdb and it’s gdbserver are using stop signal 0 as a notification that something happened during execution: a library is loaded/unloaded, a thread is created/killed and so on. On the other hand, it seems that IDA does not take such a signal into account (moreover sometimes it shows a message that the signal 0 is unknown).

This is a sample conversation between the original gdb and gdbserver:

<< from gdb; gdb continues execution
vCont;c

>> from gdbserver; it sends a signal 0 with reasons why it is stopped. in this case it is stopped because some library was loaded / unloaded
T0006:f*,;07:28e57f0*&;10:a4dac40dfc7f0* ;thread:7038;library:;

<< from gdb 
[ .. gdb requests libraries and all the stuff, prints some messages on the screen (if any) .. ]

<< from gdb; gdb continues without user interaction
vCont;c