Symbol table in linux

Symbol Table

A symbol table of a program is basically just a list containing the program’s symbols (function names, global variables, etc) and the corresponding addresses of these symbols. The reason to use a symbol table for your kernel can vary for every OSDever, but it is especially useful when loading kernel modules, because a module can be loaded ANYWHERE and it should know how to call the kernel (cleanly, not with dirty hardcode).

Extracting the Debug Symbol Table

If you want for example to get ALL the global symbols in the Kernel for debugging purposes, just use the nm utility as shown here.

$ nm mykernel.bin > mykernel.map

Important to note here that I’m assuming you are using ELF as the binary format with the symbol table section not stripped out. The resulting file contains three columns. The first is the address of the symbol, the second is what kind of symbol it is and the third is the name of the symbol.

The Modulation Problem

I will explain it from bottom. If you have a Modular and/or Microkernel, you must attach to a rule if you don’t want to lose the modulation benefits. That simple rule is to have every single needed module (only needed ones) loaded at run-time. Did you notice the problems, no? Well, I will list them:

  • That run-time modules include the PCI IDE driver, the driver corresponding to the filesystem in the root mount, and all the driver for all the ACPI says to exist. Some of this drivers are required to access a Massive Storage Unit, where the other modules are. Solution: A initrd.
  • If the modules are loaded at dynamically selected locations (mandatory due to the posibility of hardware change), you must provide a Symbol Table to the modules, else they won’t know how to call the kernel. (Don’t even think on using a typical syscall, that would be too slow and expensive, leave it for applications) This would include all the fast and low-level API functions the drivers should use.

For the dynamic-loading problem, use this solution:

  • #include all the symbols you want to export into a single place.
  • Make a function pointer array. As you have different function return types and parameters, you should do this:

where you must replace 123 with your function amount.

KRNLSYMTABLE[321] = (uint32_t)&myFunction;
  • When loading a module, you should (using paging) reference the KRNLSYMTABLE dedicated page (yes, it must be like that) to a fixed virtual memory page, so the module always knows where to find things.

Notice that this model uses a separate page directory as per driver. It isn’t the best approach, but with this the kernel won’t crash with a module.

Источник

Creating New Symbol Tables¶

This page details how symbol tables are located and used by Volatility, and documents the tools and methods that can be used to make new symbol tables.

How Volatility finds symbol tables¶

All files are stored as JSON data, they can be in pure JSON files as .json , or compressed as .json.gz or .json.xz . Volatility will automatically decompress them on use. It will also cache their contents (compressed) when used, located under the user’s home directory, in .cache/volatility3 , along with other useful data. The cache directory currently cannot be altered.

Читайте также:  Linux view kernel version

Symbol table JSON files live, by default, under the volatility3/symbols directory. The symbols directory is configurable within the framework and can usually be set within the user interface.

These files can also be compressed into ZIP files, which Volatility will process in order to locate symbol files.

Volatility maintains a cache mapping the appropriate identifier for each symbol file against its filename. This cache is updated by automagic called as part of the standard automagic that’s run each time a plugin is run. If a large number of new symbols file are detected, this may take some time, but can be safely interrupted and restarted and will not need to run again as long as the symbol files stay in the same location.

Windows symbol tables¶

For Windows systems, Volatility accepts a string made up of the GUID and Age of the required PDB file. It then searches all files under the configured symbol directories under the windows subdirectory. Any that contain metadata which matches the pdb name and GUID/age (or any compressed variant) will be used. If such a symbol table cannot be found, then the associated PDB file will be downloaded from Microsoft’s Symbol Server and converted into the appropriate JSON format, and will be saved in the correct location.

Windows symbol tables can be manually constructed from an appropriate PDB file. The primary tool for doing this is built into Volatility 3, called pdbconv.py . It can be run from the top-level Volatility path, using the following command:

PYTHONPATH=».» python volatility3/framework/symbols/windows/pdbconv.py

The PYTHONPATH environment variable is not required if the Volatility library is installed in the system’s library path or a virtual environment.

Mac or Linux symbol tables¶

For Mac/Linux systems, both use the same mechanism for identification. The generated files contain an identifying string (the operating system banner), which Volatility’s automagic can detect. Volatility caches the mapping between the strings and the symbol tables they come from, meaning the precise file names don’t matter and can be organized under any necessary hierarchy under the symbols directory.

Linux and Mac symbol tables can be generated from a DWARF file using a tool called dwarf2json. Currently a kernel with debugging symbols is the only suitable means for recovering all the information required by most Volatility plugins. Note that in most linux distributions, the standard kernel is stripped of debugging information and the kernel with debugging information is stored in a package that must be acquired separately.

A generic table isn’t guaranteed to produce accurate results, and would reduce the number of structures that all plugins could rely on. As such, and because linux kernels with different configurations can produce different structures, volatility 3 requires that the banners in the JSON file match the banners found in the image exactly, not just the version number. This can include elements such as the compilation time and even the version of gcc used for the compilation. The exact match is required to ensure that the results volatility returns are accurate, therefore there is no simple means provided to get the wrong JSON ISF file to easily match.

Читайте также:  Limit on open files in linux

