diff --git a/aulas/08-processos/a.out b/aulas/08-processos/a.out deleted file mode 100755 index 1854ff7..0000000 Binary files a/aulas/08-processos/a.out and /dev/null differ diff --git a/aulas/08-processos/mmap/#main.c# b/aulas/08-processos/mmap/#main.c# deleted file mode 100644 index cb4ca46..0000000 --- a/aulas/08-processos/mmap/#main.c# +++ /dev/null @@ -1,99 +0,0 @@ -#include -#include -#include -#include - - -#define LINE_LEN 256 // Quantidade de bytes para as linhas. -#define PATH_LEN 256 // Quantidade de bytes para os caminhos. -#define PERM_LEN 5 // Quantidade de bytes para as permissões. -#define PROG_END 5 // Fim das linhas do programa. - -typedef unsigned long u64t; -typedef int i32t; - -void read_maps(void); - - -int main(void) { - read_maps(); - return 0; -} - - -/* - * Lê e imprime o conteúdo de /proc/self/maps filtrando - * as faixas dos segmentos de memória. - */ -void read_maps(void) { - // Define um descritor de arquivos para ler /proc/self/maps... - FILE *fd = fopen("/proc/self/maps", "r"); - - // Terminar no caso de erro... - if (!fd) { - perror("Erro ao abrir /proc/self/maps"); - exit(EXIT_FAILURE); - } - - char line[LINE_LEN]; // Linhas lidas do arquivo. - u64t start; // Endereço inicial. - u64t end; // Endereço final. - char perm[PERM_LEN]; // Permissões. - char path[PATH_LEN]; // Caminho do arquivo carregado. - i32t current_line = 1; // Linha atual. - - // Itera as linhas de /proc/self/maps... - while (fgets(line, sizeof(line), fd)) { - - // Zera a string em 'path'... - path[0] = '\0'; - - /* - * Analisa a linha conforme os campos de /proc/self/maps: - * ADDR_START-ADDR_END PERM FILE_OFFSET DEVICE INODE FILE_PATH - */ - sscanf(line, "%lx-%lx %4s %*s %*s %*s %255[^\n]", &start, &end, perm, path); - - // Impressão dos segmentos do código... - if (current_line <= PROG_END) { - printf("0x%lx-0x%lx %s --> ", start, end, perm); - switch (current_line) { - case 1: - puts("Tabela de cabeçalhos do programa"); - break; - case 2: - puts("Código do programa (.text)"); - break; - case 3: - puts("Dados constantes (.rodata)"); - break; - case 4: - puts("Tabela de dados globais e dinâmicos"); - break; - case 5: - puts("Variáveis globais e estáticas (.data e .bss)"); - break; - } - current_line++; - continue; - } - - // Impressão da faixa do HEAP... - if (strstr(path, "[heap]")) { - printf("0x%lx-0x%lx %s --> [HEAP]\n", start, end, perm); - continue; - } - - // Impressão da faixa da STACK... - if (strstr(path, "[stack]")) { - printf("0x%lx-0x%lx %s --> [STACK]\n", start, end, perm); - continue; - } - - // Demais linhas com caminho... - if (path[0] != '\0') printf("0x%lx-0x%lx %s --> %s\n", start, end, perm, path); - } - - // Fecha o descritor de arquivos... - fclose(fd); -} diff --git a/aulas/08-processos/mmap/a.out b/aulas/08-processos/mmap/a.out deleted file mode 100755 index 5f34bee..0000000 Binary files a/aulas/08-processos/mmap/a.out and /dev/null differ diff --git a/aulas/08-processos/old/README.org b/aulas/08-processos/old/README.org deleted file mode 100644 index e79c5d4..0000000 --- a/aulas/08-processos/old/README.org +++ /dev/null @@ -1,229 +0,0 @@ -#+title: Curso Básico da Linguagem C -#+subtitle: Aula 4: Layout de memória -#+author: Blau Araujo -#+startup: show2levels -#+options: toc:3 - -* Aula 4: Layout de memória - -- [[][Vídeo desta aula]] - -** Introdução - -No fundo, esta é uma aula sobre variáveis. Mas, principalmente para quem está -iniciando na programação em C, dizer que variáveis são como gavetas onde nós -guardamos e acessamos dados aleatoriamente é quase a mesma coisa que tentar -formar cirurgiões com o Jogo da Operação. - -#+CAPTION: Jogo da Operação -[[./jogo-taz.png]] - -Isso funciona muito bem com crianças em alfabetização, mas não com quem está -se preparando para assumir responsabilidades programando numa linguagem que -deixa por conta da pessoa que programa todos os cuidados com as potenciais -falhas e vulnerabilidades que podem por em risco, não apenas o programa que -está sendo escrito, como também todo o sistema em que ele será executado. - -Então, nós podemos definir variáveis como elementos da linguagem que serão -associados a valores manipuláveis na memória, podemos dizer que esses valores -serão dimensionados conforme seus tipos (assunto da aula passada), que eles -serão encontrados em endereços específicos na memória... Enfim, mas nada -disso fará sentido, nem dará uma noção realista das implicações do poder que -nós temos em mãos quando somos autorizados, pela linguagem C, a manipular -quase que livremente o espaço de memória. - -Em grande parte, é a falta dessa noção que nos leva a situações de risco, -como (se prepare para o inglês): - -- Heap Overflow -- Stack Overflow -- Buffer Overflow -- Use-After-Free (UAF) -- Double Free -- Dangling Pointer -- Memory Leak -- Uninitialized Memory Access -- Out-of-Bounds Read/Write -- Null Pointer Dereference -- Stack Corruption -- Heap Corruption -- Race Conditions - -E depois, vão dizer que a linguagem C é insegura, propensa a vulnerabilidades -de memória... E por aí vai. Sim, a linguagem C não tem mecanismos que nos -impeçam de cometer erros, mas não é ela que comete os erros. - -Por isso, este talvez seja o vídeo mais longo do nosso curso. Nele, nós vamos -demonstrar como o sistema operacional, o nosso GNU/Linux, lida com a execução -de programas, especificamente no que diz respeito ao espaço de memória que é -disponibilizado para eles. - -** Processos e memória - -- O kernel gerencia a execução de programas através de /processos/. -- Processos são estruturas de dados associadas a cada um dos programas - que estão sendo executados. -- Uma parte central dessa estrutura de dados é o /layout de memória/, que - é uma faixa de endereços mapeada pelo sistema para que os programas possam - acessar a memória através de endereços adjacentes. - -#+begin_quote -Essa faixa de endereços é /virtual/ porque são endereços que não correspondem -aos endereços reais da memória física e, por isso mesmo, os programas terão -acesso a uma faixa contínua de endereços em vez de localizações espalhadas -e dispersas ao longo dos endereços reais da memória. -#+end_quote - -** O espaço de endereços (layout de memória) - -A faixa de endereços atribuída a um processo é dividida em vários /segmentos -de memória/ com finalidades específicas. - -#+caption: Layout de memória -[[./mem-layout.png]] - - -*** Dados copiados do binário do programa - -Nos endereços mais baixos da memória virtual, serão copiados os dados -presentes nas /seções/ dos binários dos nossos programas: - -- =.text=: O conteúdo executável do programa (código). -- =.rodata=: Dados constantes. -- =.data=: Dados globais e estáticos inicializados. -- =.bss=: Dados globais e estáticos não inicializados. - -*** Dados dinâmicos - -A região intermediária dos endereços mapeados, chamada de /heap/, é reservada -ao uso com: - -- Dados que requeiram espaços alocados dinamicamente ao longo da execução - do programa (com a função =malloc=, por exemplo). -- Mapeamento do conteúdo de arquivos e grandes volumes de dados. -- Conteúdo de bibliotecas carregadas dinamicamente, como a =glibc=, o - carregador dinâmico (=ld-linux=) e a biblioteca =vdso=, do Linux. - -#+begin_quote -A localização dos dados dinâmicos é aleatória dentro da faixa do /heap/ -que, conforme a necessidade, se expande na direção dos endereços mais -altos, ou seja, em direção à pilha. -#+end_quote - -*** Pilha (stack) - -Os endereços mais altos da memória virtual são reservados à /pilha de -execução/ do programa. Uma /pilha/, ou /stack/, é uma estrutura onde os dados -são, literalmente, empilhados uns sobre os outros. No GNU/Linux, a base -da pilha está no seu endereço mais alto, enquanto que os novos dados serão -empilhados na direção dos endereços mais baixos. - -Ao ser iniciada, a pilha recebe, da sua base para o topo: - -- Lista das variáveis exportadas para o processo (/ambiente/ / /envp/). -- Lista dos argumentos de linha de comando que invocaram o programa (/argv/). -- Um valor inteiro relativo à quantidade de argumentos (/argc/). - -No caso de programas escritos em C, ao serem iniciados, o dado no topo da -pilha, a quantidade de argumentos, é removido e, a partir daí, são -empilhados os dados locais da função =main=, o que inclui: - -- Variáveis declaradas nos parâmetros da função. -- Variáveis declaradas no corpo da função. - -À medida em que o programa é executado, os dados das outras funções -chamadas também serão empilhados até serem removidos após seus respectivos -términos. - -** Resumo do mapeamento de memória - -O kernel expõe diversas informações sobre os processos em execução na -forma de arquivos de texto no diretório virtual =/proc=. Nele, cada processo -terá um diretório e, nesses diretórios, nós encontramos o arquivo =maps=, -que contém uma versão resumida de todas as faixas de endereços mapeados. - -Para visualizar o mapeamento de um processo de número =PID=: - -#+begin_example -cat /proc/PID/maps -#+end_example - -** Programa =memlo.c= - -Para demonstrar como os dados de um programa são mapeados na memória virtual, -nós vamos utilizar o programma =memlo.c=: - -#+begin_src c -#include -#include -#include - -#define APGL_HINT 0x4c475041 -#define BLAU_HINT 0x55414c42 - -int bss_var; -int data_var = APGL_HINT; -const int ro_data = BLAU_HINT; - -int func(void) { - return 42; -} - -int main(int argc, char **argv, char **envp) { - - static int lsni_var; - static int lsi_var = BLAU_HINT; - - int lni_var; - int li_var = APGL_HINT; - - char *str_ptr = "Salve!"; - - void *heap_ptr = malloc(16); - - puts("[stack]"); - printf("%p início do vetor envp (%s)\n", *envp, *envp); - printf("%p início do vetor argv (%s)\n", *argv, *argv); - printf("%p envp ponteiro para envp (%p)\n", envp, *envp); - printf("%p argv ponteiro para argv (%p)\n", argv, *argv); - printf("%p lni_var variável não inicializada\n", &lni_var); - printf("%p li_var variável inicializada\n", &li_var); - printf("%p &str_ptr ponteiro com endereço da string (%p)\n", &str_ptr, "Salve!"); - printf("%p &heap_ptr ponteiro com endereço na heap (%p)\n", &heap_ptr, heap_ptr); - printf("%p argc quantidade de argumentos (%d)\n", &argc, argc); - - puts("[mmap]"); - printf("%p malloc() função da glibc\n", (void *)malloc); - printf("%p printf() função da glibc\n", (void *)printf); - - puts("[heap]"); - printf("%p heap_ptr espaço alocado dinamicamente na heap\n", heap_ptr); - - puts("[.bss]"); - printf("%p lsni_var variável local estática não inicializada\n", &lsni_var); - printf("%p bss_var variável global não inicializada\n", &bss_var); - - puts("[.data]"); - printf("%p lsi_var variável local estática inicializada\n", &lsi_var); - printf("%p data_var variável global inicializada\n", &data_var); - - puts("[.rodata]"); - printf("%p str_ptr endereço de uma string (%s)\n", str_ptr, str_ptr); - printf("%p ro_data constante global\n", &ro_data); - - puts("[.text]"); - printf("%p main() função main\n", (void *)main); - printf("%p func() função func\n", (void *)func); - - free(heap_ptr); - - sleep(300); - - return EXIT_SUCCESS; -} -#+end_src - -#+begin_quote -A análise do programa em si ficará como parte dos execícios desta aula. -#+end_quote - diff --git a/aulas/08-processos/old/a.out b/aulas/08-processos/old/a.out deleted file mode 100755 index 5a7f18a..0000000 Binary files a/aulas/08-processos/old/a.out and /dev/null differ diff --git a/aulas/08-processos/old/jogo-taz.png b/aulas/08-processos/old/jogo-taz.png deleted file mode 100644 index 20fcd6c..0000000 Binary files a/aulas/08-processos/old/jogo-taz.png and /dev/null differ diff --git a/aulas/08-processos/old/mem-layout.png b/aulas/08-processos/old/mem-layout.png deleted file mode 100644 index 8ebd5f2..0000000 Binary files a/aulas/08-processos/old/mem-layout.png and /dev/null differ diff --git a/aulas/08-processos/old/memlo.c b/aulas/08-processos/old/memlo.c deleted file mode 100644 index 74a43f2..0000000 --- a/aulas/08-processos/old/memlo.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include - -#define APGL_HINT 0x4c475041 -#define BLAU_HINT 0x55414c42 - -int bss_var; -int data_var = APGL_HINT; -const int ro_data = BLAU_HINT; - -int func(void) { - return 42; -} - -int main(int argc, char **argv, char **envp) { - - static int lsni_var; - static int lsi_var = BLAU_HINT; - - int lni_var; - int li_var = APGL_HINT; - - char *str_ptr = "Salve!"; - - void *heap_ptr = malloc(16); - - puts("[stack]"); - printf("%p início do vetor envp (%s)\n", *envp, *envp); - printf("%p início do vetor argv (%s)\n", *argv, *argv); - printf("%p envp ponteiro para envp (%p)\n", envp, *envp); - printf("%p argv ponteiro para argv (%p)\n", argv, *argv); - printf("%p lni_var variável não inicializada\n", &lni_var); - printf("%p li_var variável inicializada\n", &li_var); - printf("%p &str_ptr ponteiro com endereço da string (%p)\n", &str_ptr, "Salve!"); - printf("%p &heap_ptr ponteiro com endereço na heap (%p)\n", &heap_ptr, heap_ptr); - printf("%p argc quantidade de argumentos (%d)\n", &argc, argc); - - puts("[mmap]"); - printf("%p malloc() função da glibc\n", (void *)malloc); - printf("%p printf() função da glibc\n", (void *)printf); - - puts("[heap]"); - printf("%p heap_ptr espaço alocado dinamicamente na heap\n", heap_ptr); - - puts("[.bss]"); - printf("%p lsni_var variável local estática não inicializada\n", &lsni_var); - printf("%p bss_var variável global não inicializada\n", &bss_var); - - puts("[.data]"); - printf("%p lsi_var variável local estática inicializada\n", &lsi_var); - printf("%p data_var variável global inicializada\n", &data_var); - - puts("[.rodata]"); - printf("%p str_ptr endereço de uma string (%s)\n", str_ptr, str_ptr); - printf("%p ro_data constante global\n", &ro_data); - - puts("[.text]"); - printf("%p main() função main\n", (void *)main); - printf("%p func() função func\n", (void *)func); - - free(heap_ptr); - - sleep(300); - - return EXIT_SUCCESS; -} diff --git a/aulas/08-processos/old/var-global.c b/aulas/08-processos/old/var-global.c deleted file mode 100644 index b382999..0000000 --- a/aulas/08-processos/old/var-global.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -int b = 0x5a; - -int main(void) { - int a = 0x58; - - printf("a: %d @ %p\n", a, &a); - printf("b: %d @ %p\n", b, &b); - - return 0; -} diff --git a/aulas/08-processos/old/var-local.c b/aulas/08-processos/old/var-local.c deleted file mode 100644 index 0e3e7c9..0000000 --- a/aulas/08-processos/old/var-local.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -int main(void) { - int a = 17, b = 25; - - printf("a: %d @ %p\n", a, &a); - printf("b: %d @ %p\n", b, &b); - - return 0; -}