yangjt 发表于 2009-2-6 11:00

zapline转载CM(第十天)分析

先说明昂……半原创,算法分析是自己来得……注册机不会写……从网上so来的……:lol

看到这个东西我就晕倒了……=.=咳……

直接IDA对付……

载入后找到处理窗口回调的地方……,在这里……
CODE:004010CE ; signed int __stdcall WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM a4)
CODE:004010CE WndProc         proc near               ; DATA XREF: start+5Eo
CODE:004010CE
CODE:004010CE hWnd            = dword ptr8
CODE:004010CE iMsg            = dword ptr0Ch
CODE:004010CE wParam          = dword ptr10h
然后F5之,修修改改后代码变成了这样……嗯……我这篇文章唯一有用的地方就在这里了……好好看哦~~:loveliness:
signed int __stdcall WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM a4)
{
UINT ST10_4_0; // ST10_4@0
signed int result; // eax@4
int pIndex; // esi@7
int index; // ecx@8

if ( iMsg == WM_COMMAND )
{
    if ( wParam == 1 )                                          //If the message is from an accelerator, this value is 1
                                                                // 即鼠标点击……
    {
      pIndex = 0;
      Temp = 0;
      Score = 0;                                                // 等于207102就成功……
      while ( 1 )
      {
      index = CharTable;
      if ( index == 77 )
          break;
      Temp = CharTable;
      if ( IsDlgButtonChecked(hWnd, index) )
          Score += pIndex * CharTable * Temp;         // 做一些乘法和加法累加到某个地方……
      }
      if ( 77 * Score == 15946854 )                           // 这个地方等于多少?选中的东西经过某些运算等于207102就好了……可惜俺不会算……
      {
      MessageBoxA(
          0,
          "Congratulations! Please send a screenshot of your solution to duelist@beer.com!",
          "Duelist's Crackme #3",
          0x2000u);
      result = 1;
      }

看到这里我就晕倒了……嗯……不会做了……:'( 咳……不得不承认我数学水平之差……想了半个多小时也没想明白……:L
不过看到了CrackME的标题就想到办法了~~:lol
既然是Duelist's Crackme #3 所以就百度之……果然让我找到了……

下面内容转自看雪……
http://bbs.pediy.com/upload/2006/37/image/bxm2.jpg
算法比较简单,地址处为一个19个字节的表0x16, 0x49, 0x5E, 0x15, 0x27, 0x26, 0x21, 0x25, 0x1D, 0x59, 0x53, 0x37, 0x31, 0x48, 0x5D, 0x0C, 0x61, 0x52, 0x4D。
进一步跟踪发现各按钮对应的代号,为了和注册机一致,我把每个代号都减了1,18个按钮的代号如下:
161   2   0   7   5   6910
311121314151748
如我用注册机算出的一个号码为25726,转化为二进制110010001111110,把对应1位的选中就可以了,如
   
注册机源码如下:
#include<iostream.h>
void main()
{
    long unsigned loop=262143;
    long unsigned i,itemp,EAX,count,sum;
    char table={0x16, 0x49, 0x5E, 0x15, 0x27, 0x26, 0x21, 0x25, 0x1D, 0x59, 0x53, 0x37, 0x31,

      0x48, 0x5D, 0x0C, 0x61, 0x52, 0x4D};
    for(i=0;i<loop;i++)
    {
      sum=0;
      count=0;itemp=i;
      do
      {
      if(itemp%2==1){EAX=table*table*(count+1);sum+=EAX;}
      count++;
      itemp/=2;
      }
      while(itemp);
      if(sum*0x4d==0xf35466)
      {
      cout<<i<<endl;
      }
    }
}
我只找到了一个正确答案,可能也只有一个正确答案。
可怜我到现在还是没看明白算法到底啥意思……:'(
:Q 咳……可怜的我……

[ 本帖最后由 yangjt 于 2009-2-6 11:04 编辑 ]

zapline 发表于 2009-2-6 13:41

分析得太不清楚了啊

zhang0101 发表于 2009-2-7 11:50

看不懂诶..................
页: [1]
查看完整版本: zapline转载CM(第十天)分析