Você está na página 1de 14

MANIPULAO DE MEMRIA TRAINERS Por: Fernando Birck ( Fergo )

2 SUMRIO INTRODUO.................................................................................................................... 3 FERRAMENTAS NECESSRIAS........................................................................................... 4 IDENTIFICANDO O LOCAL DE MEMRIA .......................................................................... 5 PROGRAMANDO O TRAINER ............................................................................................ 9 CONCLUSO.................................................................................................................... 14

3 INTRODUO Bem vindo a mais um dos meus artigos. Continuando a seqncia de tutoriais voltados a linguagem assembly, desta vez vamos falar um pouco sobre manipulao de memria dentro do ambiente Windows. Para tal, resolvi escolher um tema interessante, principalmente aos jogadores, que representa muito bem o processo de modificao de memria: os trainers. Trainers so basicamente aplicativos que adicionam novos recursos a um determinado jogo, sem alterar nenhum arquivo em disco, mexendo apenas naquilo que foi carregado na memria. Um bom exemplo de trainers so aquelas ferramentas que adicionam veculos ao GTA. Voc basicamente inicia o jogo e em seguida executa o trainer, no qual voc escolhe um determinado veculo e o aplicativo faz o trabalho de gerar o automvel no jogo. Isso feito basicamente manipulando os dados carregados na memria pelo GTA e os adaptando e alterando para pode criar um novo veculo. Eles so somente um exemplo. Como outros exemplos podemos citar os aplicativos anti-vrus, que alteram boa parte do espao de memria dos aplicativos do Windows para poder ter um controle sobre o que acontece dentro deles, podendo tomar decises e alertar o usurio antes que algo ruim acontea ao sistema. Programas de captura de tela tambm funcionam de forma semelhante. Eles se integram ao espao de memria do Windows ou dos jogos e monitoram o teclado, podendo identificar quando determinada tecla foi pressionada e realizar a captura da imagem. Aps essa breve introduo, creio que j d para ter certa noo da importncia e da utilizao desse processo, seja para reforar a segurana do sistema ou para programar addons aos seus jogos. A inteno deste guia no ensinar a criar trainers, mas sim exemplificar uma forma de acessar a memria dos aplicativos. Tal conhecimento pode ser utilizado posteriormente para programar aplicativos semelhantes aos exemplificados dois pargrafos acima. No nosso estudo vamos modificar um jogo extremamente simples e sem muito sentido, que programei apenas com a finalidade de estudar esse processo. Consiste basicamente em uma janela e alguns botes, com os quais voc pode comprar itens enquanto possuir dinheiro para tal. O que ns vamos fazer bolar um trainer que adicione mais dinheiro no nosso joguinho, sem modificar nada em disco ou no executvel do programa. Vale lembrar que bom ter certo conhecimento de programao e o bsico em linguagem assembly, j que vamos fazer o debug do nosso alvo, identificar o local onde o valor do dinheiro fica armazenado e programar um trainer para modific-lo.

4 FERRAMENTAS NECESSRIAS Abaixo segue uma breve lista das ferramentas que vamos utilizar: OllyDbg o Um dos melhores debuggers disponveis. Vamos utiliz-lo para identificar o local de memria onde o jogo guarda a informao do dinheiro. o http://www.ollydbg.de/download.htm WinASM o IDE de programao em assembly. Gratuita e muito prtica de se trabalhar. Necessita o MASM32 para compilar. o http://www.winasm.net/ MASM32 o Compilador de assembly mais conhecido. Tambm gratuito. o http://www.masm32.com/masmdl.htm Alvo e cdigos-fonte o Nosso pequeno jogo e o trainer j compilado. Inclui o cdigo-fonte de ambos os aplicativos o http://www.fergonez.net/files/tut_memoria.rar

OBS.: A etapa de configurao do WinASM e do MASM32 descrita na segunda parte do meu artigo sobre a segurana do Windows, disponvel no link abaixo: http://www.fergonez.net/files/seg_windows_pt2.pdf Recomendo ler, pois os conhecimentos descritos no guia de segurana sero utilizados neste artigo. No mesmo guia consta uma breve descrio sobre o OllyDbg e o seu funcionamento. Por essa razo, no explicarei como utiliz-lo aqui.

