diff --git a/Fichiers/ex1/copy_stdio.c b/Fichiers/ex1/copy_stdio.c new file mode 100644 index 0000000..26ce2a7 --- /dev/null +++ b/Fichiers/ex1/copy_stdio.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +#define BLOCK_SIZE 1 + + +int main(int argc, char *argv[]) +{ + FILE* fin, + * fout; + char buf[BLOCK_SIZE]; + + assert( argc == 3 ); + + fin = fopen(argv[1], "r"); + assert( fin != NULL ); + + fout = fopen(argv[2],"w"); + assert( fout != NULL ); + + while(1){ + ssize_t nb_read; + nb_read = fread(buf,BLOCK_SIZE,1,fin); + if (nb_read <= 0) + break; + fwrite(buf,BLOCK_SIZE,nb_read,fout); + } + + fclose(fin); + fclose(fout); + + return 0; +} + diff --git a/Fichiers/ex1/copy_sys.c b/Fichiers/ex1/copy_sys.c new file mode 100644 index 0000000..b45f423 --- /dev/null +++ b/Fichiers/ex1/copy_sys.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#define BLOCK_SIZE 1 + + +int main(int argc, char *argv[]) +{ + int fin, + fout; + char buf[BLOCK_SIZE]; + + assert( argc == 3 ); + + fin = open(argv[1],O_RDONLY); + assert( fin >= 0 ); + + fout = open(argv[2],O_CREAT|O_WRONLY|O_TRUNC,0600); + assert( fout >= 0 ); + + while(1){ + ssize_t nb_read; + nb_read = read(fin,buf,BLOCK_SIZE); + if (nb_read <= 0) + break; + write(fout,buf,nb_read); + } + + close(fin); + close(fout); + + return 0; +} + diff --git a/Fichiers/ex2/copy_mmap.c b/Fichiers/ex2/copy_mmap.c new file mode 100644 index 0000000..fde86a1 --- /dev/null +++ b/Fichiers/ex2/copy_mmap.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + assert(argc == 3); + + int fd_in = open(argv[1], O_RDONLY); + assert(fd_in >= 0); + + struct stat st; + fstat(fd_in, &st); + + // on mappe le fichier source en mémoire + void *src = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd_in, 0); + assert(src != MAP_FAILED); + + int fd_out = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, 0644); + assert(fd_out >= 0); + + // on fixe la taille du fichier de sortie + ftruncate(fd_out, st.st_size); + + // on mappe le fichier destination en mémoire + void *dst = mmap(NULL, st.st_size, PROT_WRITE, MAP_SHARED, fd_out, 0); + assert(dst != MAP_FAILED); + + // copie mémoire → mémoire + memcpy(dst, src, st.st_size); + + // nettoyage + munmap(src, st.st_size); + munmap(dst, st.st_size); + close(fd_in); + close(fd_out); + + return 0; +} diff --git a/Memoire/adresses_virtuelles.c b/Memoire/adresses_virtuelles.c new file mode 100644 index 0000000..d648757 --- /dev/null +++ b/Memoire/adresses_virtuelles.c @@ -0,0 +1,27 @@ +/* adresses virtuelles d'un processus */ + +#include +#include +#include +#include +#include + +int t[1000] = {[0 ... 999] = 2}; + +int main(int argc, char * argv[]) +{ + int i=3; + static int j = 3; + char * m = (char*)malloc(1); + printf("je suis le pid %d\n\n",getpid()); + /* ------- Affichage des adresses --------*/ + printf("main\t\t=\t%p\n",main); + printf("gettimeofday\t=\t%p\n",gettimeofday); + printf("&argc\t\t=\t%p\n",&argc); + printf("&i\t\t=\t%p\n",&i); + printf("&j\t\t=\t%p\n",&j); + printf("t\t\t=\t%p\n",t); + printf("m\t\t=\t%p\n",m); + + getchar(); +} diff --git a/Memoire/vmap.py b/Memoire/vmap.py new file mode 100755 index 0000000..ae3a643 --- /dev/null +++ b/Memoire/vmap.py @@ -0,0 +1,159 @@ +#!/usr/bin/python +# coding=utf-8 + +"""Tool to analyze and display the contents of /proc//maps""" + +import re +import itertools +import argparse +from dataclasses import dataclass + +MAPS_LINE_RE = re.compile(r""" + (?P[0-9a-f]+)-(?P[0-9a-f]+)\s+ # Address + (?P\S+)\s+ # Permissions + (?P[0-9a-f]+)\s+ # Map offset + (?P\S+)\s+ # Device node + (?P\d+)\s+ # Inode + (?P.*)\s+ # Pathname +""", re.VERBOSE) + + +def human_bytes(size): + modifier = 1 + while size > 1024: + modifier *= 1024 + size /= 1024 + return "%.1f%s" % (size, { + 1024**0: 'b', + 1024**1: 'k', + 1024**2: 'M', + 1024**3: 'G', + 1024**4: 'T', + }.get(modifier, " x%d" % modifier)) + + +@dataclass +class Record: + addr_start: int + addr_end: int + perms: str + offset: int + dev: str + inode: int + pathname: str + + @property + def size(self): + return self.addr_end - self.addr_start + + @property + def human_size(self): + return human_bytes(self.size) + + @property + def readable(self): + return self.perms[0] == "r" + + @property + def writable(self): + return self.perms[1] == "w" + + @property + def executable(self): + return self.perms[2] == "x" + + @property + def shared(self): + return self.perms[3] == "s" + + @property + def private(self): + return self.perms[3] == "p" + + @classmethod + def parse(self, pid): + records = [] + with open("/proc/%d/maps" % pid) as fd: + for line in fd: + m = MAPS_LINE_RE.match(line) + if not m: + print("Skipping: %s" % line) + continue + addr_start, addr_end, perms, offset, dev, inode, pathname = m.groups() + addr_start = int(addr_start, 16) + addr_end = int(addr_end, 16) + offset = int(offset, 16) + records.append(Record( + addr_start=addr_start, + addr_end=addr_end, + perms=perms, + offset=offset, + dev=dev, + inode=inode, + pathname=pathname, + )) + return records + + @classmethod + def aggregate(self, records, only_used=False, only_private=False): + + named_records = {} + anonymous_records = [] + for record in records: + if only_private and not record.private: + continue + if only_used and not record.readable and not record.writable and not record.shared and not record.pathname: + continue + if record.pathname: + if record.pathname in named_records: + other = named_records[record.pathname] + named_records[record.pathname] = Record( + min(record.addr_start, other.addr_start), + max(record.addr_end, other.addr_end), + perms=''.join("?" if c1 != c2 else c1 for c1, c2 in zip(record.perms, other.perms)), + offset=0, + dev='', + inode='', + pathname=record.pathname, + ) + else: + named_records[record.pathname] = record + else: + anonymous_records.append(record) + + return list(sorted( + itertools.chain(anonymous_records, named_records.values()), + key=lambda r: r.size, + reverse=True, + )) + + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("pid", type=int, help="Process identifier (pid)") + parser.add_argument("--only-used", "-u", action="store_true", help="Only show used pages (non readable, writable, executable and private pages)") + parser.add_argument("--only-private", "-p", action="store_true", help="Only show private pages") + args = parser.parse_args() + + records = Record.parse(args.pid) + #records = Record.aggregate(records, only_used=args.only_used, only_private=args.only_private) + + print("\t".join([ + "% 16s" % "Start of range", + "% 16s" % "End of range", + "% 12s" % "Size", + "% 4s" % "Perms", + "Path", + ])) + for record in records: + print("\t".join([ + "%016x" % record.addr_start, + "%016x" % record.addr_end, + "% 12s" % record.human_size, + "% 4s" % record.perms, + record.pathname, + ])) + + print("") + print("Total: %s" % human_bytes(sum(r.size for r in records)))