26/07/2011

I need the key

Introduction

Tout droit sorti du grenier je ressors mon boitier de diablo II, oui oui ce jeu magique cube horadrim tout ca tout ca :]
Mais ce post n'est pas destiné à faire l'éloge de ce jeu mais plutôt arriver à y jouer.

Serial

Malheuresement au moment de l'installation on nous demande un Nom et un Serial, comme par hasard j'ai perdu le manuel avec ma clef CD...
"Comment ca je peux pas joueur ?!"

diablo2_serial.png

La routine de vérification ne tient pas compte du nom que vous avez entré mais uniquement du serial, j'ai du coup coder un générateur de clef (bruteforce ?).
Oui je génére toutes les clefs possibles et inimaginables et en ayant reverse toute leur routine de vérificaion, je regarde si elle est valide ou non.
Afin que ca prenne pas la vie, il faut définir la variable "dic" avec un minimum de caractères qui sont présents au début du code (commentaire 0x43f750...).
Trève de bavardage voici le code :

#! /usr/local/bin/python2.6

import sys
import binascii

###################################
# 0x43f750 .....
#
#             #0 #1 #2 #3 #4 #5
#       FF FF FF FF 00 FF 01 FF
#
#       #6 #7 #8 #9 #: #; #< #=
#       02 03 04 05 FF FF FF FF
#
#       #> #? #@ #A #B #C #D #E
#       FF FF FF FF 06 07 08 09
#
#       #F #G #H #I #J #K #L #M
#       0A 0B 0C FF 0D 0E FF 0F
#
#       #N #O #P #Q #R #S #T #U
#       10 FF 11 FF 12 FF 13 FF
#
#       #V #W #X #Y #Z #[ #\ #]
#       14 15 16 FF 17 FF FF FF
#
#       #^ #_ #` #a #b #c #d #e
#       FF FF FF FF 06 07 08 09
#
#       0A 0B 0C FF 0D 0E FF 0F
#
#       10 FF 11 FF 12 FF 13 FF
#
#       14 15 16 FF 17 FF FF FF
#
# Caracter can only be '246789BCDEFGHJKMNPRTVWXZ'
###################################

s_ebx = 1
spe = 0

def combine(alphabet, nb, base = ''):
    for c in alphabet:
        if nb == 1:
            yield base + c
        else:
            for c1 in combine(alphabet, nb - 1, base + c):
                yield c1

rep = 4
#dic = '246789BCDEFGHJKMNPRTVWXZ'
dic = '7NJDTF'
tab_43f750 = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0x00, 0xFF, 0x01, 0xFF, 0x02, 0x03,
              0x04, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
              0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF,
              0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15,
              0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
              0xFF, 0xFF, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
              0x0C, 0xFF, 0x0D, 0x0E, 0xFF, 0x0F, 0x10, 0xFF,
              0x11, 0xFF, 0x12, 0xFF, 0x13, 0xFF, 0x14, 0x15,
              0x16, 0xFF, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]

def routine_414770(res):
    if res < 0x0a:
        res += 0x30
    else:
        res += 0x37
    return res

def routine_41457e(a, b):
    global s_ebx
    global spe
    A = tab_43f750[ord(a)]
    B = tab_43f750[ord(b)]
    if A == 0xff:
        A = 0xffffffff
    if B == 0xff:
        B = 0xffffffff
    RES = A + A * 2 & 0xffffffff
    RES = RES * 8 + B & 0xffffffff
    if RES > 0x100:
        spe = spe + s_ebx
        RES = RES - 0x100
    a = RES
    a = a & 0x0f
    RES = RES >> 4
    RES = RES & 0xf
    RES = routine_414770(RES)
    a = routine_414770(a)
    s_ebx = s_ebx << 1
    return [RES, a]

def routine_3(combi):
    res = routine_41457e(combi[0], combi[1])
    res2 = routine_41457e(combi[2], combi[3])
    return res + res2

def routine(one, two, three, four):
    global s_ebx
    global spe
    s_ebx = 1
    spe = 0
    one = routine_3(one)
    two = routine_3(two)
    three = routine_3(three)
    four = routine_3(four)
    if routine_add(one, two, three, four) == True and test(one, two, three, four) == True:
        return True
    return False

def test(one, two, three, four):
    edi = 0x15
    eax = 15
    ecx = 0x16
    serial = one + two + three + four
    while eax >= 0:
        dl = serial[eax]
        ecx = ecx & 0xf
        bl = serial[ecx]
        serial[eax] = bl
        serial[ecx] = dl
        eax = eax - 1
        ecx = ecx - 1
    eax = 15
    esp_38 = 0x13AC9741
    while eax >= 0:
        ecx = serial[eax]
        if ecx <= 0x37:
            ecx = esp_38
            dl = esp_38 & 0xff
            dl = dl & 0x7
            serial[eax] = dl ^ serial[eax]
            esp_38 = esp_38 >> 3
        if ecx <= 0x41:
            cl = eax
            cl = cl & 0x1
            serial[eax] = cl ^ ecx
        eax = eax - 1
    if serial[0] == 0x30 and (serial[1] == 0x37 or serial[1] == 0x36):
        return True

def routine_41458D(a):
    if a >= 0x41 and a <= 0x5a:
        a = a + 0x20
    if a < 0x61:
        a = a - 0x30
    else:
        a = a - 0x57
    return a
    
def routine_add(one, two, three, four):
    global spe
    edi = 0x3
    for i in one:
        edx = edi + edi
        eax = routine_41458D(i) ^ edx
        edi = edi + eax
    for i in two:
        edx = edi + edi
        eax = routine_41458D(i) ^ edx
        edi = edi + eax
    for i in three:
        edx = edi + edi
        eax = routine_41458D(i) ^ edx
        edi = edi + eax
    for i in four:
        edx = edi + edi
        eax = routine_41458D(i) ^ edx
        edi = edi + eax
    edi = edi & 0xff
    if edi == spe:
        return True
    return False

if __name__ == "__main__":
    for one in  combine(dic, rep):
        for two in combine(dic, rep):
            for three in combine(dic, rep):
                for four in combine(dic, rep):
                    if routine(one, two, three, four) == True:
                        print "[+] Key found try : " + one + "-" + two + "-" + three + "-" + four

Je tiens à m'excuser si le code n'est pas très explicite, mais j'ai juste supra la flemme de tout clean :].