5 IDENTIFICANDO O LOCAL DE MEMRIA Vamos dar incio ao nosso estudo. A primeira coisa que devemos fazer analisar o bsico do nosso jogo, identificando alguma de suas caractersticas que possam facilitar o trabalho dentro do OllyDbg. Apenas execute o jogo (jogo.exe, disponvel dentro da pasta Jogo de Testes), brinque com os botes e veja um pouco do seu funcionamento. Cada vez que voc pressiona algum dos botes de compra ele adiciona o item lista de objetos adquiridos ou exibe uma mensagem caso voc no tenha dinheiro suficiente. Essa mensagem vai ser de extrema importncia na hora de localizar o endereo de memria onde armazenado o dinheiro do jogo. A mensagem de texto faz parte da API do Windows, contida dentro da user32.dll e que pode ser chamada por qualquer linguagem de programao que suporte uma linkagem com a API. O que ns vamos fazer abrir nosso alvo no OllyDbg e configurar um breakpoint na chamada da funo MessageBoxA (que exibe a caixa de texto). Fazendo isso, o programa ir congelar quando estiver prestes a exibir a mensagem. Porque ativar um breakpoint nessa funo? Pela lgica, quando voc clica em algum dos botes, o jogo teoricamente verifica pelo dinheiro disponvel. Caso seja suficiente, ele adiciona o item na lista, caso contrrio ele exibe a mensagem. Ento se ns congelarmos o programa quando a mensagem exibida, saberemos que estamos prximos do local onde feita a verificao de crdito e a comparao com o preo do aparelho em questo. Inicie o OllyDbg e abra o alvo (jogo.exe). Voc ver uma tela semelhante a essa (provavelmente o tema de cores ser diferente, mas isso no problema).

6 Vamos ento buscar pela funo da API que exibe a mensagem de texto (MessageBoxA). Dentro do Olly, pressione ALT+E. Uma janela chamada Executable Modules ser aberta. Nela esto listadas todas as DLLs das quais o aplicativo depende, dentre elas a user32.dll, que comporta a funo MessageBoxA. Selecione o primeiro item da lista, cujo nome deva ser jogo, clique com o boto direito e em seguida clique em View Names. Uma nova janela aparecer, contendo todas as funes (e no mais as DLLs) utilizadas pelo aplicativo. Repare que um dos itens a funo MessageBoxA que procurvamos. Clique novamente com o boto direito sobre essa funo e selecione a opo Set breakpoint on every reference.

Esse item far com que o programa insira um breakpoint em cada referncia feita a funo MessageBoxA, congelando o programa assim que a execuo atingir esse ponto. Feito isso, feche a janela Names e Executable Modules, retornando a tela principal do Olly. Vamos iniciar a execuo do programa dentro do debugger. Para isso, basta clicar no boto Play e o Olly comea a execuo. Para pararmos no breakpoint, precisamos fazer o programa chamar a funo MessageBox, ento tente comprar 2 TVs HDTV. Antes de o jogo exibir a mensagem de dinheiro insuficiente, o Olly vai pausar a execuo e retornar o foco para si. A linha onde o programa foi congelado ficar marcada e a regio do cdigo ser semelhante a essa:

Repare que ele foi pausado no instante em que a mensagem seria exibida. possvel notar que os quatro argumentos necessrios para a exibio da mensagem de texto j foram colocados na pilha: tipo da janela, ttulo, mensagem e a janela pai (veja o guia de segurana caso no tenha entendido esse processo). Vamos retomar agora aquela

7 lgica mencionada no incio. A lgica era que o jogo provavelmente verifica pela quantia de dinheiro e caso ela seja insuficiente, exibe a mensagem. Pois bem, ns camos nessa regio do cdigo justamente por que no possumos dinheiro suficiente para comprar o item. Vamos analisar as linhas logo acima da chamada da MessageBox:
CMP WORD PTR DS:[40309C],1194

Temos aqui uma instruo de comparao (CMP). Sua sintaxe a mostrada abaixo:
CMP destino, fonte

Essa instruo subtrai virtualmente seus operandos (fonte destino), realizando a subtrao mas no armazenando resultados, alterando apenas as flags do processador. Caso essa subtrao resulte em zero ou em um valor negativo (indicando que a fonte menor que o destino), a instruo seta a CarryFlag (CF) para 0. Outras flags so alteradas no processo, mas no vo nos interessar. Logo abaixo dessa instruo temos um jump condicional:
JNB SHORT jogo.004011B7

JNB significa Jump if not Below, que traduzindo para o portugus seria Salte se no abaixo. A condio de salto dela depende da CarryFlag. Se ela for zero, o salto realizado, caso contrrio ele executa a prxima instruo, dando continuidade a execuo. Podemos resumir essas instrues de uma maneira mais simples e didtica (no da forma mais correta), atravs de um pseudocdigo:
Se fonte <= destino Pule para endereo Caso contrrio Exiba mensagem de dinheiro insuficiente Fim Se

