Jump to content

fredericopissarra

Membros
  • Content Count

    361
  • Joined

  • Last visited

Community Reputation

278 Excellent

Recent Profile Visitors

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

  1. Não... mas você pode dizer que ele está quebrado à partir do quilometro 23 (0x17) começando no quilometro 1280 (0x50 * 16). Ou seja, no quilometro 1303.
  2. Aumentando um cadinho a resposta do Felipe.Silva (e reforçando alguns pontos): Em primeiro lugar, query strings são limitadas, senão pelo seu browser, pelo menos pelo webserver. Eu acho (assim como ficou implícito na resposta do Felipe) que o limite é de 32 KiB (mas, já ouvi falar de 4 KiB ou menos). Se você precisar enviar mais dados tem que usar o método POST que, em teoria, tem um limite muito maior. Se você gerar um script que faça bilhões de requisições (não dá pra fazer no mesmo computador!) o site não cai porque o webserver tem um limite de conexões simultâneas. As demais ele simp
  3. 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.
  4. 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ê
  5. 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
  6. 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
  7. 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
  8. #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
  9. Ninguém aqui vai fazer seus exercícios escolares por você.
  10. Fernando, o "shellcode" ai não está na pilha.
  11. 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)
  12. 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...
  13. 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).
×
×
  • Create New...