• 标 题:易语言------精科电脑算命V3.4版注册算法分析
  • 作 者:mejy
  • 时 间:2004-3-24 周三, 上午8:11
  • 链 接:http://bbs.pediy.com

n久以前写的.有些东西已经记不住了.呵呵
没完过易语言的东东,第一次玩,找了个软柿子捏捏。写出来和大家共享,这个软件的算法不难.没其他意思,仅供共享经验而已
在开始分析之前写上我的一点心得:对于易语言的东东。程序运行起来向加了一层壳一样,一切都在库里面进行.你如果用OD载入,不运行程序,就开始查找程序中的某些地址,是找不到的,例如本软件的关键48C00F处。还有易语言的库程序。而对于易语言,其实一个万能断点是GetWindowTextA(个人认为)。因为系统会用这个函数进行其他的操作,所以有可能你在此设断时,并不是你要的东西。这时我得做法是先将OD窗口话,在设断,观察EAX中的值(怎么用体会一下就知道了)。还有一个特点就是易语言好像喜欢用浮点运算。如果当程序注册失败时,出现注册失败提示的话,那么他又保露了一点,那就是MessageBoxA函数。也可在这个函数上设断,等断在这里之后,用F8单步,看看堆栈区里,看见你输入的东西了马。这时可以用内存断点,来跟踪达到特殊效果。至于如何设断点,我建议的做法是,当程序运行起来之后用Ctrl+F,来查找1000000地址,这里就是易语言的库函数空间。然后用搜索当前模块中的函数,就可以找到相应的函数。这样比直接用BP下断点感觉好一点。可以避免在系统库中转。以上仅是我在分析易语言程序时候的一点心得,至于具体效果如何,各位可以试试,不正确之处,还希望大家指出。。申明这个方法不是万金油!
0048BEE2   55               PUSH EBP   在这里设断
0048BEE3   8BEC             MOV EBP,ESP
0048BEE5   81EC 24000000    SUB ESP,24
0048BEEB   C745 FC 00000000 MOV DWORD PTR SS:[EBP-4],0
下面是一段浮点运算
0048BEF2   DB05 6C050D01    FILD DWORD PTR DS:[10D056C]取机器码的后几位
例如我得机器码是CD1119312,取1119312入栈
0048BEF8   DD5D F4          FSTP QWORD PTR SS:[EBP-C]
FSTP 的功能st(0)保存倒DEST (mem32/mem64/mem80);然后再执行一次出栈操作
0048BEFB   DD45 F4          FLD QWORD PTR SS:[EBP-C]
FLD src  装入实数到st(0)  st(0) <- src (mem32/mem64/mem80) 
将1119312到ST0
0048BEFE   DC05 837C4500    FADD QWORD PTR DS:[457C83]
00457C83中的数据为16575065.00000000这里他是怎么计算出来的我没跟出来后来才知道原来是程序中固定的
上一句的作用是将1119312和16575065相加
0048BF04   DD5D F4          FSTP QWORD PTR SS:[EBP-C] 入st7
0048BF07   DD45 F4          FLD QWORD PTR SS:[EBP-C] 装入到s’t0做下一次加法
0048BF0A   DC25 8B7C4500    FSUB QWORD PTR DS:[457C8B]
取00457C83处的值 2256.000000000000 做减法 这里也是程序中固定的
0048BF10   DD5D EC          FSTP QWORD PTR SS:[EBP-14]  
0048BF13   DD45 EC          FLD QWORD PTR SS:[EBP-14]
0048BF16   DC05 937C4500    FADD QWORD PTR DS:[457C93]
取00457C93的值1948.291666666667做加法  程序中固定的值
0048BF1C   DD5D E4          FSTP QWORD PTR SS:[EBP-1C]
0048BF1F   68 01030080      PUSH 80000301
0048BF24   6A 00            PUSH 0
0048BF26   68 BB184D00      PUSH 4D18BB
0048BF2B   DD45 E4          FLD QWORD PTR SS:[EBP-1C] 装入实数到st0
0048BF2E   E8 7028FEFF      CALL jksm.0046E7A3
0048BF33   68 01030080      PUSH 80000301
0048BF38   6A 00            PUSH 0
0048BF3A   50               PUSH EAX
0048BF3B   68 02000000      PUSH 2
0048BF40   BB CC000000      MOV EBX,0CC
0048BF45   E8 F1370000      CALL jksm.0048F73B
略调一部分
0048BFD5   53               PUSH EBX
0048BFD6   E8 6C370000      CALL jksm.0048F747
0048BFDB   83C4 04          ADD ESP,4
0048BFDE   DB45 FC          FILD DWORD PTR SS:[EBP-4] 装入正确的密码
0048BFE1   DD5D E4          FSTP QWORD PTR SS:[EBP-1C] 
0048BFE4   DD45 EC          FLD QWORD PTR SS:[EBP-14] 装入错误的密码
0048BFE7   DC65 E4          FSUB QWORD PTR SS:[EBP-1C] 相减
注意下面这些浮点指令很烦的
0048BFEA   D9E4            FTST 零检测将ST0与0。0比较,看上面的结果是否为0
0048BFEC   DFE0             FSTSW AX  保存状态子到AX
0048BFEE   F6C4 01          TEST AH,1
0048BFF1   74 02            JE SHORT jksm.0048BFF5
0048BFF3   D9E0             FCHS  改变符号
0048BFF5   DC1D 49DE4100    FCOMP QWORD PTR DS:[41DE49]
0048BFFB   DFE0             FSTSW AX
0048BFFD   F6C4 41          TEST AH,41
0048C000   B8 00000000      MOV EAX,0
0048C005   0F95C0           SETNE AL       不等于0或者不相等时置OPRD为1
0048C008   8945 E4          MOV DWORD PTR SS:[EBP-1C],EAX
0048C00B   837D E4 01       CMP DWORD PTR SS:[EBP-1C],1
0048C00F   0F85 0A000000    JNZ jksm.0048C01F  这里如果跳走的话就失败了
0048C015   E8 65000000      CALL jksm.0048C07F 这个call是计算注册码的跟进

