Can I use eBPF to get the text segment of every process? - linux-kernel

I've been interested in eBPF recently and I was wondering if I could use eBPF to get text segment of user process? Could someone tell me how to do if it's possible?

Related

Follow register changes with gdb

How can I follow on changes in specific registers using GDB?
I want to write a log each instruction's address that changed the value on this register
How can I do that using GDB ?
I want to write a log each instruction's address that changed the value on this register
The only way to do this is to single-step the program, compare values of registers to previously-saved values, and print previous value of instruction pointer if the value of the register of interest has changed.
You can automate this by using GDB embedded Python, but even with automation this will be impractically slow for any non-trivial program (as would single-stepping without actually doing anything between the steps).
P.S. Depending on what actual problem you are trying to solve (see http://xyproblem.info), more practical solutions may exist.

Software for visualizing arbitrary part of process memory content in real-time

In my practice I faced with the task - visualize some process memory content in real time. The main idea is read arbitrary part of remote process memory, represent it as image, and show in a separate window, then repeat these action with some interval, and in result get dynamic visualization of memory content. For example, it will be useful for view framebuffers/textures that located in process memory. Do exists any tools/software for this purpose? Thanks.
So, I did not find any utilities, and so I created my own tool.
This is mem2pix, program which allows to real-time visualizing some part of remote process memory, supports many pixel format type. Currently works on both Windows and Linux.

Where are page permissions stored on hardware and how can I alter them directly?

I'm trying to write a pseudo kernel driver (it uses CVE 2018-8120 to get kernel permission so it's technically not a driver) and I want to be as safe as possible when entering ring0. I'm writing a function to read and write MSR's from userland, and before the transition to ring0 I'm trying to guarantee that the void pointer given to my function can be written, I decided the ideal way to do this was to make it writable if it is not already.
The problem is that the only way I know how to do this is with VirtualProtect() and NtAllocateVirtualMemory, but VirtualProtect() sometimes fails and returns an error instead. I want to know precisely where these access permissions are stored (in ram? in some special CPU register?) how I can obtain their address and how can I modify them directly?
User-mode code should never try to muck around in kernel data structures, and any properly written kernel will prevent it anyway. The best way for user mode code to ensure that an address can be written is to write to it. If the page was not already writeable, the page fault will cause the kernel to make it so.
Nevertheless, the kernel code /cannot/ rely on the application having done so, for two reasons:
1) Even if the application does it properly, the page might be unmapped again before (or after) entering ring 0.
2) The kernel should /never/ rely on application code to do the right thing. It always has to protect itself.
The access permissions information and page data is stored in the page directory, page table, CR0 and CR3.
More information can be found here: https://wiki.osdev.org/Paging.

BPF: owner of a map

This is follow-up to who creates map in BPF since my new question is not directly relevant that thread.
So, it seems to me that there has to be a single point where a BPF map is created, either it is a bpf program or a user program that loads bpf etc.
A BPF program has to know type of maps it is going to work with at compile-time, so we need:
struct bpf_map_def SEC("maps") my_map = {
...
};
So it means that a user program, for example bpftool, will initiate creation of maps found in bpf ELF sections, as was shown in who creates map in BPF thread.
On the other hand, user application will need to add/delete entries in the map. For this to happen, it has to know map's ID in order to obtain get map's fd with bpf_map_get_fd_by_id() from libbpf. After that we can enjoy bpf_map_update_elem() and similar APIs.
On the other hand, if we declared a map section in the BPF program and do have map API in use, the map(s) will be preserved in the kernel and will be allocated IDs.
So in this case, we are going to have two maps with two different IDs: one created as a result of bpf_prog_load() from bpftool, and the other from the user application's bpf_create_map() (assuming that the application continues running, e.g. update maps, and does not return to shell).
There must be a way to bypass this ambiguity?
I am not completely sure I understand your question, let me try to rephrase this.
You load an eBPF program with bpftool, which creates all maps needed by the program. bpftool is a user space application, and ultimately creates maps with the bpf(BPF_MAP_CREATE, …) syscall.
You have another user space application foobar that interacts with these maps, possibly by using libbpf (that in turns ends up performing bpf(BPF_MAP_*, …) syscalls) to look up, update or delete elements from the maps.
As I understand it, this second application foobar also tries to create the maps. Hence you have a conflict between the maps created by bpftool and the one created by foobar.
If this is correct, the solution is “simple”: do not create the maps twice.
This means that you should either delete the calls to bpf_create_map() from your other application foobar, or load your programs with something else than bpftool. Usually, the workflow consists in having the maps described in the eBPF object file, and created by the same application that loads the program, just before loading—this is what bpftool does. Then the application has the file descriptor for the map and can work on it.
Alternatively, it is possible to pin the map under the BPF virtual file system (/sys/fs/bpf/) so that another application can retrieve the file descriptor, and also access this map. This is done with the syscall bpf(BPF_OBJ_GET, …) (not yet documented on the man page at this time, at least on my system).
If I am correct, using pinned maps can also allow one to reuse an already existing map when loading a new eBPF program. I believe tc from package iproute2 intends to do that if the map described exists and is pinned already (see file lib/bpf.c, but the code is not exactly easy to read). This would typically be performed at relocation time.
Maps IDs were added recently, and primarily for debug or introspection, but they may provide another way to retrieve the file descriptor to a map in your case, as you describe with bpf_map_get_fd_by_id(). Although you have to find a way to get the ID in the first place.
Hope this helps!

which driver is the owner of a handle?

is there any way to determine which driver is the owner of the hanlde?
I mean is it stored any where is Windows objects?
I can see handles via volatilty but all kernel handles are assigned to System.exe pid:4, I need to know exactly which driver is using this system handle?
thanks
Is there any way to determine which driver is the owner of the
handle?
When kernel modules (or thread in kernel space) call Kernel API (NtCreateFile, for example), the handles are allocated from handle table of System process. In this case, the answer is: no.
I mean is it stored any where is Windows objects?
I guess no
I need to know exactly which driver is using this system handle?
Depend on analisys you're doing. If you need to associate an object back to the driver that owns it, you can try to analize _POOL_HEADER structure to obtain information about who produced the allocation. BUT if you need to analyze an executive object (_FILE object, for example), the PoolTag field in this header will be equal to ObjectType.Key, so this way is not very useful for your purpose.
In general, if you're looking for which resources a process can access (i.e. memory-mapped files), you can analyze with memmap volatility's plugin the process' page tables and so the memory area of the process. I suggest you to use VAD structures' dedicated plugin so that you can gather an high-level information about virtual address space of the process.

Resources