• 标 题:keygen of TMG Official Keygenme #3. $^) (3千字)
  • 作 者:arbiter
  • 时 间:2002-2-22 2:11:29
  • 链 接:http://bbs.pediy.com

花了两天时间,挺好玩。虽然算法比较直观,但是还是要仔细。
scheme :      MD5 + ELGamal64.
这个dlp是故意生成的,所以解的很容易。
用miracl自带的index.c例程改一改就可以用了。当然,index.c
中的方法是有针对性的,不是任何一种dlp都可以用这个来解。
大部分代码抄的tE!的,嘿嘿。 不用白不用!
我估计从kgm #3升级到 #4这么快的原因就是因为这个太简单了。
不多说了,在多说我也不会了,哈哈!
To be continue...

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "./miracl/miracl.h"
#include "./md5/md5.h"

#pragma comment( lib, "./miracl/ms32.lib" )

typedef    unsigned char    BYTE;
typedef unsigned long    DWORD;

void FormatHash( char *s, BYTE *md )
{
    int j;
    for( j = 0; j < 16; j++ )
    {
        sprintf( s, "%02x", md[j] );
        s += 2;
    }
}

void main()
{
    MD5_CTX    c;
        BYTE    md[ MD5_DIGEST_LENGTH ];
    char    uName[60] = { 0x00 };
        char    uCode[60] = { 0x00 };
    char    temp1[20] = { 0x00 };
        char    temp2[20] = { 0x00 };
        DWORD    n_k;
    int        i, j, t;

        static char mod_n[] =    "37A218F214C32D79";
        static char ELG_p[] =     "C9D94F46D0984F43";
        static char ELG_g[] =    "4B45042B684BCBD1";
        static char ELG_x[] =     "6C18DA28FDD8FEF1";
        big    p, g, x, k, a, b, y, m, n, e;
        miracl *mip;
        
        srand( time( NULL ) );
    fprintf( stderr, ">>Keygen for [ TMG - Official keygenme #3 ] by arbiter[CCG].\n" );
        fprintf( stderr, ">>Your userName :\t" );
        gets( uName );
        MD5_Init( &c );
        MD5_Update( &c, ( BYTE* ) uName, strlen( uName ) );
        MD5_Final( md, &c );
        FormatHash( uName, md );
        strupr( uName );
        mip=mirsys( 100, 0 );
        p = mirvar( 0 );
        g = mirvar( 0 );
        x = mirvar( 0 );
        k = mirvar( 0 );
        a = mirvar( 0 );
        b = mirvar( 0 );
        y = mirvar( 0 );
        m = mirvar( 0 );
    n = mirvar( 0 );
        e = mirvar( 3 );
        
        mip->IOBASE=16;
        cinstr( p, ELG_p );
    cinstr( g, ELG_g );
    cinstr( x, ELG_x );
    cinstr( n, mod_n );
    cinstr( m, uName );

    while( 1 )
    {
        n_k = rand();
        n_k = ( n_k ^ 2 ) % 0xffffffff;
        if( ( n_k % 2 ) != 0 && ( n_k % 0x232D4D ) != 0 )
            break;
    }

    convert( n_k, k );
    
    /* m = m ^ 3 mod n, the final message to be signatured. */
    powmod( m, e, n, m );
    
    /* first part of regCode, i.e.the first part of signature. */
    powmod( g, k, p, y );
    
    decr( p, 1, p );
    /* a=xy mod p-1 */
    multiply(x,y,a);
    divide(a,p,b);

    /* b=m-a mod p-1 */
    if( compare( m, a ) != 1 )
        add( m, p, m );
    subtract(m,a,b);
    divide(b,p,a);
    
    /* m=b/k mod p-1 ( 1/k (mod p-1) first, then b*1/k (mod p-1) )
     the second part of regCode */
    xgcd(k,p,k,k,k);
    multiply(b,k,a);
    divide(a,p,b);
    
    cotstr( y, temp1 );
    cotstr( a, temp2 );
    
    mirkill( k );
    mirkill( p );
    mirkill( g );
    mirkill( x );
    mirkill( m );
    mirkill( y );
    mirkill( a );
    mirkill( b );
    mirkill( n );
    mirkill( e );
    
    t = strlen( temp1 );
    j = 16 - t;
    for( i = 0; j < j; i++ )
        uCode[j] = 0x30;
    for( i = 0; i < t; i++ )
        uCode[i + j] = temp1[i];
    t = strlen( temp2 );
    j = 16 - t;
    for( i = 0; j < j; i++ )
        uCode[j + 16] = 0x30;
    for( i = 0; i < t; i++ )
        uCode[i + j + 16] = temp2[i];

    fprintf( stderr, ">>Your userCode :\t%s\n", uCode );
    getch();
}