34
34
import gdb
35
35
import struct
36
36
import os .path
37
+ import os
37
38
from ctypes import create_string_buffer
38
39
import load_symbol_cmd
39
40
import sgx_emmt
40
41
import ctypes
42
+ import time
43
+ import re
41
44
42
45
# Calculate the bit mode of current debuggee project
43
46
SIZE = gdb .parse_and_eval ("sizeof(long)" )
56
59
ENCLAVE_INFO_SIZE = 8 * 7 + 2 * 4
57
60
INFO_FMT = 'QQQIIQQQQ'
58
61
ENCLAVES_ADDR = {}
62
+ DUMPED_ENCLAVE = {}
59
63
60
64
# The following definitions should strictly align with the struct of
61
65
# tcs_t
@@ -351,6 +355,14 @@ def fini_enclave_debug(self):
351
355
return - 1
352
356
except :
353
357
return - 1
358
+ finally :
359
+ # Delete the dumped enclave if any
360
+ global DUMPED_ENCLAVE
361
+ if self .enclave_path in DUMPED_ENCLAVE :
362
+ print ("Free-ing pointer {0}" .format (DUMPED_ENCLAVE [self .enclave_path ]))
363
+ gdb .execute ("call (void)free({0})" .format (DUMPED_ENCLAVE [self .enclave_path ]))
364
+ os .remove (self .enclave_path )
365
+ del DUMPED_ENCLAVE [self .enclave_path ]
354
366
355
367
def append_tcs_list (self , tcs_addr ):
356
368
for tcs_tmp in self .tcs_addr_list :
@@ -384,7 +396,7 @@ def retrieve_enclave_info(info_addr = 0):
384
396
if name_str == None :
385
397
return None
386
398
fmt = str (info_tuple [4 ]) + 's'
387
- enclave_path = struct .unpack_from (fmt , name_str )[0 ].decode (encoding = 'UTF-8' )
399
+ enclave_path = struct .unpack_from (fmt , name_str )[0 ].decode (encoding = 'UTF-8' )
388
400
# get the stack addr list
389
401
stack_addr_list = []
390
402
tcs_addr_list = []
@@ -686,6 +698,51 @@ def stop(self):
686
698
gdb .execute (gdb_cmd , False , True )
687
699
return False
688
700
701
+ # This breakpoint is to handle enclave creation with buffer
702
+ class CreateBufferEnclaveBreakpoint (gdb .Breakpoint ):
703
+ def __init__ (self ):
704
+ gdb .Breakpoint .__init__ (self , spec = "_create_enclave_from_buffer_ex" , internal = 1 )
705
+
706
+ def stop (self ):
707
+ bp_in_urts = is_bp_in_urts ()
708
+ if bp_in_urts == True :
709
+ print ("_create_enclave_from_buffer_ex" )
710
+ # Get se_file_t pointer (4th parameter)
711
+ file_addr = gdb .parse_and_eval ("$rcx" )
712
+ file_str = read_from_memory (file_addr , 8 + 2 * 4 )
713
+ file_tuple = struct .unpack_from ("QII" , file_str )
714
+ print ("File: " + str (file_tuple [1 ]))
715
+ if file_tuple [1 ] == 0 :
716
+ # If it is null, then it does not have a file. So we dump the buffer
717
+
718
+ # dump enclave to file
719
+ dump_name = "/tmp/enclave_dump_{0}.bin" .format (time .time ())
720
+ buffer_ptr = gdb .parse_and_eval ("$rsi" )
721
+ buffer_len = gdb .parse_and_eval ("$rdx" )
722
+ enclave_bin = read_from_memory (buffer_ptr , buffer_len )
723
+ f = open (dump_name , "wb" )
724
+ f .write (bytearray (enclave_bin ))
725
+ f .close ()
726
+ print ("Done dumping" )
727
+
728
+ # patch the file to malloc'ed buffer
729
+ str_filepath_buf = gdb .execute ("call (void*)malloc({0})" .format (len (dump_name ) + 1 ), False , True )
730
+ str_filepath_buf = int (re .search (r"0x[0-9a-f]+" , str_filepath_buf ).group (), 16 )
731
+ print ("Got malloc {0}" .format (str_filepath_buf ))
732
+ filepath_bytes = bytearray ()
733
+ filepath_bytes .extend (map (ord , dump_name ))
734
+ filepath_bytes .extend (bytes (0 ))
735
+ write_to_memory (str_filepath_buf , filepath_bytes )
736
+ print ("Done writing filename" )
737
+ write_to_memory (file_addr , struct .pack ('QII' , str_filepath_buf , len (dump_name ), 0 ))
738
+
739
+ # Store the malloc-ed pointer
740
+ global DUMPED_ENCLAVE
741
+ DUMPED_ENCLAVE [dump_name ] = str_filepath_buf
742
+
743
+ print ("Done patching" )
744
+ return False
745
+
689
746
def sgx_debugger_init ():
690
747
print ("detect urts is loaded, initializing" )
691
748
global SIZE
@@ -703,6 +760,7 @@ def sgx_debugger_init():
703
760
UpdateOcallFrame ()
704
761
LoadEventBreakpoint ()
705
762
UnloadEventBreakpoint ()
763
+ CreateBufferEnclaveBreakpoint ()
706
764
GetTCSBreakpoint ()
707
765
gdb .events .exited .connect (exit_handler )
708
766
init_enclaves_debug ()
0 commit comments