@@ -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,14 @@ 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;
57
+ #define dprintf (...) if (debug) { printf (__VA_ARGS__); fflush (stdout); }
56
58
57
59
#define MAX_FILENAME 256
58
60
std::map <target_ulong, OsiProc> running_procs;
59
61
60
62
void die (const char * fmt, ...) {
61
63
va_list args;
62
-
63
64
va_start (args, fmt);
64
65
vfprintf (stderr, fmt, args);
65
66
va_end (args);
@@ -80,116 +81,167 @@ uint32_t guest_strncpy(CPUState *cpu, char *buf, size_t maxlen, target_ulong gue
80
81
return i;
81
82
}
82
83
83
- #if defined(TARGET_I386) && !defined(TARGET_X86_64)
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) {
86
- if (debug) {
87
- printf (" [loaded] mprotect()\n " );
88
- }
89
- }
90
- // 90 long sys_old_mmap ['struct mmap_arg_struct __user *arg']
91
- void linux_old_mmap_return (CPUState *cpu, target_ulong pc, uint32_t arg_ptr) {
92
- if (debug) {
93
- printf (" [loaded] old mmap()\n " );
94
- }
95
- }
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) {
98
- CPUArchState *env = (CPUArchState*)cpu->env_ptr ;
99
- target_ulong asid = panda_current_asid (cpu);
100
- 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);
102
- return ;
103
- }
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);
106
- return ;
107
- }
108
- OsiProc proc = running_procs[asid];
109
- char *filename = osi_linux_fd_to_filename (cpu, &proc, fd);
110
- // gets us offset into the file. could be useful
111
- // uint64_t pos = osi_linux_fd_to_pos(env, &proc, fd);
112
- // 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 )) {
115
- if (debug) {
116
- printf (" [loaded] linux_mmap_pgoff(fd=%d filename=[%s] "
117
- " len=%d prot=%x flags=%x "
118
- " pgoff=%d)=" TARGET_FMT_lx " \n " , (int ) fd,
119
- filename, len, prot, flags, pgoff, env->regs [R_EAX]);
120
- }
121
- PPP_RUN_CB (on_library_load, cpu, pc, filename, env->regs [R_EAX], len)
122
- } else if ((prot & 0x04 ) == 0x04 ) {
123
- printf (" [loaded] mapped executable section without a filename!\n " );
124
- printf (" [loaded] linux_mmap_pgoff(fd=%d "
125
- " len=%d prot=%x flags=%x "
126
- " pgoff=%d)=" TARGET_FMT_lx " \n " , (int ) fd,
127
- len, prot, flags, pgoff, env->regs [R_EAX]);
128
- }
129
- }
130
- #endif
131
-
132
84
// get current process before each bb execs
133
85
// which will probably help us actually know the current process
134
86
void osi_foo (CPUState *cpu, TranslationBlock *tb) {
135
-
136
87
if (panda_in_kernel (cpu)) {
137
-
138
88
std::unique_ptr<OsiProc, decltype (free_osiproc)*> p { get_current_process (cpu), free_osiproc };
139
89
140
- // some sanity checks on what we think the current process is
90
+ // some sanity checks on what we think the current process is
141
91
// we couldn't find the current task
142
- if (!p) return ;
92
+ if (!p) {
93
+ return ;
94
+ }
143
95
// this means we didnt find current task
144
- if (p->taskd == 0 ) return ;
96
+ if (p->taskd == 0 ) {
97
+ return ;
98
+ }
145
99
// or the name
146
- if (p->name == 0 ) return ;
100
+ if (p->name == 0 ) {
101
+ return ;
102
+ }
147
103
// this is just not ok
148
- if (((int ) p->pid ) == -1 ) return ;
104
+ if (((int ) p->pid ) == -1 ) {
105
+ return ;
106
+ }
149
107
uint32_t n = strnlen (p->name , 32 );
150
108
// name is one char?
151
- if (n<2 ) return ;
109
+ if (n < 2 ) {
110
+ return ;
111
+ }
152
112
uint32_t np = 0 ;
153
113
for (uint32_t i=0 ; i<n; i++) {
154
114
np += (isprint (p->name [i]) != 0 );
155
115
}
156
116
// name doesnt consist of solely printable characters
157
117
// printf ("np=%d n=%d\n", np, n);
158
- if (np != n) return ;
118
+ if (np != n) {
119
+ return ;
120
+ }
159
121
target_ulong asid = panda_current_asid (cpu);
160
122
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 );
123
+ 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
124
}
163
125
running_procs[asid] = *p;
164
126
}
165
-
166
127
return ;
167
128
}
168
- bool init_plugin (void *self) {
169
- // panda_arg_list *args = panda_get_args("loaded");
170
129
130
+ #if defined(TARGET_I386) || defined(TARGET_ARM)
131
+ #if defined(TARGET_I386) && !defined(TARGET_X86_64) || defined(TARGET_ARM) && !defined(TARGET_AARCH64)
132
+ // technically for 32-bit it is pgoff, not offset! But I want to avoid code duplication!
133
+ void linux_mmap_return (CPUState *cpu, target_ulong pc, uint32_t addr, uint32_t len, uint32_t prot, uint32_t flags, uint32_t fd, uint32_t offset)
134
+ #elif defined(TARGET_X86_64)
135
+ void linux_mmap_return (CPUState *cpu, target_ulong pc, uint64_t addr, uint64_t len, uint64_t prot, uint64_t flags, uint64_t fd, uint64_t offset)
136
+ #elif defined(TARGET_AARCH64)
137
+ void linux_mmap_return (CPUState* cpu, target_ulong pc, uint64_t addr, uint32_t len, int32_t prot, int32_t flags, int32_t fd, uint64_t offset)
138
+ #endif
139
+ {
140
+ dprintf (" [loaded] linux_mmap_return is called!\n " );
141
+ CPUArchState *env = (CPUArchState*)cpu->env_ptr ;
142
+ target_ulong asid = panda_current_asid (cpu);
143
+ if (running_procs.count (asid) == 0 ) {
144
+ return ;
145
+ }
146
+ if (fd == -1 ) {
147
+ return ;
148
+ }
149
+ dprintf (" [loaded] linux_mmap_return is called, with OK fd and non-zero running proc\n " );
150
+ OsiProc proc = running_procs[asid];
151
+ char *filename = osi_linux_fd_to_filename (cpu, &proc, fd);
152
+ // gets us offset into the file. could be useful
153
+ // uint64_t pos = osi_linux_fd_to_pos(env, &proc, fd);
154
+ // if a filename exists and permission is executable
155
+ #if defined(TARGET_I386) && !defined(TARGET_X86_64)
156
+ dprintf (" [loaded] linux_mmap_pgoff(fd=%d filename=[%s] "
157
+ " len=%d prot=%x flags=%x "
158
+ " pgoffset=%d)=" TARGET_FMT_lx " \n " , (int ) fd,
159
+ filename, len, prot, flags, offset, env->regs [R_EAX]);
160
+ #elif defined(TARGET_ARM) && !defined(TARGET_AARCH64)
161
+ dprintf (" [loaded] linux_mmap_pgoff(fd=%d filename=[%s] "
162
+ " len=%u prot=%u flags=%u "
163
+ " pgoffset=%d)=" TARGET_FMT_lx " \n " , (int ) fd,
164
+ filename, len, prot, flags, offset, env->regs [0 ]);
165
+ #elif defined(TARGET_X86_64)
166
+ dprintf (" [loaded] linux_mmap_pgoff(fd=%lu filename=[%s] "
167
+ " len=%lu prot=%lu flags=%lu "
168
+ " pgoff=%lu)=" TARGET_FMT_lx " \n " , (unsigned long ) fd,
169
+ filename, (unsigned long ) len, (unsigned long ) prot, (unsigned long ) flags, (unsigned long ) offset, env->regs [R_EAX]);
170
+ #elif defined(TARGET_AARCH64)
171
+ printf (" [loaded] linux_mmap(fd=%d filename=[%s] "
172
+ " len=%u prot=%x flags=%x "
173
+ " pgoff=%lu)=" TARGET_FMT_lx " \n " , fd,
174
+ filename, len, prot, flags, offset, env->xregs [0 ]);
175
+ #endif
176
+
177
+ if (filename != NULL && ((prot & PROT_EXEC) == PROT_EXEC)) {
178
+ // See 'dwarf2.cpp' for the definition of 'on_library_load'
179
+ dprintf (" [loaded] Calling on_library_load\n " );
180
+ #if defined(TARGET_I386)
181
+ PPP_RUN_CB (on_library_load, cpu, pc, filename, env->regs [R_EAX], len);
182
+ #elif defined(TARGET_AARCH64)
183
+ PPP_RUN_CB (on_library_load, cpu, pc, filename, env->xregs [0 ], len);
184
+ #elif defined(TARGET_ARM) && !defined(TARGET_AARCH64)
185
+ PPP_RUN_CB (on_library_load, cpu, pc, filename, env->regs [0 ], len);
186
+ #endif
187
+ }
188
+ else if ((prot & PROT_EXEC) == PROT_EXEC) {
189
+ printf (" [loaded] mapped executable section without a filename!\n " );
190
+ }
191
+ else {
192
+ if (filename == NULL ) {
193
+ dprintf (" [loaded] I got a null file name\n " );
194
+ }
195
+ else {
196
+ dprintf (" [loaded] It seems like filename %s was null, OR PROT_EXEC was not there\n " , filename);
197
+ }
198
+ }
199
+ }
200
+ #endif
201
+
202
+ bool init_plugin (void *self) {
171
203
panda_require (" osi" );
172
204
assert (init_osi_api ());
173
205
panda_require (" osi_linux" );
174
206
assert (init_osi_linux_api ());
175
207
panda_require (" syscalls2" );
208
+ panda_arg_list *args = panda_get_args (" loaded" );
209
+ debug = panda_parse_bool_opt (args, " debug" , " enable debug output" );
176
210
177
211
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
178
212
{
179
213
panda_cb pcb;
180
214
pcb.before_block_exec = osi_foo;
181
215
panda_register_callback (self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
182
216
}
217
+ PPP_REG_CB (" syscalls2" , on_sys_mmap_pgoff_return, linux_mmap_return);
218
+ printf (" [loaded] The plugin is supported on i386\n " );
219
+ #elif defined(TARGET_ARM) && !defined(TARGET_AARCH64)
220
+ {
221
+ panda_cb pcb;
222
+ pcb.before_block_exec = osi_foo;
223
+ panda_register_callback (self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
224
+ }
183
225
184
- PPP_REG_CB (" syscalls2" , on_sys_mmap_pgoff_return, linux_mmap_pgoff_return);
185
- // 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);
226
+ PPP_REG_CB (" syscalls2" , on_do_mmap2_return, linux_mmap_return);
227
+ printf (" [loaded] The plugin is supported on ARM 32-bits\n " );
228
+ #elif defined(TARGET_X86_64) || defined(TARGET_AARCH64)
229
+ {
230
+ panda_cb pcb;
231
+ pcb.before_block_exec = osi_foo;
232
+ panda_register_callback (self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
233
+ }
234
+ // Tell Plugin 'syscall2', that if a systemcall 'mmap' occurs, then run the code in 'linux_mmap_return'
235
+ // https://www.linuxquestions.org/questions/linux-general-1/difference-between-mmap2-syscall-and-mmap_pgoff-syscall-for-32-bit-linux-4175622986/
236
+ PPP_REG_CB (" syscalls2" , on_sys_mmap_return, linux_mmap_return);
237
+ printf (" [loaded] The plugin is supported on x86-64 and ARM 64-bits\n " );
188
238
#else
189
- fprintf (stderr, " The loaded plugin is not currently supported on this platform.\n " );
239
+ fprintf (stderr, " [ loaded] The plugin is not currently supported on this platform.\n " );
190
240
return false ;
191
241
#endif
192
242
return true ;
193
243
}
194
244
195
- void uninit_plugin (void *self) { }
245
+ void uninit_plugin (void *self) {
246
+ printf (" [loaded] uninit_plugin\n " );
247
+ }
0 commit comments