Connect to luma3ds gdb stub with "GNU gdb local agent via GADP/TCP" #2721
Replies: 73 comments 333 replies
-
Can you connect to the stub via gdb? |
Beta Was this translation helpful? Give feedback.
-
Okay, this is where I am so far: |
Beta Was this translation helpful? Give feedback.
-
I keep forgetting you're on a Windows box....OK, right, so you're doing the right thing, but I probably haven't provided enough detail again. Either the "GNU gdb local agent over GADP/TCP" or the "IN-VM gdb local debugger" options should work as long as you specify the correct command in the "GDB launch command" parameter (in your case /path/to/arm-none-eabi-gdb.exe") . I would recommend the latter as it will give you more info if it dies and is easier to debug if we have to go that route. When you connect, the device may or may not be running. If it has broken, you'll be in the same state as you were with gdb.exe, and, when you select the process/inferior in the Objects Provider, the green resume/continue button should be enabled. If it's not (i.e. it's running), selecting the same object should enable the interrupt/pause button. If neither of those are true, you'll probably need to do something else in the Interpreter Console. The Interpreter Console is basically (more or less) the same environment as the gdb shell. If you are entering something like "target remote host:port" in gdb, you will have to do the same in the Interpreter. (If the Interpreter isn't visible, launch it from the Objects Provider.) You may also want to read a bit of the help - most of the windows don't display useful info until you are tracing the target. |
Beta Was this translation helpful? Give feedback.
-
I don't really get it. On my 2ds, I have Luma3ds and I turn on the debugger and |
Beta Was this translation helpful? Give feedback.
-
Yes, looks good -fire away! |
Beta Was this translation helpful? Give feedback.
-
(I say "immediate" although I realize you've been working at this for weeks!) |
Beta Was this translation helpful? Give feedback.
-
If it connected, it would be the little console-shaped icon in the Objects Provider at the far left of the toolbar |
Beta Was this translation helpful? Give feedback.
-
Sorry, I'm entering the conversation a little late. Several things to point out. First, as of now, the GDB connector (whether IN-VM or via GADP/TCP) is only supported on Linux. We use So, the simplest, though perhaps disappointing answer, is to just build and run Ghidra on Linux. Then you can use all the GDB stuff "out-of-the-box." If you insist on using Ghidra for Windows, and/or your like a good adventure, then proceed: You can use a Linux VM to host GDB, then connect to it from Ghidra on Windows. While I've not tested this myself, you might be able to forego the Linux VM for WSL. It'll probably work for WSL2, since that is essentially a Linux VM. I'm not as confident for WSL1, but it could. Note that the GADP connection over TCP cannot connect directly to a GDB stub. GADP is Ghidra's in-house protocol for communicating with its connectors. (GDB stubs use RSP, which we don't connect to directly.) We often run the actual connector in a separate "agent" process, because they are more prone to crash. Should they crash, we don't want it to take all of Ghidra with it. (the IN-VM variants loads the connector in Ghidra's process, the via GADP/TCP variants launch the agent and automatically connect via GADP). The "GADP connection over TCP" connector is used when you've already launched an agent, which is a less-common use case, but applies here. In a sense, the agent just wraps GDB as a means of translating GADP to RSP. Thus, you must build and launch the agent manually on Linux, and connect to it from your Windows Ghidra. In your ghidra repo (presumably on Windows), run:
This will generate
You will probably need the Now, from Ghidra on Windows, hit the connect button and select "GADP connection over TCP". Set the network address to your VM's virtual adapter's IP (again, localhost for WSL.) Set the port to 12345, and click connect. You should eventually receive the GDB prompt in Ghidra. You can then proceed as you normally would to connect GDB to your stub. |
Beta Was this translation helpful? Give feedback.
-
To emulate Linux, will I need Hyper-V? |
Beta Was this translation helpful? Give feedback.
-
Which version of Linux would Ghidra's debugger work well on? |
Beta Was this translation helpful? Give feedback.
-
Will the debugger ever work properly on windows? Or if it does now, to connect to 3ds-like devices? |
Beta Was this translation helpful? Give feedback.
-
@SirEnder125 yes, the post by @DrChat means there is hope - we're looking into to it! |
Beta Was this translation helpful? Give feedback.
-
Hey, sorry to bother you guys again, but do you think that |
Beta Was this translation helpful? Give feedback.
-
Hey, Going to weigh in here just to make sure we're all on the same page - if I say anything wrong, feel free to jump in because I'm not sure I have the complete picture myself. So, as I understand your scenario, you have Ghidra running on Windows (effectively the client) and the gdbstub on luma3ds (effectively the server). The gdbstub "speaks" the RSP protocol, so to communicate with it we need something that speaks RSP on the client side. Because we do not have an RSP client for, well, anything, we typically rely on a middleman. On Linux, this is gdb, which we wrap as a gdb agent. In that scenario, Ghidra launches gdb and speaks GADP to it. Gdb translates those requests to RSP and talks to the target (in your case luma3ds). On Linux, we can also create an SSH connection to GDB, issue the commands directly, and get the same result. For Windows, gdb running under Windows proper is basically a non-starter, so your options are either (a) gdb running on WSL, or (b) gdb running on a different machine. If luma3ds had an SSH server, you could talk directly to that, but I don't think it does. (Correct me if I'm wrong on this.) So, let's say we're going WSL. I know exactly nothing about WSL so again correct me if I say something stupid, but, in this case (or even in the second machine) case, you'll want to install the openssh server and gdb on the middleman. Sounds like you have already done this. When you launch the openssh server, you can, I believe, specify a host and a port for clients to talk to it. If you don't specify, the host is localhost and the port is 22. If the server is running under WSL, can the main windows account access it as localhost? I don't know the answer to this, actually. If it can, you'll want to (a) launch the openssh server, and (b) connect from Ghidra using "GDB over SSH" with the parameters set to /path/to/gdb, localhost, 22, and your username for WSL. On a good day, this will launch gdb in the WSL environment. From there, though, you'll still have to connect to the luma3ds. Probably, easiest to do this from the Interpreter using "target remote" etc. Yell if this is unclear (or, of course, incorrect) :/ |
Beta Was this translation helpful? Give feedback.
-
OK, so am guessing you've already done this, but the first thing I would try is opening a Windows cmd window and issuing the command "ssh [email protected]:2222". There are two reasons for doing this: (1) ssh does some set-up on the very first connection that's hard to get right any other way, and (2) it might give you some insight if the ssh connection itself is failing. Assuming you've already done this, my guess is one of two things is going wrong - either gdb is not actually at /usr/bin/gdb ("which gdb" should tell you the actual path) or the path is a link. For reasons I don't quite understand, various tools are not happy with links. If so, "ls -l" the ostensible path, get the real path, and replace the first argument with that. |
Beta Was this translation helpful? Give feedback.
-
Ah, ok - I think you're almost there. Sorry I wasn't clearer above - let me try again. There are, in essence, two use cases here: (1) running from gdb proper, and (2) running gdb from Ghidra. Given everything you've described, I think the second case should, to some extent, just work. In other words, if you run the raw-gdb.bat @nsadeveloper789 provided, Ghidra will build the appropriate PYTHONPATH env variable and use it to load python. In the embedded terminal, you should NOT see the "Undefined command: 'ghidra'" messages. Running gdb solo will still have this problem as we do not, by default, load the ghidra classes into python proper. That said, if you want to do this, you can make it work by navigating to the ghidra/Ghidra/Debug/Debugger-rmi-trace/build/pypkg and Debugger-agent-gdb/build/pypkg directories one at a time and running "python3 -m pip install ." in each. Keep in mind that, if you do this, you will have to make sure you do it again (or delete those packages) the next time you upgrade Ghidra. If the terminal output you provided above is coming from the terminal in Ghidra (I can't quite tell if this is gdb or Ghidra), then we have a different problem. That would indicate (I think) that Ghidra and gdb are still using a different base install for python. You could try the instructions above, I suppose (i.e. python -m pip install .) to see if this fixes things, but not quite sure what's going on if this is the case. |
Beta Was this translation helpful? Give feedback.
-
When you say "run the raw-gdb.bat," you mean through It's still unable to find ghidragdb. I've tried several things: Following the instructions exactly In each case, the result is the same. I've tried troubleshooting ghidragdb like so: If I open a fresh terminal, run python, then type If I open gdb directly (using the exact path I have provided to raw-gdb.bat), then type If I open gdb within Ghidra via I've triple checked that in each case, the exact same python is being used (by typing |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Okay, I am having one issue with setting breakpoints. I have a function that begins at 0x2f2da4. If I type The INCONSISTENT_ENABLED breakpoint is the one created by manually entering the command into gdb, and the INEFFECTIVE_ENABLED breakpoint is the one created by pressing K in the listing. Pressing K also doesn't seem to create an entry in the bottom part of the window. Is there something I can do to make this work? |
Beta Was this translation helpful? Give feedback.
-
OK, so the relevant question here is what, if anything, do you see in the Modules window? Also, I guess, are both the Dynamic and Static listings populated? You should always be able to set breakpoints in the Dynamic listing as this corresponds to the running executable's memory. The Static listing represents the memory of the program as loaded into Ghidra. The ability to set a breakpoint there depends on having an accurate map between the two listings. In general, for embedded devices and for devices with a less than fully functional gdbstub, the "maintenance" and "info proc" commands may not work leaving the mapping undetermined. You can either fake the responses to these commands per @SirEnder125's comments or force the mapping by hand from the Modules window's pull-down. The Debugger Help has some good suggestions in this regard. |
Beta Was this translation helpful? Give feedback.
-
The Modules window is empty, as is the Dynamic listing. I also don't have a memory map - I suspect this is because I simply chucked a bare code.bin file into Ghidra, set the start location to 0x100000 as required by 3DS games, and that's it. I'm poking around in the debugger help, but I'm not having much luck. I can bring up the Static Mappings window and see the mapping of the code.bin file, but I can't figure out how to actually put that into the Modules section. None of the auto-map options put anything into the Modules window and I'm not sure exactly what you mean by the "Modules window's pull-down." I'm guessing I need to set up the program a little more robustly? |
Beta Was this translation helpful? Give feedback.
-
Sorry, once again, probably not clear enough.... With code.bin in the Static window and the debugger running, go to Modules window. There should be two buttons on the top - one that looks like a double-sided arrow and one next to it that looks like a page. The mouse-over hover for the arrows icon will say "Map the current trace to the current program using identical addresses." If you've loaded code.bin at 0x100000 or rebased it there, that's probably an OK option. If you need to map the two at a relative offset, choose the icon to the right, which says "Map the current trace to various programs manually." The pull-down further to the right (with the "Settings" icon) has other options. |
Beta Was this translation helpful? Give feedback.
-
Right - the double-sided arrow does add something to the Static Mappings window, but nothing appears in the Modules window, and the Dynamic listing remains empty. Though just now I noticed that now the breakpoints do work - I just thought it wasn't working because nothing was populating the Modules window. Okay, neat. Thanks, and sorry about stumbling around so much. Now pretty much all that's left to get working is the Dynamic listing and I should have pretty much everything...? |
Beta Was this translation helpful? Give feedback.
-
I think nothing in Modules is ok if you have the static mapping. That said, I'm a little concerned about the lack of content in the Dynamic Listing. Are there any threads listed in the Threads window and/or can you navigate to a thread in the model pane and double-click it? |
Beta Was this translation helpful? Give feedback.
-
Ah, but you're running. If you break, do you get the same results? |
Beta Was this translation helpful? Give feedback.
-
Yeah, the state here is "STOPPED" - is that different from a break? Regardless of the state, I've never seen anything in the Dynamic window. |
Beta Was this translation helpful? Give feedback.
-
Hmmm, the view you posted seems a little inconsistent. STOPPED should mean broken, but the threads also say "running", and it looks like commands issued in the terminal are telling you the target is running, as well. Sometimes we see this before the first break, but could be something else going on, I suppose. |
Beta Was this translation helpful? Give feedback.
-
OK, maybe double-click on one of those threads in Threads. Also, trying going to the Model pane and navgiating down to and double-clicking a thread there. |
Beta Was this translation helpful? Give feedback.
-
One more thought: select the Dynamic window, hit G for "goto" or right-click to get it and type in manually one of the thread PCs. |
Beta Was this translation helpful? Give feedback.
-
I believe the empty Dynamic Listing is because of no result for
Just to put everything together (as far as I can tell from convo above), what I'd recommend:
|
Beta Was this translation helpful? Give feedback.
-
Hey. Someone recently told me:
I'm not sure if it is compatible. But Luma3ds does have a gdb stub. But the debugger gives me this error:
Beta Was this translation helpful? Give feedback.
All reactions