Jump to content

fredericopissarra

Membros
  • Content Count

    358
  • Joined

  • Last visited

Everything posted by fredericopissarra

  1. 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
  2. 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.
  3. 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ê
  4. 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
  5. 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
  6. 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
  7. #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
  8. Ninguém aqui vai fazer seus exercícios escolares por você.
  9. Fernando, o "shellcode" ai não está na pilha.
  10. 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)
  11. 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...
  12. 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).
  13. 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:
  14. Acho que ninguém aqui vai fazer seu exercício escolar pra você, Nilton.
  15. 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
  16. Na verdade seno pode ser calculado com a série de Taylor: Claro que você não vai efetuar infinitas somas sucessivas, só o suficiente para obter a precisão necessária (o valor máximo de N depende do tipo de ponto flutuante em uso). Implementar isso é relativamente simples... Mas, o que não entendi do seu seu enunciado é que primeiro fala-se de cosseno, depois de seno e pede-se para implementar seno (é seno ou cosseno?)... Anyway... Fernando está certo... Ninguém aqui vai fazer o exercício pra você...
  17. Se é "freeware" então, com toda certeza, o código fonte está disponível, não?
  18. Analogias só te levarão até certo ponto. Nesse "curso", que escrevi no início dos anos 90, explica melhor:
  19. Decifrando o número: Oitocentos e oitenta e cinco quintilhões, trezendos e oitenta e oito quatrilhões, quatrocentos e trinta e oito trilhões, trezendos e noventa e um bilhões, quatrocentros e setenta e três milhões, setecentos e vinte e nove mil, trezendos e sessenta e três. É isso... ?
  20. Na analogia da estrada, onde é o KM 0? São Paulo? Esse é o offset 0, se você está no km 50, está no offset 50, ao andar mais 2 km, vai pro offset 52. Note que não existe apenas ESSA estrada. O offset, no exemplo, é medido em relação a ESSA referência, mas existem outras referências pelo mundo afora. No caso do modo real, um "endereço de memória" é especificado com um par de valores: SEGMENTO e OFFSET. O segmento te dá o endereço base e o offset te dá o deslocamento dentro desse segmento... No modo real, bloco do segmento sempre tem 64 KiB de tamanho (e o offset também).
  21. "offset" é "deslocamento". Se você estiver parado onde está e se deslocar 1 metro pra frente, então está no offset +1 metro pra frente. Com relaçẽo a "endereço de memória", se você assumir como base um endereço qualquer, um "deslocamento" de N bytes para frente é o "offset" (deslocamento) com relação a essa base. No modo real o "segmento" é essa base e, junto como ele, compondo o endereço físico, tem o "offset" (deslocamento).
  22. Para mim parece ainda estar "oculto", já que não vejo nenhuma referência à código fonte por aqui.
×
×
  • Create New...