Adaptando o pseudocdigo aos valores reais mostrados pelo Olly teremos (lembre-se de que estamos sempre trabalhando com valor hexadecimal):
Se 0x1194 <= valor_do_endereo(0x40309C) Pule para 0x4011B7 Caso contrrio Chame a MessageBox(Dono, Mensagem, Ttulo, Estilo) Fim Se

Repare que ele est comparando um nmero com o valor contido em um endereo de memria. O nmero o 0x1194, que converteido para a base decimal fica 4500. O valor contido no endereo 0x40309C possvel obter pelo Olly selecionando a linha onde est localizada a instruo CMP. Logo abaixo da rea do disassembly mostrado o valor daquele endereo de memria:

Pela imagem podemos ver que o valor contido no endereo 0x40309C 0x09C4, que convertendo para a base decimal nos d 2500. So valores extremamente interessantes, pois se voc reparar, 4500 o preo do item HDTV e 2500 o dinheiro que voc possui atualmente no jogo. Notando isso, ns matamos a charada, pois identificamos qual o endereo de memria utilizado pelo alvo para armazenar a quantia de dinheiro que o jogador possui atualmente, que nesse caso 0x0040309C. Guarde bem este nmero, pois vamos utiliz-lo na hora de programar o trainer.

9 PROGRAMANDO O TRAINER Vamos dar incio ao processo de programao. Antes de entrar com cdigos, vou dar uma breve explicao de como feito esse processo, utilizando apenas os recursos e a documentao oferecida pela prpria Microsoft e pela API do Windows. Ns temos um alvo, e este possui seu espao de memria delimitado, paginado e protegido pelo sistema, para evitar que outros aplicativos invadam ou modifiquem a sua regio por descuido. No entanto, limitar completamente a memria paginada do aplicativo tornaria o sistema muito sufocado, dificultando bastante a interface entre duas ou mais aplicaes distintas. Por essa razo que o Windows possui funes especficas que permitem ter o controle do espao de memria alheio, caso contrrio no teramos aplicativos anti-malware ou at mesmo de monitoramento de recursos. O processo que vamos utilizar faz o uso apenas da API do Windows, utilizando as funes programadas e embutidas no prprio sistema. A primeira atitude obter o valor do handle (controle) da janela alvo. Tendo o controle da janela, possvel buscar o handle do processo pai do alvo, que posteriormente vai ser utilizado para obter o domnio sobre o processo e fazer a alterao desejada na memria. Todo o cdigo est disponvel dentro do arquivo RAR indicado no incio do tutorial. Ele j vem pronto para ser aberto e compilado no WinAsm. Abra o arquivo trainer.wap contido dentro da pasta Trainer. Como disse no incio do tutorial, recomendvel ter um conhecimento bsico de assembly e da sintaxe adotada pelo MASM32. Vou ressaltar alguns trechos importantes do cdigo aqui (ele est comentado no arquivo):
.data ddEndereco dd 0040309Ch

.data? hInstance dwDinheiro dwProcessId hProcess

dd dw dd dd

? ? ? ?

Temos aqui apenas algumas declaraes de variveis (as mais importantes). O endereo de memria que vamos modificar fica armazenado na varivel ddEndereo. O valor dessa varivel foi aquele endereo que obtivemos no OllyDbg. Em seguida vem as variveis no inicializadas que sero utilizadas basicamente para os handles e IDs obtidos atravs de API. Uma exceo a dwDinheiro, que armazenar a quantia de crditos injetada no alvo.

10 Em seguida vem o trecho mais importante do trainer, que a funo de callback utilizada para processar as mensagens do Windows e verificar os eventos que ocorreram. Abaixo uma imagem de como ela se assemelha (removi os comentrios para poupar espao):

Para quem j programa sobre a API do Windows esse cdigo no novidade, portanto vou ressaltar a parte mais importante, que realmente executa o patch de memria, comeando pela funo FindWindow.
invoke FindWindow,NULL,offset szJanela

E a sua estrutura, retirada do MSDN:


HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpWindowName );

Bem simples, recebe apenas dois argumentos. O primeiro o lpClassName, que no utilizado neste guia e pode ser nulo. O segundo um ponteiro para o nome da janela (foi declarada na seo .data do cdigo). Em seguida temos a funo GetWindowThreadProcessId:
invoke GetWindowThreadProcessId,eax, offset dwProcessId

