lunes, 26 de agosto de 2013

Rnd0Ms keygenme

Aprovechando que no hubo clase de 2pm, y solo por completitud, decidi hacer el ultimo keygen del reto de este mes: "RndOMs keygenme".  Este es el mas facil de los tres y solo me qudaria pendiente el reto de  unpackmg  :)


Al abrirlo en IDA Free encuentro referencias a Borland, asi que preferi trabajar con IDR (Interactive Delphi Reconstructor). Desde alli es trivial cargar el unico fromulario y saltar al procedimiento asociado al unico boton:

 Unit1::TForm1.Button1Click
 0045193C    push       ebp
 0045193D    mov        ebp,esp
 0045193F    xor        ecx,ecx
 00451941    push       ecx
 00451942    push       ecx
 00451943    push       ecx
 00451944    push       ecx
 00451945    push       ebx
 00451946    push       esi
 00451947    mov        ebx,eax
 00451949    xor        eax,eax
 0045194B    push       ebp
 0045194C    push       4519E9
 00451951    push       dword ptr fs:[eax]
 00451954    mov        dword ptr fs:[eax],esp
 00451957    lea        edx,[ebp-8]
 0045195A    mov        eax,dword ptr [ebx+304]; TForm1.Edit1:TEdit
 00451960    call       TControl.GetText
 00451965    mov        eax,dword ptr [ebp-8]
 00451968    call       @LStrLen
 0045196D    mov        esi,eax
 0045196F    lea        edx,[ebp-4]
 00451972    mov        eax,dword ptr [ebx+304]; TForm1.Edit1:TEdit
 00451978    call       TControl.GetText
 0045197D    mov        eax,esi
 0045197F    add        eax,0FFFFFFFE
 00451982    sub        eax,4
>00451985    jb         0045198E
 00451987    sub        eax,0F
>0045198A    jb         004519A7
>0045198C    jmp        004519BE
 0045198E    lea        edx,[ebp-0C]
 00451991    mov        eax,dword ptr [ebp-4]
 00451994    call       ReverseString
 00451999    mov        ecx,dword ptr [ebp-0C]
 0045199C    mov        edx,esi
 0045199E    mov        eax,ebx
 004519A0    call       00451524
>004519A5    jmp        004519BE
 004519A7    lea        edx,[ebp-10]
 004519AA    mov        eax,dword ptr [ebp-4]
 004519AD    call       UpperCase
 004519B2    mov        ecx,dword ptr [ebp-10]
 004519B5    mov        edx,esi
 004519B7    mov        eax,ebx
 004519B9    call       00451730
 004519BE    xor        eax,eax
 004519C0    pop        edx
 004519C1    pop        ecx
 004519C2    pop        ecx
 004519C3    mov        dword ptr fs:[eax],edx
 004519C6    push       4519F0
 004519CB    lea        eax,[ebp-10]
 004519CE    mov        edx,2
 004519D3    call       @LStrArrayClr
 004519D8    lea        eax,[ebp-8]
 004519DB    call       @LStrClr
 004519E0    lea        eax,[ebp-4]
 004519E3    call       @LStrClr
 004519E8    ret
<004519E9    jmp        @HandleFinally
<004519EE    jmp        004519CB
 004519F0    pop        esi
 004519F1    pop        ebx
 004519F2    mov        esp,ebp
 004519F4    pop        ebp
 004519F5    ret

Leemos el nombre con GetText, y calculamos la longitud con @LStrLen, las instrucciones en resaltado naranja muestran que esta longitud se almacena en esi, luego se mueve a eax, se le suma -2, se le resta 4 y se toma una decisión.  Luego se resta un 0xf y se toma otra decision.

Básicamente, si la longitud del nombre es menor que 5 tomaremos el primer salto  (hacia 0045198E) y si no pero es menor que 21 (6 + 0xf) entonces tomamos el segundo salto (hacia 004519A7).

Luego, si habíamos tomado el primer salto el nombre se invierte (ReverseString) y seguimos hacia una llamada a 00451524 (en amarillo), pero si habiamos tomado el segundo salto el nombre se lleva a mayúsculas (UpperCase) y seguimos con una llamada a 00451730

Miremos la primera llamada:

 Unit1::sub_00451524
 00451524    push       ebp
 00451525    mov        ebp,esp
 00451527    push       ecx
 00451528    mov        ecx,8
 0045152D    push       0
 0045152F    push       0
 00451531    dec        ecx
