Introduction and question about bootloader/toykernel debugging

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
StormSeeker
Posts: 10
Joined: Wed Aug 28, 2024 4:03 am

Re: Introduction and question about bootloader/toykernel debugging

Post by StormSeeker »

sh42 wrote: Fri Aug 30, 2024 4:30 am
StormSeeker wrote: Thu Aug 29, 2024 12:23 pm
sh42 wrote: Thu Aug 29, 2024 6:49 am Hi.

IDA pro is really a different beast. I am not sure if you can connect it live to the thing running inside of qemu. QEMU implements a GDB-server, which actually lets you connect to that, and debug the code being emulated. I am not sure if IDA pro can connect to a GDB-server to do similar things.

There is some references to gdbserver and iDA, maybe this can help you:
https://hex-rays.com/products/ida/suppo ... 1343.shtml

It would likely amount to, within IDA pro, doing the remote connection to the GDB server inside of QEMU.

If it's not natively supported, you could ask around IDA communities to see if this is something that can be scripted into IDA, or try yourself to script it.
Please, see my screencast:

https://filebin.net/aaja6c28vglavje5/Vi ... 201548.wmv

this is what I do (disregard the fact that for brevity I didn't set-up memory regions for 16bit real mode code decompiling).
In the screencast I import symbols into IDA from the kernel elf file. I could import symbols from the bootloader's elf file.

BUT I WANT SYMBOLS FOR BOTH IN THE SAME DEBUGGING SESSION
Apologies about the misunderstanding! I don't go to filebin or such sites. "i'm a bit paranoid i'm afraid". fileformats are silly and client side media players contain lots of bugs...
youtube might be a somewhat more trusted way to share video content. you can upload privately and share a link.

You might try to get your tools to load the right symbols based on the offsets it's trying to execute (trace instruction pointer and load based on certain change(s)) as it's likely your bootloader will be loaded in a totally different range as the toy kernel. For gdb this would likely boil down to fully scripting your debugging run, which is not impossible but 'playing around' will be a bit more difficult/tedious. For IDA i can't find a load-symbol-file IDC command to script it. maybe it's there on paid versions, but unlikely.

You can also check out Ghidra, which is free to use and supports a lot more than the free IDA versions. As it's open-source, its more likely someone ran into this problem and added code or features to support it.
It can also connect to gdb-server and perhaps have a different way to manage multiple files / debugging symbol sources. You can definitely load multiple binaries, and symbol files for each, just unsure how that will work when using gdb-server and connecting into QEMU. https://ghidra-sre.org/
Thanks a lot for the info, I will keep looking for a solution and I will let you know
StormSeeker
Posts: 10
Joined: Wed Aug 28, 2024 4:03 am

Re: Introduction and question about bootloader/toykernel debugging

Post by StormSeeker »

iansjack wrote: Fri Aug 30, 2024 5:59 am Just as an aside, you can always import symbols with gdb in the middle of a debugging session. A little inconvenient if swapping between files a lot, but I understand that in your case it is just a handover from the boot loader to the kernel. So you just have to load the symbols when you get to the kernel code, which will overwrite the, no longer needed, bootloader symbols.
Just to be clear: if you load symbols from a file in GDB, does GDB trash a previously loaded symbol file?
User avatar
iansjack
Member
Member
Posts: 4671
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Introduction and question about bootloader/toykernel debugging

Post by iansjack »

Yes, loading a symbol file replace the previous one. If you want all symbols available you need to link all your executables into one (not trivial when you have mixed 16-, 32-, and 64-bit code. I use grub as the bootloader, so 16-bit code doesn't come into it. The 32-bit code loaded by grub as a kernel is separate from the 64-bit code, which is loaded as a module; the 32-bit code eventually jumps to the 64-bit portion.

The 32-bit code is well debugged by now, and doesn't change, so I'm only concerned with symbols from the 64-bit code.

When it comes to boot loaders my philosophy is that there is no point in reinventing a well honed wheel. I'm not interested in 16-bit code, or even very much with 32-bit code.
StormSeeker
Posts: 10
Joined: Wed Aug 28, 2024 4:03 am

Re: Introduction and question about bootloader/toykernel debugging

Post by StormSeeker »

iansjack wrote: Sat Aug 31, 2024 1:25 am Yes, loading a symbol file replace the previous one. If you want all symbols available you need to link all your executables into one (not trivial when you have mixed 16-, 32-, and 64-bit code. I use grub as the bootloader, so 16-bit code doesn't come into it. The 32-bit code loaded by grub as a kernel is separate from the 64-bit code, which is loaded as a module; the 32-bit code eventually jumps to the 64-bit portion.

The 32-bit code is well debugged by now, and doesn't change, so I'm only concerned with symbols from the 64-bit code.

When it comes to boot loaders my philosophy is that there is no point in reinventing a well honed wheel. I'm not interested in 16-bit code, or even very much with 32-bit code.
You're quite right, but I need to teach this stuff to high-school students and I believe that knowing low level stuff and seeing it at least once is mandatory to understand what you would otherwise learn by heart. I think I've found a solution, I'll keep you posted ;-)
StormSeeker
Posts: 10
Joined: Wed Aug 28, 2024 4:03 am

Re: Introduction and question about bootloader/toykernel debugging

Post by StormSeeker »

Ok, I ended up learning some IDC scripting language for Ida Pro, then I produced a file containing the database dump as an IDC script, from this script I extracted the commands I needed with their syntax.
Then I manually created a script that identified interesting addresses in the remotely GDB debugged code (running on an X86 QEMU machine).
When I want to tag code as a function I use something like:

create_insn (0X7C21);
set_name (0X7C21, "PRINT");
add_func (0X7C21, 0X7C33);
set_func_flags (0X7C21, 0x4410);
set_frame_size (0X7C21, 0, 4, 0);

When I want to tag code or data as a simple label I use something like:

create_insn (0X7C00);
set_name (0X7C00, "BOOTLOADER_ENTRY_POINT");

Just in case someone else ever needs this.

Ah, I was also able to step through the 16bit->32bit transition code; the trick was to start debugging with a 16 bit manual memory region covering the whole space and with CS:IP debugging option in real mode, then breaking at the far jump needed after flipping the bit in the CR0 register, then modifying the manual memory region as 32 bit and disabling the CS:IP and stepping after the far jump.
Post Reply