ptrace | A Go library for the Linux ptrace system call
kandi X-RAY | ptrace Summary
kandi X-RAY | ptrace Summary
A Go library for the Linux ptrace system call.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
- Exec creates a Tracee
- Detach detaches the Tracee .
ptrace Key Features
ptrace Examples and Code Snippets
Community Discussions
Trending Discussions on ptrace
QUESTION
Sorry, I am really new to writing eBPF code, so I came upon an error that I can't seem to shake off. Running in sudo does not seem to help. And I wrote a slower crc32 program that compiles but this one does not want to execute no matter what. I am wondering if I'm breaking any convention that I am just not seeing.
...ANSWER
Answered 2021-May-24 at 21:44From the verifier's logs, you have some invalid access here:
QUESTION
We have a school project where we need to re-code "strace".
We have to only intercept syscall like write and read, but we cannot use PTRACE_SYSCALL
. I'm looking for a way to do that using PTRACE_SINGLESTEP
, I've already coded a way to print the syscall and when I'm using PTRACE_SYSCALL
it works fine, but when I use PTRACE_SINGLESTEP
I can't find a way to only print the syscalls.
Here is the code I use, maybe someone can help me figure out what's wrong with it:
...ANSWER
Answered 2021-Apr-11 at 13:30If you cannot use PTRACE_SYSCALL
to stop the child right before/after a syscall, then you will have to manually detect when one is about to happen. I doubt that checking the source code of strace
would help, since strace
is most likely using PTRACE_SYSCALL
, no reason to manually decode instructions.
Assuming you are working on x86-64, here's how you can do it:
- Using
PTRACE_SINGLESTEP
, keep stepping one instruction at a time. - Each instruction, use
PTRACE_PEEKTEXT
to fetch the next instruction pointed by the instruction pointer. - Check if the instruction is a
syscall
instruction by comparing the bytes with the opcode ofsyscall
, which is two bytes:0x0f 0x05
. Since x86 is little endian, this means checking whether the return value ofptrace(PTRACE_PEEKDATA, ...)
has the two least significant bytes set to0x050f
.
NOTE: If you are on another architecture, or if you also want to detect 32-bit syscalls, you can simply check for different/more values on step 3. On Linux x86-64, there are multiple ways to issue a syscall, with different opcodes. For example, 32-bit syscalls on Linux are done through int 0x80
(opcode 0xcd 0x80
). Check this other answer of mine for a list.
Here's an example:
QUESTION
I am using ptrace
to follow a process and monitor its behavior. At some point I would like to get the next rip
address before hitting the next instruction. In fact, I would like to call get the address of the instruction following a callq
instruction. There are a few different such instructions (near, far, relative, absolute etc) and they don't all have the same length.
Is there a way using ptrace
to get the size in bytes of the instruction, once the instruction has been retrieved. Something like the following:
ANSWER
Answered 2021-Mar-27 at 18:02ptrace doesn't have a disassembler in the kernel1, and the hardware itself won't tell you this until after the call
instruction has executed.
If you can wait until after the instruction executes, probably your best bet is to PTRACE_SINGLESTEP
then read the return address call
pushed onto the stack. (ESP/RSP will point at it2).
The other option is of course to decode it yourself (including any prefixes which might get used for padding, like when ld
relaxes 6-byte call [got_entry]
to 1+5 byte addr32 call rel32
). Either with a disassembler library, or by scanning through prefixes until you get to one of the call
opcodes, then you have the length either from it (E8 call rel32
) or from decoding the ModRM byte for an indirect FF /2 call [r/m32]
. (https://www.felixcloutier.com/x86/call).
If you wanted portability to non-x86 ISAs, many use a link register instead of pushing a return address so it's not identical; you can't just generically deref the stack pointer with uintptr_t
width.
And many of those ISAs have fixed instruction widths so you could just go one instruction forward instead of single-stepping and reading a register. (Although many support a compact encoding with 2 or 4-byte instructions, like ARM Thumb, MIPS, and RISC-V).
There are other wrinkles on some ISAs, for example MIPS has a branch delay slot so the return address is actually after the next instruction after a jal
.
Footnote 1: (fun fact: ARM Linux kernels used to have a disassembler with support for some instructions, so it could emulate single-step for you, but that hack was removed).
Footnote 2: Even for hand-written asm with a far
call, the CS:[ER]IP return address will have the offset part at the lowest address, i.e. pointed to by ESP/RSP. Of course, far calls use different opcodes, so you could treat them separately or ignore them.
I'm not sure if it's possible for prefixes to override a size in a way that will get call
to push a different-sized return address. (e.g. 16-bit in 32-bit mode). Probably not, and even if so it would only be a concern for malicious binaries trying to fool your tracer on purpose. Even hand-written asm for GNU/Linux is vanishingly unlikely to do this for any normal reason.
QUESTION
I'm trying to create a basic application which is heavy on raw syscalls only, and I don't need the C library. I'm also trying to keep size to an absolute minimum. For functions like strcpy
, strcmp
, I'm hoping to use compiler intrinsics.
On Windows with MSVC/GCC I can use /NODEFAULTLIB
or -nostdlib
to detach from the C standard library. Then I'll simply link to kernel32.lib
, user32.lib
, to use functions like WriteFile
, CreateWindowExW
, etc. I'm trying to do the same on linux but I'm running into a few problems.
It seems like for some reason, the code of the syscalls read
, write
, ptrace,
process_vm_readv
, etc are actaully in gclib? I tried to use syscall(SYS_write, ...)
as well as I was hoping that'd be inlined into my program somehow but that still needs gclib. Is there a way to call these syscalls like on Windows, where I'd link to a system library instead of the C library? I'd like to avoid writing the syscall stubs myself using inline ASM. I'm starting to work with linux programming like this so I'm not too sure. Here's a simple test application I'm using (which isn't compiling):
ANSWER
Answered 2021-Mar-16 at 22:39Here is what I got:
QUESTION
I have data that is a 50:50 mix of a normal distribution and a constant value:
...ANSWER
Answered 2021-Mar-07 at 03:45The issue here is that the likelihood of coming from each model involves probability density for the Gaussian and mass for the discrete, which are not commensurate. Specifically, the computation for comparing where a zero observation came from, will involve likelihoods
QUESTION
I'm trying to configure launch.json in vscode in order to be able to debug my program inside the editor. I' m facing 126. The vscode documentation explains here, that I need to create the 10-ptrace.confe inside /etc/sysctl.d/ and append this into it :
...ANSWER
Answered 2021-Feb-18 at 15:44gdb generates assembly code that corresponds directly to your source code "optimized code" i can suggest to try "hex editor" and edit your binary code file it's available on windows and linux. hope that could help you
QUESTION
Im trying to write a simple program that hooks into another binary (setuid binary, child process run it) using ptrace(), opens a 'flag' file and prints its content. The hook works, and i can control the binary using ptrace commands. I've executed syscall open(), and got a legitimate file descriptor(4).
My problem is that syscall read() fails, and returns a negative value of bytes, -21. errno is set to 0 (success). The machine is remote (32-bits), and i cannot install libexplain library there. I've searched the web ALOT, yet found no answers regarding the meaning of negative return values of read() syscall (according to the manual page, its only error value is -1..).
parent's code:
...ANSWER
Answered 2021-Feb-13 at 14:14While read(2)
can't return -21
, the read system call can. In other words, you are overlooking a layer between the kernel and your program; libc. Have a look at these snippets from musl libc:
QUESTION
I'm writing a debugger and want to see if its program counter is inside a function. I guess I need to check that it's between DW_AT_low_pc
and DW_AT_high_pc
. Here's the code I'm trying to debug:
ANSWER
Answered 2021-Jan-30 at 07:30I solved this by taking the program's base address by reading the first line of /proc/pid/maps
and adding it to DW_AT_low_pc
. DW_AT_high_pc
is an offset from DW_AT_low_pc
.
Then in my debugger loop I ran it single-stepped with
QUESTION
When I try to compile my eBPF program with bio.h included I get an error. How come I can include other Linux headers, but not this specific one?
I compile using the following command
...ANSWER
Answered 2020-Dec-17 at 17:05The header files you pull in come from /usr/include/linux (which gets installed from include/uapi in the kernel repo), when you compile a userspace program with #include .
he kernel space headers are deliberately different, to keep you from trying to access things which are not accessible from outside the kernel.
UPDATE: I'm not an expert on bpf programs, but a quick reading indicates bpf samples are (or were at some point) compiled using the Linux Kernel's KConfig Makefile system. If you use the samples/bpf/Makefile as a template, you may be able to compile against more in-kernel headers. I'm not sure if that is intended.
QUESTION
What did i do?
I ran qemu-x86_64 -singlestep -d nochain,cpu ./dummy
to dump all the registers of a dummy program after each instruction and used grep to save all the RIP values into a text file (qemu_rip_dump.txt). I then singlestepped the dummy program with ptrace and dumped the RIP values after each instruction into another textfile (ptrace_rip_dump.txt). I then compared both .txt files with diff
.
What result did i expect?
I expected both runs of the dummy program to execute the same instructions, thus both dump files being the same (same rip values and same amount of rip values).
What result did i actually get?
Ptrace dumped about 33.500 RIP values and Qemu dumped 29.800 RIP values. The RIP values of both textfiles start differing from the 240. instruction, most of the rip values are identical but ptrace executes about 5500 instructions qemu doesnt execute and qemu executes about 1800 instructions ptrace doesnt execute thus resulting in a difference of about 3700 instructions. Both runs seem to execute things differently throughout the whole program, for example there is a block of 3500 instructions from the 26.500-30.000 instruction (cleanup?) that the native run executes but not qemu.
What is my qestion
Why are the RIP values not the same throughout the whole execution of the program and most importantly: What do i have to do to make both runs be the same?
Extra Info
- the dummy program was a main function that returns 0, but this problem exists in every executable i have traced
- i have tried forcing qemu using the
ld-linux-x86-64.so.2
linker with-L /lib64/
- this had no effect - if i run qemu multiple times the dumps are the same (equal number and value of RIP), the same goes for ptrace
ANSWER
Answered 2020-Dec-12 at 19:52With a "does nothing" program like the one you're testing, most of the execution run will be in the guest dynamic linker and libc. Those do a lot of work behind the scenes before your program gets control, and some of that work varies between a "native" run and a "QEMU" run. There are two main sources of divergence, judging by some of the extra detail you give in the comments:
The environment QEMU provides to the guest binary is not 100% identical to that which a real host kernel provides; it's only intended to be "close enough that correct guest binaries behave in a reasonable way". For instance, there is a data structure passed to the guest called the "ELF auxiliary vector"; this contains information including "what CPU features are supported", "what user ID are you executing as", and so on. The dynamic linker iterates through this data structure at startup, so minor harmless differences in what entries are in the vector in what order will cause slightly different execution paths in the guest code.
The CPU QEMU emulates does not provide exactly the same features that your host CPU does. There's no support for emulation of AVX or SSE2, for instance. The guest libc will adjust its behaviour so that it takes advantage of CPU features when they're available, so it picks different optimised versions of functions like memcpy() or strlen() under the hood. Since the dynamic linker will end up calling these functions, this also results in divergences of execution.
You may be able to work around some of this by restricting the area of instruction tracing you look at to just starting from the beginning of the 'main' function to avoid tracing all of the dynamic linker startup. I can't think of a way to work around the differences in what CPU features are available on the host vs QEMU, though.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install ptrace
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page