0048C07F   55               PUSH EBP
0048C080   8BEC             MOV EBP,ESP
0048C082   81EC 20000000    SUB ESP,20
0048C088   C745 FC 00000000 MOV DWORD PTR SS:[EBP-4],0
0048C08F   C745 F8 00000000 MOV DWORD PTR SS:[EBP-8],0
0048C096   68 04000080      PUSH 80000004
0048C09B   6A 00            PUSH 0
0048C09D   68 23A84200      PUSH jksm.0042A823
0048C0A2   68 01000000      PUSH 1
0048C0A7   BB 64010000      MOV EBX,164
0048C0AC   E8 8A360000      CALL jksm.0048F73B
0048C0B1   83C4 10          ADD ESP,10
0048C0B4   8945 F0          MOV DWORD PTR SS:[EBP-10],EAX
0048C0B7   8955 F4          MOV DWORD PTR SS:[EBP-C],EDX
0048C0BA   DD05 3CA84200    FLD QWORD PTR DS:[42A83C] 估计这里的值也是固定的 0042A83C中       44353402.00000000
0048C0C0   DC65 F0          FSUB QWORD PTR SS:[EBP-10]
0048C0C3   DD5D E8          FSTP QWORD PTR SS:[EBP-18]
0048C0C6   DD45 E8          FLD QWORD PTR SS:[EBP-18] 将上面的值装入ST0
0048C0C9   E8 D526FEFF  CALL jksm.0046E7A3  这个CALL将他转化成十六进制值1
0048C0CE   68 01030080      PUSH 80000301
0048C0D3   6A 00            PUSH 0
0048C0D5   50               PUSH EAX
0048C0D6   68 01030080      PUSH 80000301
0048C0DB   6A 00            PUSH 0
0048C0DD   FF35 6C050D01    PUSH DWORD PTR DS:[10D056C]
0048C0E3   68 02000000      PUSH 2
0048C0E8   BB CC000000      MOV EBX,0CC
0048C0ED   E8 49360000      CALL jksm.0048F73B 这里是计算注册码的关键跟进去发现程序的作用是将上面的值1与一个固定的值0x111450进行异或运算
0048C0F2   83C4 1C          ADD ESP,1C
0048C0F5   8945 FC          MOV DWORD PTR SS:[EBP-4],EAX
略调一部分
0048C142   74 09            JE SHORT jksm.0048C14D
0048C144   53               PUSH EBX
0048C145   E8 FD350000      CALL jksm.0048F747
0048C14A   83C4 04          ADD ESP,4  上面代码将输入的假码转化成浮点形式
0048C14D   DD45 EC          FLD QWORD PTR SS:[EBP-14]
0048C150   E8 4E26FEFF      CALL jksm.0046E7A3  将浮点值转化成十六进制
0048C155   8945 F8          MOV DWORD PTR SS:[EBP-8],EAX
0048C158   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
0048C15B   3945 F8      CMP DWORD PTR SS:[EBP-8],EAX 这里比较十六进制
0048C15E   0F85 5D040000    JNZ jksm.0048C5C1 跳走则失败

程序两次计算时都调用了这个地方
100513F0   8B5424 10        MOV EDX,DWORD PTR SS:[ESP+10]
100513F4   8B4424 0C        MOV EAX,DWORD PTR SS:[ESP+C]
100513F8   83F8 01          CMP EAX,1
100513FB   8B0A             MOV ECX,DWORD PTR DS:[EDX]
100513FD   7E 2F            JLE SHORT krnln.1005142E
100513FF   56               PUSH ESI
10051400   8B7424 08        MOV ESI,DWORD PTR SS:[ESP+8]
10051404   57               PUSH EDI
10051405   8D78 FF          LEA EDI,DWORD PTR DS:[EAX-1]
10051408   8BC6             MOV EAX,ESI
1005140A   83C2 0C          ADD EDX,0C
1005140D   83E8 00          SUB EAX,0
10051410   74 0E            JE SHORT krnln.10051420
10051412   48               DEC EAX
10051413   74 07            JE SHORT krnln.1005141C
10051415   48               DEC EAX
10051416   75 0A            JNZ SHORT krnln.10051422
10051418   330A             XOR ECX,DWORD PTR DS:[EDX]  
这里是计算密码和注册码的关键 做一次异或运算就出来了
1005141A   EB 06            JMP SHORT krnln.10051422
1005141C   0B0A             OR ECX,DWORD PTR DS:[EDX]
1005141E   EB 02            JMP SHORT krnln.10051422
10051420   230A             AND ECX,DWORD PTR DS:[EDX]
10051422   4F               DEC EDI
10051423  ^75 E3            JNZ SHORT krnln.10051408
10051425   8B4424 10        MOV EAX,DWORD PTR SS:[ESP+10]
总结:程序先根据取得的安装号,计算出密码,只有密码正确才验证注册码,两个都正确则注册成功如果,只有密码正确程序会给出相应的提示,但是这里由于和密码错误的提示不同,很容易给破解留下伏笔。这个软件破解很容易。
注册信息保存在:HKEY_CURRENT_UESRSOFTWAREJSMKKLOGIN里删掉该键值可重新注册