Jump to content

fredericopissarra

Membros
  • Content Count

    357
  • Joined

  • Last visited

Community Reputation

273 Excellent

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Um "macete" para evitar ficar lembrando os offsets na pilha é usar estruturas (exemplo com o NASM, código para i386): struc fmastkf .retaddr: resd 1 ; CALL colocar isso na pilha. .a: resd 1 .b: resd 1 .c: resd 1 endstruc fma_: mov eax,[esp+fmastkf.b] ; O compilador preferiu pegar b primeiro... imul eax,[esp+fmastkf.a] ; ... e multiplicar por a. add eax,[esp+fmastkf.c] ret O empilhamento, na chamada de fma_(), é claro, é feito de trás para frente. Assim, como a é empilhado por último, ele fica mais próximo de retaddr.
  2. Pois é... nos antigos 8086 até o 80286 só tínhamos os registradores AX, BX, CX, DX, SI, DI, BP, SP, além do IP e FLAGS e os seletores. Nos modos de endereçamento era possível usar apenas BX ou BP como endereço base e SI ou DI como índice e, ao usar BP o seletor SS era usado (ao usar BX, DS era usado). Nos 386 isso mudou e qualquer registrador de uso geral pode ser usado como base e índice, mas a seleção automática de SS quando usados ESP ou EBP continua valendo. Quanto ao "sinônimo" de código otimizado eis um exemplo simples: int fma_( int a, int b, int c ) { return a*b+c; } Se você
  3. Nos modos de operação real (16 bits) e i386 (32 bits), sempre que se usa ESP ou EBP numa referência à memória, automaticamente o seletor de segmento SS é usado. Por exemplo: mov eax,[esp] ; Lê dword de SS:ESP mov eax,[ebp] ; Lê dword de SS:EBP Assim, EBP pode ser usado para apontar para qualquer lugar da pilha. Em códigos não otimizados os compiladores de linguagens de alto nível usam EBP para marcar o ínicio do stack frame usado pela função. Desse jeito: f: push ebp ; salva EBP na pilha para recuperar depois. mov ebp,esp ; EBP agora têm o endereço desse no
  4. Regra geral: TODA equação, ao ser codificada usando ponto flutuante, tem que ser condicionada para evitar condições de overflow e underflow... É bom lembrar que tipos em ponto flutuante têm menor precisão binária que os mesmos tipos, do mesmo tamanho, inteiros e que o domínio da representação desses valores (em ponto flutuante) não são ℝ, mas sim ℚ (domínio dos "racionais" -- o que, se pensar bem, é óbvio). Sobre a alegação de precisão menor... O tipo long long int tem 63 bits de precisão (1 para o sinal), enquanto double tem 53 -- a estrutura de ambos os tipos e de 64 bits. A mesma coisa a
  5. Só uma dica com relação ao Teorema de Pitágoras... Ao fazer: Se a e/ou b forem muito grandes, você poderá obter +INFINTE (overflow) como resposta. A mesma coisa acontece com a exponenciação que você usou... Uma aproximação melhor e menos provável de obter overflow é selecionando o maior dos dois valores (suponha: a) e fazer: Desde que a != 0 (neste caso h=|b|). Eis a simplificação: Assim, (b/a)², no máximo, será um valor subnormal (entre 0 e 1) e a podera ser bem mais próximo do máximo valor suportado da precisão do tipo em ponto flutuante. Além de diminuir o esforço a
  6. #include <stdio.h> #include <string.h> #include <stdlib.h> void verifica ( char txt[200], char aux[200], int b, char txt_orig[200] ); void criptografar ( char txt[200], int b ); int main() { char txt[200], aux[200], txt_orig[200]; int a, b; // FIXME: Onde é que esse 'a' é usado? FILE *arqp, *arqp2; arqp = fopen ( "arqp.txt", "r" ); if ( arqp == NULL ) { printf ( "Deu erro" ); system ( "pause" ); // FIXME: Não use system()! exit ( 1 ); } // FIXME: O arquivo de saída também pode não conseguir ser aberto! // Onde está o teste
  7. Ninguém aqui vai fazer seus exercícios escolares por você.
  8. Fernando, o "shellcode" ai não está na pilha.
  9. OUTRO problema... Simplesmente colocar os bytes dos opcodes num buffer é problemático. Sistemas modernos usam paginação para gerenciar memória e páginas podem ter o flag NX (not executable) habilitado. É o caso do segmento de dados. O programa abaixo simplesmnte causará um "segmentation fault" porque o segmento de dados não permite execução de código (mesmo que o "shellcode" esteja correto e respeite a convenção de chamada): #include <stdio.h> char *shellcode = "\x8d\x04\x7f" // lea eax,[rdi+rdi*2] "\xc3"; // ret int main( void ) { int (*f)(int)
  10. Outro problema a ser enfrentado... Um "shellcode" que funcione no modo i386 (32 bits) geralmente não funciona no modo x86-64 (64 bits)... Por exemplo, os registradores seletores de segmentos não são usados no modo x86-64.... O modo de endereçamento relativo a RIP não está disponível no modo i386 (32 bits), etc...
  11. Infelizmente a conclusão sobre os opcodes está errada. O formato de opcodes de processadores Intel (x86) é mais complicada: Um opcode pode ter até 3 btyes de tamanho, e pode ser precedido de um ou mais prefixos. Seguido de mais 1 byte contendo a lista de argumentos (ModR/M - registro ou memória), seguido do byte SIB - ainda temos o displacement (offset) e um possível valor imediato. Consulte o volume 2 do Manual de desenvolvimento de software da Intel para ver os opcodes de todas as instruções (https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html).
  12. Um exemplo do uso de strtoul() para conversão de bases (qualquer entre 2 e 36) para decimal: /* base.c Exemplo de uso de strtoul() para converter uma string em um valor inteiro de acordo com uma base numérica. O programa aceita apenas 2 argumentos: A string contendo o "valor" e a base desejada (em decimal). Exemplo: $ ./base 1010 2 10 */ #include <stdio.h> #include <stdlib.h> #include <libgen.h> #include <errno.h> int main ( int argc, char *argv[] ) { unsigned long base, n; char *p; if ( argc != 3 ) { fprintf ( stderr, "Usage:
  13. Acho que ninguém aqui vai fazer seu exercício escolar pra você, Nilton.
  14. TODOS os arquivos em /bin são de propriedade do root mesmo. O problema é que modificações feitas como root geralmente não podem ser "revertidas". Você terá que mudar as permissões manualmente (assim como as mudou antes, manualmente!). Eis o problema com seu chmod... Alguns arquivos precisam do flag SETUID lidados a permissão é rwsr-xr-x. Ao usar 777 você sobrescreveu isso. Outros diretórios não podem estar acessíveis para usuários comuns (sbin, por exemplo)... Alguns arquivos não podem ter permissões para usuários comuns (alguns de /boot, por exemplo)... Como regra geral: UNIX (e
×
×
  • Create New...