Skip to content

Commit e61aec9

Browse files
committed
Implement 64-bit loaded
1 parent 48bf566 commit e61aec9

File tree

2 files changed

+142
-62
lines changed

2 files changed

+142
-62
lines changed

panda/plugins/loaded/loaded.cpp

Lines changed: 113 additions & 26 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);
@@ -82,7 +82,9 @@ uint32_t guest_strncpy(CPUState *cpu, char *buf, size_t maxlen, target_ulong gue
8282

8383
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
8484
// 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) {
8688
if (debug) {
8789
printf("[loaded] mprotect()\n");
8890
}
@@ -94,39 +96,100 @@ void linux_old_mmap_return(CPUState *cpu, target_ulong pc, uint32_t arg_ptr) {
9496
}
9597
}
9698

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) {
98103
CPUArchState *env = (CPUArchState*)cpu->env_ptr;
99104
target_ulong asid = panda_current_asid(cpu);
100105
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);
102107
return;
103108
}
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);
106111
return;
107112
}
108113
OsiProc proc = running_procs[asid];
109114
char *filename = osi_linux_fd_to_filename(cpu, &proc, fd);
110115
// 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);
112117
// 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)) {
115119
if (debug) {
116120
printf ("[loaded] linux_mmap_pgoff(fd=%d filename=[%s] "
117121
"len=%d prot=%x flags=%x "
118122
"pgoff=%d)=" TARGET_FMT_lx "\n", (int) fd,
119123
filename, len, prot, flags, pgoff, env->regs[R_EAX]);
120124
}
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) {
123128
printf("[loaded] mapped executable section without a filename!\n");
124129
printf ("[loaded] linux_mmap_pgoff(fd=%d "
125130
"len=%d prot=%x flags=%x "
126131
"pgoff=%d)=" TARGET_FMT_lx "\n", (int) fd,
127132
len, prot, flags, pgoff, env->regs[R_EAX]);
128133
}
129134
}
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+
}
130193
#endif
131194

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

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

140-
//some sanity checks on what we think the current process is
203+
// some sanity checks on what we think the current process is
141204
// we couldn't find the current task
142-
if (!p) return;
205+
if (!p) {
206+
return;
207+
}
143208
// this means we didnt find current task
144-
if (p->taskd == 0) return;
209+
if (p->taskd == 0) {
210+
return;
211+
}
145212
// or the name
146-
if (p->name == 0) return;
213+
if (p->name == 0) {
214+
return;
215+
}
147216
// this is just not ok
148-
if (((int) p->pid) == -1) return;
217+
if (((int) p->pid) == -1) {
218+
return;
219+
}
149220
uint32_t n = strnlen(p->name, 32);
150221
// name is one char?
151-
if (n<2) return;
222+
if (n < 2) {
223+
return;
224+
}
152225
uint32_t np = 0;
153226
for (uint32_t i=0; i<n; i++) {
154227
np += (isprint(p->name[i]) != 0);
155228
}
156229
// name doesnt consist of solely printable characters
157230
// printf ("np=%d n=%d\n", np, n);
158-
if (np != n) return;
231+
if (np != n) {
232+
return;
233+
}
159234
target_ulong asid = panda_current_asid(cpu);
160235
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);
162237
}
163238
running_procs[asid] = *p;
164239
}
165-
166240
return;
167241
}
168-
bool init_plugin(void *self) {
169-
//panda_arg_list *args = panda_get_args("loaded");
170242

243+
bool init_plugin(void *self) {
171244
panda_require("osi");
172245
assert(init_osi_api());
173246
panda_require("osi_linux");
174247
assert(init_osi_linux_api());
175248
panda_require("syscalls2");
249+
panda_arg_list *args = panda_get_args("loaded");
250+
debug = panda_parse_bool_opt(args, "debug", "enable debug output");
176251

177252
#if defined(TARGET_I386) && !defined(TARGET_X86_64)
178253
{
@@ -183,10 +258,22 @@ bool init_plugin(void *self) {
183258

184259
PPP_REG_CB("syscalls2", on_sys_mmap_pgoff_return, linux_mmap_pgoff_return);
185260
// 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");
188275
#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");
190277
return false;
191278
#endif
192279
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)