Jump to content
  • Sign in to follow this  

    Forçando um game a rodar no Vista

       (0 reviews)

    Fernando Mercês

    Muitos jogos antigos apresentam problemas ao serem executados ou simplesmente instalados no Windows Vista. Isto acontece por conseqüência de diversos fatores, mas o principal é que quando o jogo (ou software) foi desenvolvido, o Windows Vista ainda não estava no mercado, o que impediu testes de serem realizados, entre outros aspectos.

    Este artigo mostra um exemplo de como utilizar a ER para estudar o executável do game e saber o que o impede de rodar no Vista.

    Você verá como uma simples alteração em 2 bytes de um arquivo PE pode salvar seu fim de semana.

    Ao tentar instalar o jogo Mortal Kombat 4 (PC) no Windows Vista Home Basic, obtivemos um erro fatal que dizia: “Start Menu Error”. A única opção era clicar no botão OK, que encerraria a execução do programa de instalação.

    Numa tentativa de contornar tal situção, copiamos o conteúdo do CD-ROM para um diretório no disco rígido e tentamos executar o game pelo seu executável direto, o MK4.EXE. Isso resultou no seguinte erro:

    1-mk.png.d6706c78c917b8d21685d1c034608938.png

    É notável que o executável checa se a instalação do jogo foi feita e, como não foi feita, recebemos a mensagem acima. Ao clicar em OK, o processo é encerrado.

    Mas o que será que o jogo checa para saber se está instalado ou não? Para responder a essa pergunta precisaremos de um debugger de executáveis. Um aplicativo que mostra, em assembly, as rotinas executadas por arquivo PE. Usaremos o OllyDbg para tal função.

    Ao abrir o executável MK4.EXE no OllyDbg, vamos procurar pela string de texto contida na mensagem de erro da primeira imagem. Para isto, clique com o botão direito do mouse no primeiro quadrante e escolha “Search for > All referenced text strings”, como sugere a imagem abaixo:

    2-strings.png.6e6e59b1f3bbb79913d8e3efa44f93a3.png

    A próxima tela mostra uma lista contendo todas as strings de texto encontradas e entendidas no arquivo MK4.EXE. Nela, clicando novamente com o botão direito do mouse e escolhendo “Search text”, abrirá uma janela como a mostrada abaixo e então digitamos o texto “CD” (sem aspas) e marcamos a opção para diferenciar o caso, para filtrar a pesquisa.

    3-cd.png.e2b52847efbe522aab2ca7b1080648a3.png

    Isso foi feito para encontrarmos a string de texto que nos foi exibida no erro incial, lembra-se? O texto era “Mortal Kombat 4 is not installed. Run Setup from the CD”. Por isso buscamos a palavra “CD”, para achar essa string dentro do executável do jogo, o que nos leva para próximo da rotina onde esta mensagem é chamada.

    Vamos ver o resultado na imagem abaixo:

    4-search.png.eb1958b7aa589c43e798b4599ad964b7.png

    O Olly nos mostra que no endereço 004AD2B1, o comando é PUSH 004F474C, que vai empurrar para a memória (stack) o nosso texto. Para localizarmos exatamente onde está este comando no programa, basta darmos um ENTER nesta linha e a tela abaixo é exibida.

     5-jnz.png.6cd2d7b251c6d98d516af9f595dd4b16.png

    Entramos no bloco onde o texto do erro é exibido na tela. Vamos subir um pouco para ver o que vem antes.

    Na linha 004AD299 temos um CALL (como um GOTO) e, depois que a CALL temina e o programa volta para sua execução normal, temos um TEST EAX, EAX, que é um comando que verifica se o conteúdo de EAX é zero. Então podemos prever que a CALL altera o valor de EAX.

    Mais abaixo, temos um JNZ 004AD2D4. Esse JNZ significa Jump if Not Zero (Pule se não for zero), o que quer dizer que a execução do programa saltará para a linha 004AD2D4 se o conteúdo de EAX não for zero.

    Bom, se a execução não saltar e seguir abaixo, cairemos na mensagem de erro. Se saltar, a pularemos. Então seria interessante alterar essa parte do programa para que sempre salte para a linha 004AD2D4. Isso significa que independente do resultado do teste anterior (TEST EAX, EAX) o salto ocorrerá, sempre. Assim nunca cairemos na mensagem novamente e programa continuará sua execução normal.

    O comando que faz o papel de salto incondicional em assembly é o JMP (Jump). Então, vamos alterar o JNZ da linha 004AD2A0 para JMP (e manter o resto da linha). Para isso, basta selecionar a linha e apertar a barra de espaços, depois clicar em Assemble.

    6-assemble.png.4dec9e693e01ab1c50fb0914511ae228.png

    Feito isso, o Olly marca nossa alteração em vermelho. Clicando com o botão direito do mouse sobre a alteração (ou próximo) e escolhendo “Copy > All modifications”, uma tela com as modificações abre e então basta clicar novamente com o botão direito e escolher “Save file”.

    7-save.png.43fb7234f94c245cba08e342f66ecc41.png

    Dei o nome de MK4-mod.EXE para facilitar o reconhecimento. Agora vamos ao teste. Ao executar este novo executável modificando, vemos o jogo rodando:

    8-win.png.f3850a60939382edbd3ef80fa5a7f716.png

    É importante esclarecer que os passos descritos aqui não são genéricos e não servem para todos os softwares que não funcionam, em primeira instância, no Vista. O funcionamento depende de vários fatores e principalmente do nível de integração do software com o SO para o qual ele foi desenvoldido.

    O objetivo deste artigo foi demonstrar como a ER pode nos ajudar a resolver pequenos (e grandes, por quê não?) problemas do dia-a-dia na informática. Este é um dentre dezenas de exemplos de uso da ER para soluções que seriam um pouco difíceis sem ela.

    Sign in to follow this  


    User Feedback

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest

  • Similar Content

    • By lucass
      Vou começar agradecendo ao @Fernando Mercês pela oportunidade e por ter sugerido este artigo, que também me motivou bastante a escrevê-lo!
      Introdução
      Não sou conhecido internet a dentro, apenas acompanho alguns canais no Discord (tal como o do Mente Binária). Meu nível de programação e engenharia reversa não é algo admirável ainda. Em um grupo especifico intitulado "Terra do 1337", que é um grupo fechado de amigos com finalidade de estudar engenharia reversa, programação e descontrair, eu surgi com uma idéia de escrever uma ferramenta que iria facilitar a vida de muitos nesta área de engenharia reversa e achei de API Inspector.
      A seguir um spoiler de como foi o início do projeto, para quem se interessar. 😉
      O que é o API Inspector
      É uma ferramenta de código-aberto voltada para área de engenharia reversa, que irá auxiliar na análise de funções correspondentes a certas API's do Windows, retornando informações obtidas dos argumentos caso a função seja chamada pela aplicação.
      O que ele faz
      Ele faz um hook (do Inglês "gancho"), que consiste num desvio na função original da API solicitada para nossa própria função e com isso podemos obter os dados (argumentos/parâmetros) que foram passados para tal função.
      Como ele funciona
      O princípio de um hook é simples: você insere no inicio da função um salto que irá levar para a sua função (que é uma cópia da função original) e depois de efetuar o que quiser, irá retornar para a função original prosseguir.
      Talvez mais fácil visualizar o que expliquei com código:
      //Aqui está a função //ZwWriteVirtualMemory | NtWriteVirtualMemory, originada do binário: ntdll.dll //créditos ao https://undocumented.ntinternals.net/ NTSYSAPI NTSTATUS NTAPI //WINAPI NtWriteVirtualMemory( IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL ); //Sua versão assembly 777F2110 mov eax,0x3A 777F2115 mov edx,ntdll.77808D30 777F211A call edx 777F211C ret 0x14 //O que nós vamos fazer é criar uma função similar á ela com o nome que decidirmos //Então vamos inserir um jmp no início da função original para nossa função, ficando assim: 777F2110 jmp api inspector.573523EC 777F2115 mov edx,ntdll.77808D30 777F211A call edx 777F211C ret 0x14 //Usei como exemplo minha próprio ferramenta! //Então quando ocorrer a chamada desta função ela será jogada em nossa função! Depois de nós fazermos que desejar vamos retorna-la, porém para uma região que aloquei onde contém //Um buffer dos bytes que foram sobrescritos da função original: 03610000 mov eax,0x3A 03610005 jmp ntdll.777F2115 //Ela irá retornar depois do jmp que existe na função original e continuar o código.... Vantagens de se utilizar o API Inspector ao invés de um debugger
      Imagine que você está visualizando as chamadas intermodulares (para bibliotecas externas, no caso) que um programa faz, utilizando um debugger (o x64dbg por exemplo) e notou que uma certa função que deseja inspecionar é chamada em diversos pontos do programa. Vejo duas opções neste caso: colocar vários breakpoints, um em cada chamada à função, no código do programa ou colocar um único breakpoint função em si, no código dela, na DLL.
      Em ambos os casos, você vai precisar analisar chamada por chamada, parâmetro por parâmetro. E se a função for chamada 20 vezes consecutivamente? O tempo que você levaria para visualizar apenas o primeiro parâmetro da chamada é o tempo que a ferramenta iria levar para exibir todas as 20 chamadas, com os argumentos formatados bonitinhos ao seu dispor. Entende a vantagem? 🙂
      E as desvantagens?
      Por hora, uma desvantagem é a quantidade de funções e API's suportadas. De fato, a primeira release não possui uma quantidade significativa que vá fazer você utilizar a ferramenta e nem uma quantidade de recursos interessantes na ferramenta. Mas é ai que vem o ponto chave, o fato de deixar ela pública remete ao próprio crescimento da mesma, no primeiro momento é necessário uma orientação da parte de vocês para me ajudar a melhorar o código visual. O segundo passo é eu e vocês começarem a fornecerem mais recursos para ela. Eu irei adicionar todo ou qualquer recurso que seja significativo para a mesma, e para isso eu já tenho mais funcionalidades para implementar na ferramenta que são excelentes.
      Interface gráfica
      Na imagem abaixo, utilizei o API Inspector para hookar a função MessageBoxW() da USER32.DLL. Depois disso, escrevi um texto num novo arquivo no Notepad++ e tentei fechar o programa. Ao fazer isso, o Notepad++ perguntou se eu queria salvar o arquivo e ele faz isso através de uma chamada à MessageBoxW(), que o API Inspector interceptou prontamente.

      Na imagem acima, a janela à esquerda mostra o que está atualmente passando pelas funções hookadas. Na janela a direita, temos um log.
      Como utilizar o API Inspector
      A única coisa que você precisa fazer é anexar a DLL do API Inspector ao processo desejado e para isso existem os softwares chamados "Injetores de DLL" que podem ser achados na internet.
      Você também pode criar o seu próprio injetor. Uma dica é pesquisar sobre injeção com a função LoadLibrary(), mas no exemplo a seguir eu vou mostrar como utilizar o Process Hacker para fazer a injeção.
      1 - Abra o Process Hacker e identifique no mesmo o processo no qual você quer injectar a DLL do API Inspector. No exemplo, usei o processo do Notepad++.

      2 - Clique com o botão direito sobre o processo e escolha Miscellaneous > Inject DLL.

      3 - Selecione a DLL API-Inspector.dll e clique em Abrir.

      4 - Se o Process Hacker possuir privilégios suficientes a ferramenta irá ser carregada, caso contrário, não.

      Após isso você precisa selecionar a API desejada, a função desejada e clicar em GO Hook!
      O step call é uma funcionalidade que vai fazer a ferramenta aguardar o pressionamento da tecla ENTER para retornar para a função original. Pronto, o seu hook está feito e você já poderá inspecionar a função desejada.
      Download e código
      No repositório do API Inspector no Github você pode baixar a versão compilada e ter acesso ao código-fonte também. Contribuições são muito bem vindas!
      Bom, eu nunca tinha escrito um artigo. Se faltou informação ou coloquei informação demais me desculpe. Estou aberto pra ler os comentários. Ah, e participem deste projeto! Eu quero fazer ele crescer muito. Caso precise de referências de como cheguei a este projeto, tem tudo na página inicial do projeto no Github.
      Agradecimentos
      Obrigado novamente ao Fernando Mercês, ao pessoal do Terra 1337 que me incentiva cada vez mais e em especial para o iPower e Luan que são colaboradores do projeto.
      Referências
      Dear ImGui Programming reference for the Win32 API NTAPI Undocumented Functions C++ 3D DirectX Programming
    • By ncaio
      ====== Bem-vindo a bordo ======

      Este é um repositório/espaço aberto/livre de conteúdo referente a hardware hacking em geral. Sinta-se a vontade para contribuir e retirar suas dúvidas. Assim como em outros espaços de conhecimento compartilhado na Internet, este Fórum tem regras. Algumas delas, são:
        * Seja educado(a) e respeitoso(a);
        * Pesquise antes;
        * Seja claro(a) e descritivo(a);
        * Esteja preparado(a) para compartilhar informações relevantes a sua dúvida;
        * Não fuja do foco;
        * Referencie autores;
        * E etc.
    • By Fabiano Furtado
      Pessoal...
      Ontem achei um artigo na Internet bem escrito, interessante e detalhado sobre Engenharia Reversa em ELF.
      É um reversing básico, mas não tããããão básico assim. Acho que vale a pena conferir.
      http://manoharvanga.com/hackme/
      Valeu!
    • By Ciro Moises Seixas Dornelles
      Olá a todos, existe alguma maneira de se extrair o conteúdo do livro de engenharia reversa para que eu posso lê-lo em um dispositivo kindle?

       
×
×
  • Create New...