首页
社区
课程
招聘
[原创]第一阶段第一题分析+完整逆向代码(看雪金山2007逆向分析挑战赛)
发表于: 2007-8-25 12:00 28187

[原创]第一阶段第一题分析+完整逆向代码(看雪金山2007逆向分析挑战赛)

2007-8-25 12:00
28187
收藏
免费 7
支持
分享
最新回复 (57)
雪    币: 313
活跃值: (440)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
26
哈哈,偶的长的很难看,大家将就看把
BOOL GenRegCode(HWND hWnd) 
{
  int  len,i;  
  TCHAR szName[MAXINPUTLEN]={0};
  TCHAR szSerial[MAXINPUTLEN]={0};
  //TCHAR szBuffer[MAXINPUTLEN]={0};
  long key=0x13572468, eax=0;
  unsigned char checksum[10]={0};
  unsigned char magic[1024]="1213121412131215121312141213121612131214121312151213121412131217121312141213121512131214121312161213121412131215121312141213121812131214121312151213121412131216121312141213121512131214121312171213121412131215121312141213121612131214121312151213121412131219";
  unsigned char tmpstring[1024]={0};

  len=GetDlgItemText(hWnd, IDC_NAME, szName, sizeof(szName)/sizeof(TCHAR)+1); // 取姓名

  for(i=0; i<len; i++)
  {
    eax = ((DWORD)szName[i]+key)*0x3721273+0x24681357;
    key = (eax<<25)|(eax>>7);
  }

  for(i=1; i<9; i++)
  {
    checksum[i] = (key>>i)&1;
  }
  checksum[9] = 1;

  do
  {
    eax = findindex(checksum, 1, 10);
    if(eax==-1)break;
    if(checksum[eax+1]==1)
    {
      wsprintf(tmpstring, "%d", eax+1);
      strcat(szSerial, tmpstring);
      checksum[eax+1]=0;
    }
    else
    {
      checksum[eax]=0;
      while(eax--)
      {
        memset(tmpstring, 0, sizeof(tmpstring));
        strncpy(tmpstring, magic, 1<<(eax));
        strcat(szSerial, tmpstring);
      }
    }
  }while(1);

  len=strlen(szSerial);
  for(i=0; i<len; i++)
  {
    szSerial[i]=0x30+(10+(szSerial[i]-0x30)-((DWORD)key>>(i%0x1f))%10)%10;
  }
  SetDlgItemText(hWnd, IDC_OUT, szSerial);       // 显示正确的序列号  
  return TRUE;
}

int findindex(char * input, char ch, int len)
{
  int i;
  for(i=0; i<len; i++)
    if(input[i]==ch)return i;
  return -1;
}
2007-8-25 20:12
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
27
强就一个字;)
2007-8-25 20:27
0
雪    币: 1969
活跃值: (46)
能力值: (RANK:550 )
在线值:
发帖
回帖
粉丝
28
由于平时写程序用到sar的机会不多,所以理解的不对,受教了。
ccfer的那个算法看不明白,郁闷......
2007-8-25 20:40
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
29
真长见识了,乍一看,以为自已能写出Keygen,最终还是卡住了,好累!

从网上摘录:
注 由二进制数转换为格雷码:从右到左检查,如果某一数字左边是0,该数字不变;如果是1,该数字改变(0变为1,1变为0)。例,二进制数11011的格雷码是10110。
……
2007-8-25 21:03
0
雪    币: 8
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
30
这里还有个动画:
http://funmath.hotgt.cn/Y-jiulianhuan5.htm
2007-8-25 21:10
0
雪    币: 105
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
31
[+] Name = pediy
[+] Hash is 0x94D44A29
5 2 6 3 6 3 6 8 4 7 8 9 4 2 1 0 0 0 5 2 1 0 5 7 8 4 7 8 9 4 2
00 00 00 01 00 01 00 00 00 01
00 01 00 01 00 01 00 00 00 01
00 01 01 01 00 01 00 00 00 01
00 00 01 01 00 01 00 00 00 01
00 00 01 00 00 01 00 00 00 01
00 01 01 00 00 01 00 00 00 01
00 01 00 00 00 01 00 00 00 01
00 00 00 00 00 01 00 00 00 01
00 00 00 00 00 01 01 00 00 01
00 01 00 00 00 01 01 00 00 01
00 01 01 00 00 01 01 00 00 01
00 00 01 00 00 01 01 00 00 01
00 00 01 01 00 01 01 00 00 01
00 01 01 01 00 01 01 00 00 01

