Echemos un vistazo a una de esas funciones:
0010EFB8 Method 6552 (0x1998):_
0010EFB8 static void
0010EFB8 com.whatsapp.n0.()
0010EFB8 const/16 v2, 0x5B
0010EFBC const/16 v3, 0x39
0010EFC0 const/16 v1, 0x19
0010EFC4 const/16 v4, 9
0010EFC8 const/4 v6, 0
0010EFCA const/4 v0, 2
0010EFCC new-array v9, v0,
0010EFD0 const-string v0, aK_20 # "k>^"
0010EFD4 invoke-virtual {v0},
0010EFDA move-result-object v0
0010EFDC array-length v5, v0
0010EFDE move v7, v5
0010EFE0 move v8, v6
0010EFE2 move-object v5, v0
0010EFE4
0010EFE4 loc_10EFE4: # CODE XREF: n0__clinit_@V+9A j
0010EFE4 if-gt v7, v8, loc_10F034
0010EFE8 new-instance v0,
0010EFEC invoke-direct {v0, v5}, (ref) imp. @ unk_2EB58>
0010EFF2 invoke-virtual {v0},
0010EFF8 move-result-object v0
0010EFFA aput-object v0, v9, v6
0010EFFE const/4 v8, 1
0010F000 const-string v0, aE_10 # "E"
0010F004 invoke-virtual {v0},
0010F00A move-result-object v0
0010F00C array-length v5, v0
0010F00E move v7, v6
0010F010 move v6, v5
0010F012 move-object v5, v0
0010F014
0010F014 loc_10F014: # CODE XREF: n0__clinit_@V+CC j
0010F014 if-gt v6, v7, loc_10F066
0010F018 new-instance v0,
0010F01C invoke-direct {v0, v5}, (ref) imp. @ unk_2EB58>
0010F022 invoke-virtual {v0},
0010F028 move-result-object v0
0010F02A aput-object v0, v9, v8
0010F02E sput-object v9, n0_z
0010F032
0010F032 locret:
0010F032 return-void
0010F034 # ---------------------------------------------------------------------------
0010F034
0010F034 loc_10F034: # CODE XREF: n0__clinit_@V:loc_10EFE4 j
0010F034 aget-char v10, v5, v8
0010F038 rem-int/lit8 v0, v8, 5
0010F03C packed-switch v0, switchdata_10F098
0010F042 # ---------------------------------------------------------------------------
0010F042
0010F042 loc_10F042: # CODE XREF: n0__clinit_@V+84 j
0010F042 move v0, v4 # default:
0010F044
0010F044 loc_10F044: # CODE XREF: n0__clinit_@V+9E j
0010F044 # n0__clinit_@V+A2 j ...
0010F044 xor-int/2addr v0, v10
0010F046 int-to-char v0, v0
0010F048 aput-char v0, v5, v8
0010F04C add-int/lit8 v0, v8, 1
0010F050 move v8, v0
0010F052 goto loc_10EFE4
0010F054 # ---------------------------------------------------------------------------
0010F054
0010F054 loc_10F054: # CODE XREF: n0__clinit_@V+84 j
0010F054 move v0, v1 # case 0: // (0x0)
0010F056 goto loc_10F044
0010F058 # ---------------------------------------------------------------------------
0010F058
0010F058 loc_10F058: # CODE XREF: n0__clinit_@V+84 j
0010F058 move v0, v2 # case 1: // (0x1)
0010F05A goto loc_10F044
0010F05C # ---------------------------------------------------------------------------
0010F05C
0010F05C loc_10F05C: # CODE XREF: n0__clinit_@V+84 j
0010F05C move v0, v3 # case 2: // (0x2)
0010F05E goto loc_10F044
0010F060 # ---------------------------------------------------------------------------
0010F060
0010F060 loc_10F060: # CODE XREF: n0__clinit_@V+84 j
0010F060 const/16 v0, 0x75 # case 3: // (0x3)
0010F064 goto loc_10F044
0010F066 # ---------------------------------------------------------------------------
0010F066
0010F066 loc_10F066: # CODE XREF: n0__clinit_@V:loc_10F014 j
0010F066 aget-char v10, v5, v7
0010F06A rem-int/lit8 v0, v7, 5
0010F06E packed-switch v0, switchdata_10F0B0
0010F074 # ---------------------------------------------------------------------------
0010F074
0010F074 loc_10F074: # CODE XREF: n0__clinit_@V+B6 j
0010F074 move v0, v4 # default:
0010F076
0010F076 loc_10F076: # CODE XREF: n0__clinit_@V+D0 j
0010F076 # n0__clinit_@V+D4 j ...
0010F076 xor-int/2addr v0, v10
0010F078 int-to-char v0, v0
0010F07A aput-char v0, v5, v7
0010F07E add-int/lit8 v0, v7, 1
0010F082 move v7, v0
0010F084 goto loc_10F014
0010F086 # ---------------------------------------------------------------------------
0010F086
0010F086 loc_10F086: # CODE XREF: n0__clinit_@V+B6 j
0010F086 move v0, v1 # case 0: // (0x0)
0010F088 goto loc_10F076
0010F08A # ---------------------------------------------------------------------------
0010F08A
0010F08A loc_10F08A: # CODE XREF: n0__clinit_@V+B6 j
0010F08A move v0, v2 # case 1: // (0x1)
0010F08C goto loc_10F076
0010F08E # ---------------------------------------------------------------------------
0010F08E
0010F08E loc_10F08E: # CODE XREF: n0__clinit_@V+B6 j
0010F08E move v0, v3 # case 2: // (0x2)
0010F090 goto loc_10F076
0010F092 # ---------------------------------------------------------------------------
0010F092
0010F092 loc_10F092: # CODE XREF: n0__clinit_@V+B6 j
0010F092 const/16 v0, 0x75 # case 3: // (0x3)
0010F096 goto loc_10F076
0010F096 # ---------------------------------------------------------------------------
0010F098 switchdata_10F098: # DATA XREF: n0__clinit_@V+84 r
0010F098 .short 0x100
0010F09A .short 4
0010F09C .int 0
0010F0A0 .int 0xC, 0xE, 0x10, 0x12
0010F0B0 switchdata_10F0B0: # DATA XREF: n0__clinit_@V+B6 r
0010F0B0 .short 0x100
0010F0B2 .short 4
0010F0B4 .int 0
0010F0B8 .int 0xC, 0xE, 0x10, 0x12
0010F0B8 Method End
Lo primero que notamos es que la función asigna algunos valores fijos a los registros v1-v4. Estos valores parecen mantenerse sin cambios a través del código de decodificación.Moviéndonos a lo largo en el código, podemos ver también que se está asignando una especie de cadena ofuscada o mangled @ 0×0010EFD0.
Obteniendo los datos hasta su terminación NULL produce lo siguiente:
6b3e5e1c7a6d3e4b5a7971345710267a344c1b7d6b224e147d7a335c0726783d4d107b6d3e41016a713a57126c7d7b551a66722e4936666c354d07705a345d10297f295618295a344c1b7d6b22691d66773e701b6f767b5f1460753e5d
La función ahora realizará un bucle a través de cada carácter de la cadena para descifrarla. La transformación es un simple XOR.¿Recuerdas los 4 registros fijos que comentábamos al principio? Son los valores utilizados para el XOR. De hecho, en realidad hay 5 valores en esa función, el quinto se utiliza simplemente como un valor literal directo en lugar de haber sido colocado en un registro.
La instrucción ‘packed-switch’ decide qué valor XOR se va a usar basándose en el índice del carácter actual dentro de la cadena MOD 5. Esto le permite recorrerla repetidamente a través de las 'claves' del XOR.
A continuación, una función Python que realiza el descifrado:
def decode_string(encoded_str, key): encoded_str = bytearray(encoded_str) decoded_str = '' for i in range(len(encoded_str)): decoded_str += chr(encoded_str[i] ^ key[i % 5]) return decoded_strY el uso:
import binascii
key = [0x19, 0x5b, 0x39, 0x75, 0x09]
encoded_str = binascii.unhexlify("6b3e5e1c7a6d3e4b5a7971345710267a344c1b7d6b224e147d7a335c0726783d4d107b6d3e41016a713a57126c7d7b551a66722e4936666c354d07705a345d10297f295618295a344c1b7d6b22691d66773e701b6f767b5f1460753e5d")
print decode_string(encoded_str, key)
Que en este caso devuelve:register/phone/countrywatcher/aftertextchanged lookupCountryCode from CountryPhoneInfo failed
KlassMaster?
Fuente:http://www.hackplayers.com/2012/08/decodificando-cadenas-ofuscadas-del.html
No hay comentarios:
Publicar un comentario