@@ -18,6 +18,7 @@ PANDAENDCOMMENT */
18
18
#include < cstdio>
19
19
#include < map>
20
20
#include < memory>
21
+ #include < sys/mman.h>
21
22
22
23
#include " panda/plugin.h"
23
24
#include " panda/plugin_plugin.h"
@@ -52,14 +53,13 @@ PPP_PROT_REG_CB(on_library_load);
52
53
// This creates the global for this call back fn (on_library_load)
53
54
PPP_CB_BOILERPLATE (on_library_load)
54
55
55
- bool debug = true ;
56
+ bool debug = false ;
56
57
57
58
#define MAX_FILENAME 256
58
59
std::map <target_ulong, OsiProc> running_procs;
59
60
60
61
void die (const char * fmt, ...) {
61
62
va_list args;
62
-
63
63
va_start (args, fmt);
64
64
vfprintf (stderr, fmt, args);
65
65
va_end (args);
@@ -94,39 +94,99 @@ void linux_old_mmap_return(CPUState *cpu, target_ulong pc, uint32_t arg_ptr) {
94
94
}
95
95
}
96
96
97
- void linux_mmap_pgoff_return (CPUState *cpu,target_ulong pc,uint32_t addr,uint32_t len,uint32_t prot,uint32_t flags,uint32_t fd,uint32_t pgoff) {
97
+ void linux_mmap_pgoff_return (CPUState *cpu, target_ulong pc,
98
+ uint32_t addr, uint32_t len,
99
+ uint32_t prot,uint32_t flags,
100
+ uint32_t fd,uint32_t pgoff) {
98
101
CPUArchState *env = (CPUArchState*)cpu->env_ptr ;
99
102
target_ulong asid = panda_current_asid (cpu);
100
103
if (running_procs.count (asid) == 0 ) {
101
- // printf ("linux_mmap_pgoff_enter for asid=0x%x fd=%d -- dont know about that asid. discarding \n", (unsigned int) asid, (int) fd);
104
+ // printf ("linux_mmap_pgoff_enter for asid=0x%x fd=%d -- dont know about that asid. discarding \n", (unsigned int) asid, (int) fd);
102
105
return ;
103
106
}
104
- if ((int32_t ) fd == -1 ){
105
- // printf ("linux_mmap_pgoff_enter for asid=0x%x fd=%d flags=%x -- not valid fd . . . \n", (unsigned int) asid, (int) fd, flags);
107
+ if ((int32_t ) fd == -1 ) {
108
+ // printf ("linux_mmap_pgoff_enter for asid=0x%x fd=%d flags=%x -- not valid fd . . . \n", (unsigned int) asid, (int) fd, flags);
106
109
return ;
107
110
}
108
111
OsiProc proc = running_procs[asid];
109
112
char *filename = osi_linux_fd_to_filename (cpu, &proc, fd);
110
113
// gets us offset into the file. could be useful
111
- // uint64_t pos = osi_linux_fd_to_pos(env, &proc, fd);
114
+ // uint64_t pos = osi_linux_fd_to_pos(env, &proc, fd);
112
115
// if a filename exists and permission is executable
113
- // TODO: fix this magic constant of 0x04 for PROT_EXEC
114
- if (filename != NULL && ((prot & 0x04 ) == 0x04 )) {
116
+ if (filename != NULL && ((prot & PROT_EXEC) == PROT_EXEC)) {
115
117
if (debug) {
116
118
printf (" [loaded] linux_mmap_pgoff(fd=%d filename=[%s] "
117
119
" len=%d prot=%x flags=%x "
118
120
" pgoff=%d)=" TARGET_FMT_lx " \n " , (int ) fd,
119
121
filename, len, prot, flags, pgoff, env->regs [R_EAX]);
120
122
}
121
- PPP_RUN_CB (on_library_load, cpu, pc, filename, env->regs [R_EAX], len)
122
- } else if ((prot & 0x04 ) == 0x04 ) {
123
+ PPP_RUN_CB (on_library_load, cpu, pc, filename, env->regs [R_EAX], len);
124
+ }
125
+ else if ((prot & PROT_EXEC) == PROT_EXEC) {
123
126
printf (" [loaded] mapped executable section without a filename!\n " );
124
127
printf (" [loaded] linux_mmap_pgoff(fd=%d "
125
128
" len=%d prot=%x flags=%x "
126
129
" pgoff=%d)=" TARGET_FMT_lx " \n " , (int ) fd,
127
130
len, prot, flags, pgoff, env->regs [R_EAX]);
128
131
}
129
132
}
133
+
134
+ #elif defined(TARGET_I386) && defined(TARGET_X86_64)
135
+ void linux_mprotect_return (CPUState* cpu, target_ulong pc,
136
+ uint64_t start, uint32_t len,
137
+ uint64_t prot) {
138
+ if (debug) {
139
+ printf (" [loaded] mprotect() on x86-64\n " );
140
+ }
141
+ }
142
+
143
+ void linux_mmap_return (CPUState *cpu, target_ulong pc,
144
+ uint64_t addr, uint64_t len, uint64_t prot,
145
+ uint64_t flags, uint64_t fd, uint64_t offset) {
146
+
147
+ if (debug) {
148
+ printf (" [loaded] linux_mmap_return 64-bit is called\n " );
149
+ }
150
+ CPUArchState *env = (CPUArchState*)cpu->env_ptr ;
151
+ target_ulong asid = panda_current_asid (cpu);
152
+ if (running_procs.count (asid) == 0 ) {
153
+ return ;
154
+ }
155
+ if ((int32_t ) fd == -1 ) {
156
+ return ;
157
+ }
158
+ if (debug) {
159
+ printf (" [loaded] linux_mmap_return 64-bit is called, with OK fd and non-zero running proc\n " );
160
+ }
161
+
162
+ OsiProc proc = running_procs[asid];
163
+ char * filename = osi_linux_fd_to_filename (cpu, &proc, fd);
164
+ // gets us offset into the file. could be useful
165
+ // uint64_t pos = osi_linux_fd_to_pos(cpu, &proc, fd);
166
+ // if a filename exists and permission is executable
167
+ if (filename != NULL && ((prot & PROT_EXEC) == PROT_EXEC)) {
168
+ if (debug) {
169
+ printf (" [loaded] linux_mmap(fd=%lu filename=[%s] len=%lu prot=%lx flags=%lx pgoff=%lu)=%lx\n " ,
170
+ fd, filename, len, prot, flags, offset, (unsigned long ) env->regs [R_EAX]);
171
+ }
172
+ PPP_RUN_CB (on_library_load, cpu, pc, filename, env->regs [R_EAX], len);
173
+ }
174
+ else if ((prot & PROT_EXEC) == PROT_EXEC) {
175
+ printf (" [loaded] mapped executable section without a filename!\n " );
176
+ printf (" [loaded] linux_mmap(fd=%lu len=%lu prot=%lx flags=%lx pgoff=%lu)=%lx\n " ,
177
+ fd, len, prot, flags, offset, (unsigned long ) env->regs [R_EAX]);
178
+ }
179
+ else {
180
+ if (debug) {
181
+ if (filename == NULL ) {
182
+ printf (" [loaded] I got a null file name\n " );
183
+ }
184
+ else {
185
+ printf (" [loaded] It seems like filename %s was null, OR PROT_EXEC was not there\n " , filename);
186
+ }
187
+ }
188
+ }
189
+ }
130
190
#endif
131
191
132
192
// get current process before each bb execs
@@ -137,42 +197,54 @@ void osi_foo(CPUState *cpu, TranslationBlock *tb) {
137
197
138
198
std::unique_ptr<OsiProc, decltype (free_osiproc)*> p { get_current_process (cpu), free_osiproc };
139
199
140
- // some sanity checks on what we think the current process is
200
+ // some sanity checks on what we think the current process is
141
201
// we couldn't find the current task
142
- if (!p) return ;
202
+ if (!p) {
203
+ return ;
204
+ }
143
205
// this means we didnt find current task
144
- if (p->taskd == 0 ) return ;
206
+ if (p->taskd == 0 ) {
207
+ return ;
208
+ }
145
209
// or the name
146
- if (p->name == 0 ) return ;
210
+ if (p->name == 0 ) {
211
+ return ;
212
+ }
147
213
// this is just not ok
148
- if (((int ) p->pid ) == -1 ) return ;
214
+ if (((int ) p->pid ) == -1 ) {
215
+ return ;
216
+ }
149
217
uint32_t n = strnlen (p->name , 32 );
150
218
// name is one char?
151
- if (n<2 ) return ;
219
+ if (n < 2 ) {
220
+ return ;
221
+ }
152
222
uint32_t np = 0 ;
153
223
for (uint32_t i=0 ; i<n; i++) {
154
224
np += (isprint (p->name [i]) != 0 );
155
225
}
156
226
// name doesnt consist of solely printable characters
157
227
// printf ("np=%d n=%d\n", np, n);
158
- if (np != n) return ;
228
+ if (np != n) {
229
+ return ;
230
+ }
159
231
target_ulong asid = panda_current_asid (cpu);
160
232
if (running_procs.count (asid) == 0 ) {
161
- printf (" adding asid=0x%x to running procs. cmd=[%s] task=0x%x\n " , (unsigned int ) asid, p->name , (unsigned int ) p->taskd );
233
+ printf (" [loaded] adding asid=0x%x to running procs. cmd=[%s] task=0x%x\n " , (unsigned int ) asid, p->name , (unsigned int ) p->taskd );
162
234
}
163
235
running_procs[asid] = *p;
164
236
}
165
-
166
237
return ;
167
238
}
168
- bool init_plugin (void *self) {
169
- // panda_arg_list *args = panda_get_args("loaded");
170
239
240
+ bool init_plugin (void *self) {
171
241
panda_require (" osi" );
172
242
assert (init_osi_api ());
173
243
panda_require (" osi_linux" );
174
244
assert (init_osi_linux_api ());
175
245
panda_require (" syscalls2" );
246
+ panda_arg_list *args = panda_get_args (" loaded" );
247
+ debug = panda_parse_bool_opt (args, " debug" , " enable debug output" );
176
248
177
249
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
178
250
{
@@ -183,10 +255,22 @@ bool init_plugin(void *self) {
183
255
184
256
PPP_REG_CB (" syscalls2" , on_sys_mmap_pgoff_return, linux_mmap_pgoff_return);
185
257
// don't use these at them moment
186
- // PPP_REG_CB("syscalls2", on_sys_old_mmap_return, linux_old_mmap_return);
187
- // PPP_REG_CB("syscalls2", on_sys_mprotect_return, linux_mprotect_return);
258
+ // PPP_REG_CB("syscalls2", on_sys_old_mmap_return, linux_old_mmap_return);
259
+ // PPP_REG_CB("syscalls2", on_sys_mprotect_return, linux_mprotect_return);
260
+ printf (" [loaded] The plugin is supported on i386\n " );
261
+ #elif defined(TARGET_I386) && defined(TARGET_X86_64)
262
+ {
263
+ panda_cb pcb;
264
+ pcb.before_block_exec = osi_foo;
265
+ panda_register_callback (self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
266
+ }
267
+ // Tell Plugin 'syscall2', that if a systemcall 'mmap' occurs, then run the code in 'linux_mmap_return'
268
+ // https://www.linuxquestions.org/questions/linux-general-1/difference-between-mmap2-syscall-and-mmap_pgoff-syscall-for-32-bit-linux-4175622986/
269
+ PPP_REG_CB (" syscalls2" , on_sys_mmap_return, linux_mmap_return);
270
+ PPP_REG_CB (" syscalls2" , on_sys_mprotect_return, linux_mprotect_return);
271
+ printf (" [loaded] The plugin is supported on x86-64\n " );
188
272
#else
189
- fprintf (stderr, " The loaded plugin is not currently supported on this platform.\n " );
273
+ fprintf (stderr, " [ loaded] The plugin is not currently supported on this platform.\n " );
190
274
return false ;
191
275
#endif
192
276
return true ;
0 commit comments