我的输出的一小段,代码就不贴了,用了递归
2007-8-25 21:47
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ToT
32
我的想法很简单,nametable[0]是可以自由从0变成1或者从1变成0的,而要将nametable[n]进行0、1的变化,需要nametable[n-1]=1,nametable[0..n-2]=0,这样,其实就是一个很简单的递归过程,虽然效率有点低,但是很容易想到。
即要将第n位将1变成0,首先将n-1位变成1,然后将n位变成0,然后再将n-1位变成0,这样就是很很简单的递归问题了
2007-8-25 21:49
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
33
现在才发现自己什么都不懂
2007-8-25 22:05
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
34
难啊 !! 看来还要多看几遍才能明白
2007-8-25 23:34
0
雪    币: 195
活跃值: (20)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
35
偶也来献丑,同样是格雷码。

#define CODE_LENGTH     9
#define TABLE_SIZE      ((1 << CODE_LENGTH) - 1)

unsigned int table[TABLE_SIZE] = {
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 8,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 9,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 8,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6,
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1
};

char    name[32];
char    serial[TABLE_SIZE + 1];

unsigned int calc_name
    (
    char            name[32],
    unsigned int    code[CODE_LENGTH]
    )
    {
    int name_length = strlen(name);
    int factor = 0x13572468;
    int tmp1, tmp2;
    unsigned char c;
    int i;

    for (i = 0; i < name_length; i++)
        {
        tmp1 = name[i];
        tmp1 += factor;
        tmp1 *= 0x03721273;
        tmp1 += 0x24681357;
        tmp2 = tmp1;
        tmp2 <<= 0x19;
        tmp1 >>= 0x07;
        tmp2 |= tmp1;
        factor = tmp2;
        }

    for (i = 1; i < CODE_LENGTH; i++)
        {
        tmp1= factor;
        tmp1 = tmp1 >> i;
        c = (unsigned char)tmp1;
        c &= 0x01;
        code[i - 1] = c;
        }

    code[8] = 1;

    return (unsigned int)factor;
    }

void calc_code1
    (
    int *   a,
    int *   b
    )
    {
    int i = CODE_LENGTH;
    a += (CODE_LENGTH - 1);
    b += (CODE_LENGTH - 1);
    *b = *a;

    for (i--; i > 0; i--, a--, b--)
        {
        *(b - 1) = (*b) ^ (*(a - 1));
        }
    }

int calc_code2
    (
    int *   a
    )
    {
    int v = 0;
    int i;

    i = CODE_LENGTH;
    a += (CODE_LENGTH - 1);
    for (; i > 0; i--, a--)
        {
        v = (v << 1) + (*a);
        }
    return v;
    }

int calc(char input[32])
    {
    int serial_length = 0;
    unsigned int name_int = 0;
    unsigned int name_code[CODE_LENGTH] = {0};
    int tmp[CODE_LENGTH] = {0};
    int i;

    name_int = calc_name(input, name_code);
    calc_code1(name_code, tmp);
    serial_length = calc_code2(tmp);

    for (i = 0; i < serial_length; i++)
        {
        serial[i] = table[serial_length - i - 1] - ((name_int >> (i % 31)) % 10);
        if (serial[i] < 0)
            serial[i] += 10;
        serial[i] += 0x30;
        }

    return 0;
    }
2007-8-26 00:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
36
ccfer一语中的-------------------pfpf
:做的时候把这当成一个模型,模型的样子大家都知道了,这下来就是求解这个模型
开始看一下很想矩阵运算,后来一步一步反推,感觉和以前看的 一个趣味故事相似,就是3个大老虎和他们的孩子3个小老虎过河,只有一条船......这里就是利用表中的第一个元素来摆渡,最后将表置为全0.
最后还是利用递归的样子解的

