I would like to debug a loaded kernel module I don't have the source code to; I suspect it's a virus. Is there a way to feed it into GDB for analysis?
How to debug an inserted kernel module
debuggingkernelkernel-modules
Related Solutions
First things first, debug the module? Just see if you can load it up in gdb it might point you straight at a line that uses the relevant variable(or close to it).
oh, and you might find this article useful
I am answering my own question. This was harder than I expected, and I want to gather all the information in one convenient place.
Install Binary, Development, and Debug Packages
This can be done using apt
(or aptitude
).
Example for Qt5:
- Compiled libraries:
qt5-default
- Development package (headers):
qtbase5-dev
- Debugging symbols:
qtbase5-dbg
Find Source Package Name
You can find it using aptitude
or the Debian package search tool: https://www.debian.org/distrib/packages#search_packages
Example: Searching for qtbase5-dbg
will find: https://packages.debian.org/jessie/qtbase5-dbg
The top of each binary package page has a link to the source package.
Example: qtbase-opensource-src
Install Source Package
If necessary, first configure your apt
source package repositories by reading this answer: https://unix.stackexchange.com/a/121042/29414
- Drop root:
su -
cd /usr/src
apt-get source ${source_package_name}
- Example:
apt-get source qtbase-opensource-src
- Example:
- The source package is downloaded, unzipped/untarred, and patched into a new directory.
- Example:
/usr/src/qtbase-opensource-src-5.3.2+dfsg/
- Example:
- Remove the downloaded TAR ball and other files (maybe
.dsc
).rm *.tar.* *.dsc
- Create a symbolic link:
ln -s qtbase-opensource-src-5.3.2+dfsg qtbase-opensource-src
Configure GDB
(This section can be completed using your non-root / regular account.)
GDB needs configuration to know where source code can be found.
Each source package is a little different, so I will use Qt5 as an example.
cd /usr/src/qtbase-opensource-src/src
- Find list of source subdirectories:
find $(pwd) -mindepth 1 -maxdepth 1 -type d
- Example:
/usr/src/qtbase-opensource-src/src/corelib ...
- Example:
- Reformat the
find
output to create GDB commands:find $(pwd) -mindepth 1 -maxdepth 1 -type d | sort | xargs -l -i printf -- 'directory %s\n' "{}"
- Example:
directory /usr/src/qtbase-opensource-src/src/3rdparty ...
- Example:
- Insert GDB commands into your
~/.gdbinit
for convenience.
Sample ~/.gdbinit
:
set auto-load safe-path /
set history save
set history filename ~/.gdb_history
directory /usr/src/qtbase-opensource-src/src/3rdparty
directory /usr/src/qtbase-opensource-src/src/android
directory /usr/src/qtbase-opensource-src/src/angle
directory /usr/src/qtbase-opensource-src/src/concurrent
directory /usr/src/qtbase-opensource-src/src/corelib
directory /usr/src/qtbase-opensource-src/src/dbus
directory /usr/src/qtbase-opensource-src/src/gui
directory /usr/src/qtbase-opensource-src/src/network
directory /usr/src/qtbase-opensource-src/src/opengl
directory /usr/src/qtbase-opensource-src/src/openglextensions
directory /usr/src/qtbase-opensource-src/src/platformsupport
directory /usr/src/qtbase-opensource-src/src/plugins
directory /usr/src/qtbase-opensource-src/src/printsupport
directory /usr/src/qtbase-opensource-src/src/sql
directory /usr/src/qtbase-opensource-src/src/testlib
directory /usr/src/qtbase-opensource-src/src/tools
directory /usr/src/qtbase-opensource-src/src/widgets
directory /usr/src/qtbase-opensource-src/src/winmain
directory /usr/src/qtbase-opensource-src/src/xml
show directories
Run GDB
This section assumes you already have a program compiled with debugging symbols linked to the library of interest, e.g., Qt5.
gdb ${program_name}
- Start the program and break at
main()
automatically:start
- Set a breakpoint in a library function:
b '${function_signature}'
Commandb(reakpoint)
with single quotes supports (very impressive!) tab completion.- Example:
b 'QStyled<tab>
->b 'QStyledItemDelegate
->::paint(<tab>
->b 'QStyledItemDelegate::paint(QPainter*, QStyleOptionViewItem const&, QModelIndex const&) const'
- Example:
- Continue to hit the new breakpoint:
c
orcontinue
- When the library breakpoint is hit, GDB will find and display the source code.
Best Answer
From a debugging perspective, the kernel is a special "process", distinct from the user space processes, which communicate with the kernel via a sort of rpc mechanism (syscalls) or mapped memory..
I don't think you can see the kernel's data structure simply by inspecting some random user process.
Another problem is, that every user space process (including the debugger) needs the kernel to run and to communicate with the users; I don't think you can just stop the kernel and believe that the debugger will continue to run.
So you need to run GDB on a second machine, and that is what is called Kernel debugging.
Please refer to (http://kgdb.linsyssoft.com/, Documentation/sh/kgdb) for more details.