Skip to content

feat(sgxs-tools): Add new sgxs-trace tool#920

Open
jovanbulck wants to merge 1 commit intofortanix:masterfrom
jovanbulck:sgxs-trace
Open

feat(sgxs-tools): Add new sgxs-trace tool#920
jovanbulck wants to merge 1 commit intofortanix:masterfrom
jovanbulck:sgxs-trace

Conversation

@jovanbulck
Copy link
Copy Markdown
Contributor

New sgxs-trace tool

sgxs-trace extracts SGXS enclaves by tracing the system calls of a running process and intercepting its interactions with the underlying Linux SGX driver. At this level, sgxs-trace can extract enclaves in the SGXS format from any program that loads one or more enclaves into its address space, regardless of the SDK or libOS originally used to produce the enclave.

Intuitively, sgxs-trace can be considered the "inverse" of sgxs-load: it reconstructs enclaves exactly as they are loaded into memory.

$ sgxs-trace -- ./app && mv enclave0.sgxs app.sgxs
$ sgxs-trace -- sgxs-load encl.sgxs encl.sig && mv enclave0.sgxs load.sgxs
$ sha256sum app.sgxs load.sgxs encl.sgxs | awk '{print $1}' | uniq | wc -l
1

This is a from-scratch Rust re-implementation of the C-based sgx-tracer tool.

Use cases

Basically sgxs-trace makes it possible to convert enclaves from any runtime/SDK/libOS to the standardized SGXS format.

This allows the other sgxs-tools utilities to be used more widely beyond EDP only + may help elevating the SGXS format to a platform-independent and SDK-agnostic "middle end" enclave binary format. For instance, bare-sgx now also support SGXS for minimal C enclaves and we have a modified Pandora loader to load SGXS enclave into angr (SGXS support might even be upstreamed to angr at some point).

Example sgxs-trace operation

Example on a sample enclave from the Intel SDK:

asciicast

Full output below for a minimal bare-sgx enclave.

jo@aeolus:~/bare-sgx/app/ecall_ptr$ sgxs-trace -v -- ./app 
[sgxs-trace] SGX_IOC_ENCLAVE_CREATE
[sgxs-trace]     L Secs { size: 134217728, baseaddr: 140640448937984, ssaframesize: 1, miscselect: (empty), attributes: Attributes { flags: MODE64BIT, xfrm: 3 }, mrenclave: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], mrsigner: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], isvprodid: 0, isvsvn: 0 }
[sgxs-trace] Opened File { fd: 3, path: "/home/jo/bare-sgx/app/ecall_ptr/enclave0.sgxs", read: false, write: true }
[sgxs-trace] SGX_IOC_ENCLAVE_ADD_PAGES
[sgxs-trace]     L AddPages { src: 140640692580352, offset: 4096, length: 4096, secinfo: 140729532227552, chunks: 65535 }
[sgxs-trace]     L Secinfo { flags: R | X | PT_B1 }
[sgxs-trace] SGX_IOC_ENCLAVE_ADD_PAGES
[sgxs-trace]     L AddPages { src: 140640692580352, offset: 8192, length: 4096, secinfo: 140729532227552, chunks: 65535 }
[sgxs-trace]     L Secinfo { flags: R | X | PT_B1 }
[sgxs-trace] SGX_IOC_ENCLAVE_ADD_PAGES
[sgxs-trace]     L AddPages { src: 140640692580352, offset: 12288, length: 4096, secinfo: 140729532227552, chunks: 65535 }
[sgxs-trace]     L Secinfo { flags: R | W | PT_B1 }
[sgxs-trace] SGX_IOC_ENCLAVE_ADD_PAGES
[sgxs-trace]     L AddPages { src: 140640692580352, offset: 16384, length: 4096, secinfo: 140729532227552, chunks: 65535 }
[sgxs-trace]     L Secinfo { flags: R | W | PT_B1 }
[sgxs-trace] SGX_IOC_ENCLAVE_ADD_PAGES
[sgxs-trace]     L AddPages { src: 140640692580352, offset: 24576, length: 4096, secinfo: 140729532227552, chunks: 65535 }
[sgxs-trace]     L Secinfo { flags: PT_B0 }
[sgxs-trace] SGX_IOC_ENCLAVE_ADD_PAGES
[sgxs-trace]     L AddPages { src: 140640692580352, offset: 28672, length: 4096, secinfo: 140729532227552, chunks: 0 }
[sgxs-trace]     L Secinfo { flags: R | W | PT_B1 }
[sgxs-trace] SGX_IOC_ENCLAVE_INIT
[sgxs-trace]     L Sigstruct { header: [6, 0, 0, 0, 225, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], vendor: 0, date: 539362324, header2: [1, 1, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 1, 0, 0, 0], swdefined: 0, modulus: "(384 bytes)", exponent: 3, signature: "(384 bytes)", miscselect: (empty), miscmask: 4294967295, attributes: Attributes { flags: DEBUG | MODE64BIT, xfrm: 3 }, attributemask: [18446744073709551613, 18446744073709551612], enclavehash: [94, 12, 68, 216, 210, 184, 39, 250, 173, 200, 248, 91, 232, 213, 28, 188, 196, 4, 63, 161, 18, 183, 102, 83, 166, 212, 30, 168, 163, 216, 255, 44], isvprodid: 0, isvsvn: 0, q1: "(384 bytes)", q2: "(384 bytes)" }
[sgxs-trace]     L mrenclave: 5e0c44d8d2b827faadc8f85be8d51cbcc4043fa112b76653a6d41ea8a3d8ff2c
[main.c] loaded enclave at 0x7fe968006000
[main.c] reading enclave memory..
	L mem at 0x7fe968006000 is ffffffffffffffff
[main.c] calling enclave TCS..
	L enclave returned 1300 + 37 = 1337
	L enclave returned 1300 - 37 = 1263
[sgxs-trace] exiting; extracted 1 SGXS enclave to directory .
jo@aeolus:~/bare-sgx/app/ecall_ptr$ sgxs-info summary enclave0.sgxs 
      0-    fff (unmapped)
   1000-   2fff Reg  r-x  (data) meas=all
   3000-   3fff Reg  rw- (empty) meas=all
   4000-   4fff Reg  rw-  (data) meas=all
   5000-   5fff (unmapped)
   6000-   6fff Tcs  ---  (data) meas=all [oentry=0x1000, ossa=0x7000, nssa=1]
   7000-   7fff Reg  rw- (empty) meas=none
   8000-7ffffff (unmapped)

Compatibility

Tested on various SDKs with the Linux in-kernel /dev/sgx_enclave driver, but should be compatible with the older out-of-tree driver as well (through the sgxs-loaders crate definitions). Since it uses ptrace internally, I guess this is not compatible with Windows.

`sgxs-trace` extracts SGXS enclaves by tracing the system calls of
a running process and intercepting its interactions with the
underlying Linux SGX driver. By operating at this level,
`sgxs-trace` can extract enclaves in the SGXS format from _any_
program that loads one or more enclaves into its address space.

The resulting SGXS files can then be used with `sgxs-tools`,
regardless of the SDK or libOS originally used to produce the
enclave.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant