[LINUX] Try to play with the uprobe that supports Systemtap directly

This article is the 10th day article of Linux Advent Calendar 2016.

Overview

Uprobes that can be used from ftrace, eBPF / bcc, Systemtap, etc. I can't find a sample (kernel module) that can be executed by uprobes alone like kprobes. So, Christmas is near, so this time I will introduce a sample of uprobes that anyone can easily use (I do not say that you should feel free to make a kernel module). The detailed implementation explanation is omitted, but the corresponding instruction is rewritten to 0xcc and skipped.

environment

Distribution: Ubuntu 16.04 Kernel used for investigation and verification: 4.4.0-45-generic

uprobes API

uprobes is a Linux kernel mechanism that probes user processes from kernel space. Normally uprobes is used from a user-space configurable interface like ftrace A kernel module that uses uprobes is generated from a unique script like Systemtap, and is used in it.

Since Christmas is near this time, I will write a kernel module for direct contact with uprobes.

First, let's take a look at the kernel-side API for using the uprobes mechanism.

/*
 * uprobe_register - register a probe
 * @inode: the file in which the probe has to be placed.
 * @offset: offset from the start of the file.
 * @uc: information on howto handle the probe..
 *
 * Apart from the access refcount, uprobe_register() takes a creation
 * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
 * inserted into the rbtree (i.e first consumer for a @inode:@offset
 * tuple).  Creation refcount stops uprobe_unregister from freeing the
 * @uprobe even before the register operation is complete. Creation
 * refcount is released when the last @uc for the @uprobe
 * unregisters.
 *
 * Return errno if it cannot successully install probes
 * else return 0 (success)
 */
int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)

It can be seen that the information that needs to be set is roughly the inode of the probe target file, the probe target offset of the probe target file, and the handler to be executed when the probe is performed.

Next, let's look at the uprobe_consumer structure that sets the function at the time of probe.

struct uprobe_consumer {
        int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
        int (*ret_handler)(struct uprobe_consumer *self,
                                unsigned long func,
                                struct pt_regs *regs);
        bool (*filter)(struct uprobe_consumer *self,
                                enum uprobe_filter_ctx ctx,
                                struct mm_struct *mm);

        struct uprobe_consumer *next;
};

From the definition of the uprobe_consumer structure, it can be seen that the pt_regs structure is passed via the handler at the time of probe.

sample

This time, run the following appropriate C sample application and try to probe the debuggee_func function call.

#include <stdio.h>

int debuggee_func(int a, int b)
{
        int result;
        result = a + b;
        return result;
}

void main()
{
        int result;
        result = debuggee_func(1, 2);
        printf("result: %d", result);
}

Next, the sample kernel module that uses uprobes is placed below. Please check the sample code below for processing such as conversion from file path to inode.

https://github.com/kentaost/uprobes_sample/blob/master/uprobes_sample.c

The following DEBUGGEE_FILE in this uprobes sample kernel module represents the file to be debugged, and DEBUGGEE_FILE_OFFSET represents the offset. The offset is obtained from the address of the target function and the start address of the text segment for the target binary using readelf or the like. In my environment, the debuggee_func function was 0x526 (0x400526 --0x400000), so I embedded this value and made it.

#define DEBUGGEE_FILE "/home/kentaost/debuggee_app"
#define DEBUGGEE_FILE_OFFSET (0x526)

After insmoding this sample kernel module, if you run the sample application and look at dmesg, you can see the evidence of probing as follows.

…
[xxxx.xxxxxx] handler is executed
[xxxx.xxxxxx] ret_handler is executed

As you can see from the uprobe_register function, it is not a mechanism to set the probe for each user process. For example, you can see that even if you launch the same program multiple times, it will be probed.

As an aside, if you do your best, you can prepare a user space stack trace in the same way as Systemtap below. (Systemtap prepares tapset so that you don't have to work hard, so usually use Systemtap and tapset)

http://qiita.com/kentaost/items/a2e882d2978fba9e17d3

Summary

Although omitted this time, if you also understand the internal implementation of uprobes, you can understand the behavior when probing a user process with Systemtap etc. (when using uprobes). There is no use for direct use, but you should use ftrace and Systemtap obediently except for Christmas.

Recommended Posts

Try to play with the uprobe that supports Systemtap directly
Try to solve the fizzbuzz problem with Keras
Try to solve the man-machine chart with Python
I wanted to play with the Bezier curve
How to try the friends-of-friends algorithm with pyfof
Try to solve the programming challenge book with python3
Try to visualize the room with Raspberry Pi, part 1
Try to solve the internship assignment problem with Python
Try to get the contents of Word with Golang
[Neo4J] ④ Try to handle the graph structure with Cypher
Try to specify the axis with PyTorch's Softmax function
Try to create a waveform (audio spectrum) that moves according to the sound with python
Try to factorial with recursion
Try to automate the operation of network devices with Python
Try to extract the keywords that are popular in COTOHA
The story that the private key is set to 600 with chmod
Try to visualize the nutrients of corn flakes that M-1 champion Milkboy said with Python
Try to decipher the garbled attachment file name with Python
Try to extract the features of the sensor data with CNN
Try to generate a death metal jacket image with DCGAN + scrape the metal database site for that
Try to solve the N Queens problem with SA of PyQUBO
Try to write a program that abuses the program and sends 100 emails
Try to solve the shortest path with Python + NetworkX + social data
From "drawing" to "writing" the configuration diagram: Try drawing the AWS configuration diagram with Diagrams
Try to operate Facebook with Python
Try to profile with ONNX Runtime
Try to introduce the theme to Pelican
Cython to try in the shortest
Try blurring the image with opencv2
Try to output audio with M5STACK
The fastest way to try EfficientNet
The easiest way to try PyQtGraph
How to call a POST request that supports Japanese (Shift-JIS) with requests
Put Cabocha 0.68 on Windows and try to analyze the dependency with Python
Try to image the elevation data of the Geographical Survey Institute with Python
Try to solve the traveling salesman problem with a genetic algorithm (Theory)
Try to react only the carbon at the end of the chain with SMARTS
Convert the program that imports Google's client library to .exe with pyinstaller
Address to the bug that node.surface cannot be obtained with python3 + mecab
[Cloudian # 5] Try to list the objects stored in the bucket with Python (boto3)
Try to separate the background and moving object of the video with OpenCV
[Introduction to WordCloud] Let's play with scraping ♬
Try to reproduce color film with Python
Try logging in to qiita with Python
Try to face the integration by parts
Play around with the pythonista3 ui module
Try the Variational-Quantum-Eigensolver (VQE) algorithm with Blueqat
Try using the camera with Python's OpenCV
Fractal to make and play with Python
I want to play with aws with python
Try to predict cherry blossoms with xgboost
Try converting to tidy data with pandas
Quickly try to visualize datasets with pandas
Python amateurs try to summarize the list ①
First YDK to try with Cisco IOS-XE
Try rewriting the file with the less command
Match the colorbar to the figure with matplotlib
Play with puns using the COTOHA API
Try to generate an image with aliasing
The road to compiling to Python 3 with Thrift
Try to solve the traveling salesman problem with a genetic algorithm (Python code)