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里删掉该键值可重新注册