#define M1(x,fname,index) x[index]=(11- (fname>>(index%31))%10 )%10;index++
#define M2(x,fname,index) x[index]=(12- (fname>>(index%31))%10 )%10;index++
#define M3(x,fname,index) x[index]=(13- (fname>>(index%31))%10 )%10;index++
#define M4(x,fname,index) x[index]=(14- (fname>>(index%31))%10 )%10;index++
#define M5(x,fname,index) x[index]=(15- (fname>>(index%31))%10 )%10;index++
#define M6(x,fname,index) x[index]=(16- (fname>>(index%31))%10 )%10;index++
#define M7(x,fname,index) x[index]=(17- (fname>>(index%31))%10 )%10;index++
#define M8(x,fname,index) x[index]=(18- (fname>>(index%31))%10 )%10;index++
#define M9(x,fname,index) x[index]=(19- (fname>>(index%31))%10 )%10;index++
unsigned int fname =0;
int index =0;
int x[1000]={0} ;
void f1()
{
        M1(x,fname,index);
}
void f2()
{
        f1();
        M2(x,fname,index);
        f1();
}
void f3()
{
        f2();
        M3(x,fname,index);
        f2();
}
void f4()
{
        f3();
        M4(x,fname,index);
        f3();
}
void f5()
{
        f4();
        M5(x,fname,index);
        f4();
}
void f6()
{
        f5();
        M6(x,fname,index);
        f5();
}
void f7()
{
        f6();
        M7(x,fname,index);
        f6();
}
void f8()
{
        f7();
        M8(x,fname,index);
        f7();
}
void f9()
{
        f8();
        M9(x,fname,index);
        f8();
}
2007-8-26 01:07
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
37
计算机不是个好东西
2007-8-26 01:30
0
雪    币: 260
活跃值: (102)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
38
偶被卡的不行,愣是没想明白怎么能注册成功,后来干脆放弃了!楼主强啊!
2007-8-26 09:20
0
雪    币: 295
活跃值: (461)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
39
重在参与,题照做方法照想.只要能让我们看到后面的题目就可以了.
2007-8-26 11:07
0
雪    币: 295
活跃值: (461)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
40
#define M(i,x,fname,index) x[index]=(10+i- (fname>>(index%31))%10 )%10;printf("%d",x[index++]);

#define f(i) if( i==1) M(i,x,fname,index) \
else\
f(i-1);M(i,x,fname,index);f(i-1)

void main()
{
   calfname(inputName);//根据输入名字计算名字hash值
  calTable01(fname);//根据hash值计算01表
  //输出结果
  for(i=1;i<10;i++)
  {
      if( table01[i] )
            f(i);
  }
}
上面几行代码就可以搞定第一题了
2007-8-26 11:11
0
雪    币: 109
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
41
贴一下我的解法,标准递归,很容易理解:

        /**
         * 算法思路是: 依次使 9,8,7,...,1 位变成 0. 因为,假如使第 9 位变成 0 了,
         * 那么再把第 8 位变成 0 时就不需要考虑第 9 位了. 同样,第 8 位变成 0 后,
         * 再改变第 7 位时就不需要考虑 8,9 位. 问题难度将逐步降低,直到最终解决,
         * 而且,这个思路可以递归实现.
         */
        for (i = 9; i; i--)
        {
                if ( bits[i] != 0 )
                {
                        xor(bits,i);
                }
        }

下面是 xor 函数实现:

