Oficina
Bloco de Notas com linhas numeradas
Seg 28 Mai 2007 20:28 |
- Detalhes
- Categoria: Oficina de Assembly
- Atualização: Quinta, 18 Junho 2009 11:44
- Autor: vovó Vicki
- Acessos: 23201
Enxertando o código no executável
Já temos um projeto de código, agora é preciso incluí-lo no executável. Mais uma vez, vamos por partes para não nos perdermos.
Inserindo o código da altura da janela
É preciso encontrar espaço ocioso no executável que possa ser utilizado para incluir o código. Usando o PE Explorer (faça o download do trial na Heaven Tools), verificamos o seguinte nos cabeçalhos das seções:
Nome | Tam.Virtual | End.Virtual | Tam.Dados | Ponteiro | Características | Sobra |
.text | 00003EFC | 00401000 | 00004000 | 00001000 | 60000020 | 104 (260) |
.data | 0000083C | 00405000 | 00001000 | 00005000 | C0000040 | 7C4 (1988) |
.idata | 00000E22 | 00406000 | 00001000 | 00006000 | 40000040 | 1DE (478) |
.rsrc | 00006000 | 00407000 | 00006000 | 00007000 | 40000040 | -0- |
.reloc | 00000AAE | 0040D000 | 00001000 | 0000D000 | 42000040 | 552 (1362) |
- Procurando espaço livre
Vamos tomar a seção .data como exemplo. Esta seção foi dimensionada para ocupar um espaço de 1000 (tamanho dos dados) a partir do endereço 405000. Seu tamanho virtual é 83C e o espaço total disponível é de 1000, indicando que ainda há 7C4 bytes livres (1000 - 83C = 7C4). Tudo isto no sistema hexadecimal. Transformando os números para o sistema decimal, apenas por curiosidade, sabemos que o espaço reservado é de 4096, o espaço ocupado é de 2108, restando portanto 1988 bytes livres.
A segunda maior sobra de espaço se encontra na seção .reloc, onde há 1362 (552 em hexa) bytes disponíveis. Vamos escolher a seção .reloc para abrigar nosso código adicional. Ele cabe perfeitamente neste espaço livre, portanto, não vai haver a necessidade de ampliar o tamanho da seção escolhida.
- Calculando o tamanho do salto
Segue-se agora uma longa jornada de cálculos. O primeiro deles será determinar o endereço do primeiro salto. Conforme visto anteriormente, foi decidido fazer um desvio no ponto onde o programa põe na pilha o valor da altura e da largura da janela-filha "edit". Reveja o trecho de código obtido através do debugador OllyDbg (note as referências preciosas que o programa fornece!):
O OllyDbg está disponível na seção de downloads em Informática / Debuggers.
Portanto, faremos um salto incondicional - jmp do endereço 40122D para o início do espaço vago da seção .reloc. Pelo cabeçalho de seções verificamos que o endereço virtual inicial de .reloc é 40D000 e nós queremos colocar o código adicional AAEh bytes adiante. Basta somar ao endereço virtual da seção o tamanho do código para obter o endereço inicial do código adicional, ou seja, 40D000 + AAE = 40DAAE. Nosso salto, então, deverá ser de 40122D para 40DAAE, o que corresponde a um salto de C881 bytes. Como sabemos que nossa instrução, por ser um salto longo, conterá 5 bytes, precisamos descontar os mesmos para calcular o valor correto para o salto: 40DAAE - 40122D - 5 = C87C.
De posse deste valor, vamos compor a instrução lembrando que a distância do salto é indicada em 4 bytes na ordem inversa, ou seja, 00 00 C8 7C será indicado como 7C C8 00 00:
Instrução | Código hexadecimal | Observação |
JMP | E9 | Salto incondicional longo |
byte 1 | 7C | |
byte 2 | C8 | |
byte 3 | 00 | |
byte 4 | 00 | Resultado: E9 7CC80000 |
Para o salto de retorno é preciso pular alguns bytes "para trás". No exemplo anterior, pulamos 51324 bytes "para frente", no retorno teremos que saltar 51343 bytes "para trás", ou seja, -51343 (menos 51343). Em hexadecimal, 401235 - 40DABF - 5 = FFFF3771.
- Alterando o código para o salto
O programa original deve sofrer as seguintes alterações para a introdução do salto:
Endereço | Código original | Alterar para |
0040122D | FF7424 0C PUSH DWORD PTR SS:[ESP+C] | E9 7C C8 00 |
00401231 | FF7424 0C PUSH DWORD PTR SS:[ESP+C] | 00 90 90 90 |
00401235 | 6A 00 PUSH 0 |
Observe que ocupamos apenas o primeiro byte (FF) da instrução no endereço 401231 para poder completar nossa instrução de salto. Restaram os códigos 74, 24 e 0C que foram anulados com três instruções NOP (90) para manter íntegro o tamanho do código original e não desestruturar outros endereçamentos existentes. Com o salto devidamente inserido, este bloco de código passa a ser:
Endereço | Salto adicionado | |
0040122D | E9 7CC80000 | JMP NOTEPAD.0040DAAE |
00401232 | 90 | NOP |
00401233 | 90 | NOP |
00401234 | 90 | NOP |
00401235 | 6A 00 | PUSH 0 |
- Adicionando o código para alterar o tamanho da janela "edit"
Quando alcançar a linha 40122D, o salto é efetuado e a execução do código continua no endereço 40DAAE, exatamente o ponto onde vamos inserir o bloco 1 do código adicional. Nele, antes de refazermos as operações das linhas 40122D e 401231 que foram suprimidas para poder inserir o salto, a altura da janela "edit" é diminuída em 20 pixels. Para tanto, utilizamos o registrador EAX:
Endereço | Hexa | Operação | Observações |
0040DAAE | E9 7CC80000 | MOV EAX,DWORD PTR SS:[ESP+C] | ; Obtém o valor da altura |
0040DAB2 | 83E8 14 | SUB EAX,14 | ; Subtrai 14h = 20d da altura |
0040DAB5 | A3 70DB4000 | MOV DWORD PTR DS:[40DB70],EAX | ; Guarda nova altura em 40DB70 |
0040DABA | 50 | PUSH EAX | ; Nova altura na pilha |
0040DABB | FF7424 0C | SS:[ESP+C] | ; Largura no topo da pilha |
0040DABF | E9 7137FFFF | JMP NOTEPAD.00401235 | ; Retorna ao ponto de chamada |
Use um editor hexadecimal (Hackman ou Hacker's View, por exemplo) e faça as alterações propostas numa cópia do programa notepad.exe (o Hacker's View permite a entrada de código assembly e calcula os jumps, o que facilita muito o trabalho). Qualquer um dos programas sugeridos mostra o código a partir da posição 0 (zero) e NÃO pelo endereço virtual. Portanto, é preciso conhecer a posição dos endereços virtuais pelo seu deslocamento (offset) a partir da posição zero. Isto se consegue subtraindo a base da imagem (00400000) do endereço pretendido. Por exemplo, o deslocamento do endereço 40122D é 122D (40122D - 400000 = 122D). Caso você encontre dificuldades, o W32Dasm indica no rodapé o offset de cada linha de código
- Testando a primeira etapa
Após fazer as modificações sugeridas é aconselhável testar o programa modificado. Tudo que esperamos é que a janela-filha "edit" tenha uma altura menor do que a janela principal. Se tudo correu bem, a janela do novo bloco de notas tem um "rodapé" de 20 pixels (a diferença de altura entre as duas janelas), o qual será usado para imprimir o texto com a indicação dos números das linhas.