IrpTrace最新版注册算法分析

文章目录

  • IrpTrace注册算法分析
    • 前言
    • 分析
      • 运行
      • 算法流程
    • 注册码

IrpTrace注册算法分析

前言

没有时间系列:由于工作需要用到该软件,于是顺便研究注册算法玩玩。又是一款歪果仁的软件,搞搞应该没事吧?文末有惊喜!

【版本】02.00.002
IrpTrace已经很久不更新了,这是我能在网上找到的最新版。。。。。

分析

运行

IrpTrace最新版注册算法分析_第1张图片

算法流程

注册算法在模块TSCUST.DLL中,并且此模块保留了调试符号。第一次见在正式的商业软件中这么干的,心可真大。所有功能一目了然。

这个窗口的按钮事件如下图所示:

IrpTrace最新版注册算法分析_第2张图片

函数 C C u s t L i b : : R e q u e s t S e r i a l N u m b e r \textcolor{cornflowerblue}{CCustLib::RequestSerialNumber} CCustLib::RequestSerialNumber会校验用户输入的序列号,校验成功就会调用 C C u s t L i b : : R e g i s t e r P r o d u c t \textcolor{cornflowerblue}{CCustLib::RegisterProduct} CCustLib::RegisterProduct注册产品。

C C u s t L i b : : R e q u e s t S e r i a l N u m b e r \textcolor{cornflowerblue}{CCustLib::RequestSerialNumber} CCustLib::RequestSerialNumber实际调用 C C u s t L i b : : C h e c k S e r i a l N u m b e r \textcolor{cornflowerblue}{CCustLib::CheckSerialNumber} CCustLib::CheckSerialNumber校验序列号

C C u s t L i b : : C h e c k S e r i a l N u m b e r \textcolor{cornflowerblue}{CCustLib::CheckSerialNumber} CCustLib::CheckSerialNumber内部分两个流程对序列号进行校验:

  1. 校验序列号是否过期,对应函数为 I s S N E x p i r e d \textcolor{cornflowerblue}{IsSNExpired} IsSNExpired
  2. 校验序列号与特定常量的校验和是否满足某个关系式,对应函数为 C h e c k S e r i a l N u m b e r 3 \textcolor{cornflowerblue}{CheckSerialNumber3} CheckSerialNumber3

下面先分析 I s S N E x p i r e d \textcolor{cornflowerblue}{IsSNExpired} IsSNExpired函数

IrpTrace最新版注册算法分析_第3张图片

G e t S N E x p i r a t i o n D a t e \textcolor{cornflowerblue}{GetSNExpirationDate} GetSNExpirationDate函数用序列号中某些位置的元素算出3个变量v5v6v7(IDA分析有些问题,并不是serial)。这些位置满足关系如下:

IrpTrace最新版注册算法分析_第4张图片

s e r i a l [ 0 ] \textcolor{orange}{serial[0]} serial[0]可以是任意可见字符,从而计算得到pos变量。 p o s   =   3 ∗ ( s e r i a l [ 0 ]   %   0 x A ) \textcolor{orange}{pos\ =\ 3*(serial[0]\ \%\ 0xA)} pos = 3(serial[0] % 0xA)

v5v6v7分别对应图中的a2a3a4。代表的含义是serial下标为pos对应的元素所在全局变量g_lpszCodeStr中的下标。由此可见serial中的元素包含于g_lpszCodeStr中。然后作为函数 C o m p a r e W i t h B u i l d D a t e \textcolor{cornflowerblue}{CompareWithBuildDate} CompareWithBuildDate的参数校验是否过期。

在这里插入图片描述

函数 G e t P r o d u c t B u i l d D a t e \textcolor{cornflowerblue}{GetProductBuildDate} GetProductBuildDate会根据字符串**“Aug 16 2015”取得v6+1**,v6+2v6+3的值分别是0xf80x10

C o m p a r e D a t e s \textcolor{cornflowerblue}{CompareDates} CompareDates中会将传入的参数进行分组计算值,这里记为y1y2,然后比较 y 1 − y 2 < 0 \textcolor{orange}{y1-y2<0} y1y2<0则说明过期。

IrpTrace最新版注册算法分析_第5张图片

y 1 = C a l c D a y s ( v 5 , v 5 , v 7 ) , y 2 = C a l c D a y s ( v 6 + 3 , v 6 + 2 , v 6 + 1 ) \textcolor{orange}{y1 = CalcDays(v5,v5,v7),y2 = CalcDays(v6+3,v6+2,v6+1)} y1=CalcDays(v5,v5,v7)y2=CalcDays(v6+3,v6+2,v6+1)

IrpTrace最新版注册算法分析_第6张图片

