Skip to content

Commit 3b310f7

Browse files
committed
Updating loaded for 64-bit systems
1 parent cc88392 commit 3b310f7

File tree

2 files changed

+138
-61
lines changed

2 files changed

+138
-61
lines changed

panda/plugins/loaded/loaded.cpp

Lines changed: 109 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ PANDAENDCOMMENT */
1818
#include <cstdio>
1919
#include <map>
2020
#include <memory>
21+
#include <sys/mman.h>
2122

2223
#include "panda/plugin.h"
2324
#include "panda/plugin_plugin.h"
@@ -52,14 +53,13 @@ PPP_PROT_REG_CB(on_library_load);
5253
// This creates the global for this call back fn (on_library_load)
5354
PPP_CB_BOILERPLATE(on_library_load)
5455

55-
bool debug = true;
56+
bool debug = false;
5657

5758
#define MAX_FILENAME 256
5859
std::map <target_ulong, OsiProc> running_procs;
5960

6061
void die(const char* fmt, ...) {
6162
va_list args;
62-
6363
va_start(args, fmt);
6464
vfprintf(stderr, fmt, args);
6565
va_end(args);
@@ -94,39 +94,99 @@ void linux_old_mmap_return(CPUState *cpu, target_ulong pc, uint32_t arg_ptr) {
9494
}
9595
}
9696

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) {
98101
CPUArchState *env = (CPUArchState*)cpu->env_ptr;
99102
target_ulong asid = panda_current_asid(cpu);
100103
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);
102105
return;
103106
}
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);
106109
return;
107110
}
108111
OsiProc proc = running_procs[asid];
109112
char *filename = osi_linux_fd_to_filename(cpu, &proc, fd);
110113
// 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);
112115
// 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)) {
115117
if (debug) {
116118
printf ("[loaded] linux_mmap_pgoff(fd=%d filename=[%s] "
117119
"len=%d prot=%x flags=%x "
118120
"pgoff=%d)=" TARGET_FMT_lx "\n", (int) fd,
119121
filename, len, prot, flags, pgoff, env->regs[R_EAX]);
120122
}
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) {
123126
printf("[loaded] mapped executable section without a filename!\n");
124127
printf ("[loaded] linux_mmap_pgoff(fd=%d "
125128
"len=%d prot=%x flags=%x "
126129
"pgoff=%d)=" TARGET_FMT_lx "\n", (int) fd,
127130
len, prot, flags, pgoff, env->regs[R_EAX]);
128131
}
129132
}
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+
}
130190
#endif
131191