To determine the string for a particular memory image, use the banners plugin. Once the specific banner is known, try to locate that exact kernel debugging package for the operating system. Unfortunately each distribution provides its debugging packages under different package names and there are so many that the distribution may not keep all old versions of the debugging symbols, and therefore it may not be possible to find the right symbols to analyze a linux memory image with volatility. With Macs there are far fewer kernels and only one distribution, making it easier to ensure that the right symbols can be found.

Once a kernel with debugging symbols/appropriate DWARF file has been located, dwarf2json will convert it into an appropriate JSON file. Example code for automatically creating a JSON from URLs for the kernel debugging package and the package containing the System.map, can be found in stock-linux-json.py . The System.map file is recommended for completeness, but a kernel with debugging information often contains the same symbol offsets within the DWARF data, which dwarf2json can extract into the JSON ISF file.

The banners available for volatility to use can be found using the isfinfo plugin, but this will potentially take a long time to run depending on the number of JSON files available. This will list all the JSON (ISF) files that volatility3 is aware of, and for linux/mac systems what banner string they search for. For volatility to use the JSON file, the banners must match exactly (down to the compilation date).

Steps for constructing a new kernel ISF JSON file:

  • Run the banners plugin on the image to determine the necessary kernel
  • Locate a copy of the debug kernel that matches the identified banner
    • Clone or update the dwarf2json repo: git clone https://github.com/volatilityfoundation/dwarf2json
    • Run go build in the directory if the source has changed
    • For Mac change linux to mac
    • For Mac change linux to mac

    Источник

    Embedded Guru

    Every kernel image that you build has a symbol table with it. The Linux kernel symbol table contains names and addresses of all the kernel symbols. When you install the kernel it will be present in /boot/System.map-

    When you define a new function in your module, the default behavior of this function is local, only the module in which the function is defined can access it, cannot be accessed by other modules. To export this module we need to use EXPORT_SYMBOL or EXPORT_SYMBOL_GPL. Once you export them, they will be available to other modules to use.

    • Get link
    • Facebook
    • Twitter
    • Pinterest
    • Email
    • Other Apps

    Comments

    Post a Comment

    bb.utils.contains yocto

    Image

    bb.utils.contains is most commonly used function in Yocto. grep in poky directory returned with 696 count. $ grep -nr ‘bb.utils.contains’ poky/ | wc -l 696 It’s definition is present in ‘poky/bitbake/lib/bb/utils.py’ file This function returns third argument if the second argument is subset of the first argument else returns fourth argument Let’s take an example to understand this. You can see from the above screenshot, when the second argument is a subset of first argument, «present» was returned, else «notpresent» was returned We can also use bb.utils.contains inside if loop. This we can use inside a recipe. if $; then FOO = ‘HELLO’ fi

    make config vs oldconfig vs defconfig vs menuconfig vs savedefconfig

    Image

    Building the Linux Kernel is a two-step process: Configuring the Kernel options Building the Kernel with those options. There are many methods available for configuring the kernel. make config: Text-based Configuration. Options are prompted one after another. All options need to be answered Access to former options is not possible make menuconfig: Menu-driven user interface Allows to navigate forwards and backward directly between features Allows to load and save files with filenames different from «.config» Provides search feature It uses ncurses library for GUI. If the ncurses library is not installed, make menuconfig option fails. To install ncurses library on Ubuntu: sudo apt-get install libncurses5-dev make defconfig: Creates a «.config» file with default options from the ARCH supplied defconfig Configurations are generally stored in the directory: arch/$(ARCH)/configs $ ls arch/x86/configs/ i386_defconfi

    PR, PN and PV Variable in Yocto

    PN : Represents the name of the recipe. The name is usually extracted from the recipe file name. PR: Represents the revision of the recipe. Default value for this revision is «r0». Subsequent revisions of the recipe conventionally will have «r1», «r2» and so on. PV: Represents the version of the recipe. Normally extracted from the recipe file name. For example: ffmpeg_3.4.2.bb recipe. $ : ffmpeg $ : 3.4.2

    Источник

    What is symbol table and how is it integrated into the executable?

    The -g set are debugging symbols, which make things a lot easier as they allow you to see your code and look at variables while debugging.

    Another set of symbols is included by default when you compile. These are the linking symbols and live in the ELF (executable linkable format) symbol table. This contains a lot less info than the debug symbols, but contain the most important stuff, such as the addresses of the things in your executable (or library or object file). Without this information gdb won’t even know where main is, so (gdb) break main would fail.

    If you don’t have the debugging symbols ( -g ) then you will still be able to (gdb) break main but you gdb will not have any concept of the lines of code in your source file. When you try to step through the code you will only advance 1 machine instruction at a time, rather than a line at a time.

    The strip command is often used to strip off symbols from an executable (or other object file). This is often used if you don’t want someone to be able to see the symbols or if you want to save space in the file. Symbol tables can get big. Strip removes both the debug symbols and the linker symbols, but it has several command line switches which can limit what it removes.

    If you run the file command on your program one of the things it will tell you is weather or not the executable is has been stripped.

    $ gcc my_prog.c -o my_prog $ file my_prog my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped $ strip my_prog my_prog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped $ 

    Источник

Оцените статью
Adblock
detector