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