]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_codesigning/dtrace/codesign-watch.d
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_codesigning / dtrace / codesign-watch.d
diff --git a/Security/libsecurity_codesigning/dtrace/codesign-watch.d b/Security/libsecurity_codesigning/dtrace/codesign-watch.d
new file mode 100755 (executable)
index 0000000..64aa5fd
--- /dev/null
@@ -0,0 +1,368 @@
+#!/usr/sbin/dtrace -q -s
+/*
+ * Demonstration D script for watching Code Signing activity in the system
+ *
+ * As presented, this script will record and report all Code Signing activity
+ * in one process (argument=pid), or all processes (argument='*').
+ * You are encouraged to modify it as you will. (A good start is to comment out
+ * the print statements you don't like to see.)
+ */
+typedef uint64_t DTHandle;             /* generic API handle (NOT a pointer) */
+typedef uint8_t Hash[20];              /* SHA-1 */
+
+typedef struct {                               /* from implementation */
+       uint32_t cputype;
+       uint32_t cpusubtype;
+       off_t offset;
+       uint8_t fileOnly;
+} DiskRepContext;
+
+
+/*
+ * Local variables used for suitable casting (only)
+ */
+self uint8_t *hash;
+
+
+/*
+ * Startup (this may take a while)
+ */
+:::BEGIN
+{
+       printf("Ready...\n");
+}
+
+
+/*
+ * Finishing (add statistics tracers here)
+ */
+:::END
+{
+}
+
+
+/*
+ * Track kernel-related objects.
+ * Each process has their own, and they're usually created very early.
+ */
+struct {
+       DTHandle rep;                           /* DiskRep */
+       DTHandle staticCode;            /* static code */
+       DTHandle code;                          /* dynamic code */
+} kernel[pid_t];
+
+
+/*
+ * Track DiskRep objects.
+ * DiskReps are drivers for on-disk formats. Beyond their natural concerns,
+ * they also carry the path information for StaticCode objects.
+ */
+typedef struct {
+       DTHandle me;                            /* own handle, if valid */
+       string path;                            /* canonical path */
+       string type;                            /* type string */
+       DiskRepContext ctx;                     /* construction context, if any */
+       DTHandle sub;                           /* sub-DiskRep if any */
+} DiskRep;
+DiskRep rep[DTHandle];                 /* all the DiskReps we've seen */
+
+self uint64_t ctx;                             /* passes construction context, NULL if none */
+
+codesign$1:::diskrep-create-*  /* preset none */
+{ self->ctx = 0; }
+
+codesign$1:::diskrep-create-kernel
+{
+       rep[arg0].me = kernel[pid].rep = arg0;
+       rep[arg0].path = "(kernel)";
+       rep[arg0].type = "kernel";
+       printf("%8u %s[%d]%s(%p,KERNEL)\n",
+               timestamp, execname, pid, probename, arg0);
+}
+
+codesign$1:::diskrep-create-macho
+{
+       rep[arg0].me = arg0;
+       rep[arg0].path = copyinstr(arg1);
+       rep[arg0].type = "macho";
+       self->ctx = arg2;
+       printf("%8u %s[%d]%s(%p,%s)\n",
+               timestamp, execname, pid, probename, arg0, rep[arg0].path);
+}
+
+codesign$1:::diskrep-create-bundle-path
+{
+       rep[arg0].me = arg0;
+       rep[arg0].path = copyinstr(arg1);
+       rep[arg0].type = "bundle";
+       self->ctx = arg2;
+       rep[arg0].sub = arg3;
+       printf("%8u %s[%d]%s(%p,%s,%p)\n",
+               timestamp, execname, pid, probename,
+               arg0, rep[arg0].path, rep[arg0].sub);
+}
+
+codesign$1:::diskrep-create-bundle-ref
+{
+       rep[arg0].me = arg0;
+       rep[arg0].path = "(from ref)";
+       rep[arg0].type = "bundle";
+       self->ctx = arg2;
+       rep[arg0].sub = arg3;
+       printf("%8u %s[%d]%s(%p,%s,%p)\n",
+               timestamp, execname, pid, probename,
+               arg0, rep[arg0].path, rep[arg0].sub);
+}
+
+codesign$1:::diskrep-create-file
+{
+       rep[arg0].me = arg0;
+       rep[arg0].path = copyinstr(arg1);
+       rep[arg0].type = "file";
+       printf("%8u %s[%d]%s(%p,%s)\n",
+               timestamp, execname, pid, probename, arg0, rep[arg0].path);
+}
+
+self DiskRepContext *ctxp;
+
+codesign$1:::diskrep-create-*
+/ self->ctx /
+{
+       self->ctxp = (DiskRepContext *)copyin(self->ctx, sizeof(DiskRepContext));
+       rep[arg0].ctx = *self->ctxp;
+       printf("%8u %s[%d] ...context: arch=(0x%x,0x%x) offset=0x%x file=%d\n",
+               timestamp, execname, pid,
+               self->ctxp->cputype, self->ctxp->cpusubtype,
+               self->ctxp->offset, self->ctxp->fileOnly);
+}
+
+codesign$1:::diskrep-destroy
+{
+       printf("%8u %s[%d]%s(%p,%s)\n",
+               timestamp, execname, pid, probename, arg0, rep[arg0].path);
+       rep[arg0].me = 0;
+}
+
+
+/*
+ * Track Code Signing API objects
+ */
+typedef struct {
+       DTHandle me;
+       DTHandle host;
+       DTHandle staticCode;    /* lazily acquired */
+       uint8_t *hash;                  /* dynamic hash from identify() */
+} Code;
+Code code[DTHandle];
+
+typedef struct {
+       DTHandle me;
+       DTHandle rep;
+       uint8_t *hash;                  /* static hash from ...::cdHash() */
+} StaticCode;
+StaticCode staticCode[DTHandle];
+
+
+codesign$1:::static-create
+/ arg1 == kernel[pid].rep /
+{
+       staticCode[arg0].me = kernel[pid].staticCode = arg0;
+       staticCode[arg0].rep = arg1;
+       printf("%8u %s[%d]%s(%p=KERNEL[%p])\n",
+               timestamp, execname, pid, probename, arg0, arg1);
+}
+
+codesign$1:::static-create
+/ arg1 != kernel[pid].rep /
+{
+       staticCode[arg0].me = arg0;
+       staticCode[arg0].rep = arg1;
+       printf("%8u %s[%d]%s(%p,%s[%p])\n",
+               timestamp, execname, pid, probename, arg0, rep[arg1].path, arg1);
+}
+
+codesign$1:::dynamic-create
+/ arg1 == 0 /
+{
+       code[arg0].me = kernel[pid].code = arg0;
+       printf("%8u %s[%d]%s(%p=KERNEL)\n",
+               timestamp, execname, pid, probename, arg0);
+}
+
+codesign$1:::dynamic-create
+/ arg1 == kernel[pid].code /
+{
+       code[arg0].me = arg0;
+       printf("%8u %s[%d]%s(%p,<KERNEL>)\n",
+               timestamp, execname, pid, probename, arg0);
+}
+
+codesign$1:::dynamic-create
+/ arg1 != 0 && arg1 != kernel[pid].code /
+{
+       code[arg0].me = arg0;
+       code[arg0].host = arg1;
+       printf("%8u %s[%d]%s(%p,%p)\n",
+               timestamp, execname, pid, probename, arg0, arg1);
+}
+
+security_debug$1:::sec-destroy
+/ code[arg0].me == arg0 /
+{
+       code[arg0].me = 0;
+       printf("%8u %s[%d]destroy code(%p)\n",
+               timestamp, execname, pid, arg0);
+}
+
+security_debug$1:::sec-destroy
+/ staticCode[arg0].me == arg0 /
+{
+       staticCode[arg0].me = 0;
+       printf("%8u %s[%d]destroy staticCode(%p)\n",
+               timestamp, execname, pid, arg0);
+}
+
+
+/*
+ * Identification operations
+ */
+codesign$1:::guest-identify-*
+{
+       printf("%8u %s[%d]%s(%p,%d,%s[%p])\n",
+               timestamp, execname, pid, probename,
+               arg0, arg1, rep[staticCode[arg2].rep].path, arg2);
+       code[arg0].staticCode = arg2;
+}
+
+codesign$1:::guest-cdhash-*
+{
+       self->hash = code[arg0].hash = (uint8_t *)copyin(arg1, sizeof(Hash));
+       printf("%8u %s[%d]%s(%p,H\"%02x%02x%02x...%02x%02x\")\n",
+               timestamp, execname, pid, probename, arg0,
+               self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
+}
+
+codesign$1:::static-cdhash
+{
+       self->hash = staticCode[arg0].hash = (uint8_t *)copyin(arg1, sizeof(Hash));
+       printf("%8u %s[%d]%s(%p,H\"%02x%02x%02x...%02x%02x\")\n",
+               timestamp, execname, pid, probename, arg0,
+               self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
+}
+
+
+/*
+ * Guest registry/proxy management in securityd
+ */
+typedef struct {
+       DTHandle guest;
+       string path;
+       uint32_t status;
+       uint8_t *hash;
+} SDGuest;
+SDGuest guests[DTHandle, DTHandle];            /* host x guest */
+
+securityd*:::host-register
+{
+       printf("%8u HOST DYNAMIC(%p,%d)\n",
+               timestamp, arg0, arg1);
+}
+
+securityd*:::host-proxy
+{
+       printf("%8u HOST PROXY(%p,%d)\n",
+               timestamp, arg0, arg1);
+}
+
+securityd*:::host-unregister
+{
+       printf("%8u HOST DESTROYED(%p)\n",
+               timestamp, arg0);
+}
+
+securityd*:::guest-create
+{
+       guests[arg0, arg2].guest = arg2;
+       guests[arg0, arg2].path = copyinstr(arg5);
+       guests[arg0, arg2].status = arg3;
+       printf("%8u GUEST CREATE(%p,%s[0x%x],host=0x%x,status=0x%x,flags=%d)\n",
+               timestamp,
+               arg0, guests[arg0, arg2].path, arg2, arg1, arg3, arg4);
+}
+
+securityd*:::guest-cdhash
+/ arg2 != 0 /
+{
+       self->hash = guests[arg0, arg1].hash = (uint8_t *)copyin(arg2, sizeof(Hash));
+       printf("%8u GUEST HASH(%p,%s[0x%x],H\"%02x%02x%02x...%02x%02x\")\n",
+               timestamp,
+               arg0, guests[arg0, arg1].path, arg1,
+               self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
+}
+
+securityd*:::guest-cdhash
+/ arg2 == 0 /
+{
+       printf("%8u GUEST HASH(%p,%s[0x%x],NONE)\n",
+               timestamp, arg0, guests[arg0, arg1].path, arg1);
+}
+
+securityd*:::guest-change
+{
+       printf("%8u GUEST CHANGE(%p,%s[0x%x],status=0x%x)\n",
+               timestamp,
+               arg0, guests[arg0, arg1].path, arg1, arg2);
+}
+
+securityd*:::guest-destroy
+{
+       printf("%8u GUEST DESTROY(%p,%s[0x%x])\n",
+               timestamp,
+               arg0, guests[arg0, arg1].path, arg1);
+}
+
+
+/*
+ * Signing Mach-O allocation tracking
+ */
+codesign$1:::allocate-arch
+{
+       printf("%8u %s[%d]%s(%s,%d)\n",
+               timestamp, execname, pid, probename, copyinstr(arg0), arg1);
+}
+
+codesign$1:::allocate-archn
+{
+       printf("%8u %s[%d]%s((0x%x,0x%x),%d)\n",
+               timestamp, execname, pid, probename, arg0, arg1,  arg2);
+}
+
+codesign$1:::allocate-write
+{
+       printf("%8u %s[%d]%s(%s,offset 0x%x,%d of %d)\n",
+               timestamp, execname, pid, probename,
+               copyinstr(arg0), arg1, arg2, arg3);
+}
+
+codesign$1:::allocate-validate
+{
+       printf("%8u %s[%d]%s(%s,%d)\n",
+               timestamp, execname, pid, probename, copyinstr(arg0), arg1);
+}
+
+
+/*
+ * Evaluation tracking
+ */
+codesign$1:::eval-dynamic-start
+{
+       printf("%8u %s[%d]%s(%p,%s)\n",
+               timestamp, execname, pid, probename, arg0, copyinstr(arg1));
+}
+
+codesign$1:::eval-dynamic-end
+{
+       printf("%8u %s[%d]%s(%p)\n",
+               timestamp, execname, pid, probename, arg0);
+}
+