11 Sua sintaxe descrita pelo MSDN tambm:


DWORD GetWindowThreadProcessId( HWND hWnd, LPDWORD lpdwProcessId );

Ela pede o handle da janela e um ponteiro para armazenar o valor do ProcessID. O handle foi obtido na funo anterior (FindWindow) e ficou armazenado em EAX (registrador de retorno padro do Windows). Estamos passando o EAX diretamente como parmetro desta funo. O ldwProcessId o ponteiro para uma DWORD onde ser armazenado o valor do ProcessId, aps o processamento da funo. Tendo o ProcessId possvel j obter o acesso ao programa alvo. Isso feito pela funo OpenProcess:
invoke OpenProcess,PROCESS_ALL_ACCESS, FALSE, dwProcessId

Sua sintaxe:
HANDLE OpenProcess( DWORD fdwAccess, BOOL fInherit, DWORD IDProcess );

Essa funo pede trs argumentos: tipo de acesso (total, restrito, para debug, etc), herana (se vai ser possvel controlar os processos filhos) e o ID do processo alvo. Ela retorna um handle para o processo aberto (caso seja bem sucedida), que movido para o hProcess. Por fim, esse hProcess utilizado na operao mais importante do programa, que a escrita na memria do alvo, executado pela funo WriteProcessMemory:
invoke WriteProcessMemory,hProcess, ddEndereco, addr dwDinheiro, 2, offset lpWrittenBytes

Sintaxe:
BOOL WriteProcessMemory( HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesWritten );

Ela pede cinco argumentos. Os nomes so auto-explicativos, mas vou explicar cada um deles mesmo assim. hProcess o handle do processo alvo, obtido na operao anterior. lpBaseAddress o endereo de memria que ser modificado pela funo. Ele foi declarado l no incio do cdigo, na seo .data, como sendo 0040309Ch (ou 0x0040309C nos padres do C/C++). O prximo argumento o lpBuffer, um ponteiro para os valores que sero inseridos. No nosso caso ele corresponde ao dinheiro

12 injetado. nSize a quantidade de bytes a serem escritos a partir do buffer indicado no lpBuffer. Como estamos inserindo uma WORD, devemos escrever dois bytes na memria. Por ltimo tem o lpNumberOfBytesWritten que armazena a quantidade de bytes escritos com sucesso. No vamos utilizar ele no nosso trainer, mas sempre bom verificar se o nmero de bytes escritos corresponde ao nmero que bytes que desejvamos escrever. Um valor diferente indica uma falha parcial ou total na operao ( possvel verificar pelo estado do EAX aps a execuo, pois caso ele seja nulo, a execuo foi mal-sucedida). A ltima funo da API utilizada durante o processo a CloseHandle:
invoke CloseHandle, hProcess

Sintaxe:
BOOL CloseHandle( HANDLE hObject );

Como o prprio nome j diz, ela apenas fecha o processo aberto, liberando a conexo previamente estabelecida entre o alvo e o trainer. Seu nico argumento o hObject, onde devemos passar o handle do processo (ou qualquer outro objeto) a ser fechado. No nosso caso o hProcess. Essas funes descritas realizam todo o processo de modificao de memria, utilizando apenas os meios legais e oficiais oferecidos pela Microsoft. O projeto do WinAsm j vem com um arquivo .rc, contendo os itens da janela do trainer, ento basta apenas compilar o projeto para gerar o executvel.

Ele vai compilar, linkar e executar o trainer aps a concluso do processo. Lembre-se de que para o trainer funcionar, preciso ter o jogo rodando junto, ento abra o alvo (jogo.exe na pasta Jogo de Teste) antes de aplicar o patch. Com ambos os aplicativos abertos, basta determinar a quantia de dinheiro e clicar em Aplicar. Automaticamente a quantia disponvel no jogo ser alterada para o valor escolhido.

13

14 CONCLUSO Vamos ficando por aqui. Espero que este guia tenha sido til, explicando um pouco sobre o uso das APIs do Windows para obter dados de outros aplicativos. Como disse no incio do tutorial, o trainer foi apenas um exemplo devido praticidade de se fazer um tutorial baseado neles. O mesmo processo pode ser utilizado para criao de outros softwares, principalmente queles relativos a segurana do sistema, proteo residente ou qualquer aplicao em que preciso monitorar as aes antes que elas aconteam ou sejam processadas pelo alvo, como no caso dos aplicativos de captura de tela. Abraos e at a prxima! Fergo Agosto 2007 Website: http://www.fergonez.net

Você também pode gostar