diff options
Diffstat (limited to 'qemu_mode/libcompcov')
-rw-r--r-- | qemu_mode/libcompcov/Makefile | 8 | ||||
-rw-r--r-- | qemu_mode/libcompcov/README.md (renamed from qemu_mode/libcompcov/README.compcov) | 16 | ||||
-rw-r--r-- | qemu_mode/libcompcov/compcovtest.cc | 32 | ||||
-rw-r--r-- | qemu_mode/libcompcov/libcompcov.so.c | 213 | ||||
-rw-r--r-- | qemu_mode/libcompcov/pmparser.h | 434 |
5 files changed, 412 insertions, 291 deletions
diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile index c984588b..d078ae06 100644 --- a/qemu_mode/libcompcov/Makefile +++ b/qemu_mode/libcompcov/Makefile @@ -18,25 +18,25 @@ HELPER_PATH = $(PREFIX)/lib/afl VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) -CFLAGS ?= -O3 -funroll-loops +CFLAGS ?= -O3 -funroll-loops -I ../../include/ CFLAGS += -Wall -Wno-unused-result -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign LDFLAGS += -ldl all: libcompcov.so compcovtest libcompcov.so: libcompcov.so.c ../../config.h - $(CC) $(CFLAGS) -shared -fPIC $< -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) -shared -fPIC $< -o ../../$@ $(LDFLAGS) .NOTPARALLEL: clean clean: rm -f *.o *.so *~ a.out core core.[1-9][0-9]* - rm -f libcompcov.so compcovtest + rm -f ../../libcompcov.so compcovtest compcovtest: compcovtest.cc $(CXX) $< -o $@ install: all - install -m 755 libcompcov.so $${DESTDIR}$(HELPER_PATH) + install -m 755 ../../libcompcov.so $${DESTDIR}$(HELPER_PATH) install -m 644 README.compcov $${DESTDIR}$(HELPER_PATH) diff --git a/qemu_mode/libcompcov/README.compcov b/qemu_mode/libcompcov/README.md index 2a4a0ee5..5aaa3dd8 100644 --- a/qemu_mode/libcompcov/README.compcov +++ b/qemu_mode/libcompcov/README.md @@ -1,10 +1,8 @@ -================================================================ -strcmp() / memcmp() CompareCoverage library for AFLplusplus-QEMU -================================================================ +# strcmp() / memcmp() CompareCoverage library for afl++ QEMU Written by Andrea Fioraldi <andreafioraldi@gmail.com> -This Linux-only companion library allows you to instrument strcmp(), memcmp(), +This Linux-only companion library allows you to instrument `strcmp()`, `memcmp()`, and related functions to log the CompareCoverage of these libcalls. Use this with caution. While this can speedup a lot the bypass of hard @@ -18,14 +16,20 @@ For optimized binaries this is an issue, those functions are often inlined and this module is not capable to log the coverage in this case. If you have the source code of the fuzzing target you should nto use this -library and QEMU but build ot with afl-clang-fast and the laf-intel options. +library and QEMU but build it with afl-clang-fast and the laf-intel options. To use this library make sure to preload it with AFL_PRELOAD. +``` export AFL_PRELOAD=/path/to/libcompcov.so - export AFL_QEMU_COMPCOV=1 + export AFL_COMPCOV_LEVEL=1 afl-fuzz -Q -i input -o output <your options> -- <target args> +``` + +The AFL_COMPCOV_LEVEL tells to QEMU and libcompcov how to log comaprisons. +Level 1 logs just comparison with immediates / read-only memory and level 2 +logs all the comparisons. The library make use of https://github.com/ouadev/proc_maps_parser and so it is Linux specific. However this is not a strict dependency, other UNIX operating diff --git a/qemu_mode/libcompcov/compcovtest.cc b/qemu_mode/libcompcov/compcovtest.cc index fd1fda00..171e4526 100644 --- a/qemu_mode/libcompcov/compcovtest.cc +++ b/qemu_mode/libcompcov/compcovtest.cc @@ -3,13 +3,13 @@ // Author: Mateusz Jurczyk (mjurczyk@google.com) // // Copyright 2019 Google LLC -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // https://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -17,7 +17,8 @@ // limitations under the License. // -// solution: echo -ne 'The quick brown fox jumps over the lazy dog\xbe\xba\xfe\xca\xbe\xba\xfe\xca\xde\xc0\xad\xde\xef\xbe' | ./compcovtest +// solution: echo -ne 'The quick brown fox jumps over the lazy +// dog\xbe\xba\xfe\xca\xbe\xba\xfe\xca\xde\xc0\xad\xde\xef\xbe' | ./compcovtest #include <cstdint> #include <cstdio> @@ -25,39 +26,40 @@ #include <cstring> int main() { - char buffer[44] = { /* zero padding */ }; + + char buffer[44] = {/* zero padding */}; fread(buffer, 1, sizeof(buffer) - 1, stdin); if (memcmp(&buffer[0], "The quick brown fox ", 20) != 0 || strncmp(&buffer[20], "jumps over ", 11) != 0 || strcmp(&buffer[31], "the lazy dog") != 0) { + return 1; + } uint64_t x = 0; fread(&x, sizeof(x), 1, stdin); - if (x != 0xCAFEBABECAFEBABE) { - return 2; - } + if (x != 0xCAFEBABECAFEBABE) { return 2; } uint32_t y = 0; fread(&y, sizeof(y), 1, stdin); - if (y != 0xDEADC0DE) { - return 3; - } + if (y != 0xDEADC0DE) { return 3; } uint16_t z = 0; fread(&z, sizeof(z), 1, stdin); switch (z) { - case 0xBEEF: - break; + + case 0xBEEF: break; - default: - return 4; + default: return 4; + } printf("Puzzle solved, congrats!\n"); abort(); return 0; + } + diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c index 582230db..dd9e2773 100644 --- a/qemu_mode/libcompcov/libcompcov.so.c +++ b/qemu_mode/libcompcov/libcompcov.so.c @@ -5,7 +5,7 @@ Written and maintained by Andrea Fioraldi <andreafioraldi@gmail.com> - Copyright 2019 Andrea Fioraldi. All rights reserved. + Copyright 2019 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -27,23 +27,24 @@ #include <sys/types.h> #include <sys/shm.h> -#include "../../types.h" -#include "../../config.h" +#include "types.h" +#include "config.h" #include "pmparser.h" #ifndef __linux__ -# error "Sorry, this library is Linux-specific for now!" -#endif /* !__linux__ */ +#error "Sorry, this library is Linux-specific for now!" +#endif /* !__linux__ */ /* Change this value to tune the compare coverage */ #define MAX_CMP_LENGTH 32 -static void *__compcov_code_start, - *__compcov_code_end; +static void *__compcov_code_start, *__compcov_code_end; -static u8 *__compcov_afl_map; +static u8* __compcov_afl_map; + +static u32 __compcov_level; static int (*__libc_strcmp)(const char*, const char*); static int (*__libc_strncmp)(const char*, const char*, size_t); @@ -53,27 +54,54 @@ static int (*__libc_memcmp)(const void*, const void*, size_t); static int debug_fd = -1; +#define MAX_MAPPINGS 1024 + +static struct mapping { void *st, *en; } __compcov_ro[MAX_MAPPINGS]; + +static u32 __compcov_ro_cnt; + +/* Check an address against the list of read-only mappings. */ + +static u8 __compcov_is_ro(const void* ptr) { + + u32 i; + + for (i = 0; i < __compcov_ro_cnt; i++) + if (ptr >= __compcov_ro[i].st && ptr <= __compcov_ro[i].en) return 1; + + return 0; + +} + +static size_t __strlen2(const char* s1, const char* s2, size_t max_length) { -static size_t __strlen2(const char *s1, const char *s2, size_t max_length) { // from https://github.com/googleprojectzero/CompareCoverage - + size_t len = 0; - for (; len < max_length && s1[len] != '\0' && s2[len] != '\0'; len++) { } + for (; len < max_length && s1[len] != '\0' && s2[len] != '\0'; len++) {} return len; + } /* Identify the binary boundaries in the memory mapping */ static void __compcov_load(void) { - + __libc_strcmp = dlsym(RTLD_NEXT, "strcmp"); __libc_strncmp = dlsym(RTLD_NEXT, "strncmp"); __libc_strcasecmp = dlsym(RTLD_NEXT, "strcasecmp"); __libc_strncasecmp = dlsym(RTLD_NEXT, "strncasecmp"); __libc_memcmp = dlsym(RTLD_NEXT, "memcmp"); - - char *id_str = getenv(SHM_ENV_VAR); - int shm_id; + + if (getenv("AFL_QEMU_COMPCOV")) { __compcov_level = 1; } + if (getenv("AFL_COMPCOV_LEVEL")) { + + __compcov_level = atoi(getenv("AFL_COMPCOV_LEVEL")); + + } + + char* id_str = getenv(SHM_ENV_VAR); + int shm_id; if (id_str) { @@ -81,55 +109,72 @@ static void __compcov_load(void) { __compcov_afl_map = shmat(shm_id, NULL, 0); if (__compcov_afl_map == (void*)-1) exit(1); + } else { - + __compcov_afl_map = calloc(1, MAP_SIZE); + } if (getenv("AFL_INST_LIBS")) { - + __compcov_code_start = (void*)0; __compcov_code_end = (void*)-1; return; + } char* bin_name = getenv("AFL_COMPCOV_BINNAME"); procmaps_iterator* maps = pmparser_parse(-1); - procmaps_struct* maps_tmp = NULL; + procmaps_struct* maps_tmp = NULL; while ((maps_tmp = pmparser_next(maps)) != NULL) { - + /* If AFL_COMPCOV_BINNAME is not set pick the first executable segment */ if (!bin_name || strstr(maps_tmp->pathname, bin_name) != NULL) { - + if (maps_tmp->is_x) { - if (!__compcov_code_start) - __compcov_code_start = maps_tmp->addr_start; - if (!__compcov_code_end) - __compcov_code_end = maps_tmp->addr_end; + + if (!__compcov_code_start) __compcov_code_start = maps_tmp->addr_start; + if (!__compcov_code_end) __compcov_code_end = maps_tmp->addr_end; + } + } + + if ((maps_tmp->is_w && !maps_tmp->is_r) || __compcov_ro_cnt == MAX_MAPPINGS) + continue; + + __compcov_ro[__compcov_ro_cnt].st = maps_tmp->addr_start; + __compcov_ro[__compcov_ro_cnt].en = maps_tmp->addr_end; + } pmparser_free(maps); -} +} static void __compcov_trace(u64 cur_loc, const u8* v0, const u8* v1, size_t n) { size_t i; - + if (debug_fd != 1) { + char debugbuf[4096]; - snprintf(debugbuf, sizeof(debugbuf), "0x%llx %s %s %lu\n", cur_loc, v0 == NULL ? "(null)" : (char*)v0, v1 == NULL ? "(null)" : (char*)v1, n); + snprintf(debugbuf, sizeof(debugbuf), "0x%llx %s %s %lu\n", cur_loc, + v0 == NULL ? "(null)" : (char*)v0, + v1 == NULL ? "(null)" : (char*)v1, n); write(debug_fd, debugbuf, strlen(debugbuf)); + } - + for (i = 0; i < n && v0[i] == v1[i]; ++i) { - - __compcov_afl_map[cur_loc +i]++; + + __compcov_afl_map[cur_loc + i]++; + } + } /* Check an address against the list of read-only mappings. */ @@ -137,8 +182,8 @@ static void __compcov_trace(u64 cur_loc, const u8* v0, const u8* v1, size_t n) { static u8 __compcov_is_in_bound(const void* ptr) { return ptr >= __compcov_code_start && ptr < __compcov_code_end; -} +} /* Replacements for strcmp(), memcmp(), and so on. Note that these will be used only if the target is compiled with -fno-builtins and linked dynamically. */ @@ -148,122 +193,145 @@ static u8 __compcov_is_in_bound(const void* ptr) { int strcmp(const char* str1, const char* str2) { void* retaddr = __builtin_return_address(0); - - if (__compcov_is_in_bound(retaddr)) { - size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH +1); - + if (__compcov_is_in_bound(retaddr) && + !(__compcov_level < 2 && !__compcov_is_ro(str1) && + !__compcov_is_ro(str2))) { + + size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH + 1); + if (n <= MAX_CMP_LENGTH) { - + u64 cur_loc = (u64)retaddr; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); cur_loc &= MAP_SIZE - 1; - + __compcov_trace(cur_loc, str1, str2, n); + } + } return __libc_strcmp(str1, str2); -} +} #undef strncmp int strncmp(const char* str1, const char* str2, size_t len) { void* retaddr = __builtin_return_address(0); - - if (__compcov_is_in_bound(retaddr)) { - size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH +1); + if (__compcov_is_in_bound(retaddr) && + !(__compcov_level < 2 && !__compcov_is_ro(str1) && + !__compcov_is_ro(str2))) { + + size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH + 1); n = MIN(n, len); - + if (n <= MAX_CMP_LENGTH) { - + u64 cur_loc = (u64)retaddr; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); cur_loc &= MAP_SIZE - 1; - + __compcov_trace(cur_loc, str1, str2, n); + } + } - + return __libc_strncmp(str1, str2, len); -} +} #undef strcasecmp int strcasecmp(const char* str1, const char* str2) { void* retaddr = __builtin_return_address(0); - - if (__compcov_is_in_bound(retaddr)) { + + if (__compcov_is_in_bound(retaddr) && + !(__compcov_level < 2 && !__compcov_is_ro(str1) && + !__compcov_is_ro(str2))) { + /* Fallback to strcmp, maybe improve in future */ - size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH +1); - + size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH + 1); + if (n <= MAX_CMP_LENGTH) { - + u64 cur_loc = (u64)retaddr; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); cur_loc &= MAP_SIZE - 1; - + __compcov_trace(cur_loc, str1, str2, n); + } + } return __libc_strcasecmp(str1, str2); -} +} #undef strncasecmp int strncasecmp(const char* str1, const char* str2, size_t len) { void* retaddr = __builtin_return_address(0); - - if (__compcov_is_in_bound(retaddr)) { + + if (__compcov_is_in_bound(retaddr) && + !(__compcov_level < 2 && !__compcov_is_ro(str1) && + !__compcov_is_ro(str2))) { + /* Fallback to strncmp, maybe improve in future */ - size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH +1); + size_t n = __strlen2(str1, str2, MAX_CMP_LENGTH + 1); n = MIN(n, len); - + if (n <= MAX_CMP_LENGTH) { - + u64 cur_loc = (u64)retaddr; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); cur_loc &= MAP_SIZE - 1; - + __compcov_trace(cur_loc, str1, str2, n); + } + } return __libc_strncasecmp(str1, str2, len); -} +} #undef memcmp int memcmp(const void* mem1, const void* mem2, size_t len) { void* retaddr = __builtin_return_address(0); - - if (__compcov_is_in_bound(retaddr)) { + + if (__compcov_is_in_bound(retaddr) && + !(__compcov_level < 2 && !__compcov_is_ro(mem1) && + !__compcov_is_ro(mem2))) { size_t n = len; - + if (n <= MAX_CMP_LENGTH) { - + u64 cur_loc = (u64)retaddr; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); cur_loc &= MAP_SIZE - 1; - + __compcov_trace(cur_loc, mem1, mem2, n); + } + } return __libc_memcmp(mem1, mem2, len); + } /* Init code to open init the library. */ @@ -271,9 +339,10 @@ int memcmp(const void* mem1, const void* mem2, size_t len) { __attribute__((constructor)) void __compcov_init(void) { if (getenv("AFL_QEMU_COMPCOV_DEBUG") != NULL) - debug_fd = open("compcov.debug", O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); + debug_fd = + open("compcov.debug", O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0644); __compcov_load(); -} +} diff --git a/qemu_mode/libcompcov/pmparser.h b/qemu_mode/libcompcov/pmparser.h index 34d0cd50..e7fcf187 100644 --- a/qemu_mode/libcompcov/pmparser.h +++ b/qemu_mode/libcompcov/pmparser.h @@ -24,43 +24,49 @@ implied warranty. #include <errno.h> #include <linux/limits.h> -//maximum line length in a procmaps file -#define PROCMAPS_LINE_MAX_LENGTH (PATH_MAX + 100) +// maximum line length in a procmaps file +#define PROCMAPS_LINE_MAX_LENGTH (PATH_MAX + 100) /** * procmaps_struct * @desc hold all the information about an area in the process's VM */ -typedef struct procmaps_struct{ - void* addr_start; //< start address of the area - void* addr_end; //< end address - unsigned long length; //< size of the range - - char perm[5]; //< permissions rwxp - short is_r; //< rewrote of perm with short flags - short is_w; - short is_x; - short is_p; - - long offset; //< offset - char dev[12]; //< dev major:minor - int inode; //< inode of the file that backs the area - - char pathname[600]; //< the path of the file that backs the area - //chained list - struct procmaps_struct* next; //<handler of the chinaed list +typedef struct procmaps_struct { + + void* addr_start; //< start address of the area + void* addr_end; //< end address + unsigned long length; //< size of the range + + char perm[5]; //< permissions rwxp + short is_r; //< rewrote of perm with short flags + short is_w; + short is_x; + short is_p; + + long offset; //< offset + char dev[12]; //< dev major:minor + int inode; //< inode of the file that backs the area + + char pathname[600]; //< the path of the file that backs the area + // chained list + struct procmaps_struct* next; //<handler of the chinaed list + } procmaps_struct; /** * procmaps_iterator * @desc holds iterating information */ -typedef struct procmaps_iterator{ - procmaps_struct* head; - procmaps_struct* current; +typedef struct procmaps_iterator { + + procmaps_struct* head; + procmaps_struct* current; + } procmaps_iterator; + /** * pmparser_parse - * @param pid the process id whose memory map to be parser. the current process if pid<0 + * @param pid the process id whose memory map to be parser. the current process + * if pid<0 * @return an iterator over all the nodes */ procmaps_iterator* pmparser_parse(int pid); @@ -83,198 +89,238 @@ void pmparser_free(procmaps_iterator* p_procmaps_it); * _pmparser_split_line * @description internal usage */ -void _pmparser_split_line(char*buf,char*addr1,char*addr2,char*perm, char* offset, char* device,char*inode,char* pathname); +void _pmparser_split_line(char* buf, char* addr1, char* addr2, char* perm, + char* offset, char* device, char* inode, + char* pathname); /** * pmparser_print * @param map the head of the list * @order the order of the area to print, -1 to print everything */ -void pmparser_print(procmaps_struct* map,int order); - +void pmparser_print(procmaps_struct* map, int order); /** * gobal variables */ -//procmaps_struct* g_last_head=NULL; -//procmaps_struct* g_current=NULL; - - -procmaps_iterator* pmparser_parse(int pid){ - procmaps_iterator* maps_it = malloc(sizeof(procmaps_iterator)); - char maps_path[500]; - if(pid>=0 ){ - sprintf(maps_path,"/proc/%d/maps",pid); - }else{ - sprintf(maps_path,"/proc/self/maps"); - } - FILE* file=fopen(maps_path,"r"); - if(!file){ - fprintf(stderr,"pmparser : cannot open the memory maps, %s\n",strerror(errno)); - return NULL; - } - int ind=0;char buf[PROCMAPS_LINE_MAX_LENGTH]; - //int c; - procmaps_struct* list_maps=NULL; - procmaps_struct* tmp; - procmaps_struct* current_node=list_maps; - char addr1[20],addr2[20], perm[8], offset[20], dev[10],inode[30],pathname[PATH_MAX]; - while( !feof(file) ){ - fgets(buf,PROCMAPS_LINE_MAX_LENGTH,file); - //allocate a node - tmp=(procmaps_struct*)malloc(sizeof(procmaps_struct)); - //fill the node - _pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname); - //printf("#%s",buf); - //printf("%s-%s %s %s %s %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname); - //addr_start & addr_end - //unsigned long l_addr_start; - sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start ); - sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end ); - //size - tmp->length=(unsigned long)(tmp->addr_end-tmp->addr_start); - //perm - strcpy(tmp->perm,perm); - tmp->is_r=(perm[0]=='r'); - tmp->is_w=(perm[1]=='w'); - tmp->is_x=(perm[2]=='x'); - tmp->is_p=(perm[3]=='p'); - - //offset - sscanf(offset,"%lx",&tmp->offset ); - //device - strcpy(tmp->dev,dev); - //inode - tmp->inode=atoi(inode); - //pathname - strcpy(tmp->pathname,pathname); - tmp->next=NULL; - //attach the node - if(ind==0){ - list_maps=tmp; - list_maps->next=NULL; - current_node=list_maps; - } - current_node->next=tmp; - current_node=tmp; - ind++; - //printf("%s",buf); - } - - //close file - fclose(file); - - - //g_last_head=list_maps; - maps_it->head = list_maps; - maps_it->current = list_maps; - return maps_it; +// procmaps_struct* g_last_head=NULL; +// procmaps_struct* g_current=NULL; + +procmaps_iterator* pmparser_parse(int pid) { + + procmaps_iterator* maps_it = malloc(sizeof(procmaps_iterator)); + char maps_path[500]; + if (pid >= 0) { + + sprintf(maps_path, "/proc/%d/maps", pid); + + } else { + + sprintf(maps_path, "/proc/self/maps"); + + } + + FILE* file = fopen(maps_path, "r"); + if (!file) { + + fprintf(stderr, "pmparser : cannot open the memory maps, %s\n", + strerror(errno)); + return NULL; + + } + + int ind = 0; + char buf[PROCMAPS_LINE_MAX_LENGTH]; + // int c; + procmaps_struct* list_maps = NULL; + procmaps_struct* tmp; + procmaps_struct* current_node = list_maps; + char addr1[20], addr2[20], perm[8], offset[20], dev[10], inode[30], + pathname[PATH_MAX]; + while (!feof(file)) { + + fgets(buf, PROCMAPS_LINE_MAX_LENGTH, file); + // allocate a node + tmp = (procmaps_struct*)malloc(sizeof(procmaps_struct)); + // fill the node + _pmparser_split_line(buf, addr1, addr2, perm, offset, dev, inode, pathname); + // printf("#%s",buf); + // printf("%s-%s %s %s %s + // %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname); addr_start & + // addr_end unsigned long l_addr_start; + sscanf(addr1, "%lx", (long unsigned*)&tmp->addr_start); + sscanf(addr2, "%lx", (long unsigned*)&tmp->addr_end); + // size + tmp->length = (unsigned long)(tmp->addr_end - tmp->addr_start); + // perm + strcpy(tmp->perm, perm); + tmp->is_r = (perm[0] == 'r'); + tmp->is_w = (perm[1] == 'w'); + tmp->is_x = (perm[2] == 'x'); + tmp->is_p = (perm[3] == 'p'); + + // offset + sscanf(offset, "%lx", &tmp->offset); + // device + strcpy(tmp->dev, dev); + // inode + tmp->inode = atoi(inode); + // pathname + strcpy(tmp->pathname, pathname); + tmp->next = NULL; + // attach the node + if (ind == 0) { + + list_maps = tmp; + list_maps->next = NULL; + current_node = list_maps; + + } + + current_node->next = tmp; + current_node = tmp; + ind++; + // printf("%s",buf); + + } + + // close file + fclose(file); + + // g_last_head=list_maps; + maps_it->head = list_maps; + maps_it->current = list_maps; + return maps_it; + } +procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it) { -procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){ - if(p_procmaps_it->current == NULL) - return NULL; - procmaps_struct* p_current = p_procmaps_it->current; - p_procmaps_it->current = p_procmaps_it->current->next; - return p_current; - /* - if(g_current==NULL){ - g_current=g_last_head; - }else - g_current=g_current->next; - - return g_current; - */ -} + if (p_procmaps_it->current == NULL) return NULL; + procmaps_struct* p_current = p_procmaps_it->current; + p_procmaps_it->current = p_procmaps_it->current->next; + return p_current; + /* + if(g_current==NULL){ + + g_current=g_last_head; + }else + g_current=g_current->next; -void pmparser_free(procmaps_iterator* p_procmaps_it){ - procmaps_struct* maps_list = p_procmaps_it->head; - if(maps_list==NULL) return ; - procmaps_struct* act=maps_list; - procmaps_struct* nxt=act->next; - while(act!=NULL){ - free(act); - act=nxt; - if(nxt!=NULL) - nxt=nxt->next; - } + return g_current; + */ } +void pmparser_free(procmaps_iterator* p_procmaps_it) { + + procmaps_struct* maps_list = p_procmaps_it->head; + if (maps_list == NULL) return; + procmaps_struct* act = maps_list; + procmaps_struct* nxt = act->next; + while (act != NULL) { -void _pmparser_split_line( - char*buf,char*addr1,char*addr2, - char*perm,char* offset,char* device,char*inode, - char* pathname){ - // - int orig=0; - int i=0; - //addr1 - while(buf[i]!='-'){ - addr1[i-orig]=buf[i]; - i++; - } - addr1[i]='\0'; - i++; - //addr2 - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - addr2[i-orig]=buf[i]; - i++; - } - addr2[i-orig]='\0'; - - //perm - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - perm[i-orig]=buf[i]; - i++; - } - perm[i-orig]='\0'; - //offset - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - offset[i-orig]=buf[i]; - i++; - } - offset[i-orig]='\0'; - //dev - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - device[i-orig]=buf[i]; - i++; - } - device[i-orig]='\0'; - //inode - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - inode[i-orig]=buf[i]; - i++; - } - inode[i-orig]='\0'; - //pathname - pathname[0]='\0'; - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' ' && buf[i]!='\n'){ - pathname[i-orig]=buf[i]; - i++; - } - pathname[i-orig]='\0'; + free(act); + act = nxt; + if (nxt != NULL) nxt = nxt->next; + + } } +void _pmparser_split_line(char* buf, char* addr1, char* addr2, char* perm, + char* offset, char* device, char* inode, + char* pathname) { + + // + int orig = 0; + int i = 0; + // addr1 + while (buf[i] != '-') { + + addr1[i - orig] = buf[i]; + i++; + + } + + addr1[i] = '\0'; + i++; + // addr2 + orig = i; + while (buf[i] != '\t' && buf[i] != ' ') { + + addr2[i - orig] = buf[i]; + i++; + + } + + addr2[i - orig] = '\0'; + + // perm + while (buf[i] == '\t' || buf[i] == ' ') + i++; + orig = i; + while (buf[i] != '\t' && buf[i] != ' ') { + + perm[i - orig] = buf[i]; + i++; + + } + + perm[i - orig] = '\0'; + // offset + while (buf[i] == '\t' || buf[i] == ' ') + i++; + orig = i; + while (buf[i] != '\t' && buf[i] != ' ') { + + offset[i - orig] = buf[i]; + i++; + + } + + offset[i - orig] = '\0'; + // dev + while (buf[i] == '\t' || buf[i] == ' ') + i++; + orig = i; + while (buf[i] != '\t' && buf[i] != ' ') { + + device[i - orig] = buf[i]; + i++; + + } + + device[i - orig] = '\0'; + // inode + while (buf[i] == '\t' || buf[i] == ' ') + i++; + orig = i; + while (buf[i] != '\t' && buf[i] != ' ') { + + inode[i - orig] = buf[i]; + i++; + + } + + inode[i - orig] = '\0'; + // pathname + pathname[0] = '\0'; + while (buf[i] == '\t' || buf[i] == ' ') + i++; + orig = i; + while (buf[i] != '\t' && buf[i] != ' ' && buf[i] != '\n') { + + pathname[i - orig] = buf[i]; + i++; + + } + + pathname[i - orig] = '\0'; + +} #endif + |