首页
社区
课程
招聘
[原创]WinSnap 3.1 注册算法分析 & 算法还原
发表于: 2009-8-8 21:29 17194

[原创]WinSnap 3.1 注册算法分析 & 算法还原

2009-8-8 21:29
17194

WinSnap是一款屏幕截图软件,可以方便地对屏幕截图并可进行处理。其下载地址是:
http://www.ntwind.com/software/winsnap.html
其最新版为3.10,未注册版本只有30天使用期。

一. 程序分析
首先用PEID查一下是否加壳,显示“什么也没发现”。
既然不知道有没有壳,那就直接载入OD分析,使用通用的方法对GetDlgItemTextW下断即可很容易获取输入的用户名和序列号。然后就是字符转换函数,将用户名和序列号由Unicode转换为ASCII。

再走几步就到了对用户注册合法性校验的函数,地址为0x00409A10,下面用IDA载入程序对这个函数进行静态分析。
此函数非常庞大,下面分几部分进行说明。
首先,函数开始部分将用户名转换为大写,紧接着就是对用户名进行处理。
我们可以看到首先就是对sub_409790函数的调用,传递的参数是用于处理用户名缓冲区和-1。
此函数在用户名处理的过程中被多次调用。

.text:00409790 sub_409790      proc near               ; CODE XREF: CheckPas+75p
.text:00409790                                         ; CheckPas+1D2p
.text:00409790
.text:00409790 var_104         = byte ptr -104h
.text:00409790 var_4           = dword ptr -4
.text:00409790 pUserNameBuf    = dword ptr  4
.text:00409790 arg_4           = dword ptr  8
.text:00409790
.text:00409790                 sub     esp, 104h
.text:00409796                 mov     eax, dword_44F050
.text:0040979B                 xor     eax, esp
.text:0040979D                 mov     [esp+104h+var_4], eax
.text:004097A4                 mov     eax, [esp+104h+arg_4] ; 参数2:-1
.text:004097AB                 push    ebx
.text:004097AC                 push    ebp
.text:004097AD                 mov     ebp, [esp+10Ch+pUserNameBuf]
.text:004097B4                 push    esi
.text:004097B5                 push    edi
.text:004097B6                 mov     edi, ebp        ; edi 用户名指针
.text:004097B8                 test    eax, eax
.text:004097BA                 jge     short loc_4097CA
.text:004097BC                 mov     eax, ebp
.text:004097BE                 lea     edx, [eax+1]
.text:004097C1
.text:004097C1 loc_4097C1:                             ; CODE XREF: sub_409790+36j
.text:004097C1                 mov     cl, [eax]
.text:004097C3                 inc     eax
.text:004097C4                 test    cl, cl
.text:004097C6                 jnz     short loc_4097C1
.text:004097C8                 sub     eax, edx        ; 计算用户名长度
.text:004097CA
.text:004097CA loc_4097CA:                             ; CODE XREF: sub_409790+2Aj
.text:004097CA                 xor     edx, edx        ; 数组索引变量
.text:004097CC                 mov     esi, eax        ; esi 用户名长度
.text:004097CE                 mov     edi, edi        ; edi 用户名指针
.text:004097D0
.text:004097D0 loc_4097D0:                             ; CODE XREF: sub_409790+70j
.text:004097D0                 mov     bl, dl
.text:004097D2                 add     bl, 0Dh
.text:004097D5                 mov     byte_457B78[edx], dl
.text:004097DB                 mov     [esp+edx+114h+var_104], bl
.text:004097DF                 test    eax, eax
.text:004097E1                 jle     short loc_4097F9
.text:004097E3                 mov     cl, [edi]
.text:004097E5                 add     cl, al
.text:004097E7                 xor     cl, bl
.text:004097E9                 sub     esi, 1
.text:004097EC                 mov     [esp+edx+114h+var_104], cl ; 存放经过处理的用户名的局部数组
.text:004097F0                 jnz     short loc_4097F8
.text:004097F2                 mov     edi, ebp
.text:004097F4                 mov     esi, eax
.text:004097F6                 jmp     short loc_4097F9
.text:004097F8 ; ---------------------------------------------------------------------------
.text:004097F8
.text:004097F8 loc_4097F8:                             ; CODE XREF: sub_409790+60j
.text:004097F8                 inc     edi
.text:004097F9
.text:004097F9 loc_4097F9:                             ; CODE XREF: sub_409790+51j
.text:004097F9                                         ; sub_409790+66j
.text:004097F9                 inc     edx
.text:004097FA                 cmp     edx, 100h
.text:00409800                 jl      short loc_4097D0
.text:00409802                 xor     eax, eax
.text:00409804                 xor     ecx, ecx        ; 
.text:00409806                 mov     dword_457C78, eax
.text:0040980B                 mov     dword_457C7C, eax
.text:00409810
.text:00409810 loc_409810:                             ; CODE XREF: sub_409790+B2j
.text:00409810                 mov     dl, byte_457B78[eax]
.text:00409816                 movzx   esi, [esp+eax+114h+var_104]
.text:0040981B                 movzx   edi, dl
.text:0040981E                 add     esi, ecx
.text:00409820                 add     edi, esi
.text:00409822                 and     edi, 0FFh
.text:00409828                 mov     ecx, edi
.text:0040982A                 mov     bl, byte_457B78[ecx]
.text:00409830                 mov     byte_457B78[eax], bl
.text:00409836                 inc     eax
.text:00409837                 cmp     eax, 100h
.text:0040983C                 mov     byte_457B78[ecx], dl
.text:00409842                 jl      short loc_409810
.text:00409844                 mov     ecx, [esp+114h+var_4]
.text:0040984B                 pop     edi
.text:0040984C                 pop     esi
.text:0040984D                 pop     ebp
.text:0040984E                 pop     ebx
.text:0040984F                 xor     ecx, esp
.text:00409851                 call    sub_4322D2
.text:00409856                 add     esp, 104h
.text:0040985C                 retn
.text:0040985C sub_409790      endp