<00451532    jne        0045152D
 00451534    xchg       ecx,dword ptr [ebp-4]
 00451537    push       ebx
 00451538    mov        dword ptr [ebp-8],ecx
 0045153B    mov        dword ptr [ebp-4],edx
 0045153E    mov        ebx,eax
 00451540    mov        eax,dword ptr [ebp-8]
 00451543    call       @LStrAddRef
 00451548    xor        eax,eax
 0045154A    push       ebp
 0045154B    push       4516B4
 00451550    push       dword ptr fs:[eax]
 00451553    mov        dword ptr fs:[eax],esp
 00451556    lea        eax,[ebp-10]
 00451559    mov        edx,4516CC; 'R'
 0045155E    call       @LStrLAsg
 00451563    lea        eax,[ebp-14]
 00451566    mov        edx,4516D8; 'e'
 0045156B    call       @LStrLAsg
 00451570    lea        eax,[ebp-18]
 00451573    mov        edx,4516E4; 'g'
 00451578    call       @LStrLAsg
 0045157D    lea        eax,[ebp-1C]
 00451580    mov        edx,4516F0; 'i'
 00451585    call       @LStrLAsg
 0045158A    lea        eax,[ebp-20]
 0045158D    mov        edx,4516FC; 's'
 00451592    call       @LStrLAsg
 00451597    lea        eax,[ebp-24]
 0045159A    mov        edx,451708; 't'
 0045159F    call       @LStrLAsg
 004515A4    lea        eax,[ebp-28]
 004515A7    mov        edx,451714; 'd '
 004515AC    call       @LStrLAsg
 004515B1    lea        eax,[ebp-2C]
 004515B4    mov        edx,451708; 't'
 004515B9    call       @LStrLAsg
 004515BE    lea        eax,[ebp-34]
 004515C1    mov        edx,451720; 'o '
 004515C6    call       @LStrLAsg
 004515CB    lea        eax,[ebp-30]
 004515CE    mov        edx,45172C; 'r'
 004515D3    call       @LStrLAsg
 004515D8    pushad
 004515D9    mov        edx,dword ptr [ebp-4]
 004515DC    mov        esi,dword ptr [ebp-8]
 004515DF    mov        ecx,1
 004515E4    xor        ebx,ebx
 004515E6    xor        eax,eax
 004515E8    movzx      eax,byte ptr ds:[esi+ecx]
 004515ED    add        ebx,eax
 004515EF    xor        ebx,0FFF
 004515F5    shr        ebx,1
 004515F7    inc        ecx
 004515F8    cmp        ecx,edx
<004515FA    jne        004515E8
 004515FC    mov        dword ptr [ebp-0C],ebx
 004515FF    popad
 00451600    lea        edx,[ebp-38]
 00451603    mov        eax,dword ptr [ebp-0C]
 00451606    call       IntToStr
 0045160B    mov        eax,dword ptr [ebp-38]
 0045160E    push       eax
 0045160F    lea        edx,[ebp-3C]
 00451612    mov        eax,dword ptr [ebx+308]
 00451618    call       TControl.GetText
 0045161D    mov        eax,dword ptr [ebp-3C]
 00451620    pop        edx
 00451621    call       CompareStr
 00451626    test       eax,eax
>00451628    jne        00451679
 0045162A    push       dword ptr [ebp-10]
 0045162D    push       dword ptr [ebp-14]
 00451630    push       dword ptr [ebp-18]
 00451633    push       dword ptr [ebp-1C]
 00451636    push       dword ptr [ebp-20]
 00451639    push       dword ptr [ebp-24]
 0045163C    push       dword ptr [ebp-14]
 0045163F    push       dword ptr [ebp-30]
 00451642    push       dword ptr [ebp-14]
 00451645    push       dword ptr [ebp-28]
 00451648    push       dword ptr [ebp-2C]
 0045164B    push       dword ptr [ebp-34]
 0045164E    lea        edx,[ebp-44]
 00451651    mov        eax,dword ptr [ebx+304]
 00451657    call       TControl.GetText
 0045165C    push       dword ptr [ebp-44]
 0045165F    lea        eax,[ebp-40]
 00451662    mov        edx,0D
 00451667    call       @LStrCatN
 0045166C    mov        edx,dword ptr [ebp-40]
 0045166F    mov        eax,[00454BD0]; 0x0 gvar_00454BD0:TForm1
 00451674    call       TControl.SetText
 00451679    xor        eax,eax
 0045167B    pop        edx
 0045167C    pop        ecx
 0045167D    pop        ecx
 0045167E    mov        dword ptr fs:[eax],edx
 00451681    push       4516BB
 00451686    lea        eax,[ebp-44]
 00451689    call       @LStrClr
 0045168E    lea        eax,[ebp-40]
 00451691    call       @LStrClr
 00451696    lea        eax,[ebp-3C]
 00451699    call       @LStrClr
 0045169E    lea        eax,[ebp-38]
 004516A1    mov        edx,0B
 004516A6    call       @LStrArrayClr
 004516AB    lea        eax,[ebp-8]
 004516AE    call       @LStrClr
 004516B3    ret
