Skip to content

Instantly share code, notes, and snippets.

@chisophugis
Created August 18, 2012 01:09
Show Gist options
  • Save chisophugis/3383753 to your computer and use it in GitHub Desktop.
Save chisophugis/3383753 to your computer and use it in GitHub Desktop.
uddt_fasttrap_sprint
//usr/bin/true && clang $0 && exec ./a.out
//usr/bin/true && exit 1
/* This program demonstrates how to dynamically create DTrace probes with
* fasttrap. It currently works on Mac x86(_64) but can be easily adapted
* to other platforms.
*
* Quickstart:
* To see it work, just execute it (that magic at the top will compile and
* run it). It will dynamically create a probe and print its probe
* specification. Then just trace it with `dtrace(1M)`. You'll see that it
* detects when the probe is enabled.
*/
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <err.h>
#include <sys/fasttrap.h>
#define PAGE_SIZE 4096
void *get_rwx_page(void)
{
void *ret;
if ((ret = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANON|MAP_PRIVATE, -1, 0)) == NULL) {
err(1, "mmap");
}
return ret;
}
int main()
{
int fd;
void *execmem;
uint8_t *execmem_bytes;
if ((fd = open("/dev/fasttrap", O_RDWR)) < 0) {
err(1, "open");
}
execmem_bytes = execmem = get_rwx_page();
/* fill with RET */
memset(execmem, 0xC3, PAGE_SIZE);
/* create the fasttrap probe */
fasttrap_probe_spec_t probe;
probe.ftps_pid = getpid();
/* These two are Mac-specific. Just ftps_type = DTFTP_OFFSETS on
* Solaris */
probe.ftps_provider_type = DTFTP_PROVIDER_PID;
probe.ftps_probe_type = DTFTP_OFFSETS;
/* Just dummy names for now. */
const char *funcname = "testfunc";
const char *modname = "testmod";
strcpy((char*)&probe.ftps_func, funcname);
strcpy((char*)&probe.ftps_mod, modname);
probe.ftps_pc = (uintptr_t)execmem;
probe.ftps_size = 1; /* just the RET */
probe.ftps_noffs = 1;
probe.ftps_offs[0] = 0; /* offset 0; i.e., just that instruction */
if (ioctl(fd, FASTTRAPIOC_MAKEPROBE, &probe) < 0)
err(1, "ioctl FASTTRAPIOC_MAKEPROBE");
printf("Created probe 'pid%d:%s:%s:0'\n", (int)getpid(), modname, funcname);
/* just repeatedly fire our probe */
for (;;) {
usleep(500 * 1000); /* don't spin too fast */
/* trigger dynamically created function */
(*(void (*)(void))execmem)();
/* TODO: could use FASTTRAP_INSTR instead of hardcoding
* 0xCC, but whatevs */
/* If instr is the INT3 trap instruction */
if (execmem_bytes[0] == 0xCC)
printf("Probe is enabled\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment