challenges.re - RE 02#
O Challenges.re é um site com uma compilação de exercícios de Reverse Engineering. Estou escrevendo este documento apenas para meu próprio uso, para praticar meus conhecimentos em programação assembly e engenharia reversa. Se você pretende resolver esses exercícios por conta própria algum dia, por favor, não leia minha solução, tente resolver sozinho. Minha resposta pode estar errada, então não confie em mim, confie no processo.
Pergunta#
Reverse Engineering challenge #2. Tags: . O que esse código faz?
Código Assembly#
Para esclarecer minhas dúvidas sobre este exercício, decidi comentar cada linha com uma descrição mais detalhada.
mov eax,DWORD PTR [esp+0x4] ; MOVE o valor do endereço ESP+0x4 para EAX
bswap eax ; Troca a posição dos bytes de um valor, por exemplo: 0x123456 => 0x563412
mov edx,eax ; Mover o valor de EAX para EDX
and eax,0xf0f0f0f ; Faça uma comparação AND com 0x0F0F0F0F e armazene em EAX.
and edx,0xf0f0f0f0 ; Faça uma comparação AND com 0xF0F0F0F0 e armazene no EDX.
shr edx,0x4 ; Desloca o binário de EDX 4 bits para a direita (divida por 16).
shl eax,0x4 ; Desloca o binário de EAX 4 bits para a esquerda (multiplique por 2⁴)
or eax,edx ; Faça uma comparação OR e armazene em EAX.
mov edx,eax ; Mover o valor EAX para EDX
and eax,0x33333333 ; Faça uma comparação AND e armazene em EAX.
and edx,0xcccccccc ; Faça uma comparação AND e armazene no EDX.
shr edx,0x2 ; Desloca o binário de EDX 2 bits para a direita (divida por 4).
shl eax,0x2 ; Desloca o binário de EAX 2 bits para a esquerda (multiplique por 2²).
or eax,edx ; Faça uma comparação OR e armazene em EAX.
mov edx,eax ; Mover o valor EAX para EDX
and eax,0x55555555 ; Faça uma comparação AND e armazene em EAX.
and edx,0xaaaaaaaa ; Faça uma comparação AND e armazene no EDX.
add eax,eax ; Adicione EAX com EAX (EAX += EAX || EAX*=2)
shr edx,1 ; Desloque o bit binário de EDX 1 para a direita (divida por 2).
or eax,edx ; Faça uma comparação OR e armazene em EAX.
ret ; Operação de retorno Usei o valor 0x123456 como exemplo, pois assim fica mais claro para mim.
Para explicar o que este código faz, vou acompanhar os valores em EAX e EDX e ver como eles mudam. Podemos observar:
; EAX: ; EDX: ;
; function f does a thing
; And return
mov eax,DWORD PTR [esp+0x4] ; MOVE o valor do endereço ESP+0x4 para EAX
; EAX: 0x1234; EDX: 0x0;
bswap eax ; Troca a posição dos bytes de um valor, por exemplo: 0x123456 => 0x563412
; EAX: 0x3412; EDX: 0x0;
mov edx,eax ; Mover o valor de EAX para EDX
; EAX: 0x3412; EDX: 0x3412;
and eax,0xf0f0f0f ; Faça uma comparação AND com 0x0F0F0F0F e armazene em EAX.
; EAX: 0x402; EDX: 0x3412;
and edx,0xf0f0f0f0 ; Faça uma comparação AND com 0xF0F0F0F0 e armazene no EDX.
; EAX: 0x402; EDX: 0x3010;
shr edx,0x4 ; Desloca o binário de EDX 4 bits para a direita (divida por 16).
; EAX: 0x402; EDX: 0x301;
shl eax,0x4 ; Desloca o binário de EAX 4 bits para a esquerda (multiplique por 2⁴)
; EAX: 0x4020; EDX: 0x301;
or eax,edx ; Faça uma comparação OR e armazene em EAX.
; EAX: 0x4321; EDX: 0x301;
mov edx,eax ; Mover o valor EAX para EDX
; EAX: 0x4321; EDX: 0x4321;
and eax,0x33333333 ; Faça uma comparação AND e armazene em EAX.
; EAX: 0x321; EDX: 0x4321;
and edx,0xcccccccc ; Faça uma comparação AND e armazene no EDX.
; EAX: 0x321; EDX: 0x4000;
shr edx,0x2 ; Desloca o binário de EDX 2 bits para a direita (divida por 4).
; EAX: 0x321; EDX: 0x1000;
shl eax,0x2 ; Desloca o binário de EAX 2 bits para a esquerda (multiplique por 2²).
; EAX: 0xC84; EDX: 0x1000;
or eax,edx ; Faça uma comparação OR e armazene em EAX.
; EAX: 0x1C84; EDX: 0x1000;
mov edx,eax ; Mover o valor EAX para EDX
; EAX: 0x1C84; EDX: 0x1C84;
and eax,0x55555555 ; Faça uma comparação AND e armazene em EAX.
; EAX: 0x1404; EDX: 0x1C84;
and edx,0xaaaaaaaa ; Faça uma comparação AND e armazene no EDX.
; EAX: 0x1404; EDX: 0x880;
add eax,eax ; Adicione EAX com EAX (EAX += EAX || EAX*=2)
; EAX: 0x2808; EDX: 0x880;
shr edx,1 ; Desloque o bit binário de EDX 1 para a direita (divida por 2).
; EAX: 0x2808; EDX: 0x440;
or eax,edx ; Faça uma comparação OR e armazene em EAX.
; EAX: 0x2C48; EDX: 0x440;
ret ; Operação de retorno Se separarmos as funções deste programa, podemos dividi-lo em duas partes: uma para “inverter” e outra para “embaralhar”:
; EAX: ; EDX: ;
; function f does a thing
; And return
inverter_os_bytes:
mov eax,DWORD PTR [esp+0x4]
; EAX: 0x1234; EDX: 0x0;
bswap eax
; EAX: 0x3412; EDX: 0x0;
mov edx,eax
; EAX: 0x3412; EDX: 0x3412;
and eax,0xf0f0f0f
; EAX: 0x402; EDX: 0x3412;
and edx,0xf0f0f0f0
; EAX: 0x402; EDX: 0x3010;
shr edx,0x4
; EAX: 0x402; EDX: 0x301;
shl eax,0x4
; EAX: 0x4020; EDX: 0x301;
or eax,edx
; EAX: 0x4321; EDX: 0x301;
embaralhar:
mov edx,eax
; EAX: 0x4321; EDX: 0x4321;
and eax,0x33333333
; EAX: 0x321; EDX: 0x4321;
and edx,0xcccccccc
; EAX: 0x321; EDX: 0x4000;
shr edx,0x2
; EAX: 0x321; EDX: 0x1000;
shl eax,0x2
; EAX: 0xC84; EDX: 0x1000;
or eax,edx
; EAX: 0x1C84; EDX: 0x1000;
mov edx,eax
; EAX: 0x1C84; EDX: 0x1C84;
and eax,0x55555555
; EAX: 0x1404; EDX: 0x1C84;
and edx,0xaaaaaaaa
; EAX: 0x1404; EDX: 0x880;
add eax,eax
; EAX: 0x2808; EDX: 0x880;
shr edx,1
; EAX: 0x2808; EDX: 0x440;
or eax,edx
; EAX: 0x2C48; EDX: 0x440;
retO que este código faz:#
Esta função recebe uma mensagem do ESP (Stack Pointer) + 0x4, inverte os bytes e realiza uma operação AND com os bits pares e ímpares. Isso embaralha a mensagem.
Mas, ao inserir a mensagem embaralhada na função, ela será reembaralhada para a mensagem original. Semelhante a um XOR.
Exemplo:
input: 0x1234 => output: 0x2C48
input: 0x2C48 => output: 0x1234