以上代码将处理后的用户名存放在大小为100h字节的UserNameBuf中,
其中,主要运算过程是根据UserNameBuf的值进行运算后建立一个100h字节的局部变量,接着根据局部数组
的值对457B78中的元素进行运算,用运算后的结构作为索引457B78数组的值进行两两置换,也就是矩阵的运算。
现给出它的伪代码。

void sub_409790(void pasbuf, int par2)
{
  BYTE buf[0x100];
  void pUserNameBuf = pasbuf;
  DWORD len = par2;
  if(par2 < 0)
    len = GetLen(pUserNameBuf);
  DWORD temp = len;
  DWORD index = 0;
  while(index < 0x100)
  {
    bl = (BYTE)index + 0xD;
    457B78[index] = (BYTE)index;
    buf[index] = bl;
    if(len > 0)
    {
      // 根据用户名缓冲区运算后对局部数组赋值
      buf[index] = (*pUserNameBuf + (BYTE)len) ^ bl;
      temp--;
      if(temp != 0)
        pUserNameBuf++;
      else {
        pUserNameBuf = par1;
        temp = len;
      }
    }
    index++;
  }
  [457C78] = 0;
  [457C7C] = 0;
  index = 0;
  temp2 = 0;
  while(index < 0x100)
  {
    // 根据buf的值对索引进行运算,然后置换索引对应的值
    dl = 457B78[index];
    temp2 = ((DWORD)dl + (DWORD)buf[index] + temp2) ^ 0xFF;
    457B78[index] = temp2;
    457B78[temp2] = dl;
    index++;
  }
}
409790(UserNameBuf, -1);
DWORD num = 0x100;
while(num != 0)
{
  var1 = [457C7C];   //eax
  index1 = [457C78];  //esi
  
  num2 = 0;
  while(num2 < 0x100) 
  {
    for(int i=0; i<4; i++)
    {
      var1 = var1++ & 0xFF;
      temp = 457B78[var1];
      index1 = (temp + index1) & 0xFF;
      457B78[var1] = 457B78[index1];
      457B78[index1] = temp;
      index2 = (temp + 457B78[var1]) & 0xFF;
      UserNameBuf[num2 + i] = 457B78[index2];
    }
    
    num2 += 4;  
  }
  [457C7C] = var1;
  [457C78] = index1;
  sub_409790(UserNameBuf, 0x100);
  num--;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (34)
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
厉害,拜读了,
2009-8-9 02:00
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
强大,菜鸟特来膜拜
2009-8-9 13:53
0
雪    币: 3003
活跃值: (479)
能力值: ( LV15,RANK:1395 )
在线值:
发帖
回帖
粉丝
4
太强了,学习一下
2009-8-9 14:06
0
雪    币: 170
活跃值: (90)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
不错 mark下 有时间跟一下
2009-8-11 01:15
0
雪    币: 388
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
好好学习了 .
2009-8-11 13:12
0
雪    币: 97697
活跃值: (200759)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
7
Support.
2009-8-11 13:35
0
雪    币: 1373
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
学习了,分析彻底。
2009-8-12 14:16
0
雪    币: 222
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
分析写得很完整。不错,要学习。
2009-8-12 17:50
0
雪    币: 1027
活跃值: (1422)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
确实值得学习。好文章。
2009-8-13 22:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
非常好用,谢谢楼主,辛苦了~
2009-8-14 15:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢楼主,辛苦了!!!!
2009-8-14 15:58
0
雪    币: 338
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
强大.分析的好!~~
2009-8-14 20:53
0
雪    币: 232
活跃值: (15)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
14
学习了...
2009-8-15 00:51
0
雪    币: 151
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
强人。
2009-8-19 22:36
0
雪    币: 250
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
好有耐心啊,膜拜
2009-8-20 10:14
0
雪    币: 172
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
SUper man
2009-8-20 10:17
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
18
看完了,还是不明白,到底有没有壳。。
2009-8-20 10:49
0
雪    币: 160
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
不错,分析得也挺详细的
2009-8-20 10:59
0
雪    币: 388
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
分析的很透彻啊,谢谢楼主分享,学习下
2009-9-29 15:24
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
分析很透彻,下载一个跟跟看
2009-10-1 02:13
0
雪    币: 111
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
22
分析很详细了,学习了,
2009-10-1 13:11
0
雪    币: 264
活跃值: (135)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
学习一下,很详细。谢谢
2009-10-21 14:57
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
24
拜读,学习永远不迟
2009-10-21 18:04
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
楼主辛苦  学习了
2009-12-27 00:22
0
游客
登录 | 注册 方可回帖
返回
//