<004516B4    jmp        @HandleFinally
<004516B9    jmp        00451686
 004516BB    mov        eax,dword ptr [ebp-0C]
 004516BE    pop        ebx
 004516BF    mov        esp,ebp
 004516C1    pop        ebp
 004516C2    ret

Para cada byte desde el segundo (ecx se setea a 1 en la primera linea resaltada, no a 0), acumulu su representacion en ebx, luego hago xor con 0xfff y luego un shr de 1.  Ese es todo el calculo, tambien se ve en negritas como se va conformado el "Registd to " que se concatenara con @LStrCatN y que luego se usara para establecer el texto de algun control con SetText.

Si miramos la segunda call, tenemos esto:

 Unit1::sub_00451730
 00451730    push       ebp
 00451731    mov        ebp,esp
 00451733    push       ecx
 00451734    mov        ecx,8
 00451739    push       0
 0045173B    push       0
 0045173D    dec        ecx
<0045173E    jne        00451739
 00451740    xchg       ecx,dword ptr [ebp-4]
 00451743    push       ebx
 00451744    mov        dword ptr [ebp-8],ecx
 00451747    mov        dword ptr [ebp-4],edx
 0045174A    mov        ebx,eax
 0045174C    mov        eax,dword ptr [ebp-8]
 0045174F    call       @LStrAddRef
 00451754    xor        eax,eax
 00451756    push       ebp
 00451757    push       4518C0
 0045175C    push       dword ptr fs:[eax]
 0045175F    mov        dword ptr fs:[eax],esp
 00451762    lea        eax,[ebp-10]
 00451765    mov        edx,4518D8; 'R'
 0045176A    call       @LStrLAsg
 0045176F    lea        eax,[ebp-14]
 00451772    mov        edx,4518E4; 'e'
 00451777    call       @LStrLAsg
 0045177C    lea        eax,[ebp-18]
 0045177F    mov        edx,4518F0; 'g'
 00451784    call       @LStrLAsg
 00451789    lea        eax,[ebp-1C]
 0045178C    mov        edx,4518FC; 'i'
 00451791    call       @LStrLAsg
 00451796    lea        eax,[ebp-20]
 00451799    mov        edx,451908; 's'
 0045179E    call       @LStrLAsg
 004517A3    lea        eax,[ebp-24]
 004517A6    mov        edx,451914; 't'
 004517AB    call       @LStrLAsg
 004517B0    lea        eax,[ebp-28]
 004517B3    mov        edx,451920; 'd '
 004517B8    call       @LStrLAsg
 004517BD    lea        eax,[ebp-2C]
 004517C0    mov        edx,451914; 't'
 004517C5    call       @LStrLAsg
 004517CA    lea        eax,[ebp-34]
 004517CD    mov        edx,45192C; 'o '
 004517D2    call       @LStrLAsg
 004517D7    lea        eax,[ebp-30]
 004517DA    mov        edx,451938; 'r'
 004517DF    call       @LStrLAsg
 004517E4    pushad
 004517E5    mov        edx,dword ptr [ebp-4]
 004517E8    mov        esi,dword ptr [ebp-8]
 004517EB    mov        ecx,2
 004517F0    xor        ebx,ebx
 004517F2    xor        eax,eax
 004517F4    movzx      eax,byte ptr ds:[esi+ecx]
 004517F9    add        ebx,eax
 004517FB    xor        ebx,0AF
 00451801    shl        ebx,1
 00451803    inc        ecx
 00451804    cmp        ecx,edx
