Características de Arrays em Engenharia Reversa

void processarDados()
{
    int valores[10] = { 10, 20, 30, 40, 50, 60, 70, 80 };
    valores[0] = 110;
    valores[1] = 120;
    valores[2] = 130;
    valores[3] = 140;
    valores[4] = 150;
    valores[5] = 160;
    valores[6] = 170;
    valores[7] = 180;
    return;
}

    5:     int valores[10] = { 10, 20, 30, 40, 50, 60, 70, 80 };
0012F590  mov         dword ptr [ebp-28h],0Ah  
0012F597  mov         dword ptr [ebp-24h],14h  
0012F59E  mov         dword ptr [ebp-20h],1Eh  
0012F5A5  mov         dword ptr [ebp-1Ch],28h  
0012F5AC  mov         dword ptr [ebp-18h],32h  
0012F5B3  mov         dword ptr [ebp-14h],3Ch  
0012F5BA  mov         dword ptr [ebp-10h],46h  
0012F5C1  mov         dword ptr [ebp-0Ch],50h  
0012F5C8  xor         eax,eax  
0012F5CA  mov         dword ptr [ebp-8],eax  
0012F5CD  mov         dword ptr [ebp-4],eax  
    6:     valores[0] = 110;
0012F5D0  mov         eax,4  
0012F5D5  imul        ecx,eax,0  
0012F5D8  mov         dword ptr [ebp+ecx-28h],6Eh  
    7:     valores[1] = 120;
0012F5E0  mov         eax,4  
0012F5E5  shl         eax,0  
0012F5E8  mov         dword ptr [ebp+eax-28h],78h  
    8:     valores[2] = 130;
0012F5F0  mov         eax,4  
0012F5F5  shl         eax,1  
0012F5F7  mov         dword ptr [ebp+eax-28h],82h  
    9:     valores[3] = 140;
0012F5FF  mov         eax,4  
0012F604  imul        ecx,eax,3  
0012F607  mov         dword ptr [ebp+ecx-28h],8Ch  
    10:    valores[4] = 150;
0012F60F  mov         eax,4  
0012F614  shl         eax,2  
0012F617  mov         dword ptr [ebp+eax-28h],96h  
    11:    valores[5] = 160;
0012F61F  mov         eax,4  
0012F624  imul        ecx,eax,5  
0012F627  mov         dword ptr [ebp+ecx-28h],0A0h  
    12:    valores[6] = 170;
0012F62F  mov         eax,4  
0012F634  imul        ecx,eax,6  
0012F637  mov         dword ptr [ebp+ecx-28h],0AAh  
    13:    valores[7] = 180;
0012F63F  mov         eax,4  
0012F644  imul        ecx,eax,7  
0012F647  mov         dword ptr [ebp+ecx-28h],0B4h  

Identificação de Arrays em Engenharia Reversa


Este é um array local de inteiros int valores[10] na pilha

Na desmontagem, suas características são:

  1. Um bloco contínuo de espaço na pilha
  2. Base fixa (ebp-28h)
  3. Espaçamento fixo de 4 bytes entre elementos
  4. Padrão de acesso consistente: [ebp + índice*4 - 28h]
  5. Índice × tamanho do elemento = deslocamento

Ao encontrar esse padrão em engenharia reversa, é altamente provável que seja um array.

Estrutura da Stack Frame e Array (Importante)


1️⃣ Tamanho da Stack Frame

0012F5B3  sub esp,0F4h

Isso indica:

  • A função alocou 0xF4 = 244 bytes na pilha
  • Inclui: array, variáveis temporárias, preenchimneto de depuração, cookie, etc.

2️⃣ Endereço de início do array

mov dword ptr [ebp-28h],0Ah
mov dword ptr [ebp-24h],14h
mov dword ptr [ebp-20h],1Eh
...
mov dword ptr [ebp-0Ch],50h

Esta é a evidência mais direta de um array:

Elemento Endereço
valores[0] ebp-28h
valores[1] ebp-24h
valores[2] ebp-20h
valores[3] ebp-1Ch
valores[4] ebp-18h
valores[5] ebp-14h
valores[6] ebp-10h
valores[7] ebp-0Ch

Incremento de +4 bytes entre cada elemento → Array de int

3️⃣ Por que é int valores[10]?

mov dword ptr [ebp-8],eax
mov dword ptr [ebp-4],eax

  • De -28h a -4h cobre 40 bytes
  • 40 ÷ 4 = 10 inteiros
  • Apesar de só 8 elementos serem inicializados, o tamanho do array é 10

Em engenharia reversa: Não se deixe enganar pela quantidade de inicializações, observe o tamanho do espaço alocado

Características da Inicialização de Arrays em Reversa


Código fonte:

int valores[10] = {10, 20, 30, 40, 50, 60, 70, 80};

Correspondente em assembly:

mov dword ptr [ebp-28h],0Ah
mov dword ptr [ebp-24h],14h
mov dword ptr [ebp-20h],1Eh
mov dword ptr [ebp-1Ch],28h
...
mov dword ptr [ebp-0Ch],50h

Técnicas de Identificação em Reversa

  • Escritas contínuas
  • Passo fixo
  • Execução incondicional

️ Isso representa a inicialização de array expandida em tempo de compilação

Características Principais do Acesso por Índice (Foco)


1️⃣ valores[0] = 110;

mov eax,4
imul ecx,eax,0
mov dword ptr [ebp+ecx-28h],6Eh

Redução:

ecx = 4 * 0
[ebp - 28h + ecx] = 110

Fórmula padrão:

valores[i] = *(base + i * sizeof(int))

2️⃣ valores[1] = 120;

mov eax,4
shl eax,0
mov dword ptr [ebp+eax-28h],78h

  • shl 01 * 4
  • Deslocmaento = 4

️ Acessando valores[1]

3️⃣ valores[2] / valores[4] (usando shl)

shl eax,1   ; 2 * 4
shl eax,2   ; 4 * 4

O compilador usa deslocamento (shift) em vez de multiplicação (mais rápido)

4️⃣ valores[3] / valores[5~7] (usando imul)

imul ecx,eax,3
imul ecx,eax,5
imul ecx,eax,7

Quando o índice não é potência de 2 → usa imul

Resumo em Reversa: "Fórmula Ouro" de Acesso a Arrays

[ebp + índice * tamanho_do_elemento + deslocamento_base]

Neste caso específico:

[ebp + índice*4 - 28h]

Por que os Acessos não são Uniformes? (shl / imul misturados)


Esta é uma estratégia de otimização do compilador, não diferença no código fonte:

Índice Método gerado
1, 2, 4 shl
3, 5, 6, 7 imul

Em engenharia reversa:

Qualquer padrão com índice × constante + base fixa = array

Não se preocupe com a instrução específica.

Lista de Verificação para Identificação de Arrays em Reversa (Aplicação Prática)


Ao encontrar as seguintes características, pode marcar diretamente como array:

Endereços contínuos na pilha ✔ Deslocamento inicial fixo (ebp-28h) ✔ Espaçamento entre elementos = tamanho do tipo ✔ Índice envolvido em multipilcação/deslocamento ✔ Vários acessos à mesma base

Reconstrução Final em Reversa (Completa)


void processarDados()
{
    int valores[10];
    
    valores[0] = 110;
    valores[1] = 120;
    valores[2] = 130;
    valores[3] = 140;
    valores[4] = 150;
    valores[5] = 160;
    valores[6] = 170;
    valores[7] = 180;
}

Resumo em Uma Frase (Mnemônico de Reversa)

"Contínuo + base fixa + índice × tamanho = array"

Tags: engenharia reversa assembly desmontagem C++ Arrays

Publicado em 7-3 18:47