Crack for Newbies Crackme v3.0算法分析
【破文标题】Crack for Newbies Crackme v3.0算法分析
【破解作者】hrbx
【作者主页】hrbx.ys168.com
【作者邮箱】[email protected]
【破解平台】WinXP
【使用工具】flyOD1.10、Peid
【破解日期】2006-7-30
【软件名称】Crack for Newbies Crackme v3.0
【软件大小】515 K
【下载地址】https://www.chinapyg.com/viewthread.php?tid=6528&highlight=
【加壳方式】无
【软件简介】Crack for Newbies Crackme v3.0
-----------------------------------------------------------------------------------------------
【破解声明】我是一只小菜鸟,偶得一点心得,愿与大家分享:)
-----------------------------------------------------------------------------------------------
【破解过程】
1.查壳。用PEID扫描,显示为:Microsoft Visual C++ 6.0 ,实际上为易语言,软件无壳。
2.试运行。程序要求输入启动密码才能进入,进入后输入注册信息后点"注册"按钮,程序无错误提示。
3.找出启动密码。OD载入程序,F9运行,来到:
00403831 N>55 push ebp ; OD载入暂停在这里
00403832 8BEC mov ebp,esp
00403834 6A FF push -1
00403836 68 F0624000 push Newbies_.004062F0
Alt+M查看内存,找到:
----------------------------------------------------------------------------------------------
地址 大小 物主 区段 类型 初始访问 访问
00409000 00004000 (16384.) Newbies_ 00400000 .ecode mag 01001002 RWE R
----------------------------------------------------------------------------------------------
在.ecode段F2下断,输入启动密码后点“进入”按钮,立即中断:
0040C24F 55 push ebp ; 在此中断
0040C250 8BEC mov ebp,esp
0040C252 81EC 08000000 sub esp,8
0040C258 6A FF push -1
0040C25A 6A 08 push 8
0040C25C 68 06000116 push 16010006
0040C261 68 01000152 push 52010001
0040C266 E8 DD030000 call Newbies_.0040C648
0040C26B 83C4 10 add esp,10
0040C26E 8945 FC mov dword ptr ss:,eax ; 假码"9876543210"
0040C271 68 CB904000 push Newbies_.004090CB ; ASCII "Can't open file!",启动密码
0040C276 FF75 FC push dword ptr ss: ;
0040C279 E8 34FFFFFF call Newbies_.0040C1B2 ; 真假码比较
0040C27E 83C4 08 add esp,8
0040C281 83F8 00 cmp eax,0
0040C284 B8 00000000 mov eax,0
0040C289 0F94C0 sete al
0040C28C 8945 F8 mov dword ptr ss:,eax
0040C28F 8B5D FC mov ebx,dword ptr ss:
0040C292 85DB test ebx,ebx
0040C294 74 09 je short Newbies_.0040C29F
0040C296 53 push ebx
0040C297 E8 A0030000 call Newbies_.0040C63C
0040C29C 83C4 04 add esp,4
0040C29F 837D F8 00 cmp dword ptr ss:,0
0040C2A3 0F84 38000000 je Newbies_.0040C2E1 ; 暴破点1,NOP掉
0040C2A9 68 02000080 push 80000002
0040C2AE 6A 00 push 0
0040C2B0 68 01000000 push 1
0040C2B5 6A 00 push 0
0040C2B7 6A 00 push 0
0040C2B9 6A 00 push 0
0040C2BB 68 01000100 push 10001
0040C2C0 68 04000106 push 6010004
0040C2C5 68 05000152 push 52010005
0040C2CA 68 03000000 push 3
0040C2CF BB 20030000 mov ebx,320
0040C2D4 E8 69030000 call Newbies_.0040C642
0040C2D9 83C4 28 add esp,28
0040C2DC E9 00000000 jmp Newbies_.0040C2E1
0040C2E1 8BE5 mov esp,ebp
0040C2E3 5D pop ebp
0040C2E4 C3 retn
可以看出,启动密码即是:Can't open file!
4.追出注册码。输入启动密码后进入程序,输入注册信息:
=============================
用户名:hrbx
注册码:9876543210
=============================
Alt+M查看内存,在.ecode段F2下断,点“注册”按钮,立即中断:
0040C30C 55 push ebp ; 在此中断
0040C30D 8BEC mov ebp,esp
0040C30F 81EC 2C000000 sub esp,2C
0040C315 C745 FC 00000000mov dword ptr ss:,0
0040C31C C745 F8 00000000mov dword ptr ss:,0
0040C323 C745 F4 00000000mov dword ptr ss:,0
0040C32A C745 F0 00000000mov dword ptr ss:,0
0040C331 6A FF push -1
0040C333 6A 08 push 8
0040C335 68 0C000116 push 1601000C
0040C33A 68 05000152 push 52010005
0040C33F E8 04030000 call Newbies_.0040C648
0040C344 83C4 10 add esp,10
0040C347 8945 EC mov dword ptr ss:,eax
0040C34A 8B45 EC mov eax,dword ptr ss:
0040C34D 50 push eax
0040C34E 8B5D FC mov ebx,dword ptr ss:
0040C351 85DB test ebx,ebx
0040C353 74 09 je short Newbies_.0040C35E
0040C355 53 push ebx
0040C356 E8 E1020000 call Newbies_.0040C63C
0040C35B 83C4 04 add esp,4
0040C35E 58 pop eax
0040C35F 8945 FC mov dword ptr ss:,eax ; 用户名"hrbx"
0040C362 6A FF push -1
0040C364 6A 08 push 8
0040C366 68 0C000116 push 1601000C
0040C36B 68 05000152 push 52010005
0040C370 E8 D3020000 call Newbies_.0040C648
0040C375 83C4 10 add esp,10
0040C378 8945 EC mov dword ptr ss:,eax
0040C37B 68 04000080 push 80000004
0040C380 6A 00 push 0
0040C382 8B45 EC mov eax,dword ptr ss:
0040C385 85C0 test eax,eax
0040C387 75 05 jnz short Newbies_.0040C38E
0040C389 B8 DC904000 mov eax,Newbies_.004090DC
0040C38E 50 push eax
0040C38F 68 01000000 push 1
0040C394 BB 30010000 mov ebx,130
0040C399 E8 A4020000 call Newbies_.0040C642 ; 获取用户名长度
0040C39E 83C4 10 add esp,10
0040C3A1 8945 E8 mov dword ptr ss:,eax ; 用户名长度保存,EAX=4
0040C3A4 8B5D EC mov ebx,dword ptr ss:
0040C3A7 85DB test ebx,ebx
0040C3A9 74 09 je short Newbies_.0040C3B4
0040C3AB 53 push ebx
0040C3AC E8 8B020000 call Newbies_.0040C63C
0040C3B1 83C4 04 add esp,4
0040C3B4 8B45 E8 mov eax,dword ptr ss:
0040C3B7 8945 F8 mov dword ptr ss:,eax
0040C3BA 8B45 F8 mov eax,dword ptr ss:
0040C3BD 33C9 xor ecx,ecx
0040C3BF 50 push eax
0040C3C0 8D45 F4 lea eax,dword ptr ss:
0040C3C3 8BD8 mov ebx,eax
0040C3C5 58 pop eax
0040C3C6 41 inc ecx
0040C3C7 51 push ecx
0040C3C8 53 push ebx
0040C3C9 890B mov dword ptr ds:,ecx
0040C3CB 50 push eax
0040C3CC 3BC8 cmp ecx,eax
0040C3CE 0F8F 26010000 jg Newbies_.0040C4FA
0040C3D4 68 01030080 push 80000301
0040C3D9 6A 00 push 0
0040C3DB FF75 F4 push dword ptr ss:
0040C3DE 68 04000080 push 80000004
0040C3E3 6A 00 push 0
0040C3E5 8B45 FC mov eax,dword ptr ss:
0040C3E8 85C0 test eax,eax
0040C3EA 75 05 jnz short Newbies_.0040C3F1
0040C3EC B8 DC904000 mov eax,Newbies_.004090DC
0040C3F1 50 push eax ; 用户名"hrbx"
0040C3F2 68 02000000 push 2
0040C3F7 BB 44010000 mov ebx,144
0040C3FC E8 41020000 call Newbies_.0040C642 ; 依次取用户名每位字符的ASCII值
0040C401 83C4 1C add esp,1C
0040C404 8945 EC mov dword ptr ss:,eax ; EAX=0x68('h')
0040C407 DB45 F0 fild dword ptr ss: ; 载入地址ss:的值(初值为0),记为Sum
0040C40A DD5D E4 fstp qword ptr ss:
0040C40D DD45 E4 fld qword ptr ss:
0040C410 DB45 EC fild dword ptr ss: ; 用户名每位字符的ASCII值用浮点数表示,记为N
0040C413 DD5D DC fstp qword ptr ss:
0040C416 DC45 DC fadd qword ptr ss: ; Sum=Sum+N
0040C419 DD5D D4 fstp qword ptr ss: ; st=104.0
0040C41C DD45 D4 fld qword ptr ss:
0040C41F E8 C1FEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C424 8945 F0 mov dword ptr ss:,eax ; EAX=0x68(104)
0040C427 DB45 F0 fild dword ptr ss:
0040C42A DD5D E8 fstp qword ptr ss:
0040C42D DD45 E8 fld qword ptr ss: ; ss:=104.0
0040C430 DC0D DD904000 fmul qword ptr ds: ; 取完低8位乘以固定数N1,Sum=Sum*N1
0040C436 DD5D E0 fstp qword ptr ss: ; 固定数N1=ds:=108.0
0040C439 DD45 E0 fld qword ptr ss: ; st=11232.0
0040C43C E8 A4FEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C441 8945 F0 mov dword ptr ss:,eax ; EAX=0x2BE0(11232)
0040C444 DB45 F0 fild dword ptr ss:
0040C447 DD5D E8 fstp qword ptr ss:
0040C44A DD45 E8 fld qword ptr ss:
0040C44D DC0D E5904000 fmul qword ptr ds: ; 取完低8位乘以固定数N2,Sum=Sum*N2
0040C453 DD5D E0 fstp qword ptr ss: ; 固定数N2=ds:=101.0
0040C456 DD45 E0 fld qword ptr ss: ; st=1134432.0
0040C459 E8 87FEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C45E 8945 F0 mov dword ptr ss:,eax ; eax=0x114F60(1134432)
0040C461 DB45 F0 fild dword ptr ss:
0040C464 DD5D E8 fstp qword ptr ss:
0040C467 DD45 E8 fld qword ptr ss:
0040C46A DC0D ED904000 fmul qword ptr ds: ; 取完低8位乘以固定数N3,Sum=Sum*N3
0040C470 DD5D E0 fstp qword ptr ss: ; 固定数N3=ds:=110.0
0040C473 DD45 E0 fld qword ptr ss: ; st=124787520.0
0040C476 E8 6AFEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C47B 8945 F0 mov dword ptr ss:,eax ; EAX=0x7701B40(124787520)
0040C47E DB45 F0 fild dword ptr ss:
0040C481 DD5D E8 fstp qword ptr ss:
0040C484 DD45 E8 fld qword ptr ss:
0040C487 DC0D F5904000 fmul qword ptr ds: ; 取完低8位乘以固定数N4,Sum=Sum*N4
0040C48D DD5D E0 fstp qword ptr ss: ; 固定数N4=ds:=103.0
0040C490 DD45 E0 fld qword ptr ss: ; st=1.2853114560000000000e+10
0040C493 E8 4DFEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C498 8945 F0 mov dword ptr ss:,eax ; EAX=0xFE1AF6C0
0040C49B DB45 F0 fild dword ptr ss:
0040C49E DD5D E8 fstp qword ptr ss:
0040C4A1 DD45 E8 fld qword ptr ss:
0040C4A4 DC0D FD904000 fmul qword ptr ds: ; 取完低8位乘以固定数N5,Sum=Sum*N5
0040C4AA DD5D E0 fstp qword ptr ss: ; 固定数N5=ds:=120.0
0040C4AD DD45 E0 fld qword ptr ss: ; st=-3814479360.0
0040C4B0 E8 30FEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C4B5 8945 F0 mov dword ptr ss:,eax ; EAX=0x1CA3AA00
0040C4B8 DB45 F0 fild dword ptr ss:
0040C4BB DD5D E8 fstp qword ptr ss:
0040C4BE DD45 E8 fld qword ptr ss:
0040C4C1 DC0D 05914000 fmul qword ptr ds: ; 取完低8位乘以固定数N6,Sum=Sum*N6
0040C4C7 DD5D E0 fstp qword ptr ss: ; 固定数N6=ds:=117.0
0040C4CA DD45 E0 fld qword ptr ss: ; st=5.6217088512000000000e+10
0040C4CD E8 13FEFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C4D2 8945 F0 mov dword ptr ss:,eax ; EAX=0x16CCB200
0040C4D5 DB45 F0 fild dword ptr ss:
0040C4D8 DD5D E8 fstp qword ptr ss:
0040C4DB DD45 E8 fld qword ptr ss:
0040C4DE DC0D E5904000 fmul qword ptr ds: ; 取完低8位乘以固定数N7,Sum=Sum*N7
0040C4E4 DD5D E0 fstp qword ptr ss: ; 固定数N7=ds:=101.0
0040C4E7 DD45 E0 fld qword ptr ss: ; st=3.8633880064000000000e+10
0040C4EA E8 F6FDFFFF call Newbies_.0040C2E5 ; 取运算结果的低8位
0040C4EF 8945 F0 mov dword ptr ss:,eax ; EAX=0xFEC23A00
0040C4F2 58 pop eax
0040C4F3 5B pop ebx
0040C4F4 59 pop ecx
0040C4F5 ^ E9 CCFEFFFF jmp Newbies_.0040C3C6
0040C4FA 83C4 0C add esp,0C
0040C4FD 837D F8 01 cmp dword ptr ss:,1
0040C501 0F8C B4000000 jl Newbies_.0040C5BB
0040C507 68 01030080 push 80000301
0040C50C 6A 00 push 0
0040C50E FF75 F0 push dword ptr ss: ; 运算结果ss:=0x27899E00(663330304)
0040C511 68 01000000 push 1
0040C516 BB 68010000 mov ebx,168
0040C51B E8 22010000 call Newbies_.0040C642 ; 运算结果转为字符串"663330304"
0040C520 83C4 10 add esp,10
0040C523 8945 EC mov dword ptr ss:,eax
0040C526 6A FF push -1
0040C528 6A 08 push 8
0040C52A 68 10000116 push 16010010
0040C52F 68 05000152 push 52010005
0040C534 E8 0F010000 call Newbies_.0040C648
0040C539 83C4 10 add esp,10
0040C53C 8945 E8 mov dword ptr ss:,eax ; 假码"9876543210"
0040C53F 8B45 EC mov eax,dword ptr ss: ; 真码"663330304"
0040C542 50 push eax
0040C543 FF75 E8 push dword ptr ss:
0040C546 E8 67FCFFFF call Newbies_.0040C1B2 ; 真假码比较
0040C54B 83C4 08 add esp,8
0040C54E 83F8 00 cmp eax,0
0040C551 B8 00000000 mov eax,0
0040C556 0F94C0 sete al
0040C559 8945 E4 mov dword ptr ss:,eax
0040C55C 8B5D E8 mov ebx,dword ptr ss:
0040C55F 85DB test ebx,ebx
0040C561 74 09 je short Newbies_.0040C56C
0040C563 53 push ebx
0040C564 E8 D3000000 call Newbies_.0040C63C
0040C569 83C4 04 add esp,4
0040C56C 8B5D EC mov ebx,dword ptr ss:
0040C56F 85DB test ebx,ebx
0040C571 74 09 je short Newbies_.0040C57C
0040C573 53 push ebx
0040C574 E8 C3000000 call Newbies_.0040C63C
0040C579 83C4 04 add esp,4
0040C57C 837D E4 00 cmp dword ptr ss:,0
0040C580 0F84 30000000 je Newbies_.0040C5B6 ; 暴破点2,改为NOP
0040C586 6A 00 push 0
0040C588 6A 00 push 0
0040C58A 6A 00 push 0
0040C58C 68 01030080 push 80000301
0040C591 6A 00 push 0
0040C593 68 00000000 push 0
0040C598 68 04000080 push 80000004
0040C59D 6A 00 push 0
0040C59F 68 0D914000 push Newbies_.0040910D ; 注册成功提示 "Well done!"
0040C5A4 68 03000000 push 3
0040C5A9 BB 00030000 mov ebx,300
0040C5AE E8 8F000000 call Newbies_.0040C642
0040C5B3 83C4 28 add esp,28
0040C5B6 E9 05000000 jmp Newbies_.0040C5C0
0040C5BB E8 14000000 call Newbies_.0040C5D4
0040C5C0 8B5D FC mov ebx,dword ptr ss:
0040C5C3 85DB test ebx,ebx
0040C5C5 74 09 je short Newbies_.0040C5D0
0040C5C7 53 push ebx
0040C5C8 E8 6F000000 call Newbies_.0040C63C
0040C5CD 83C4 04 add esp,4
0040C5D0 8BE5 mov esp,ebp
0040C5D2 5D pop ebp
0040C5D3 C3 retn
-----------------------------------------------------------------------------------------------
【破解总结】
1.程序启动密码为:Can't open file!
2.程序内置7个固定数,分别为:N1=108,N2=101,N1=110,N1=103,N1=120,N1=117,N1=101。
3.地址ss:的值(初值为0),记为Sum,依次取用户名每位字符的ASCII值记为N,Sum=Sum+N,
取加法结果低8位乘以固定数N1,取乘法结果低8位后再乘以固定数N2,重复运算直到乘完固定数N7,结果保存
在地址ss:中,用于用户名下一位字符的运算,运算最终结果以10进制整数表示转为字符串即为注册码。
一中可用注册信息:
=============================
用户名:hrbx
注册码:663330304
=============================
暴破更改以下位置:
0040C2A3 je Newbies_.0040C2E1 ; je====>NOP
0040C580 je Newbies_.0040C5B6 ; je====>NOP
【VB注册机源码】
Function Low(num As Double) As Double '自定义取低8位函数
Dim Tmp As Double
If (num > (2 ^ 32)) Or (num < -(2 ^ 32)) Then
Tmp = num / &HFFFFFFF
Tmp = Int(Tmp / &H10)
Tmp = Tmp * (2 ^ 32)
Low = num - Tmp
Else
Low = num
End If
End Function
Private Sub Generate_Click()
Dim Name As String
Dim Sum As Double
Dim i As Long
Dim Tmp As Long
Dim ByteAry() As Byte
On Error Resume Next
If Text1.Text = "" Then
Text2.Text = "请输入用户名!"
Else
Name = Trim(Text1.Text)
Sum = 0
ByteAry = StrConv(Name, vbFromUnicode)
For i = LBound(ByteAry) To UBound(ByteAry)
If ByteAry(i) > 128 Or ByteAry(i) < 0 Then
Tmp = ByteAry(i) - 256
Sum = Low(Sum + Tmp)
Sum = Low(Sum * 108)
Sum = Low(Sum * 101)
Sum = Low(Sum * 110)
Sum = Low(Sum * 103)
Sum = Low(Sum * 120)
Sum = Low(Sum * 117)
Sum = Low(Sum * 101)
Else
Tmp = ByteAry(i)
Sum = Low(Sum + Tmp)
Sum = Low(Sum * 108)
Sum = Low(Sum * 101)
Sum = Low(Sum * 110)
Sum = Low(Sum * 103)
Sum = Low(Sum * 120)
Sum = Low(Sum * 117)
Sum = Low(Sum * 101)
End If
Next i
If (Sum > (2 ^ 31) Or Sum < -(2 ^ 31)) Then Sum = Low(Sum - 2 ^ 32)
Text2.Text = Sum
End If
End Sub
-----------------------------------------------------------------------------------------------
【版权声明】本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[ 本帖最后由 hrbx 于 2006-7-30 11:50 编辑 ] 注册机做的好花哨 厉害,学习。。。。。。。。。。
29A 8#浮点指令教程(FPU instructions tutorial)
来源:29A第8期翻译:nbw nbwo.blogbus.com
注:
翻译的不好,有些地方没弄明白,没敢翻译,有些地方不翻译了(cos,sin)。翻译这东西主要为了自己熟悉一下,因为看一遍实在体会不深刻。
既然出于这目的,我也不能保证翻译的正确性,希望大家原谅!
你或许想为什么要写或者读一篇关于FPU指令的教程,如果你认为这对写病毒没什么帮助,也无助于改善生活,那么你就想错了。
这些指令会有很大帮助。
顾名生义,浮点指令不仅支持整数,也支持十进制小数。相信我这些指令可以帮你躲避杀毒软件的检测(效果也不错:))。怎么实现呢?
只需在加密/解密部分或者变形引擎中利用它们处理一下。因为半数的杀毒软件在检测这些指令时会挂起或者忽略这些文件,这样你就可以
隐藏自己。
现在我们开始正题:
首先应该检测一下你的系统是否支持FPU指令集。也就是检查一下是否配备了协处理器。这个可以通过一条简单的指令来监测:SMSW EAX
检查一下低位,为1,则有协处理器支持,否则我们可以跑去看电影了。
看一下协处理器,如果处理器位386,486,586....,那么协处理器为387,487,587....以及相应的FPIs。
现在看一下IEEE标准754标准文档,这些是用FPU处理浮点数据的Intel标准文档。
指令格式如下:
S-Sign, E-Exponent, F-Fraction 或简单表达为: S,E,F.
S的长度为1bit(定点为0,否则为1)。F的长度为:总长度-E长度-1。
一般浮点数表达形式为:S,2^E*F
这里,FPU为我们提供了专门的“堆栈”来进行计算或者保存数据等操作,包括:
ST(0), ST(1), ST(2),....ST(9)
ST(0)也可以称为ST。相关操作执行时,这些堆栈用来存放浮点数据。
现在看一下操作数的载入过程。当第一次载入时候,数据被存放在ST,以后每次操作,堆栈上升,开始被载入的操作数也随之上移,
直到ST(9)。比如:
load a : ST(0) = a; ST(1) = 0; ST(2) = 0.....
load b : ST(0) = b; ST(1) = a; ST(2) = 0.....
load c : ST(0) = c; ST(1) = b; ST(2) = a.....
希望这里已经把事情讲明白了。
最常用到的寄存器是ST(0)和ST(1)。
下面是从文档中查到的FPU指令表。
谀哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
? 数据转移和常量 ?
滥哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
FLD src 装载实数: st(0) = src (mem32/mem64/mem80)
FILD src 装载整数: st(0) = src (mem16/mem32/mem64)
FBLD src 装载BCD: st(0) = src (mem80)
FLDZ 清零: st(0) = 0.0
FLD1 置1: st(0) = 1.0
FLDPI 载入圆周率: st(0) = ?(ie, pi)
FLDL2T 载入 log2(10): st(0) = log2(10)
FLDL2E 载入 log2(e): st(0) = log2(e)
FLDLG2 载入 log10(2): st(0) = log10(2)
FLDLN2 载入 loge(2): st(0) = loge(2)
FST dest 保存实数: dest = st(0) (mem32/mem64)
FSTP dest dest = st(0) (mem32/mem64/mem80) and pop stack
FIST dest 保存整数: dest = st(0) (mem32/mem64)
FISTP dest dest = st(0) (mem16/mem32/mem64) and pop stack
FBST dest 保存 BCD: dest = st(0) (mem80)
FBSTP dest dest = st(0) (mem80) and pop stack
谀哪哪哪哪?
? 比较 ?
滥哪哪哪哪?
FCOM 比较实数: Set flags as for st(0) - st(1)
FCOM op 设定st(0)的标记 - op (mem32/mem64)
FCOMP op 比较 st(0) 和 op (reg/mem); 然后出栈
FCOMPP 比较 st(0) 和 st(1) 并出栈操作2次
FICOM op 比较整数: 设置st(0)标记 - op (mem16/mem32)
FICOMP op 比较 st(0) 和 op (mem16/mem32) 并出栈
FTST 判零操作: 比较 st(0) 是否为 0.0
FUCOM st(i) 无序比较: st(0) to st(i)
FUCOMP st(i) 比较 st(0) 和 st(i) 并出栈
FUCOMPP st(i) 比较 st(0) 和 st(i) 并出栈2次
FXAM 检查: st(0) (设置条件代码)(译:我也不懂)
谀哪哪哪哪哪目
? 运算 ?
滥哪哪哪哪哪馁
FADD 加实数: st(0) = st(0) + st(1)
FADD src st(0) = st(0) + src (mem32/mem64)
FADD st(i),st st(i) = st(i) + st(0)
FADDP st(i),st st(i) = st(i) + st(0) and pop stack
FIADD src 加整数: st(0) = st(0) + src (mem16/mem32)
FSUB 减实数: st(0) = st(0) - st(1)
FSUB src st(0) = st(0) - src (reg/mem)
FSUB st(i),st st(i) = st(i) - st(0)
FSUBP st(i),st st(i) = st(i) - st(0) and pop stack
FSUBR st(i),st 减去保留数: st(0) = st(i) - st(0)
FSUBRP st(i),st st(0) = st(i) - st(0); pop stack
FISUB src 减去整数: st(0) = st(0) - src (mem16/mem32)
FISUBR src 减去保留的整数: st(0) = src - st(0) (mem16/mem32)
FMUL 乘以实数: st(0) = st(0) * st(1)
FMUL st(i) st(0) = st(0) * st(i)
FMUL st(i),st st(i) = st(0) * st(i)
FMULP st(i),st st(i) = st(0) * st(i) and pop stack
FIMUL src 乘以整数: st(0) = st(0) * src (mem16/mem32)
FDIV 除以实数: st(0) = st(0) ?st(1)
FDIV st(i) st(0) = st(0) ?t(i)
FDIV st(i),st st(i) = st(0) ?st(i)
FDIVP st(i),st st(i) = st(0) ?st(i) and pop stack
FIDIV src 除以整数: st(0) = st(0) ?src (mem16/mem32)
FDIVR st(i),st 除以保留的实数: st(0) = st(i) ?st(0)
FDIVRP st(i),st st(0) = st(i) ?st(0) and pop stack(译:除法操作后有出栈操作)
FIDIVR src 除以保留的整数: st(0) = src ?st(0) (mem16/mem32)
FSQRT 开方: st(0) = sqrt st(0)
FSCALE 求2的幂: st(0) = 2 ^ st(0)
FXTRACT Extract exponent: st(0) = exponent of st(0) and gets pushed
as st(0) = significand of st(0)
FPREM Partial remainder: st(0) = st(0) MOD st(1)
FPREM1 Partial Remainder (IEEE): same as FPREM, but in IEEE standard
FRNDINT Round to nearest int: st(0) = INT( st(0) ), depends on RC flag
FABS Get absolute value: st(0) = ABS( st(0) ), removes sign (changes to postive)
FCHS Change sign: st(0) = -st(0)
谀哪哪哪哪哪哪哪目
?Transcendental ?
滥哪哪哪哪哪哪哪馁
FCOS Cosine: st(0) = COS( st(0) )
FPTAN Partial tangent: st(0) = TAN( st(0) )
FPATAN. Partial Arctangent: st(0) = ATAN( st(0) )
FSIN Sine: st(0) = SIN( st(0) )
FSINCOS Sine and Cosine: st(0) = SIN( st(0) ) and is pushed to st(1)
st(0) = COS( st(0) )
F2XM1 Calculate (2 ^ x)-1: st(0) = - 1
FYL2X Calculate Y * log2(X): st(0) is Y, st(1) is X; this replaces st(0) and
st(1) with: st(0) * log2( st(1) )
FYL2XP1 Calculate Y * log2(X+1): st(0) is Y; st(1) is X; this replaces st(0)
and st(1) with: st(0) * log2( st(1)+1 )
谀哪哪哪哪哪哪哪哪哪?
?Processor Control ?
滥哪哪哪哪哪哪哪哪哪?
FINIT 初始化FPU
FSTSW AX STore Status Word in EAX., ie. EAX = MSW
FSTSW dest dest = MSW (mem16)
FLDCW src LoaD Control Word: FPU CW = src (mem16)
FSTCW dest STore Control Word: dest = FPU CW
FCLEX Clear exceptions
FSTENV dest STore ENVironment: stores status, control and tag words
and exception pointers into memory at dest
FLDENV src LoaD ENVironment: loads environment from memory at src
FSAVE dest Store FPU state: store FPU state into 94-bytes at dest
FRSTOR src Load FPU state: restore FPU state as saved by FSAVE
FINCSTP Increment FPU stack ptr: st(6)<-st(5); st(5)<-st(4),...,st(0)
FDECSTP Decrement FPU stack ptr: st(0)<-st(1); st(1)<-st(2),...,st(7)
The above 2 instuctions put the corresponding values too in the
inc/dec stacks.
FFREE st(i) Mark reg st(i) as unused
FNOP No operation: st(0) = st(0), equivalent to nop.
WAIT/FWAIT Synchronize FPU & CPU: Halt CPU until FPU finishes current opcode.
FXCH - eXCHange instruction st(0) <- st(1)
st(1) <- st(0) similar to xchg.
假设我们需要做以下操作:
tan(cos(sin(a*b+c*d)))/4
需要做的很简单,具体如下:
首先,需要知道,在数据载入以前,首先采用FILD初始化,因为按照IEEE354文档,FLD需要一个整数。
我想说的是,假设你需要将变量VAR初始化为12345678h,那么,当使用FLD VAR获取类似于1.2345e-67
(很恐怖?)。但是如果你使用FILD指令,VAR被载入12345678h,并且这也是我们需要的。
下面看一下具体代码:
finit ;该句非常必要
fild dword ptr ;ST(0) = a, dwords形式
fild dword ptr ;ST(0) = b, ST(1) = a
fadd ;ST(0) = a+b
fistp dword ptr ;Var=ST(0), 存放在临时变量中
fild dword ptr ;ST(0) = c
fild dword ptr ;ST() = d, ST(1) = c
fadd ;ST(0) = c+d
fild dword ptr ;ST(0) = Var, ST(1) = c+d
fmul ;ST(0) = Var*(c+d)
fsin ;sin of ST(0)
fcos ;cos of ST(0)
ftan ;tan of ST(0)
mov Var2, 4h ;Var2 = 4
fild dword ptr ;ST(0) = Var2 = 4, ST(1) = tan(cos(sin(a*b+c*d)))/4
很简单,也很长?
另外需要注意的地方是,需要指定.387(或者.487,.587)。
比如:
.386
.387
.data
[...]
.code
[...]
End
这些指定声明了对32位FPU寄存器的使用。
如果有问题,请联系:[email protected]
-Surya/powerdryv
-23rd June, 2004
译者备注:
最下面举例,计算:
tan(cos(sin(a*b+c*d)))/4
作者的代码:
finit ;thats very very necesarry
fild dword ptr ;ST(0) = a, we work in dwords
fild dword ptr ;ST(0) = b, ST(1) = a
fadd ;ST(0) = a+b
;这句应该是fmul
fistp dword ptr ;Var=ST(0), store in a temp. variable
fild dword ptr ;ST(0) = c
fild dword ptr ;ST() = d, ST(1) = c
;应为“ST(0) = d,”
fadd ;ST(0) = c+d
;这句应该是fmul
fild dword ptr ;ST(0) = Var, ST(1) = c+d
fmul ;ST(0) = Var*(c+d)
fsin ;sin of ST(0)
fcos ;cos of ST(0)
ftan ;tan of ST(0)
mov Var2, 4h ;Var2 = 4
fild dword ptr ;ST(0) = Var2 = 4, ST(1) = tan(cos(sin(a*b+c*d)))/4
我不懂fpu,或许说的不对。。
29A出此文,让人有些郁闷,真有凑文之嫌 算法蛮复杂的.1 兄弟好强!!!
能给偶这样的菜鸟解释下你是怎么看出来是易的吗??
还有,为什么在.ecode段下断啊?? 1.用OD载入后ALT+M查看可以看到.ecode段,就差不多可以确定是易语言编写的了。
运行程序后在堆栈区可以看见像:0012FC70 |100EDB10 krnln.100EDB10这样的信息就可以肯定是易语言的程序了。
2.易语言程序下断.ecode段,经常可以断在核心处。
[ 本帖最后由 hrbx 于 2006-7-31 12:19 编辑 ] 原帖由 hrbx 于 2006-7-31 12:15 发表
1.用OD载入后ALT+M查看可以看到.ecode段,就差不多可以确定是易语言编写的了。
运行程序后在堆栈区可以看见像:0012FC70 |100EDB10 krnln.100EDB10这样的信息就可以肯定是易语言的程序了。
2.易语言程序下断 ...
多谢兄弟指点~~~
有学习拉 `~~
好想再多给兄弟多加几分,可惜没有那个权利,呵呵~~
页:
[1]