132192
// get current process before each bb execs
@@ -137,42 +197,54 @@ void osi_foo(CPUState *cpu, TranslationBlock *tb) {
137197

138198
std::unique_ptr<OsiProc, decltype(free_osiproc)*> p { get_current_process(cpu), free_osiproc };
139199

140-
//some sanity checks on what we think the current process is
200+
// some sanity checks on what we think the current process is
141201
// we couldn't find the current task
142-
if (!p) return;
202+
if (!p) {
203+
return;
204+
}
143205
// this means we didnt find current task
144-
if (p->taskd == 0) return;
206+
if (p->taskd == 0) {
207+
return;
208+
}
145209
// or the name
146-
if (p->name == 0) return;
210+
if (p->name == 0) {
211+
return;
212+
}
147213
// this is just not ok
148-
if (((int) p->pid) == -1) return;
214+
if (((int) p->pid) == -1) {
215+
return;
216+
}
149217
uint32_t n = strnlen(p->name, 32);
150218
// name is one char?
151-
if (n<2) return;
219+
if (n < 2) {
220+
return;
221+
}
152222
uint32_t np = 0;
153223
for (uint32_t i=0; i<n; i++) {
154224
np += (isprint(p->name[i]) != 0);
155225
}
156226
// name doesnt consist of solely printable characters
157227
// printf ("np=%d n=%d\n", np, n);
158-
if (np != n) return;
228+
if (np != n) {
229+
return;
230+
}
159231
target_ulong asid = panda_current_asid(cpu);
160232
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);
162234
}
163235
running_procs[asid] = *p;
164236
}
165-
166237
return;
167238
}
168-
bool init_plugin(void *self) {
169-
//panda_arg_list *args = panda_get_args("loaded");
170239

240+
bool init_plugin(void *self) {
171241
panda_require("osi");
172242
assert(init_osi_api());
173243
panda_require("osi_linux");
174244
assert(init_osi_linux_api());
175245
panda_require("syscalls2");
246+
panda_arg_list *args = panda_get_args("loaded");
247+
debug = panda_parse_bool_opt(args, "debug", "enable debug output");
176248

177249
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
178250
{
@@ -183,10 +255,22 @@ bool init_plugin(void *self) {
183255

184256
PPP_REG_CB("syscalls2", on_sys_mmap_pgoff_return, linux_mmap_pgoff_return);
185257
// 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");
188272
#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");
190274
return false;
191275
#endif
192276
return true;

panda/plugins/loaded_libs/loaded_libs.cpp

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
#define __STDC_FORMAT_MACROS
22

33
#include <cstdio>
4-
54
#include "panda/plugin.h"
65

76
#include "syscalls2/syscalls_ext_typedefs.h"
87
#include "syscalls2/syscalls2_info.h"
98
#include "syscalls2/syscalls2_ext.h"
109

1110
extern "C" {
12-
13-
bool init_plugin(void *);
14-
void uninit_plugin(void *);
11+
bool init_plugin(void *);
12+
void uninit_plugin(void *);
1513

1614
#include "osi/osi_types.h"
1715
#include "osi/osi_ext.h"
1816
}
1917

20-
2118
#include<map>
2219
#include<vector>
2320
#include<set>
@@ -40,24 +37,31 @@ uint64_t get_libs_failed_count = 0;
4037
void get_libs(CPUState *env) {
4138

4239
get_libs_count ++;
43-
4440
bool fail = false;
4541
OsiProc *current = get_current_process(env);
46-
if (current == NULL) fail=true;
47-
if (program_name && strcmp(current->name, program_name)) fail=true;
48-
if (current->pid == 0) fail=true;
42+
if (current == NULL) {
43+
fail = true;
44+
}
45+
if (program_name && strcmp(current->name, program_name)) {
46+
fail = true;
47+
}
48+
if (current->pid == 0) {
49+
fail = true;
50+
}
4951
GArray *ms = get_mappings(env, current);
50-
if (ms == NULL) fail=true;
52+
if (ms == NULL) {
53+
fail = true;
54+
}
5155
OsiThread *thread = get_current_thread(env);
52-
if (thread == NULL) fail=true;
53-
56+
if (thread == NULL) {
57+
fail = true;
58+
}
5459
assert (pandalog);
5560

5661
if (fail) {
5762
get_libs_failed_count ++;
5863
}
5964
else {
60-
6165
Panda__LogEntry ple = PANDA__LOG_ENTRY__INIT;
6266
Panda__LoadedLibs ll = PANDA__LOADED_LIBS__INIT;
6367
Panda__Module** m = (Panda__Module **) malloc (sizeof (Panda__Module *) * ms->len);
@@ -90,7 +94,6 @@ void get_libs(CPUState *env) {
9094
ll.tid = thread->tid;
9195

9296
Asid asid = panda_current_asid(env);
93-
9497
ple.has_asid = true;
9598
ple.asid = asid;
9699
ple.asid_libraries = &ll;
@@ -106,54 +109,44 @@ void get_libs(CPUState *env) {
106109
cleanup_osi(current, thread, ms);
107110
}
108111

109-
110-
111112
// 9 long sys_mmap(
112-
113113
void mmap_return(CPUState *cpu, target_ulong pc, unsigned long addr, unsigned long length, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long offset) {
114114
get_libs(cpu);
115115
}
116116

117-
118117
uint64_t bb_count = 0;
119-
120118
void before_block(CPUState *env, TranslationBlock *tb) {
121-
122119
// check up on module list every 50 bb
123120
bb_count ++;
124121
if ((bb_count % 100) == 0) {
125122
get_libs(env);
126123
}
127-
128124
}
129125

130-
131126
bool init_plugin(void *self) {
132127
panda_require("osi");
133128
assert(init_osi_api());
134129
panda_require("syscalls2");
135130

136131
#ifdef TARGET_X86_64
137-
PPP_REG_CB("syscalls2", on_sys_mmap_return, mmap_return);
132+
PPP_REG_CB("syscalls2", on_sys_mmap_return, mmap_return);
133+
panda_cb pcb;
134+
pcb.before_block_exec = before_block;
135+
panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
136+
137+
panda_arg_list *args;
138+
args = panda_get_args("loaded_libs");
139+
program_name = panda_parse_string_opt(args, "program_name", NULL, "program name to collect libraries for");
140+
return true;
138141
#else
139-
/* #error "No on_sys_mmap_return for target" */
142+
/* #error "No on_sys_mmap_return for target" */
143+
printf("loaded_libs plugin is not available for this architecture");
144+
return false;
140145
#endif
141-
142-
panda_cb pcb;
143-
pcb.before_block_exec = before_block;
144-
panda_register_callback(self, PANDA_CB_BEFORE_BLOCK_EXEC, pcb);
145-
146-
panda_arg_list *args;
147-
args = panda_get_args("loaded_libs");
148-
program_name = panda_parse_string_opt(args, "program_name", NULL, "program name to collect libraries for");
149-
150-
return true;
151146
}
152147

153148
void uninit_plugin(void *self) {
154-
155149
cout << "get_libs_count = " << get_libs_count << "\n";
156150
cout << "get_libs_failed_count = " << get_libs_failed_count << "\n";
157151
cout << "frac = " << ((float) get_libs_failed_count) / get_libs_count << "\n";
158-
159152
}

0 commit comments

Comments
 (0)