/**
* 将 bits数组的第 pos 位取反,也就是 bits[pos] ^= 1.
*
* 为将 pos 位取反,必须先:
* 1. bits[pos - 1] = 1
* 2. bits[1] 到 bits[pos - 2] 都为 0
* 这个函数通过递归调用来满足这两个条件.
*
* @note 未做递归深度检查. CrackMe2 中序列号最长 4096 (就是前面定义的 MAX_TIMES),这里假设不会超过这个值.
*/
static void xor(uint8_t bits[10],int pos)
{
        int i;

        /// 递归结束条件
        if (pos == 1)
        {
                bits[1] ^= 1;
                m_codes[m_count++] = 1;
                return;
        }

        /// 先递归调用来满足条件 1
        if ( bits[pos - 1] == 0 )
        {
                xor(bits,pos - 1);
        }

        /// 再递归调用来满足条件2
        for (i = pos - 2; i; i--)
        {
                if ( bits[i] != 0 )
                {
                        xor(bits,i);
                }
        }
       
        /// 2 个条件满足了,现在可以将第 pos 位取反了
        bits[pos] ^= 1;

        /// 记录第几步改变了第几位,后面根据这个生成序列号
        m_codes[m_count++] = pos;
}
2007-8-26 11:18
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
42
顶...辛苦了
2007-8-26 11:35
0
雪    币: 255
活跃值: (37)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
43
我的分析方法是不是北部对?
分析的速度很慢
步骤一:任意输入,用户名:aaaaa 注册码:bbbbb
        我们查找getdlgitemtexta首值,找到后下硬件访问断点,点击注册我们的程序将停在这里:

00400499  |.  8D45 EC       lea     eax, dword ptr [ebp-14]          ;《--------这里!
0040049C  |.  6A 10         push    10                               ; /Count = 10 (16.)
0040049E  |.  50            push    eax                              ; |Buffer
0040049F  |.  68 E9030000   push    3E9                              ; |ControlID = 3E9 (1001.)
004004A4  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
004004A7  |.  FFD6          call    esi                              ; \GetDlgItemTextA
004004A9  |.  85C0          test    eax, eax                         ;  字符是零吗?
004004AB  |.  74 6C         je      short 00400519                   ;  是的话就跳
004004AD  |.  8D85 E8EFFFFF lea     eax, dword ptr [ebp-1018]        ;  否则就把地址内容放A中
004004B3  |.  68 00100000   push    1000                             ; /Count = 1000 (4096.)
004004B8  |.  50            push    eax                              ; |Buffer
004004B9  |.  68 EA030000   push    3EA                              ; |ControlID = 3EA (1002.)
004004BE  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
004004C1  |.  FFD6          call    esi                              ; \GetDlgItemTextA

004004C3  |.  85C0          test    eax, eax                         ;  指向下一个窗口数 ,                                                                      ;窗口有数据吗?
004004C5 >|.  74 52         je      short 00400519                   ;  没有数据就跳到下一                                                                       ;个窗口
004004C7  |.  8D7D EC       lea     edi, dword ptr [ebp-14]          ;  字符的第一个放到DI里
004004CA  |.  83C9 FF       or      ecx, FFFFFFFF                    ;  对C放1

经过分析知道这是读取用户名,和用户注册码的地方
步骤二:

004004DA  |> /0FBE4415 EC   /movsx   eax, byte ptr [ebp+edx-14]      ;  把用户名转换到A寄存                                                                     ;  器里
004004DF  |. |03C3          |add     eax, ebx                        ;  AB相加
004004E1  |. |69C0 73127203 |imul    eax, eax, 3721273               ;  乘上3721273放到A里
004004E7  |. |05 57136824   |add     eax, 24681357                   ;  再加上24681357
004004EC  |. |8BF0          |mov     esi, eax                        ;  转化结果放SI里
004004EE  |. |C1E6 19       |shl     esi, 19                         ;  左移动19位
004004F1  |. |C1F8 07       |sar     eax, 7                          ;  循环右移动7位
004004F4  |. |0BF0          |or      esi, eax                        ;  结果相或
004004F6  |. |42            |inc     edx                             ;  D增加一
004004F7  |. |3BD1          |cmp     edx, ecx                        ;  到4了吗?
004004F9  |. |8BDE          |mov     ebx, esi                        ;  把SI的结果保存到BX                                                                                                         ;  里
004004FB  |.^\7C DD         \jl      short 004004DA