令T=CalcDays(x1,x2,x3),对应的数学表达式:
T = { x 1 , x 2 ≤ 1 &   x 3 ≤ 0   ( 1 ) x 1 + a [ x 2 ] , x 2 > 1 &   x 3 ≤ 0   ( 2 ) x 1 + a [ x 2 ] + 0 x 16 ∗ ( x 3 − 1 ) , x 2 > 1 &   x 3 ≥ 1   ( 3 ) 其中 x 1 , x 2 , x 3 分别表示 C a l c D a y s 的参数 x 1 , x 2 , x 3 T = \begin{cases}\quad{x_1,x_2\leq1\&\ x_3\leq0}\ (1) \\ \quad x_1+a[x_2],x2>1\&\ x_3\leq0\ (2)\\ \quad x_1+a[x_2]+0x16*(x_3-1),x_2>1\&\ x_3\ge1\ (3) \end{cases}\\其中x_1,x_2,x_3分别表示CalcDays的参数x1,x2,x3 T= x1,x21& x30 (1)x1+a[x2],x2>1& x30 (2)x1+a[x2]+0x16(x31),x2>1& x31 (3)其中x1x2x3分别表示CalcDays的参数x1,x2,x3
C o m p a r e D a t e s \textcolor{cornflowerblue}{CompareDates} CompareDates函数要求
T ( x 1 , x 2 , x 3 ) ≥ T ( 0 x f , 0 x 8 , 0 x 10 ) ≥ 0 x 14 D A T(x_1,x_2,x_3)\ge T(0xf,0x8,0x10)\ge0x14DA T(x1,x2,x3)T(0xf,0x8,0x10)0x14DA
易知上式中的(1)不满足条件,并且T函数每个分段都是单调递增的,所以推出其中一种满足的输入
x 1 ∈ N , x 2 ≥ 0 x 8 , x 3 ≥ 0 x f x_1\in N,x_2 \ge 0x8,x_3 \ge 0xf x1Nx20x8,x30xf
也就是说 s e r i a l [ g _ l p s z C o d e S t r [ p o s ] ] \textcolor{orange}{serial[g\_lpszCodeStr[pos]]} serial[g_lpszCodeStr[pos]]可以是g_lpszCodeStr中的任意字符, s e r i a l [ g _ l p s z C o d e S t r [ p o s + 1 ] ] \textcolor{orange}{serial[g\_lpszCodeStr[pos+1]]} serial[g_lpszCodeStr[pos+1]]必须是 中 g _ l p s z C o d e S t r [ 8 : 63 ] 中\textcolor{orange}{g\_lpszCodeStr[8:63]} g_lpszCodeStr[8:63]的字符, s e r i a l [ g _ l p s z C o d e S t r [ p o s + 2 ] ] \textcolor{orange}{serial[g\_lpszCodeStr[pos+2]]} serial[g_lpszCodeStr[pos+2]]必须是 g _ l p s z C o d e S t r [ 0 x f : 63 ] \textcolor{orange}{g\_lpszCodeStr[0xf:63]} g_lpszCodeStr[0xf:63]中的字符。

接下来看校验和部分

IrpTrace最新版注册算法分析_第7张图片

G e t C h e c k s u m 3 \textcolor{cornflowerblue}{GetChecksum3} GetChecksum3函数计算一个特定字符串**“IT0200”的校验和,结果为0x090C0000**。不妨记d1为serial前4个字节的DWORD值,d2为serial接下来的4个字节的DWORD值。满足关系式:
d 1   m o d   9 = 3 d 2   m o d   0 x C = 3 d1\ mod\ 9=3\\d2\ mod\ 0xC=3\\ d1 mod 9=3d2 mod 0xC=3
通过前面的分析,我们得知serial中的字符来自于g_lpszCodeStr变量,也就是 “P7JFC5NMSXO09LDKGTQ2ZVHY8W16R3EA4BIU”63个,枚举满足上式的空间在 6 3 4 \textcolor{orange}{63^4} 634以内,时间不会超过1s。

通过枚举得到一种满足条件的组合PPPN7PP7,这8个字符均来自serial中的某些位置。

这8个位置的产生满足以下条件:

IrpTrace最新版注册算法分析_第8张图片

其中变量 M E M O R Y [ 0 x 2 F 714 ]   =   { 7 , 3 , 9 , 0 x a , 8 , 4 , 2 , 5 , 1 , 1 , 0 x b , 6 , 3 , 5 , 7 , 0 x b , 0 x a , 4 , 9 , 8 , 2 , 0 x a , 2 , 9 , 7 , 6 , 4 , 8 , 2 , 0 x b } \textcolor{orange}{MEMORY[0x2F714]\ =\ \{7,3,9,0xa,8,4,2,5,1,1,0xb,6,3,5,7,0xb,0xa,4,9,8,2,0xa,2,9,7,6,4,8,2,0xb\} } MEMORY[0x2F714] = {7,3,9,0xa,8,4,2,5,1,1,0xb,6,3,5,7,0xb,0xa,4,9,8,2,0xa,2,9,7,6,4,8,2,0xb}

至此,已经得到了serial的所有字符,只剩下位置pos不知道了。

而pos是由serial[0]来确定的,serial[0]可以是g_lpszCodeStr中任意位置的元素。所以可以先随机指定一个serial[0],从而确定pos,根据pos来确定剩下11个字符的位置就可以了。

注册码

下面列举一些可用的注册码:

APPPRN7PP7S0

QPPPBN7POPE7

APPPRN7PP7SA

RVYPPSPN7PP7

SOPPPN87PP7L

8PKPPN7P98P7

你可能感兴趣的:(逆向,网络安全)