Skip to content

Commit 8d4b671

Browse files
committed
Enable gdb plugin to work with enclave from buffer
- Initially, the gdb requires the enclave file to load the symbol. However, if we create the enclave from `sgx_create_enclave_from_buffer_ex`, the file information is not populated by the URTS, which prevents the gdb plugin to load the symbols - This patch allows the gdb plugin to hook into the `_create_enclave_from_buffer_ex` function and perform necessary patching to allow enclave not from file to be debugged
1 parent 4887b30 commit 8d4b671

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

sdk/debugger_interface/linux/gdb-sgx-plugin/gdb_sgx_plugin.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@
3434
import gdb
3535
import struct
3636
import os.path
37+
import os
3738
from ctypes import create_string_buffer
3839
import load_symbol_cmd
3940
import sgx_emmt
4041
import ctypes
42+
import time
43+
import re
4144

4245
# Calculate the bit mode of current debuggee project
4346
SIZE = gdb.parse_and_eval("sizeof(long)")
@@ -56,6 +59,7 @@
5659
ENCLAVE_INFO_SIZE = 8 * 7 + 2 * 4
5760
INFO_FMT = 'QQQIIQQQQ'
5861
ENCLAVES_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+
689746
def 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

Comments
 (0)