分析可知是一个用户名的函数变换:
函数如下:
unsingned int b=0x13572468; //常数
unsingned int a=0;          //中间变量1
unsingned int s=0;          //中间变量2
read();//读入一个用户名
func1(){  //用户名转化函数
   for(i=0;i<4;i++){
        a=read();
        a=(a+b)*3721273+24681357;
        s=a;
        s=s<<19;
        a=s>>7;
        s=s|a;
        b=s;
     }
}
====================================
//参数2的调用
004002CC  /$  55            push    ebp                              ;  传递了两个参数,用户名,运算,和注册玛的地址
004002CD  |.  8BEC          mov     ebp, esp                         ;  保护堆栈指针
004002CF  |.  81EC 28010000 sub     esp, 128                         ;  分配堆栈
004002D5      8065 DC 00    and     byte ptr [ebp-24], 0             ;  对12eab4缓冲区清零
004002D9  |.  53            push    ebx                              ;  保存结果用户运算结果
004002DA  |.  56            push    esi                              ;  保存结果
004002DB  |.  57            push    edi                              ;  保护将要用到的寄存器
004002DC  |.  33C0          xor     eax, eax                         ;  对A清零
004002DE  |.  8D7D DD       lea     edi, dword ptr [ebp-23]          ;  地址偏移量送DI
004002E1  |.  AB            stos    dword ptr es:[edi]               ;  串操作指令,对此地址清零
004002E2  |.  80A5 D8FEFFFF>and     byte ptr [ebp-128], 0            ;  对低八位清零
004002E9  |.  6A 40         push    40
004002EB  |.  AB            stos    dword ptr es:[edi]               ;  保存节
004002EC  |.  AA            stos    byte ptr es:[edi]                ;  保存字节
004002ED  |.  59            pop     ecx
004002EE  |.  33C0          xor     eax, eax                         ;  清零
004002F0  |.  8DBD D9FEFFFF lea     edi, dword ptr [ebp-127]         ;  对一首址放DI里
004002F6  |.  804D F4 FF    or      byte ptr [ebp-C], 0FF            ;  对地址12edcc的低字节的内容之一
004002FA  |.  F3:AB         rep     stos dword ptr es:[edi]          ;  对一个指定的区域清零
004002FC  |.  804D E8 FF    or      byte ptr [ebp-18], 0FF           ;  对底字节之一
00400300  |.  83C9 FF       or      ecx, FFFFFFFF
00400303  |.  66:AB         stos    word ptr es:[edi]                ;  对双字清陵
00400305  |.  AA            stos    byte ptr es:[edi]                ;  清零
00400306  |.  8B7D 0C       mov     edi, dword ptr [ebp+C]           ;  对注册码地址放到DI里
00400309  |.  33C0          xor     eax, eax                         ;  A清零
0040030B  |.  F2:AE         repne   scas byte ptr es:[edi]           ;  把AL或AX的内容与目标串作比较,比较结果反映在标志位
0040030D  |.  F7D1          not     ecx                              ;  厕得有几个字符?

00400313  |.  C645 F5 63    mov     byte ptr [ebp-B], 63             ;  对12EACD填充数据
00400317  |.  C645 F6 FB    mov     byte ptr [ebp-A], 0FB
0040031B  |.  C645 F7 9A    mov     byte ptr [ebp-9], 9A
0040031F  |.  C645 F8 03    mov     byte ptr [ebp-8], 3
00400323  |.  C645 F9 A3    mov     byte ptr [ebp-7], 0A3
00400327  |.  C645 FA DA    mov     byte ptr [ebp-6], 0DA
0040032B  |.  C645 FB 72    mov     byte ptr [ebp-5], 72
0040032F  |.  C645 FC FE    mov     byte ptr [ebp-4], 0FE
00400333  |.  C645 FD C9    mov     byte ptr [ebp-3], 0C9
00400337  |.  C645 FE B7    mov     byte ptr [ebp-2], 0B7
0040033B  |.  C645 E9 6A    mov     byte ptr [ebp-17], 6A
0040033F  |.  C645 EA D1    mov     byte ptr [ebp-16], 0D1
00400343  |.  C645 EB D2    mov     byte ptr [ebp-15], 0D2
00400347  |.  C645 EC 4E    mov     byte ptr [ebp-14], 4E
0040034B  |.  C645 ED 82    mov     byte ptr [ebp-13], 82
0040034F  |.  C645 EE DA    mov     byte ptr [ebp-12], 0DA
00400353  |.  C645 EF 72    mov     byte ptr [ebp-11], 72
00400357  |.  C645 F0 FE    mov     byte ptr [ebp-10], 0FE
0040035B  |.  C645 F1 C9    mov     byte ptr [ebp-F], 0C9
0040035F  |.  C645 F2 B7    mov     byte ptr [ebp-E], 0B7

