Skip to content

Commit a06b8b4

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 Signed-off-by: Gilang Mentari Hamidy <gilang.hamidy@kuleuven.be>
1 parent 7385e10 commit a06b8b4

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@
3333
import gdb
3434
import struct
3535
import os.path
36+
import os
3637
from ctypes import create_string_buffer
3738
import load_symbol_cmd
3839
import sgx_emmt
3940
import ctypes
41+
import time
4042
import re
4143

4244
# Calculate the bit mode of current debuggee project
@@ -56,6 +58,7 @@
5658
ENCLAVE_INFO_SIZE = 8 * 7 + 2 * 4
5759
INFO_FMT = 'QQQIIQQQQ'
5860
ENCLAVES_ADDR = {}
61+
DUMPED_ENCLAVE = {}
5962

6063
# The following definitions should strictly align with the struct of
6164
# tcs_t
@@ -354,6 +357,13 @@ def fini_enclave_debug(self):
354357
return -1
355358
except:
356359
return -1
360+
finally:
361+
# Delete the dumped enclave if any
362+
global DUMPED_ENCLAVE
363+
if self.enclave_path in DUMPED_ENCLAVE:
364+
gdb.execute("call (void)free({0})".format(DUMPED_ENCLAVE[self.enclave_path]))
365+
os.remove(self.enclave_path)
366+
del DUMPED_ENCLAVE[self.enclave_path]
357367

358368
def append_tcs_list(self, tcs_addr):
359369
for tcs_tmp in self.tcs_addr_list:
@@ -691,6 +701,46 @@ def stop(self):
691701
gdb.execute(gdb_cmd, False, True)
692702
return False
693703

704+
# This breakpoint is to handle enclave creation with buffer
705+
class CreateBufferEnclaveBreakpoint(gdb.Breakpoint):
706+
def __init__(self):
707+
gdb.Breakpoint.__init__ (self, spec="_create_enclave_from_buffer_ex", internal=1)
708+
709+
def stop(self):
710+
bp_in_urts = is_bp_in_urts()
711+
if bp_in_urts == True:
712+
# Get se_file_t pointer (4th parameter)
713+
file_addr = gdb.parse_and_eval("$rcx")
714+
file_str = read_from_memory(file_addr, 8 + 2*4)
715+
file_tuple = struct.unpack_from("QII", file_str)
716+
717+
if file_tuple[1] == 0:
718+
# If it is null, then it does not have a file. So we dump the buffer
719+
720+
# dump enclave to file
721+
dump_name = "/tmp/enclave_dump_{0}.bin".format(time.time())
722+
buffer_ptr = gdb.parse_and_eval("$rsi")
723+
buffer_len = gdb.parse_and_eval("$rdx")
724+
enclave_bin = read_from_memory(buffer_ptr, buffer_len)
725+
f = open(dump_name, "wb")
726+
f.write(bytearray(enclave_bin))
727+
f.close()
728+
729+
# patch the file to malloc'ed buffer
730+
str_filepath_buf = gdb.execute("call (void*)malloc({0})".format(len(dump_name) + 1), False, True)
731+
str_filepath_buf = int(re.search(r"0x[0-9a-f]+", str_filepath_buf).group(), 16)
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+
write_to_memory(file_addr, struct.pack('QII', str_filepath_buf, len(dump_name), 0))
737+
738+
# Store the malloc-ed pointer
739+
global DUMPED_ENCLAVE
740+
DUMPED_ENCLAVE[dump_name] = str_filepath_buf
741+
742+
return False
743+
694744
def sgx_debugger_init():
695745
print ("detect urts is loaded, initializing")
696746
global SIZE
@@ -708,6 +758,7 @@ def sgx_debugger_init():
708758
UpdateOcallFrame()
709759
LoadEventBreakpoint()
710760
UnloadEventBreakpoint()
761+
CreateBufferEnclaveBreakpoint()
711762
GetTCSBreakpoint()
712763
gdb.events.exited.connect(exit_handler)
713764
init_enclaves_debug()

0 commit comments

Comments
 (0)