forked from NRZCode/ia32-64
258 lines
9.5 KiB
HTML
258 lines
9.5 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:x86="http://www.felixcloutier.com/x86"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="style.css"></link><title>EDBGWR
|
|||
|
— Write to a Debug Enclave</title></head><body><header><nav><ul><li><a href='index.html'>Index</a></li><li>December 2023</li></ul></nav></header><h1>EDBGWR
|
|||
|
— Write to a Debug Enclave</h1>
|
|||
|
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<th>Opcode/Instruction</th>
|
|||
|
<th>Op/En</th>
|
|||
|
<th>64/32 bit Mode Support</th>
|
|||
|
<th>CPUID Feature Flag</th>
|
|||
|
<th>Description</th></tr>
|
|||
|
<tr>
|
|||
|
<td>EAX = 05H ENCLS[EDBGWR]</td>
|
|||
|
<td>IR</td>
|
|||
|
<td>V/V</td>
|
|||
|
<td>SGX1</td>
|
|||
|
<td>This leaf function writes a dword/quadword to a debug enclave.</td></tr></table>
|
|||
|
<h2 id="instruction-operand-encoding">Instruction Operand Encoding<a class="anchor" href="#instruction-operand-encoding">
|
|||
|
¶
|
|||
|
</a></h2>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<td>Op/En</td>
|
|||
|
<td colspan="2">EAX</td>
|
|||
|
<td>RBX</td>
|
|||
|
<td>RCX</td></tr>
|
|||
|
<tr>
|
|||
|
<td>IR</td>
|
|||
|
<td>EDBGWR (In)</td>
|
|||
|
<td>Return error code (Out)</td>
|
|||
|
<td>Data to be written to a debug enclave (In)</td>
|
|||
|
<td>Address of Target memory in the EPC (In)</td></tr></table>
|
|||
|
<h3 id="description">Description<a class="anchor" href="#description">
|
|||
|
¶
|
|||
|
</a></h3>
|
|||
|
<p>This leaf function copies the content in EBX/RBX to an EPC page belonging to a debug enclave. Eight bytes are written in 64-bit mode, four bytes are written in non-64-bit modes. The size of data cannot be overridden.</p>
|
|||
|
<p>The effective address of the target location inside the EPC is provided in the register RCX.</p>
|
|||
|
<h2 id="edbgwr-memory-parameter-semantics">EDBGWR Memory Parameter Semantics<a class="anchor" href="#edbgwr-memory-parameter-semantics">
|
|||
|
¶
|
|||
|
</a></h2>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<td>EPCQW</td></tr>
|
|||
|
<tr>
|
|||
|
<td>Write access permitted by Enclave</td></tr></table>
|
|||
|
<p>The instruction faults if any of the following:</p>
|
|||
|
<h2 id="edbgwr-faulting-conditions">EDBGWR Faulting Conditions<a class="anchor" href="#edbgwr-faulting-conditions">
|
|||
|
¶
|
|||
|
</a></h2>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<td>RCX points into a page that is an SECS.</td>
|
|||
|
<td>RCX does not resolve to a naturally aligned linear address.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>RCX points to a page that does not belong to an enclave that is in debug mode.</td>
|
|||
|
<td>RCX points to a location inside a TCS that is not the FLAGS word.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>An operand causing any segment violation.</td>
|
|||
|
<td>May page fault.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>CPL > 0.</td>
|
|||
|
<td></td></tr></table>
|
|||
|
<p>The error codes are:</p>
|
|||
|
<figure id="tbl-38-20">
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<th>Error Code (see <span class="not-imported">Table 38-4</span>)</th>
|
|||
|
<th>Description</th></tr>
|
|||
|
<tr>
|
|||
|
<td>No Error</td>
|
|||
|
<td>EDBGWR successful.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>SGX_PAGE_NOT_DEBUGGABLE</td>
|
|||
|
<td>The EPC page cannot be accessed because it is in the PENDING or MODIFIED state.</td></tr></table>
|
|||
|
<figcaption><span class="not-imported">Table 38-20</span>. EDBGWR Return Value in RAX</figcaption></figure>
|
|||
|
<p>This instruction ignores the EPCM RWX attributes on the enclave page. Consequently, violation of EPCM RWX attributes via EDBGRD does not result in a #GP.</p>
|
|||
|
<h3 id="concurrency-restrictions">Concurrency Restrictions<a class="anchor" href="#concurrency-restrictions">
|
|||
|
¶
|
|||
|
</a></h3>
|
|||
|
<figure id="tbl-38-21">
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<th rowspan="2">Leaf</th>
|
|||
|
<th rowspan="2">Parameter</th>
|
|||
|
<th colspan="3">Base Concurrency Restrictions</th></tr>
|
|||
|
<tr>
|
|||
|
<th></th>
|
|||
|
<th>On Conflict </th>
|
|||
|
<th></th></tr>
|
|||
|
<tr>
|
|||
|
<td>EDBGWR EDBGWR
|
|||
|
Target [DS:RCX]
|
|||
|
Shared EDBGWR
|
|||
|
Target [DS:RCX]
|
|||
|
</td>
|
|||
|
<td>Target [DS:RCX]</td>
|
|||
|
<td></td>
|
|||
|
<td></td>
|
|||
|
<td></td></tr></table>
|
|||
|
<figcaption><span class="not-imported">Table 38-21</span>. Base Concurrency Restrictions of EDBGWR</figcaption></figure>
|
|||
|
<figure id="tbl-38-22">
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<th rowspan="3">Leaf</th>
|
|||
|
<th rowspan="3">Parameter</th>
|
|||
|
<th colspan="6">Additional Concurrency Restrictions</th></tr>
|
|||
|
<tr>
|
|||
|
<th colspan="2">vs. EACCEPT, EACCEPTCOPY, vs. EADD, EEXTEND, EINIT
|
|||
|
vs. ETRACK, ETRACKC
|
|||
|
Access vs. ETRACK, ETRACKC
|
|||
|
Access On Conflict
|
|||
|
Access vs. ETRACK, ETRACKC
|
|||
|
Access On Conflict
|
|||
|
EMODPE, EMODPR, EMODT</th>
|
|||
|
<th colspan="2">vs. EADD, EEXTEND, EINIT vs. EADD, EEXTEND, EINIT
|
|||
|
vs. ETRACK, ETRACKC
|
|||
|
</th>
|
|||
|
<th colspan="2">vs. ETRACK, ETRACKC</th></tr>
|
|||
|
<tr>
|
|||
|
<th>Access On Conflict
|
|||
|
Access On Conflict
|
|||
|
Access Access On Conflict
|
|||
|
Access On Conflict
|
|||
|
</th>
|
|||
|
<th></th>
|
|||
|
<th></th>
|
|||
|
<th></th>
|
|||
|
<th></th>
|
|||
|
<th></th></tr>
|
|||
|
<tr>
|
|||
|
<td>EDBGWR</td>
|
|||
|
<td>Target [DS:RCX]</td>
|
|||
|
<td>Concurrent</td>
|
|||
|
<td></td>
|
|||
|
<td>Concurrent</td>
|
|||
|
<td></td>
|
|||
|
<td>Concurrent</td>
|
|||
|
<td></td></tr></table>
|
|||
|
<figcaption><span class="not-imported">Table 38-22</span>. Additional Concurrency Restrictions of EDBGWR</figcaption></figure>
|
|||
|
<h3 id="operation">Operation<a class="anchor" href="#operation">
|
|||
|
¶
|
|||
|
</a></h3>
|
|||
|
<h2 id="temp-variables-in-edbgwr-operational-flow">Temp Variables in EDBGWR Operational Flow<a class="anchor" href="#temp-variables-in-edbgwr-operational-flow">
|
|||
|
¶
|
|||
|
</a></h2>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<th>Name</th>
|
|||
|
<th>Type</th>
|
|||
|
<th>Size (Bits)</th>
|
|||
|
<th>Description</th></tr>
|
|||
|
<tr>
|
|||
|
<td>TMP_MODE64</td>
|
|||
|
<td>Binary</td>
|
|||
|
<td>1</td>
|
|||
|
<td>((IA32_EFER.LMA = 1) && (CS.L = 1)).</td></tr>
|
|||
|
<tr>
|
|||
|
<td>TMP_SECS</td>
|
|||
|
<td></td>
|
|||
|
<td>64</td>
|
|||
|
<td>Physical address of SECS of the enclave to which source operand belongs.</td></tr></table>
|
|||
|
<p>TMP_MODE64 := ((IA32_EFER.LMA = 1) && (CS.L = 1));</p>
|
|||
|
<p>IF ( (TMP_MODE64 = 1) and (DS:RCX is not 8Byte Aligned) )</p>
|
|||
|
<p>THEN #GP(0); FI;</p>
|
|||
|
<p>IF ( (TMP_MODE64 = 0) and (DS:RCX is not 4Byte Aligned) )</p>
|
|||
|
<p>THEN #GP(0); FI;</p>
|
|||
|
<p>IF (DS:RCX does not resolve within an EPC)</p>
|
|||
|
<p>THEN #PF(DS:RCX); FI;</p>
|
|||
|
<p>(* make sure no other Intel SGX instruction is accessing the same EPCM entry *)</p>
|
|||
|
<p>IF (Another instruction modifying the same EPCM entry is executing)</p>
|
|||
|
<p>THEN #GP(0); FI;</p>
|
|||
|
<p>IF (EPCM(DS:RCX).VALID = 0)</p>
|
|||
|
<p>THEN #PF(DS:RCX); FI;</p>
|
|||
|
<p>(* make sure that DS:RCX (DST) is pointing to a PT_REG or PT_TCS or PT_SS_FIRST or PT_SS_REST *)</p>
|
|||
|
<p>IF ( (EPCM(DS:RCX).PT ≠ PT_REG) and (EPCM(DS:RCX).PT ≠ PT_TCS)</p>
|
|||
|
<p>and (EPCM(DS:RCX).PT ≠ PT_SS_FIRST) and (EPCM(DS:RCX).PT ≠ PT_SS_REST))</p>
|
|||
|
<p>THEN #PF(DS:RCX); FI;</p>
|
|||
|
<p>(* make sure that DS:RCX points to an accessible EPC page *)</p>
|
|||
|
<p>IF ( (EPCM(DS:RCX).PENDING is not 0) or (EPCM(DS:RCS).MODIFIED is not 0) )</p>
|
|||
|
<p>THEN</p>
|
|||
|
<p>RFLAGS.ZF := 1;</p>
|
|||
|
<p>RAX := SGX_PAGE_NOT_DEBUGGABLE;</p>
|
|||
|
<p>GOTO DONE;</p>
|
|||
|
<p>FI;</p>
|
|||
|
<p>(* If destination is a TCS, then make sure that the offset into the page can only point to the FLAGS field*)</p>
|
|||
|
<p>IF ( ( EPCM(DS:RCX). PT = PT_TCS) and ((DS:RCX) & FF8H ≠ offset_of_FLAGS & 0FF8H) )</p>
|
|||
|
<p>THEN #GP(0); FI;</p>
|
|||
|
<p>(* Locate the SECS for the enclave to which the DS:RCX page belongs *)</p>
|
|||
|
<p>TMP_SECS := GET_SECS_PHYS_ADDRESS(EPCM(DS:RCX).ENCLAVESECS);</p>
|
|||
|
<p>(* make sure the enclave owning the PT_REG or PT_TCS page allow debug *)</p>
|
|||
|
<p>IF (TMP_SECS.ATTRIBUTES.DEBUG = 0)</p>
|
|||
|
<p>THEN #GP(0); FI;</p>
|
|||
|
<p>IF ( (TMP_MODE64 = 1) )</p>
|
|||
|
<p>THEN (DS:RCX)[63:0] := RBX[63:0];</p>
|
|||
|
<p>ELSE (DS:RCX)[31:0] := EBX[31:0];</p>
|
|||
|
<p>FI;</p>
|
|||
|
<p>(* clear EAX and ZF to indicate successful completion *)</p>
|
|||
|
<p>RAX := 0;</p>
|
|||
|
<p>RFLAGS.ZF := 0;</p>
|
|||
|
<p>DONE:</p>
|
|||
|
<p>(* clear flags *)</p>
|
|||
|
<p>RFLAGS.CF,PF,AF,OF,SF := 0</p>
|
|||
|
<h3 id="flags-affected">Flags Affected<a class="anchor" href="#flags-affected">
|
|||
|
¶
|
|||
|
</a></h3>
|
|||
|
<p>ZF is set if the page is MODIFIED or PENDING; RAX contains the error code. Otherwise ZF is cleared and RAX is set to 0. CF, PF, AF, OF, SF are cleared.</p>
|
|||
|
<h3 class="exceptions" id="protected-mode-exceptions">Protected Mode Exceptions<a class="anchor" href="#protected-mode-exceptions">
|
|||
|
¶
|
|||
|
</a></h3>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<td rowspan="6">#GP(0)</td>
|
|||
|
<td>If the address in RCS violates DS limit or access rights.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If DS segment is unusable.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If RCX points to a memory location not 4Byte-aligned.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a page belonging to a non-debug enclave.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a page which is not PT_TCS or PT_REG.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a location inside TCS that is not the FLAGS word.</td></tr>
|
|||
|
<tr>
|
|||
|
<td rowspan="3">#PF(error</td>
|
|||
|
<td>code) If a page fault occurs in accessing memory operands.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a non-EPC page.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to an invalid EPC page.</td></tr></table>
|
|||
|
<h3 class="exceptions" id="64-bit-mode-exceptions">64-Bit Mode Exceptions<a class="anchor" href="#64-bit-mode-exceptions">
|
|||
|
¶
|
|||
|
</a></h3>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<td rowspan="5">#GP(0)</td>
|
|||
|
<td>If RCX is non-canonical form.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If RCX points to a memory location not 8Byte-aligned.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a page belonging to a non-debug enclave.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a page which is not PT_TCS or PT_REG.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a location inside TCS that is not the FLAGS word.</td></tr>
|
|||
|
<tr>
|
|||
|
<td rowspan="3">#PF(error</td>
|
|||
|
<td>code) If a page fault occurs in accessing memory operands.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to a non-EPC page.</td></tr>
|
|||
|
<tr>
|
|||
|
<td>If the address in RCX points to an invalid EPC page.</td></tr></table><footer><p>
|
|||
|
This UNOFFICIAL, mechanically-separated, non-verified reference is provided for convenience, but it may be
|
|||
|
inc<span style="opacity: 0.2">omp</span>lete or b<sub>r</sub>oke<sub>n</sub> in various obvious or non-obvious
|
|||
|
ways. Refer to <a href="https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4">Intel® 64 and IA-32 Architectures Software Developer’s Manual</a> for anything serious.
|
|||
|
</p></footer></body></html>
|