1 #!/usr/sbin/dtrace -q -s
3 * Demonstration D script for watching Code Signing activity in the system
5 * As presented, this script will record and report all Code Signing activity
6 * in one process (argument=pid), or all processes (argument='*').
7 * You are encouraged to modify it as you will. (A good start is to comment out
8 * the print statements you don't like to see.)
10 typedef uint64_t DTHandle; /* generic API handle (NOT a pointer) */
11 typedef uint8_t Hash[20]; /* SHA-1 */
13 typedef struct { /* from implementation */
22 * Local variables used for suitable casting (only)
28 * Startup (this may take a while)
37 * Finishing (add statistics tracers here)
45 * Track kernel-related objects.
46 * Each process has their own, and they're usually created very early.
49 DTHandle rep; /* DiskRep */
50 DTHandle staticCode; /* static code */
51 DTHandle code; /* dynamic code */
56 * Track DiskRep objects.
57 * DiskReps are drivers for on-disk formats. Beyond their natural concerns,
58 * they also carry the path information for StaticCode objects.
61 DTHandle me; /* own handle, if valid */
62 string path; /* canonical path */
63 string type; /* type string */
64 DiskRepContext ctx; /* construction context, if any */
65 DTHandle sub; /* sub-DiskRep if any */
67 DiskRep rep[DTHandle]; /* all the DiskReps we've seen */
69 self uint64_t ctx; /* passes construction context, NULL if none */
71 codesign$1:::diskrep-create-* /* preset none */
74 codesign$1:::diskrep-create-kernel
76 rep[arg0].me = kernel[pid].rep = arg0;
77 rep[arg0].path = "(kernel)";
78 rep[arg0].type = "kernel";
79 printf("%8u %s[%d]%s(%p,KERNEL)\n",
80 timestamp, execname, pid, probename, arg0);
83 codesign$1:::diskrep-create-macho
86 rep[arg0].path = copyinstr(arg1);
87 rep[arg0].type = "macho";
89 printf("%8u %s[%d]%s(%p,%s)\n",
90 timestamp, execname, pid, probename, arg0, rep[arg0].path);
93 codesign$1:::diskrep-create-bundle-path
96 rep[arg0].path = copyinstr(arg1);
97 rep[arg0].type = "bundle";
100 printf("%8u %s[%d]%s(%p,%s,%p)\n",
101 timestamp, execname, pid, probename,
102 arg0, rep[arg0].path, rep[arg0].sub);
105 codesign$1:::diskrep-create-bundle-ref
108 rep[arg0].path = "(from ref)";
109 rep[arg0].type = "bundle";
111 rep[arg0].sub = arg3;
112 printf("%8u %s[%d]%s(%p,%s,%p)\n",
113 timestamp, execname, pid, probename,
114 arg0, rep[arg0].path, rep[arg0].sub);
117 codesign$1:::diskrep-create-file
120 rep[arg0].path = copyinstr(arg1);
121 rep[arg0].type = "file";
122 printf("%8u %s[%d]%s(%p,%s)\n",
123 timestamp, execname, pid, probename, arg0, rep[arg0].path);
126 self DiskRepContext *ctxp;
128 codesign$1:::diskrep-create-*
131 self->ctxp = (DiskRepContext *)copyin(self->ctx, sizeof(DiskRepContext));
132 rep[arg0].ctx = *self->ctxp;
133 printf("%8u %s[%d] ...context: arch=(0x%x,0x%x) offset=0x%x file=%d\n",
134 timestamp, execname, pid,
135 self->ctxp->cputype, self->ctxp->cpusubtype,
136 self->ctxp->offset, self->ctxp->fileOnly);
139 codesign$1:::diskrep-destroy
141 printf("%8u %s[%d]%s(%p,%s)\n",
142 timestamp, execname, pid, probename, arg0, rep[arg0].path);
148 * Track Code Signing API objects
153 DTHandle staticCode; /* lazily acquired */
154 uint8_t *hash; /* dynamic hash from identify() */
161 uint8_t *hash; /* static hash from ...::cdHash() */
163 StaticCode staticCode[DTHandle];
166 codesign$1:::static-create
167 / arg1 == kernel[pid].rep /
169 staticCode[arg0].me = kernel[pid].staticCode = arg0;
170 staticCode[arg0].rep = arg1;
171 printf("%8u %s[%d]%s(%p=KERNEL[%p])\n",
172 timestamp, execname, pid, probename, arg0, arg1);
175 codesign$1:::static-create
176 / arg1 != kernel[pid].rep /
178 staticCode[arg0].me = arg0;
179 staticCode[arg0].rep = arg1;
180 printf("%8u %s[%d]%s(%p,%s[%p])\n",
181 timestamp, execname, pid, probename, arg0, rep[arg1].path, arg1);
184 codesign$1:::dynamic-create
187 code[arg0].me = kernel[pid].code = arg0;
188 printf("%8u %s[%d]%s(%p=KERNEL)\n",
189 timestamp, execname, pid, probename, arg0);
192 codesign$1:::dynamic-create
193 / arg1 == kernel[pid].code /
195 code[arg0].me = arg0;
196 printf("%8u %s[%d]%s(%p,<KERNEL>)\n",
197 timestamp, execname, pid, probename, arg0);
200 codesign$1:::dynamic-create
201 / arg1 != 0 && arg1 != kernel[pid].code /
203 code[arg0].me = arg0;
204 code[arg0].host = arg1;
205 printf("%8u %s[%d]%s(%p,%p)\n",
206 timestamp, execname, pid, probename, arg0, arg1);
209 security_debug$1:::sec-destroy
210 / code[arg0].me == arg0 /
213 printf("%8u %s[%d]destroy code(%p)\n",
214 timestamp, execname, pid, arg0);
217 security_debug$1:::sec-destroy
218 / staticCode[arg0].me == arg0 /
220 staticCode[arg0].me = 0;
221 printf("%8u %s[%d]destroy staticCode(%p)\n",
222 timestamp, execname, pid, arg0);
227 * Identification operations
229 codesign$1:::guest-identify-*
231 printf("%8u %s[%d]%s(%p,%d,%s[%p])\n",
232 timestamp, execname, pid, probename,
233 arg0, arg1, rep[staticCode[arg2].rep].path, arg2);
234 code[arg0].staticCode = arg2;
237 codesign$1:::guest-cdhash-*
239 self->hash = code[arg0].hash = (uint8_t *)copyin(arg1, sizeof(Hash));
240 printf("%8u %s[%d]%s(%p,H\"%02x%02x%02x...%02x%02x\")\n",
241 timestamp, execname, pid, probename, arg0,
242 self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
245 codesign$1:::static-cdhash
247 self->hash = staticCode[arg0].hash = (uint8_t *)copyin(arg1, sizeof(Hash));
248 printf("%8u %s[%d]%s(%p,H\"%02x%02x%02x...%02x%02x\")\n",
249 timestamp, execname, pid, probename, arg0,
250 self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
255 * Guest registry/proxy management in securityd
263 SDGuest guests[DTHandle, DTHandle]; /* host x guest */
265 securityd*:::host-register
267 printf("%8u HOST DYNAMIC(%p,%d)\n",
268 timestamp, arg0, arg1);
271 securityd*:::host-proxy
273 printf("%8u HOST PROXY(%p,%d)\n",
274 timestamp, arg0, arg1);
277 securityd*:::host-unregister
279 printf("%8u HOST DESTROYED(%p)\n",
283 securityd*:::guest-create
285 guests[arg0, arg2].guest = arg2;
286 guests[arg0, arg2].path = copyinstr(arg5);
287 guests[arg0, arg2].status = arg3;
288 printf("%8u GUEST CREATE(%p,%s[0x%x],host=0x%x,status=0x%x,flags=%d)\n",
290 arg0, guests[arg0, arg2].path, arg2, arg1, arg3, arg4);
293 securityd*:::guest-cdhash
296 self->hash = guests[arg0, arg1].hash = (uint8_t *)copyin(arg2, sizeof(Hash));
297 printf("%8u GUEST HASH(%p,%s[0x%x],H\"%02x%02x%02x...%02x%02x\")\n",
299 arg0, guests[arg0, arg1].path, arg1,
300 self->hash[0], self->hash[1], self->hash[2], self->hash[18], self->hash[19]);
303 securityd*:::guest-cdhash
306 printf("%8u GUEST HASH(%p,%s[0x%x],NONE)\n",
307 timestamp, arg0, guests[arg0, arg1].path, arg1);
310 securityd*:::guest-change
312 printf("%8u GUEST CHANGE(%p,%s[0x%x],status=0x%x)\n",
314 arg0, guests[arg0, arg1].path, arg1, arg2);
317 securityd*:::guest-destroy
319 printf("%8u GUEST DESTROY(%p,%s[0x%x])\n",
321 arg0, guests[arg0, arg1].path, arg1);
326 * Signing Mach-O allocation tracking
328 codesign$1:::allocate-arch
330 printf("%8u %s[%d]%s(%s,%d)\n",
331 timestamp, execname, pid, probename, copyinstr(arg0), arg1);
334 codesign$1:::allocate-archn
336 printf("%8u %s[%d]%s((0x%x,0x%x),%d)\n",
337 timestamp, execname, pid, probename, arg0, arg1, arg2);
340 codesign$1:::allocate-write
342 printf("%8u %s[%d]%s(%s,offset 0x%x,%d of %d)\n",
343 timestamp, execname, pid, probename,
344 copyinstr(arg0), arg1, arg2, arg3);
347 codesign$1:::allocate-validate
349 printf("%8u %s[%d]%s(%s,%d)\n",
350 timestamp, execname, pid, probename, copyinstr(arg0), arg1);
355 * Evaluation tracking
357 codesign$1:::eval-dynamic-start
359 printf("%8u %s[%d]%s(%p,%s)\n",
360 timestamp, execname, pid, probename, arg0, copyinstr(arg1));
363 codesign$1:::eval-dynamic-end
365 printf("%8u %s[%d]%s(%p)\n",
366 timestamp, execname, pid, probename, arg0);