The gdb wrapper library (libgdbwrap)
The libgdbwrap provides a library to wrap any proprietary protocol to the gdb serial protocol in a very simple way.
The main features of the libgdbwrap are:
- Provides basic functions, like stepping, breakpoint setting, continue, etc.
- Supports multiple ways of communication with a server.
- A simplicity of implementation.
- Little dependancy with the rest of the project.
The Functions of libgdbwrap
The libgdbwrap provides the following functions:
| gdbwrap_init | Initialize and returns a gdbwrap_t descriptor. |
| gdbwrap_erroroccured | Returns TRUE (1) if an error occurred, FALSE (0) otherwise. |
| gdbwrap_cmdnotsup | Returns TRUE if command not supported, FALSE otherwise. |
| gdbwrap_atoh | Ascii to hex conversion. |
| gdbwrap_lastsignal | Returns the last signal. |
| gdbwrap_is_active | TRUE if server is active, FALSE if dead or has finished. |
| gdbwrap_current_set | Set the gdbwrapworld global variable. |
| gdbwrap_current_get | Get the gdbwrapworld global variable. |
| gdbwrap_close | Deallocate the memory of the gdbwrap_t descriptor |
| gdbwrap_hello | Set a connexion with the server. |
| gdbwrap_bye | Send a kill command to the server. |
| gdbwrap_reason_halted | Retrieve the register states and the last signal. |
| gdbwrap_readgenreg | Read general purpose registers. |
| gdbwrap_continue | Send a continue command. |
| gdbwrap_setbp | Set a breakpoint remotely by adding a 0xcc. |
| gdbwrap_simplesetbp | Use the embedded command to set a breakpoint.| |
| gdbwrap_delbp | Delete a 0xcc breakpoint. |
| gdbwrap_simpledelbp | Use the embedded command to delete a breakpoint. |
| gdbwrap_readmem | Read the remote memory. |
| gdbwrap_writemem | Write in the remote memory. |
| gdbwrap_writereg | Write into the remote registers. |
| gdbwrap_shipallreg | Send all registers to the server in one shot. |
| gdbwrap_ctrl_c | Send an asynchronous stop to the server. |
| gdbwrap_signal | Send a signal to the server. |
| gdbwrap_stepi | Make the server step on 1 instruction. |
| gdbwrap_remotecmd | Send a custom command to the server. |
Structure of the gdbwrapper library
The library contains the following files:
- include/gdbwrapper.h : all the function definitions and structures that will be exported.
- include/gdbwrapper-internals.h: internal variables & definitions. In this file you can activate the DEBUG mode by setting the DEBUG_GDBWRAP to true.
- The main file of libgdbwrap is gdbwrapper.c, which contains the whole gdb protocol implementation.
- doc/gdbserialproto.txt: The gdb serial documentation.
The gdbwrapper.c is split in two parts. The first one, contains local functions (defined as static), implementing the raw parts of the gdb protocol: packet extraction, packet manipulation, run-length decoding, checksum calculation, etc. It also contains all the definitions of the gdb commands.
The second part of the file is the actual definition of the functions. To explain how it works, we take an example. Suppose we want to implement the gdb "stepping" instruction. By looking at the gdbserialproto.txt (or by analyzing the traces with wireshark for example), we figure out that the instruction is encoded as `s [addr]`. Thus, the stepping instruction can be encoded in only one line:
char *reply = gdbwrap_send_data(desc, "s")
where "desc" is the current descriptor and "s" is the command. gdbwrap_send_data will return you the reply from the server, so in case you are interested in it, you just save it with a reply pointer.
If you want to test the server behavior, the gdbwrap_remotecmd becomes handy. It helps in sending directly raw messages to the server and the how it replies.
Special functions like gdbwrap_writemem contain a small hack to fit the server the communicate with. Since the gdb protocol implements different commands for a same result, it might happen that a server will understand one but not the other. By setting a static variable, we can easily choose which command is supported by the server: if a command is not supported, we increment it and thus, choose the supported function.
Another function that must be explained is gdbwrap_hello. This function initiates a connexion with the server and consequently, has its importance. During this first transaction, the client must query the stub about its abilities with special command:qSupported. Currently, we are only interested in the maximum packet size and we discard the rest of the message. This function must probably be updated if we decide to support other servers.
Latest news
This list shows major modifications in libgdbwrap since the first version:
| April 13 2009 | Update of the wiki page |
| December 21 2008 | First release of libgdbwrap |
Portability of e2dbg
Currently, libgdwrap only support Intel ia-32.
Dependencies
- libaspect : the types specification library, a lower-level component necessary for the ERESI language interpreter.
