3333 * examples/plugins/example.cpp -I . -I capstone/include/
3434 *
3535 * To use:
36- * $ ./e9tool -M 'plugin[example]' -A 'plugin[example]' program
36+ * $ ./e9tool -M 'plugin(example).match()' \
37+ * -P 'plugin(example).patch()' program
3738 * $ ./a.out
3839 * Trace/breakpoint trap
3940 */
@@ -54,6 +55,10 @@ using namespace e9frontend;
5455 */
5556extern void *e9_plugin_init_v1 (FILE *out, const ELF *elf)
5657{
58+ // The e9_plugin_init_v1() is called once per plugin by E9Tool. This can
59+ // be used to emit additional E9Patch messages, such as address space
60+ // reservations and trampoline templates.
61+
5762 /*
5863 * This example uses 3 counters (one for calls/jumps/returns).
5964 * We allocate and initialize the counters to UINT16_MAX (or the value
@@ -97,49 +102,38 @@ extern void *e9_plugin_init_v1(FILE *out, const ELF *elf)
97102 code << 0x9f << ' ,' ;
98103 code << 0x50 << ' ,' ;
99104
100- // Increment the counter and branch if <= 0:
105+ // Increment the counter and trap if <= 0:
101106 //
102107 // mov counter(%rip),%rax
103108 // sub $0x1,%rax
104109 // mov %rax,counter(%rip)
105- // jle .Ltrap
110+ // jg .Lok
111+ // int3
106112 //
107113 code << 0x48 << ' ,' << 0x8b << ' ,' << 0x05 << " ,\" $counter\" ," ;
108114 code << 0x48 << ' ,' << 0x83 << ' ,' << 0xe8 << ' ,' << 0x01 << ' ,' ;
109115 code << 0x48 << ' ,' << 0x89 << ' ,' << 0x05 << " ,\" $counter\" ," ;
110- code << 0x7e << " ,{\" rel8\" :\" .Ltrap\" }," ;
116+ code << 0x7f << " ,{\" rel8\" :\" .Lok\" }," ;
117+ code << 0xcc << ' ,' ;
111118
112119 // Restore state & return from trampoline:
113120 //
114- // .Lcont :
121+ // .Lok :
115122 // pop %rax
116123 // add $0x7f,%al
117124 // sahf
118125 // pop %rax
119126 // lea 0x4000(%rsp),%rsp
120- // $instruction
121- // $continue
122127 //
123- code << " \" .Lcont \" ," ;
128+ code << " \" .Lok \" ," ;
124129 code << 0x58 << ' ,' ;
125130 code << 0x04 << ' ,' << 0x7f << ' ,' ;
126131 code << 0x9e << ' ,' ;
127132 code << 0x58 << ' ,' ;
128133 code << 0x48 << ' ,' << 0x8d << ' ,' << 0xa4 << ' ,' << 0x24 << ' ,'
129- << 0x00 << ' ,' << 0x40 << ' ,' << 0x00 << ' ,' << 0x00 << ' ,' ;
130- code << " \" $instruction\" ," ;
131- code << " \" $continue\" ," ;
134+ << 0x00 << ' ,' << 0x40 << ' ,' << 0x00 << ' ,' << 0x00 ;
132135
133- // Trap:
134- //
135- // .Ltrap:
136- // int3
137- // jmp .Lcont
138- code << " \" .Ltrap\" ," ;
139- code << 0xcc << ' ,' ;
140- code << 0xeb << " ,{\" rel8\" :\" .Lcont\" }" ;
141-
142- sendTrampolineMessage (out, " $cflimit" , code.str ().c_str ());
136+ sendTrampolineMessage (out, " $limit" , code.str ().c_str ());
143137
144138 return nullptr ;
145139}
@@ -149,6 +143,12 @@ extern void *e9_plugin_init_v1(FILE *out, const ELF *elf)
149143 */
150144extern intptr_t e9_plugin_match_v1 (FILE *out, const Context *cxt, void *arg)
151145{
146+ // The e9_plugin_match_v1() function is invoked once by E9Tool for each
147+ // disassembled instruction. The function should return a value that is
148+ // used for matching.
149+
150+ // For this example we return a non-zero value for all
151+ // control-flow-transfer instructions:
152152 switch (cxt->I ->mnemonic )
153153 {
154154 case MNEMONIC_RET:
@@ -175,15 +175,41 @@ extern intptr_t e9_plugin_match_v1(FILE *out, const Context *cxt, void *arg)
175175extern void e9_plugin_patch_v1 (FILE *out, Phase phase, const Context *cxt,
176176 void *arg)
177177{
178+ // The e9_plugin_patch_v1() function is invoked by E9Tool in order to
179+ // build "patch" messages for E9Patch. This function is invoked in three
180+ // main phases: CODE, DATA and METADATA, as described below.
181+ //
182+ // Patching phases:
183+ //
184+ // - CODE : Called once per trampoline template.
185+ // Specifies the "code" part of the trampoline template that
186+ // will be executed for each matching instruction.
187+ //
188+ // - DATA : Called once per trampoline template.
189+ // Specifies the "data" part of the trampoline template that
190+ // can be referenced/used by the code part. The data must be
191+ // read-only. The data part is optional.
192+ //
193+ // - METADATA: Called once per patched instruction.
194+ // Specifies the "metadata" which instantiates any macros
195+ // in the trampoline template (both code or data). Data
196+ // that is instruction-specific should be specified as
197+ // metadata. The metadata is optional.
198+
178199 switch (phase)
179200 {
180201 case PHASE_CODE:
181- fputs (" \" $cflimit\" ," , out);
202+ // The trampoline code simply invokes the $limit template
203+ // (defined above):
204+ fputs (" \" $limit\" ," , out);
182205 return ;
183206 case PHASE_DATA:
207+ // There is no trampoline data:
184208 return ;
185209 case PHASE_METADATA:
186210 {
211+ // The trampoline metadata instantiates the $counter macro with
212+ // the counter address corresponding to the instruction type:
187213 intptr_t counter = e9_plugin_match_v1 (nullptr , cxt, arg);
188214 counter = COUNTERS + (counter - 1 ) * sizeof (size_t );
189215 fprintf (out, " \" $counter\" :{\" rel32\" :\" 0x%lx\" }," , counter);
0 commit comments