Jump to content

Fernando Mercês

Administrators
  • Posts

    1,523
  • Joined

  • Last visited

  • Days Won

    173

Posts posted by Fernando Mercês

  1. Oi Ana!

    Parabéns pela decisão em estudar Assembly. 🙂

    No teu código falta especificar o destino nas instruções MOV. Por exemplo: mov, 4 tá pedindo para mover/copiar o valor 4, mas para onde? Falta especificar um destino, entende? O que você precisa aí é saber em qual registrador você quer colocar tais valores. O nome do registrador vai antes da vírgula.

    Você pode ler mais sobre o assunto no nosso livro, por exemplo, ou em centenas de outros livros e artigos na internet.

    Outra coisa: em Assembly, você não "muda" o conteúdo de um label assim:

    mov nome, dword 'Jon' ; Mudar o nome Ana para Jon Linhares

    Para atingir o que você quer, o jeito mais simples é especificar, na seção .data, dois labels, nome1 e nome2, e aí usá-los um em cada bloco de código que imprime um nome.

    Por fim, a syscall que sai do programa é a SYS_EXIT. Ela recebe um argumento (você pode conferir aqui ou dando um man 2 exit). Sendo assim, você precisa fazer:

    mov ebx, 0
    mov eax, 1
    int 0x80

    Isso é equivalente à uma chamada exit(0), entende? E sair com o código de retorno zero é o padrão para dizer para o SO que "deu tudo certo". 😉

    Valeu!

    • Curtir 1
  2. Em 04/08/2023 em 07:43, jhow disse:

    Nao chegou nessa parte nao , ela da erro aonde eu mostrei...

    Então é mais um indício de que o software está ok e o problema é com a máquina mesmo. É cedo para afirmar, mas é um indício. 🙂

    Em 04/08/2023 em 07:43, jhow disse:

    Sao 2 ram de 4MB, eu fiz o comando mem /c e deu invalid keyword.

    Já experimentou remover os dois pentes de memória e limpar seus contatos com borracha? Ao ligar o PC, é legal ver no POST (aqueles testes que rolam quando o computador liga) se a memória está sendo reconhecida em sua totalidade (8MB no seu caso).

    Em 04/08/2023 em 07:43, jhow disse:

    Tentei rodar no celular e deu erro da FOTO 

    É um emulador de MS-DOS pra celular?

    Abraço!

  3. Eu dei uma olhada aqui e tudo parece bastante interessante. Não tenho o dispositivo com o qual este programa conversa, mas num emulador aqui ele pelo menos subiu:

    image_2023-08-04_000159778.png

    Aí chega a aparecer esta tela?

    Eu tô achando que o problema é o seguinte: a memória RAM está se esgotando e o programa não consegue nem memória para alocar uma string de erro "Out of memory" nessa função:

    void sub_42AEC0()
    {
      char var_4[4]; // [esp+20h] [ebp-4h] BYREF
    
      __InitExceptBlock();
      string::string((string *)var_4, aOutOfMemory);
      xalloc::xalloc((xalloc *)&__xalloc, (const string *)var_4, 0);
      string::~string((TStringRef **)var_4, 2);
    }

    No caso acima, var_4 é null se o operador new falhar. Veja v5 abaixo:

    string *__cdecl string::string(string *this, char *s)
    {
      size_t v2; // eax
      TStringRef *v3; // eax
      TStringRef *v5; // [esp+28h] [ebp-4h]
    
      __InitExceptBlock();
      v5 = (TStringRef *)operator new(0x12u);
      if ( v5 )
      {
        if ( s )
          v2 = strlen(s);
        else
          v2 = 0;
        TStringRef::TStringRef(v5, s, v2, 0, 0, 0);
        --*(_DWORD *)_DestructorCountPtr;
        v3 = v5;
      }
      else
      {
        v3 = 0;
      }
      *(_DWORD *)this = v3;
      ++*(_DWORD *)_DestructorCountPtr;
      return this;
    }

    Com var_4 sendo NULL, o fluxo entra em xalloc(NULL, 0) e dentro dela tem mais duas chamadas, onde uma chega no mov eax, [eax] problemático em 0x0042C253.

    Combinando então o seguinte:

    1. Você não alterou nada no sistema.
    2. O sistema rodou no meu emulador.
    3. Minha suspeita de ser um erro de alocação de memória.

    Meu palpite é que um pente de memória deste computador tenha queimado ou esteja com algum mau contato e ele está com metade da memória que ele deveria ter. Não sei. Você pode tentar ver quanto de memória tem livre com o comando mem /c e dizer aqui pra gente (postar uma foto da saída). Ou tentar desligar, limpar os pentes de memória e ligar novamente o PC.

    Só ideias por enquanto...

  4. Opa, deixa eu te pedir mais umas coisas:

    1. Uma foto do conteúdo do AUTOEXEC.BAT que mostre tudo (tá cortando um pedaço na que você mandou).
    2. Uma foto do conteúdo do INIT.BAT. É só comandar type c:\progs\sr632\v3.10\obj\init.bat
    3. Uma foto da saída do comando dir c:\
    4. Uma cópia da pasta inteira (eu sei que você tá buscando os disquetes já, mas só pra não esquecer).

    Abraço!

  5. Em 02/08/2023 em 10:37, jhow disse:

    Vou ver se consigo um disquete pra copiar a pasta , pq a cpu e muito antigo so tem entrada pra disquete,nao possui usb , e so tem o sistema Ms-Dos , a maquina e uma rebobinadeira.

    Boa!

    Em 02/08/2023 em 10:37, jhow disse:

    O que sera que pode ter causado esse erro?

    Ainda não sei. Enquanto você não acha os disquetes, consegue tirar uma foto do conteúdo do AUTOEXEC.BAT e CONFIG.SYS? Os comandos são:

    cd \
    type autoexec.bat
    type config.sys

    Seria legal também ter a versão do DOS e uma listagem desse diretório OBJ aí:

    ver
    dir c:\progs\sr632\v3.10\obj

    Valeu!

  6. Olá!

    O programa que você executou tentou acessar um endereço de memória inválido e por isso o SO matou o processo. No caso, ele dá um dump dos opcodes das instruções me 0x42C24B e diz que o errou ocorreu na instrução em 0x42C253. Então dá pra inferir o seguinte:

    # rasm2 -ax86 -d e84cabffff8b450c8b008903
    call 0xffffab51
    mov eax, dword [ebp + 0xc]
    mov eax, dword [eax]
    mov dword [ebx], eax

    Colocando os endereços, ficaria:

    42C24B    call 0xffffab51
    42C250    mov eax, dword [ebp + 0xc]
    42C253    mov eax, dword [eax]
    42C255    mov dword [ebx], eax

    Então o erro seria na instrução mov eax, dword [eax]. Como no momento que essa instrução roda EAX é 0 (tem um dump dos valores dos registradores na imagem), o programa tenta acessar o endereço de memória 0, o que bate com o erro final (The instruction referenced illegal address 00000000).

    A instrução anterior copia um valor para EAX a partir de EBP + C, que parece ser o segundo argumento da função dona dessa instrução. Não dá pra saber se é a main() do programa, mas você pode tentar passar um argumento pra ver se o erro muda:

    C:\PROGS\SR632\V3.10\OBJ>NEW.EXE 1 2

    Se precisar de mais ajuda, acho que vai ter que copiar a pasta PROGS, compactá-la e enviar aqui pra gente. Assim alguém pode dar uma olhada num disassembler e tentar te ajudar com o erro.

    Abraço!

  7. Oi Ana, bem vinda à Mente Binária. 🙂

    O nasm.us parece estar fora mesmo. No entanto, vejo algumas opções:

    • Se você usa Linux, pode instalar pelo gerenciador de pacotes. Ex.: apt install nasm.
    • Se você usa Windows, pode baixar do Fossies.
    • Se usa macOS, acho pode instalar com o brew.sh: brew install nasm.
    • Você pode estudar Assembly com o fasm alternativamente.

    Espero que ajude. Bons estudos aí!

  8. Oi @capgaivo!

    Se liga na linha onde você faz a conta:

    emed = (qmin + qmax) / 2;

    Nessa linha, o que está à direita do igual é avaliado primeiro. Neste caso, dois tipos int são somados (qmin e qmax). O resultado, que também é um int, é  dividido por um outro int de valor 2. Ou seja, você tem um valor int sendo dividido por outro valor int. O resultado é, naturalmente, um valor do tipo int também.

    Aí como emed é float, o int resultante é promovido para float. No caso, 25 / 2 = 12 (tudo int) e 12 promovido para float é 12.0.

    Acredito que a forma mais rápida de resolver isso seja dividindo por 2.0f ou (float)2, ao invés de 2. Então você terá uma conta à direita do igual que dividirá um int por um float e o resultado de int / float é float. 😉

    Resumindo, em geral:

    • int / int = int
    • float / int = float
    • int / float = float

    PS.: Você pode se sentir uma inclinação de dividir por 2.0, mas sem o sufixo f, o 2.0 é um literal do tipo double. Então você teria um resultado do tipo double que depois seria convertido pra float. Eu não lembro das implicações disto. Talvez outra pessoa possa ajudar mais, mas eu recomendaria fazer float com float mesmo. 🙂

    Abraço.

     

    • Agradecer 1
  9. Opa, consegue editar esse código-fonte pra ficar melhor de ler? Pode usar o botão "Código (<>)" do editor aqui do site quando for fazê-lo. Exempleo de como fica:

    int main(void) {
    	printf("oiee\n");
    }

    Se você remover essas linhas em branco, vai ficar muuuito melhor pra galera ajudar. 😉

    Abraço!

  10. Oi @Nitczi, bem vindo(a) ao nosso portal! 🙂

    Eu não tenho mais o sample exato que utilizei, mas anexei um aqui bem parecido.

    Importante lembrar, no entanto, que na aula 24 eu falo que não mostrei o código-fonte do binário e nem o disponibilizei para download porque deixei o exercício para quem assistir o treinamento de implementar este binário em C. É bem fácil. Você só vai chamar duas funções. Recomendo que faça o seu depois de analisar este. 😉

    Abraço e bons estudos!

     

     

     

     

     

    antidebug.zip

    • Agradecer 1
  11. Em 20/05/2023 em 19:57, Samuel Araujo disse:

    Uauu, que honra o Fernando comentando meu erro!!!

    Hahaha tamo aqui pra isso. Honra minha em ajudar num primeiro tópico tão foda. 🙂

    Em 20/05/2023 em 19:57, Samuel Araujo disse:

    Muito obrigado, agora tudo faz sentido..Agr que vc falou se n me engano vc cita em alguma aula do curso de C que o ultimo caractere é o de nova linha, acho que é a aula sobre array, n lembro...

    Desconheço hehe. No caso de uma C string (um array de chars), o último elemento é um nullbyte mesmo. Só pra deixar claro, no caso aí da SYS_read (mov rax, 0), o que acontece é que como você tá usando um terminal (o usuário digita num terminal), o padrão para encerrar a linha é o newline (0x0a). Então não é que a SYS_read pára ao encontrar o newline, é que o usuário manda um newline através de um terminal interativo. Então, quando você busca um newline pra encontrar o "fim da linha", só vai funcionar assim, quando o usuário digita. Se ele ler da entrada padrão ou encerrar a digitação com outro caractere que não seja o ENTER, seu programa não vai pegar (referência). Mas para os fins do que você está estudando agora, acho que ok. 👌 

    Em 20/05/2023 em 19:57, Samuel Araujo disse:

    Eu acompanho o mente binaria faz 2 anos já, vcs me influenciaram a aprender programação, e não só isso...Me deram um caminho para aprender pelo baixo nível...fiquei 9 mêses estudando o livro de Arquitetura e Organização de Computadores do Willian Stalins, e agr comecei a estudar a matéria de programação, capengando com erros e pesquisas, estudos..Mas é isso, continue com o projeto e muito obrigado novamente.

    Que bela história @Samuel Araujo! 9 meses estudando um livro. Poxa, muito foda mesmo. 🙂 E ficamos felizes em saber que fazermos parte da tua jornada de aprendizado. Precisamos, estamos aqui! E se quiser compartilhar programas como esse com a gente, só postar aqui no fórum. 

    Abraço!

  12. Em 20/05/2023 em 14:19, Samuel Araujo disse:
            cmp al, 0 
            je valido ; compara com nullo (fim da entrada do usuario) e salta pro fim do programa 

    Oi Samuel. Bem vindo à Mente Binária! 🙂

    O trecho que citei não tá certo. O fim da string de entrada não contém um caractere nulo (0x00) e sim um caractere de nova linha, porque o usuário pressionou ENTER, que é o 0x0a. Ou seja, se você comparar com 0x0a, 10 ou `\n` (que dá tudo no mesmo), resolve este caso. 😉

    Abraço.

  13. Opa, bem vindo!

    Só para clarificar, qual das seguintes coisas você quer?

    1. Colocar um ícone para aparecer no .exe quando este é listado no Windows Explorer.
    2. Colocar um ícone dentro da janela exibida pela MessageBox() (não é na barra de título).
    3. Criar uma janela que exiba um ícone na barra de títulos.

    São coisas diferentes. 🙂

    Ah, como você tá compilando e linkando este programa? Quais os comandos?

    Abraço!

  14. Boas vindas 🙂

    Se você pede para o usuário digitar uma frase, na verdade você fica "refém" de uma ação de input, não de output. A string, depois de lida, será armazenada num buffer (uma variável), certo? Basta que você altere lá, em tempo de execução.

    Se quiser postar o programa posso tentar ajudar mais.

    Abraço!

  15. Olá, @allanval! Talvez tenha, mas você precisa se certificar de não estar cometendo crime (checar a licença). Se for correção de bug de um software da qual a empresa/pessoa desenvolvedora faliu/sumiu, então pode ser ok, mas ainda assim, é melhor se certificar primeiro.

    Tecnicamente você vai precisar estudar engenharia reversa. Tá no lugar certo. 🙂 Aqui tem um guia.

    Abraço e boa sorte!

  16. Acho que entendo como está pensando, mas já adianto que é um método pouco efetivo. De qualquer forma, acredito que precise de um script na maioria dos debuggers. No x64dbg dá pra fazer com tracing também (Debug -> Trace over/into...):

    image.thumb.png.65b60df89bbeaae778dbafe33696efc0.png

    Explicando:

    A condição que coloquei em Command Condition é que o resultado da função dis.match(cip, "^j") seja True. Essa função vai disassembler a instrução apontada por cip (eip ou rip) e ver se esta começa com j. Quando tal condição for atendida, o que está em Command Text vai executar. Pus dois comandos: um pra colocar um breakpoint no endereço atual e outro para desabilitar esse breakpoint, de modo que a execução continue. Fazendo isso você terá um breakpoint desabilitado em cada salto. Basta reiniciar o programa, habilitar todos os BPs e rodá-lo para atingir teu objetivo.

    Repare que se usar Trace over, não vai pegar os saltos dentro das funções. Se usar Trace into pega, mas vai ser bem mais lento (tracing em geral é lento mesmo).

    Abraço.

  17. 2 horas atrás, Insurgente disse:

    Muito obrigado Fernando. Fiz o download da sua versão compilada e está funcionando. Não sei utilizar ainda, mas vou aprender mais tarde.

    Show. Por nada. 🙂

    2 horas atrás, Insurgente disse:

    Eu tive apenas que fazer o download da biblioteca "VCRUNTIME140.dll"  e colocá-la no diretório "C:\Windows\System32" do Windows 7.

    Mesmo depois de instalar as runtime libraries conforme indiquei? Estranho...

    Abraço!

  18. Opa, acho que tem uma confusão aí...

    Você não tem que compilar o make. O arquivo Makefile é lido pelo comando make, que já invoca o compilador pra você. Ou seja, é uma facilidade. Então, ao invés de você usar o compilador diretamente (com o comando gcc, por exemplo), você usa o comando make, porque quem fez o Hyperion já colocou um arquivo Makefile na pasta do projeto pra facilitar tua vida, entende?

    No entanto, o Windows não vem com o comando make nativo. Por isso, no readme.txt do projeto há a recomendação que você use o MinGW ou o Visual Studio. Dá um trabalhinho em qualquer um dos casos e reconheço que nada disso é óbvio para quem não está acostumado.

    De repente eu consigo fazer um vídeo mostrando o processo. Por hora, compilei aqui pra você, mas não testei o programa e nem sei o que ele faz. Recomendo rodar só em VM. Ah, vai precisar das runtime libraries do Visual C++ pra rodar.

    Um abraço.

    hyperion.rar

×
×
  • Create New...