3434import gdb
3535import struct
3636import os .path
37+ import os
3738from ctypes import create_string_buffer
3839import load_symbol_cmd
3940import sgx_emmt
4041import ctypes
42+ import time
43+ import re
4144
4245# Calculate the bit mode of current debuggee project
4346SIZE = gdb .parse_and_eval ("sizeof(long)" )
5659ENCLAVE_INFO_SIZE = 8 * 7 + 2 * 4
5760INFO_FMT = 'QQQIIQQQQ'
5861ENCLAVES_ADDR = {}
62+ DUMPED_ENCLAVE = {}
5963
6064# The following definitions should strictly align with the struct of
6165# tcs_t
@@ -351,6 +355,14 @@ def fini_enclave_debug(self):
351355 return - 1
352356 except :
353357 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 ]
354366
355367 def append_tcs_list (self , tcs_addr ):
356368 for tcs_tmp in self .tcs_addr_list :
@@ -384,7 +396,7 @@ def retrieve_enclave_info(info_addr = 0):
384396 if name_str == None :
385397 return None
386398 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' )
388400 # get the stack addr list
389401 stack_addr_list = []
390402 tcs_addr_list = []
@@ -686,6 +698,51 @@ def stop(self):
686698 gdb .execute (gdb_cmd , False , True )
687699 return False
688700
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+
689746def sgx_debugger_init ():
690747 print ("detect urts is loaded, initializing" )
691748 global SIZE
@@ -703,6 +760,7 @@ def sgx_debugger_init():
703760 UpdateOcallFrame ()
704761 LoadEventBreakpoint ()
705762 UnloadEventBreakpoint ()
763+ CreateBufferEnclaveBreakpoint ()
706764 GetTCSBreakpoint ()
707765 gdb .events .exited .connect (exit_handler )
708766 init_enclaves_debug ()
0 commit comments