===============================================
00400363  |.  8BF1          mov     esi, ecx                         ;  保存注册字的数目
00400365  |.  8BFB          mov     edi, ebx                         ;  BX到DI
00400367  |>  8B45 08       /mov     eax, dword ptr [ebp+8]          ;  一字节的数放A里
0040036A  |.  8BCF          |mov     ecx, edi                        ;  DI内容到C
0040036C  |.  D3E8          |shr     eax, cl                         ;  循环右移动CL个字节
0040036E  |.  22C3          |and     al, bl                          ;  A与B的低字节相与
00400370  |.  88443D DC     |mov     byte ptr [ebp+edi-24], al       ;  把A低字节的内容放到一地址
00400374  |.  47            |inc     edi
00400375  |.  83FF 09       |cmp     edi, 9
00400378  |.^ 7C ED         \jl      short 00400367
0040037A  |.  33FF          xor     edi, edi                         ;  循环9次后放DI清零
0040037C  |.  885D E5       mov     byte ptr [ebp-1B], bl            ;  低字节送次
0040037F  |.  85F6          test    esi, esi                         ;  SI是零吗?
00400381  |.  7E 6B         jle     short 004003EE                   ;  小于等于的话就跳
00400383  |>  8B45 0C       /mov     eax, dword ptr [ebp+C]          ;  把注册码放EA内
00400386  |.  8A0407        |mov     al, byte ptr [edi+eax]          ;  把注册玛送BL
00400389  |.  3C 30         |cmp     al, 30                          ;  注册玛合30 比较,在A里是0
0040038B  |.  8845 FF       |mov     byte ptr [ebp-1], al            ;  注册码放到12EAD7内存里
0040038E  |.  0F8C 97000000 |jl      0040042B                        ;  小于30的话,就跳
00400394  |.  3C 39         |cmp     al, 39                          ;  和39比较
00400396      0F8F 8F000000 jg      0040042B                         ;  大于39吗?大于就就跳在ASC里是是9
0040039C  |.  8BC7          |mov     eax, edi                        ;  否DI放A
0040039E  |.  6A 1F         |push    1F
004003A0  |.  99            |cdq                                     ;  字扩展
004003A1  |.  59            |pop     ecx
004003A2  |.  F7F9          |idiv    ecx
004003A4  |.  8B45 08       |mov     eax, dword ptr [ebp+8]          ;  送A
004003A7  |.  6A 0A         |push    0A

=====================================================
就再也分析不下去了
都是动态的
2007-8-26 18:53
0
雪    币: 267
活跃值: (1913)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
44
分析的非常详细,就差手把手的当面教了
2007-8-26 19:00
0
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
45
楼上的源码好简单
2007-8-26 21:50
0
雪    币: 219
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
46
我也来学习一下!~~~~
2007-8-26 22:08
0
雪    币: 328
活跃值: (10)
能力值: ( LV9,RANK:210 )
在线值:
发帖
回帖
粉丝
47
[QUOTE=孤行有你;350890]我的分析方法是不是北部对?
分析的速度很慢
步骤一:任意输入,用户名:aaaaa 注册码:bbbbb
        我们查找getd...
s=s<<19;
a=s>>7;

[/QUOTE]

这里明显有问题
2007-8-27 08:13
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
48
[QUOTE=blue_devil_bomb;350713]#define M(i,x,fname,index) x[index]=(10+i- (fname>>(index%31))%10 )%10;printf("%d",x[index++]);

#define f(i) if( i==1) M(i,x,fname,...[/QUOTE]

代码是很短了,但是好难看懂;)我没有理清你的思路,给大家讲下吧;)
2007-8-27 08:57
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
49
思路很清楚,感谢分享;)这可能和人的思维习惯有关系;)
我着手太细了,你这个是整体思路.
2007-8-27 10:16
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
50
哈,昨天没看这个版,好详细,不如当面来教我吧
2007-8-27 11:10
0
游客
登录 | 注册 方可回帖
返回
//