Jump to content

Felipe.Silva

Membros
  • Content Count

    68
  • Joined

  • Last visited

Community Reputation

57 Excellent

2 Followers

Recent Profile Visitors

1,840 profile views
  1. A heap é uma estrutura especial de memória usada pelo processo. O que tem de especial nela é o fato de seu tamanho ser variável, já que sua memória pode ser alocada ou desalocada dinamicamente pelo processo. Isso pode ser feito usando syscalls do sistema operacional e o mesmo é responsável por alocar mais páginas de memória para a seção caso seja necessário. No Linux o segmento de dados pode ser aumentado ou diminuído usando a syscall brk, e é esse espaço de memória que os programas normalmente usam para a heap. Em C nós normalmente não usamos a heap diretamente e, ao invés disso, usamos
  2. O próprio Wine tem um debugger (winedbg) que você pode utilizar para depurar um .exe, dá para usar ele como gdb's server com a opção --gdb, caso você saiba usar o gdb... Porém o que o edb (e outros debuggers) faz é depurar processos e não arquivos executáveis. Se você pode iniciar um processo para o .exe então você pode depurá-lo. O passo-a-passo fica: Execute o .exe com o Wine. Abra o edb com privilégios root, menu "File" clique em "Attach". Procure pelo processo, dá para pesquisar pelo nome ou pelo PID. É necessário executar o edb como root porque é necessário privilégio
  3. Na programação orientada a objetos existe o conceito de encapsulamento, que resumidamente é o conceito de não alterar uma variável diretamente mas sim usando uma função. Isso faz com que a variável fique "encapsulada" dentro do objeto e permite que qualquer lógica seja aplicada na alteração daquela variável. E é exatamente o que você quer fazer... Toda vez que as variáveis A e B são alteradas existe uma certa lógica ocorrendo com elas, não é? Então eu sugeriria você colocar tudo dentro de uma struct e implementar funções para modificar os valores de A e B. Tipo assim: struct var {
  4. opcode = (ir & 0xf000)>>12; Quando você fez isso daqui, você pegou os 4 bits mais significativos de ir. Para pegar só 1 é a mesma coisa, só vai mudar o número de bits setados no valor com que está sendo feito o AND. if ( ac & (1 << 15) ) pc = address; // Negativo! ac é menor que zero if ( ac && !(ac & (1 << 15)) ) pc = address; // ac é diferente de zero e positivo.
  5. Acontece que ac é unsigned short int, por isso a comparação do if do C não interpreta como um número sinalizado. Mas aí é só você fazer um casting para um número sinalizado que o código já vai estar correto. Exemplo: if((short int)ac < 0) pc = address; Mas se por algum motivo você quiser fazer a verificação manualmente, bastaria você pegar o bit mais significativo (MSB) do número e ver se ele está ligado ou não. Se estiver, significa que o número é negativo... Mas como eu disse, isso não é necessário.
  6. Você não está atualizando o registrador "pc" corretamente. Remova as linhas "pc = pc + 1;" e, ao invés disso, atualize o pc imediatamente após carregar a instrução da memória. Tu pode fazer assim: ir = Mem[pc++]; O pc precisa ser atualizado sempre que uma instrução for executada. Como você só estava atualizando em algumas instruções, o loop ficava rodando indefinidamente porque pc estava sempre apontando para a mesma instrução. Sobre saber se as instruções fazem o que era esperado... Para isso eu sugiro que você compile o código no seu PC, execute e veja se o resultado foi o espe
  7. Injeção de código é uma técnica que consiste em adicionar instruções extras em um executável. Essas instruções podem ser adicionadas em vários lugares do programa, inclusive executar antes do entry point original. O uso mais comum para injeção de código é para fins maliciosos, onde um shellcode poderia ser inserido no executável e dar acesso remoto para um atacante. Mas um exemplo de uso "justo" para essa técnica é para fins de patching no executável quando você quer que algo seja alterado em tempo de execução no binário. Se você já tentou injetar código em um executável manualmente
  8. Opa, não apenas é possível como é o hobby de muita gente kkk. O primeiro passo para fazer a engenharia reversa em um firmware é justamente fazer o dump (você usou o termo certo) do código do firmware, isto é chamado de extração de firmware. Sobre ter bloqueios, sim muitas vezes pode ter. Mas existem técnicas para tentar burlar alguns bloqueios. Eu não manjo do assunto mas vou te passar referências de quem manja: Embedded Hacking: Extração de Firmware usando SPI H2HC University 2018 - Internet of Sh!t - Hacking de Dispositivos Embarcados - Maycon Vitali Os dois conteúdos é do
  9. Texto ocupa muito espaço visual, mas não tanto espaço em memória. Por exemplo, um artigo de 65536 caracteres é grande "pakas" para se ler, mas só ocupa 64 KiB. (considerando somente caracteres ASCII) O que é muita coisa para um embarcado com 32 KiB, mas para uma requisição HTTP com um servidor não é lá grande coisa a ponto de causar uma negação de serviço. Por exemplo no PHP, o tamanho máximo para upload de um arquivo é por padrão 2 MiB. Uma imagem em full HD pode alcançar fácil 4~5 MiB. Agora respondendo as perguntas: Depende da infraestrutura do site e como ele foi programado. Um s
  10. Tenho uma ferramenta em Bash no meu GitHub chamada 'new' que pode ser útil para gerar executáveis assim, sem precisar de modificar "na mão". No repositório tu pode olhar a pasta "templates" que um deles é o bin-elf64. A sequência de comandos ficaria assim: $ nasm tst.asm -o tst.bin $ new bin-elf64 file=tst.bin out=tst $ chmod +x tst $ ./tst Um "Hello World!" fica com 171 bytes. Mas um detalhe: Menor não necessariamente significa melhor. Isso aí é só de brincadeira, o executável não vai ficar mais eficiente porque você "capou" ele. Mas como passa-tempo é válido.
  11. A questão é que usando um registrador de 64 bits, a instrução divide o valor contido em RDX:RAX pelo valor passado como operando. Considere que RDX são os 8 bytes mais significativos do valor, e RAX seriam os 8 bytes menos significativos. Simplesmente zerar RDX traria um resultado incorreto se o número em RAX fosse negativo, o certo seria fazer um sign-extend e a instrução CQO faz isso para você: mov rax, 2345 cqo ; RDX:RAX = sign_extend(RAX) idiv rbx
  12. Colega, pelo que pesquisei aqui isto é uma instrução intrísseca do compilador do Visual Studio (Microsoft). Tem muita coisa em C que não é padronização da linguagem mas sim de alguma implementação específica, esta é uma delas. https://docs.microsoft.com/pt-br/cpp/intrinsics/sidt?view=vs-2019 Se você usa o GCC, e suponho que sim, você pode usar Inline Assembly para isso. (outros compiladores também suportam Inline Assembly, mas com sintaxe diferente) Vou deixar um exemplo: #include <stdio.h> #include <inttypes.h> typedef struct idtr_s { void *base; uint16
  13. $ gcc jonth.c -o test.c -E Eu usei -E do GCC para ver o conteúdo expandido. Depois procurei pelo texto "main(" no arquivo de saída e encontrei. Aproveitando das diretivas de linha que o GCC insere, eu vi que o conteúdo estava expandindo no arquivo /usr/include/X11/Xlib.c na linha 3889. Nesta linha contém a seguinte declaração: extern XIM XIMOfIC( XIC /* ic */ ); O `#define` da linha 5 seta o macro de nome XIMOfIC. Perto do final desse macro nós temos um macro "O" ali. Veja em negrito: Acontece que aonde tem esse "O" é expandido o conteúdo do macro B. Pelo visto um
×
×
  • Create New...