> For the complete documentation index, see [llms.txt](https://docs.hex-rays.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hex-rays.com/archive/gdb-qemu.md).

# Using IDA's GDB debugger with QEMU emulator

Using IDA's GDB debugger with QEMU emulator

Copyright 2009 Hex-Rays SA

QEMU is a processor emulator which can emulate a handful of processors, including Intel x86 and ARM architectures. It includes a GDB stub which can be used with new GDB debugger plugin in IDA 5.4.

## Getting QEMU

QEMU's home page is at <http://bellard.org/qemu/>. Win32 builds can be downloaded from Takeda Toshiya's page at <http://homepage3.nifty.com/takeda-toshiya/qemu/>. This primer assumes you downloaded QEMU 0.9.1 for Win32 or later. We will debug the small Linux included with QEMU.

## Enabling GDB stub

After unpacking QEMU, make a copy of the *qemu-win.bat* file, for example *qemu-win-gdb.bat* and edit it. Add *-s -S* to the qemu.exe call (-s enables GDB stub and -S instructs QEMU to stop at the system start):

![Editing qemu-win-gdb.bat to enable the GDB stub](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-1a3a0b948f5290f405c84282120308055ec58516%2Fgdb_qemu_bat_file.png?alt=media)

Run the .bat file. QEMU will stop and wait for the debugger.

![QEMU stopped, waiting for the debugger](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-49461c13d4e6e5a20153062b5abc4ce7dee7b947%2Fgdb_qemu_stopped.png?alt=media)

## Debugging with IDA

Start IDA.

![Welcome to IDA dialog](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-0b762e8bb51911bbacb5e3e682dee5cc7a759940%2Fgdb_qemu_welcome.png?alt=media)

If you get the welcome dialog, choose "Go".

![Debugger, Attach, Remote GDB debugger menu](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-e1fe637e1318ece6d3b3b11e3578dfdd9954b406%2Fgdb_qemu_attach_menu.png?alt=media)

Choose Debugger | Attach | Remote GDB debugger.

![Debug application setup dialog for gdb](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-b0a9b322405a8021bce557f8c5549fd272e1c800%2Fgdb_qemu_debug_setup.png?alt=media)

Enter "localhost" for hostname and 1234 for the port number. Click "Debugger specific options".

![GDB configuration dialog](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-8d0df001199130b4dec9a5a9bccdf95608709855%2Fgdb_qemu_configuration.png?alt=media)

QEMU needs special configuration because it behave slightly differently from other GDB stubs. Uncheck "Software breakpoints at EIP+1" and check "Use CS:IP in real mode". Make sure Processor is set to "Intel x86". Click OK, then click OK in "Debug application setup" dialog.

![Choose process to attach to dialog](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-df924bfdfef4e8fa84fc64bb9acb1ec369755b87%2Fgdb_qemu_choose_process.png?alt=media)

Choose \<attach to the process started on target> and click OK.

## Debugging the BIOS

![BIOS entrypoint disassembled incorrectly as 32-bit](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-c5f3c6938c2d125910ea0fd3459404538770f2ad%2Fgdb_qemu_bios_wrong.png?alt=media)

The BIOS entrypoint is displayed but the disassembly is wrong since the default MEMORY segment is 32-bit.

Let's create some manual memory regions to reflect the real memory map.

![Debugger menu, Manual memory regions](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-79bafeef4b29112094d0285b7d6b6ac3034e3d52%2Fgdb_qemu_manual_memory_menu.png?alt=media)

Go to Debugger | Manual memory regions.

![Manual memory regions, Insert context menu](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-13693b61f975af915e3984dd7f5ae478cd8ccb71%2Fgdb_qemu_insert_region.png?alt=media)

Right-click and choose "Insert..." (or press Ins).

![Add debugger memory region dialog for BIOS](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-1aee8e54b4d6c8aba38c8f42e3c265fdcec54658%2Fgdb_qemu_add_bios_region.png?alt=media)

Enter the following details:

Start address: F0000\
End address: 100000\
Base address: F000\
Name: BIOS\
Class: CODE\
select "16-bit segment"

Click OK.

![BIOS code disassembled correctly after adding the memory region](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-5d05962d43b7338c6c38af89066fca636d5d0783%2Fgdb_qemu_bios_correct.png?alt=media)

Now the disassembly is correct and you can trace the BIOS code.

## Debugging the kernel

To debug the Linux kernel, we first need to create memory regions where it will execute. The usual kernel entrypoint is at address 100000, and it can use memory almost to the maximum 4G address.

Open memory regions list (Debugger | Manual memory regions) and add a new region:

![Add debugger memory region dialog for the Linux kernel](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-b3a8b1585ae8f8cfaaa24ec3f4fdcfd515490879%2Fgdb_qemu_add_linux_region.png?alt=media)

Start address: 100000\
End address: F0000000\
Base address: 0\
Name: LINUX\
Class: CODE\
select "32-bit segment"

Click OK.

We now have two regions:

![Manual memory regions list showing BIOS and LINUX regions](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-aa5aa214c62cda4db9e3ba844a3ce1b20afb1f7a%2Fgdb_qemu_two_regions.png?alt=media)

Double-click the LINUX region to go to its beginning.

![Add breakpoint context menu at the LINUX region start](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-3a1c72da06a993817b6e25931b064047cb05dc81%2Fgdb_qemu_add_breakpoint_menu.png?alt=media)

Press F2 or choose "Add breakpoint" from the context menu.

![Breakpoint settings dialog for a hardware execute breakpoint](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-fc8d6592f75d2e53886e87d4b136a01d0f9ea335%2Fgdb_qemu_breakpoint_settings.png?alt=media)

Check "Hardware breakpoint" and select "Execute" in "Modes". Click OK.

![Execution stopped at the LINUX region entrypoint](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-f92500770311c42fe4408bc361963fbedd6d158f%2Fgdb_qemu_kernel_entry.png?alt=media)

Now press F9 or choose Debugger | Continue process. You should see BIOS and LILO messages on the screen, and the execution will stop at the "Loading Linux...." message.

![Initial loader decompressing the kernel](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-7914009143714e24fbab8648827fd11becdbc6cf%2Fgdb_qemu_initial_loader.png?alt=media)

This is the initial loader which decompresses the kernel. If you press F9 once more, you'll see "Uncompressing Linux..." and then "Ok, booting the kernel" messages in QEMU and IDA will stop at the decompressed kernel entrypoint:

![Code that sets up paging and jumps to the real kernel entrypoint](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-b7d13fdc0bcba94f93b20d4cbca98e48f3a8758d%2Fgdb_qemu_paging_setup.png?alt=media)

This code sets up paging table, enables paging, and then jumps to the "real" kernel entrypoint.

## Adding symbols

Kernel symbols are available as */proc/ksyms* or */proc/kallsyms* pseudo-file after booting. If you get that file from the VM to the host, you can add the symbols to your disassembly. Go to File | Python command... and enter the following short script:

*ksyms = open(r"*[*D:\ksyms*](d:/ksyms/README.md)*") #path to the ksyms file*\
*for line in ksyms:*\
*addr = int(line\[:8], 16)*\
*name = line\[9:-1] # use line\[11:-1] in case of kallsyms*\
*idaapi.set\_debug\_name(addr, name)*\
*MakeNameEx(addr, name, SN\_NOWARN)*\
*Message("%08X: %s\n"%(addr, name))*

Click OK and wait a bit until it finishes. After that you should see the symbols in the disassembly and name list:

![Kernel symbols loaded into the Names list](https://1926493584-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FD7fgl4EL0WWJ18ZQcIxE%2Fuploads%2Fgit-blob-36a2054604a232d1f9418647d30828faffd79082%2Fgdb_qemu_kernel_symbols.png?alt=media)

Happy debugging!

Copyright 2009 Hex-Rays SA


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hex-rays.com/archive/gdb-qemu.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
