Skip to content

Commit ea857f3

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 4887b30 commit ea857f3

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

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

Lines changed: 52 additions & 0 deletions
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,13 @@ 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+
gdb.execute("call (void)free({0})".format(DUMPED_ENCLAVE[self.enclave_path]))
363+
os.remove(self.enclave_path)
364+
del DUMPED_ENCLAVE[self.enclave_path]
354365

355366
def append_tcs_list(self, tcs_addr):
356367
for tcs_tmp in self.tcs_addr_list:
@@ -686,6 +697,46 @@ def stop(self):
686697
gdb.execute(gdb_cmd, False, True)
687698
return False
688699

700+
# This breakpoint is to handle enclave creation with buffer
701+
class CreateBufferEnclaveBreakpoint(gdb.Breakpoint):
702+
def __init__(self):
703+
gdb.Breakpoint.__init__ (self, spec="_create_enclave_from_buffer_ex", internal=1)
704+
705+
def stop(self):
706+
bp_in_urts = is_bp_in_urts()
707+
if bp_in_urts == True:
708+
# Get se_file_t pointer (4th parameter)
709+
file_addr = gdb.parse_and_eval("$rcx")
710+
file_str = read_from_memory(file_addr, 8 + 2*4)
711+
file_tuple = struct.unpack_from("QII", file_str)
712+
713+
if file_tuple[1] == 0:
714+
# If it is null, then it does not have a file. So we dump the buffer
715+
716+
# dump enclave to file
717+
dump_name = "/tmp/enclave_dump_{0}.bin".format(time.time())
718+
buffer_ptr = gdb.parse_and_eval("$rsi")
719+
buffer_len = gdb.parse_and_eval("$rdx")
720+
enclave_bin = read_from_memory(buffer_ptr, buffer_len)
721+
f = open(dump_name, "wb")
722+
f.write(bytearray(enclave_bin))
723+
f.close()
724+
725+
# patch the file to malloc'ed buffer
726+
str_filepath_buf = gdb.execute("call (void*)malloc({0})".format(len(dump_name) + 1), False, True)
727+
str_filepath_buf = int(re.search(r"0x[0-9a-f]+", str_filepath_buf).group(), 16)
728+
filepath_bytes = bytearray()
729+
filepath_bytes.extend(map(ord, dump_name))
730+
filepath_bytes.extend(bytes(0))
731+
write_to_memory(str_filepath_buf, filepath_bytes)
732+
write_to_memory(file_addr, struct.pack('QII', str_filepath_buf, len(dump_name), 0))
733+
734+
# Store the malloc-ed pointer
735+
global DUMPED_ENCLAVE
736+
DUMPED_ENCLAVE[dump_name] = str_filepath_buf
737+
738+
return False
739+
689740
def sgx_debugger_init():
690741
print ("detect urts is loaded, initializing")
691742
global SIZE
@@ -703,6 +754,7 @@ def sgx_debugger_init():
703754
UpdateOcallFrame()
704755
LoadEventBreakpoint()
705756
UnloadEventBreakpoint()
757+
CreateBufferEnclaveBreakpoint()
706758
GetTCSBreakpoint()
707759
gdb.events.exited.connect(exit_handler)
708760
init_enclaves_debug()

0 commit comments

Comments
 (0)