-
-
[原创]超简单算法--长坤立体大师V3.0算法分析
-
2005-2-21 08:58
7125
-
[原创]超简单算法--长坤立体大师V3.0算法分析
【软件大小】: 314 KB
【软件语言】: 简体中文
【软件类别】: 国产软件 / 共享版 / 图像处理
【应用平台】: Win9x/NT/2000/XP
【加入时间】: 2005-02-20 11:40:16
【软件下载】: http://www2.skycn.com/soft/22105.html
【软件介绍】: a) 可将普通照片快速加工成立体照片;
b) 可以即时观看立体效果,直接打印或存盘输出;
c) 使用简单,功能强大,立体效果好。
不需要立体模板,不需要立体相机不用专业技术,会上网者半小时可学会 。
【作者声明】:初学破解,仅作学习交流之用,失误之处敬请大侠赐教!
【破解工具】:Ollydbg1.10、WDasmv10.0
这个软件的算法极其简单,但由于涉及到一些浮点指令,还是贴出来,当作是对浮点指令的一个温习吧!如
果你熟悉浮点指令就不要再往下看了!
用PEid检测无壳,为Dephi编写!首先运行程序,输入密码:138651(电脑编号为自动生成为68295),点注册
出错!用WDasm反汇编查找字串参考下断,记下断点,OD载入来到如下代码:
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
..........
004958ED |>
LEA EDX,
DWORD PTR SS:[
EBP-1D4]
; 我们在此下断
004958F3 |>
MOV EAX,
DWORD PTR DS:[
EBX+2F0]
004958F9 |>
CALL photo3d.00441CB0
004958FE |>
MOV EAX,
DWORD PTR SS:[
EBP-1D4]
; 到这里EAX="68295",我的电脑编号
00495904 |>
CALL photo3d.00409078
; 这个Call将我的电脑编号转换成Hex值
00495909 |>
MOV DWORD PTR SS:[
EBP-1D8],
EAX ; 这里可看到EAX=10AC7(68295的Hex形式)
0049590F |>
FILD DWORD PTR SS:[
EBP-1D8]
; 浮点指令,把10AC7的整数形式(即68295)装入到st0中
00495915 |>
FDIV DWORD PTR DS:[495A4C]
;DS:[495A4C]中为定值1000000,68295/1000000->st0=0.068295
0049591B |>
CALL photo3d.004029B8
; 浮点堆栈操作
00495920 |>
FMUL DWORD PTR DS:[495A50]
; DS:[495A50]中为10000,st0*10000->st0=682.95
00495926 |>
FADD DWORD PTR DS:[495A54]
; DS:[495A4C]中为固定值1980,1980+st0=2662.95->st0
0049592C |>
CALL photo3d.004029E8
; 这个Call实现Dec->Hex,EAX中返回0A66(2662的Hex值)
00495931 |>
CMP EDX,
DWORD PTR SS:[
ESP+4]
; 这个比较不清楚干什么的
00495935 |>
JNZ SHORT photo3d.0049593A
00495937 |>
CMP EAX,
DWORD PTR SS:[
ESP]
; 真假码比较,EAX中为真码的Hex值
0049593A |>
POP EDX
0049593B |>
POP EAX
0049593C |>
JNZ photo3d.00495A01
; 关键跳转
..........
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
是不是很简单,让我们再看看电脑编号是怎样产生的,反汇编时看Import函数时我们注意到有
GetVolumeInformationA
函数,有门,用这个函数下断,OD载入,中断,先不要理他,F9过,出现启
动画面后马上又中断,OK!我们断下来,看到以下代码:
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
0049D32A |.>
MOV EBX,
EAX
0049D32C |.>
PUSH 0
; /pFileSystemNameSize = NULL
0049D32E |.>
PUSH 0
; |pFileSystemNameBuffer = NULL
0049D330 |.>
LEA EAX,
DWORD PTR SS:[
ESP+C]
; |
0049D334 |.>
PUSH EAX ; |pFileSystemFlags
0049D335 |.>
LEA EAX,
DWORD PTR SS:[
ESP+C]
; |
0049D339 |.>
PUSH EAX ; |pMaxFilenameLength
0049D33A |.>
PUSH EBX ; |pVolumeSerialNumber
0049D33B |.>
PUSH 0
; |MaxVolumeNameSize = 0
0049D33D |.>
PUSH 0
; |VolumeNameBuffer = NULL
0049D33F |.>
PUSH photo3d.0049D350
; |RootPathName = "c:\"
0049D344 |.>
CALL <JMP.&kernel32.GetVolumeInformat>
; \GetVolumeInformationA
0049D349 |.>
MOV EAX,
DWORD PTR DS:[
EBX]
; EAX=14531ADA,我的硬盘序列号
0049D34B |.>
POP ECX
0049D34C |.>
POP EDX
0049D34D |.>
POP EBX
0049D34E \.>
RETN
0049D34F >
DB 00
0049D350 .>ASCII
"c:\",0
0049D354 .>
MOV DWORD PTR DS:[4A0F00],32
取得我的硬盘序列号,RETN后返回后来到这里:
00495B56 |>
MOV DWORD PTR SS:[
EBP-C],
EAX
00495B59 |>
XOR EAX,
EAX
00495B5B |>
MOV DWORD PTR SS:[
EBP-8],
EAX
00495B5E |>
FILD QWORD PTR SS:[
EBP-C]
; 不用再解释了吧,340990682(Dec值)-->st0
00495B61 |>
FDIV DWORD PTR DS:[495D0C]
;DS:[495D0C]中为定值10000,st0=340990682/10000=34099.0682
00495B67 |>
CALL photo3d.004029B8
; 这个Call我们也跟进去看看吧!
-----------------------------------------------------------------------------------
004029B8 />
FLD ST ; st0-->st1?,寄存器区可看到 st0=st1=34099.0682
004029BA |>
SUB ESP,4
004029BD |>
FSTCW WORD PTR SS:[
ESP]
; 将FPU的控制字保存到SS:[ESP]
004029C0 |>
FSTCW WORD PTR SS:[
ESP+2]
004029C4 |>
WAIT
004029C5 |>
OR WORD PTR SS:[
ESP+2],0F00
; 不知作什么用?
004029CC |>
FLDCW WORD PTR SS:[
ESP+2]
; 从SS:[ESP+2]装入FPU的控制字
004029D0 |>
FRNDINT ; st0取整,st0=34099
004029D2 |>
WAIT
004029D3 |>
FLDCW WORD PTR SS:[
ESP]
004029D6 |>
ADD ESP,4
004029D9 |>
FSUBP ST(1),
ST ;st0=st1-st0=34099.0682-34099=0.0682,然后执行一次出栈
004029DB \>
RETN
-------------------------------------------------------------------------------------
00495B6C |>
FMUL DWORD PTR DS:[495D10]
; DS:[495D10]中为定值1000000,st0=st0*1000000=68200
00495B72 |>
CALL photo3d.004029E8
; 同前,这个Call实现Dec->Hex,EAX中返回为10A68
00495B77 |>
PUSH EDX
00495B78 |>
PUSH EAX
00495B79 |>
MOV EAX,
DWORD PTR DS:[4A0EE8]
; DS:[4A0EE8]中为5F,定值
00495B7E |>
CDQ
00495B7F |>
ADD EAX,
DWORD PTR SS:[
ESP]
; SS:[ESP]中为上面算得的值,EAX=10A68+5F=10AC7
00495B82 |>
ADC EDX,
DWORD PTR SS:[
ESP+4]
00495B86 |>
ADD ESP,8
00495B89 |>
PUSH EDX ; /Arg2
00495B8A |>
PUSH EAX ; |EAX=10AC7
00495B8B |>
LEA EAX,
DWORD PTR SS:[
EBP-4]
; |作Buffer用,Call后返回值就在这里面
00495B8E |>
CALL photo3d.00409044
; \同理,这个Call将Hex-->Dec
00495B93 |>
MOV EDX,
DWORD PTR SS:[
EBP-4]
; SS:[EBP-4]中为"68295",我的电脑编号哦!
00495B96 |>
MOV EAX,
DWORD PTR DS:[
EBX+2F0]
.........
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
【总结】:软件的算法太简单,由我们的硬盘序列号a(Dec进制值)-->a/10000=b-->取b的小数部
分c-->c*1000000=d(Hex进制值)-->d+5F=e(Dec进制值),然后由生成的电脑编号e-->e/100+1980=f再
取整就是正确的注册码了!
有一点没弄明白,用GetWindowTextA不能下断,不清楚软件是怎么取得我们输入的假码的,懒得再跟了!另外Dephi中取得字符串都有哪些方法啊,有知道的兄弟贡献出来啊!
欢迎e-mail到sharpair@163.com交流!
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。