05. Criando um Patcher
Este tutorial ensina como alterar os bytes de um executável para alterar o seu comportamento sem precisar do OllyDbg. Vou utilizar o executável do tutorial anterior ( Tutorial #4 ).
-Download: fergo_nag.zip
INTRODUÇÃO
Se você leu o tutorial #4, você deve estar lembrado que tivemos que anular uma linha, para que uma mensagem de texto não fosse exibida. No caso, preenchemos a chamada da função messagebox com NOPs ( cujo código é 90 em hexadecimal e ocupa somente 1 byte ). Mas como fazer isso sem que o usuário tenha conhecimento de RCE e/ou OllyDbg? Você faz um outro utilitário que modifica o alvo!
Vamos lá. Tinhamos a seguinte situação no tutorial 4
Preciso explicar algumas coisas. Cada instrução em ASM tem um valor, que geralmente ocupa 1 byte, seguido de algum argumento. A segunda coluna do Olly, contém o valor da instrução ( OpCode ) em Hexadecimal, e a terceira coluna mostra o que chamamos de Mnemônico, ou seja, o "apelido" ao OpCode, que facilita o nosso entendimento.
Reparare na linha 00401029. Temos o OpCode "E8 B0010000" e o mnemônico referente ao OpCode: "CALL <SMP.&user32.MessageBoxA". Nesse caso, E8 indica um CALL e os outros 4 bytes "B0010000" ( lembre-se que estamos trabalhando com valores hexadecimais, que variam de 00 a FF ( 0 a 255 ) e 2 algarismos ocupam 1 byte na memória ) representam a função MessageBoxA.
Agora vou falar um pouco do "Address", o número da linha. O número da linha indica simplesmente a localização de cada instrução a ser executada, em hexadecimal. Ela inicia em 0 e vai aumentando a cada instrução. Digamos que eu tenha um comando no endereço 00, e esse comando ocupa 2 bytes ( um PUSH seguido de uma constante, por exemplo: PUSH 69 ). A próxima instrução vai estar no endereço 00 mais os 2 bytes que a instrução anterior ocupa, logo, ela vai estar no endereço 02. É através deste endereço que nós vamos nos localizar para fazer o Patch, mas tem um porém: o arquivo executável não começa logo com os comandos. Antes de iniciar os comandos, ele tem todo um cabeçalho, que indica diversas características, etc. Esse cabeçalho tem um tamanho de 1024 bytes ( 400 em Hex ) e somente após ele que começam as instruções. Ou seja, o primeiro comando não vai estar no byte 0, mas sim no byte 1025 ( 401 em Hex ).
Voltando ao programa. Repare na linha 00401023. Ali começam a ser puxados todos os 4 argumento que o CALL necessita para exibir a MessageBox.
No tutorial anterior, nós anulamos tudo referente a MsgBox. Quando você mandou preencher as linhas com NOPs, por exemplo, ele colocou o valor 90 ( NOP ) no byte 29 ( que continha o E8 ( CALL )), mas também incluiu diversos outros NOPs em linhas que nem existiam, sabe porque? Porque não basta ele anular o byte 29, ele tem que anular os outros 4 bytes seguintes também ( lembre-se que era E8 B1 01 00 00). Por isso que ele adicionou NOPs nos bytes 29, 2A, 2B, 2C, 2D também. Então, se queremos fazer um patcher, temos que anular tudo o que é referente a nossa mensagem de texto.
Veja a tabela abaixo que mostra os bytes originais do arquivo e os bytes que vamos modificar:
Bytes originais | Bytes Modificados | |
23 | 6A ( PUSH ) | 90 |
24 | 30 | 90 |
25 | 50 ( PUSH EAX ) | 90 |
26 | 53 ( PUSH EBX ) | 90 |
27 | 6A ( PUSH ) | 90 |
28 | 00 | 90 |
29 | E8 ( CALL ) | 90 |
2A | B1 | 90 |
2B | 01 | 90 |
2C | 00 | 90 |
2D | 00 | 90 |
2E | 56 ( PUSH ESI ) | 90 |
CRIANDO O PATCHER
Antes de iniciar o patcher, vamos lembrar o que e onde devemos alterar. Nós temos que preencher 11 bytes ( desde o primeiro PUSH no endereço 00401023 até o 00 no endereço 0040102D ) com o valor 90, que indica nenhuma operação. Onde vamos alterar? No arquivo executável é claro. Quais bytes? 23 ( 35 em decimal ), 24 ( 36 em decimal ) e assim por diante? NÃO! Lembre-se que antes de iniciar os comandos, tem 1024 bytes compondo o cabeçalho do executável. 1024 é 400 em Hexadecimal ( use a calculadora do windows ), então vamos ter que alterar do byte 423 até 42D ( 1059 até 1069 ).
Vamos lá. Vou escrever novamente o código em VB, pois é simples de entender. Poderia ter escrito de uma maneira menor, mas ficaria mais complicado o entendimento. Adicione um Command Button com nome de cmbPatch ). Lembrando que o patcher deve estar na mesma pasta do alvo
Private Sub cmbPatch\_Click()
....Dim bytFile() As Byte 'Nosso array ( vetor ) de bytes
....Dim strFile As String 'Nosso alvo
....Dim i As Integer 'Só para as iterações
....strFile = App.Path & "\\fergonag.exe" 'Define o local onde está o alvo
....ReDim bytFile(FileLen(strFile) - 1) As Byte 'Redimensiona o nosso array de bytes para o tamanho do alvo
....Open strFile For Binary As #1
........Get #1, , bytFile() 'Pega todos os bytes do alvo e coloca no nosso array
....Close #1
....For i = &H423 To &H42D
........bytFile(i) = &H90 'Coloca o valor 90 do byte 423 (hex) até 42D
....Next
....Open strFile For Binary As #1
........Put #1, , bytFile() 'Devolve os bytes já modificados para o alvo
........MsgBox "Alvo alterado com sucesso", vbInformation, "Wee" 'Mostra mensagem de texto avisando que tudo ocorreu bem
....Close #1
End Sub
Pronto, agora é só compilar e partir pro abraço. Não tenho certeza, mas talvez isso funcione até com VB Script :P
Se quiser baixar o código fonte acima já nos padrões do VB clique aqui
F3rGO!