<00451806    jne        004517F4
 00451808    mov        dword ptr [ebp-0C],ebx
 0045180B    popad
 0045180C    lea        edx,[ebp-38]
 0045180F    mov        eax,dword ptr [ebp-0C]
 00451812    call       IntToStr
 00451817    mov        eax,dword ptr [ebp-38]
 0045181A    push       eax
 0045181B    lea        edx,[ebp-3C]
 0045181E    mov        eax,dword ptr [ebx+308]
 00451824    call       TControl.GetText
 00451829    mov        eax,dword ptr [ebp-3C]
 0045182C    pop        edx
 0045182D    call       CompareStr
 00451832    test       eax,eax
>00451834    jne        00451885
 00451836    push       dword ptr [ebp-10]
 00451839    push       dword ptr [ebp-14]
 0045183C    push       dword ptr [ebp-18]
 0045183F    push       dword ptr [ebp-1C]
 00451842    push       dword ptr [ebp-20]
 00451845    push       dword ptr [ebp-24]
 00451848    push       dword ptr [ebp-14]
 0045184B    push       dword ptr [ebp-30]
 0045184E    push       dword ptr [ebp-14]
 00451851    push       dword ptr [ebp-28]
 00451854    push       dword ptr [ebp-2C]
 00451857    push       dword ptr [ebp-34]
 0045185A    lea        edx,[ebp-44]
 0045185D    mov        eax,dword ptr [ebx+304]
 00451863    call       TControl.GetText
 00451868    push       dword ptr [ebp-44]
 0045186B    lea        eax,[ebp-40]
 0045186E    mov        edx,0D
 00451873    call       @LStrCatN
 00451878    mov        edx,dword ptr [ebp-40]
 0045187B    mov        eax,[00454BD0]; 0x0 gvar_00454BD0:TForm1
 00451880    call       TControl.SetText
 00451885    xor        eax,eax
 00451887    pop        edx
 00451888    pop        ecx
 00451889    pop        ecx
 0045188A    mov        dword ptr fs:[eax],edx
 0045188D    push       4518C7
 00451892    lea        eax,[ebp-44]
 00451895    call       @LStrClr
 0045189A    lea        eax,[ebp-40]
 0045189D    call       @LStrClr
 004518A2    lea        eax,[ebp-3C]
 004518A5    call       @LStrClr
 004518AA    lea        eax,[ebp-38]
 004518AD    mov        edx,0B
 004518B2    call       @LStrArrayClr
 004518B7    lea        eax,[ebp-8]
 004518BA    call       @LStrClr
 004518BF    ret
<004518C0    jmp        @HandleFinally
<004518C5    jmp        00451892
 004518C7    mov        eax,dword ptr [ebp-0C]
 004518CA    pop        ebx
 004518CB    mov        esp,ebp
 004518CD    pop        ebp
 004518CE    ret

Vemos que el procedimiento es casi el mismo, solo que esta vez ecx es igual a 2 en lugar de 1, y hacemos xor con 0xaf en lugar de 0xfff, ahhh y el corrimeinto de bits es al contrario, un shl en lugar de shr,

El código del keygen es muy simple:

name = input("name: ")
serial = 0
if len(name) > 5:
    for c in name.upper()[2:]:
        serial += ord(c)
        serial = serial ^ 0xaf
        serial = serial  << 1
else:
    for c in name[::-1][1:]:
        serial += ord(c)
        serial = serial ^ 0xfff
        serial = serial >> 1
print("serial:", serial)

No me fije mucho mas en la comprobacion de nombres largos, es seguro que no funcionara para mas de 21. Pero probé algunos seriales de  menos de 5 y de mas de 5, y todos funcionaron, para "rmolina" el serial es 10328.





Bonus: Las dimensiones de la ventana no eran adecuadas para esta maquina, tanto que ni se veia el botón al abrirlo.  Ademas, como el mensaje de "Registered to" sale en el Caption, necesitaba agrandarla para poder mostrar el pantllazo.  Para esto, edite el binario con Resource Hacker en RCDATA / TFORM1 y elimine las siguientes lineas:

  Constraints.MaxHeight = 154
  Constraints.MaxWidth = 234
  Constraints.MinHeight = 154
  Constraints.MinWidth = 234


No hay comentarios:

Publicar un comentario