首页
社区
课程
招聘
解决 od 格式化 long double 错误
发表于: 2006-10-21 14:21 28435

解决 od 格式化 long double 错误

dummy 活跃值
23
2006-10-21 14:21
28435
收藏
免费 7
支持
分享
最新回复 (26)
雪    币: 47147
活跃值: (20460)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
这个帖http://bbs.pediy.com/showthread.php?s=&threadid=33485提到了OD处理浮点的另一bug

即OD里显示如下浮点指令会崩溃:

fld     tbyte ptr [4013A6]

004013A6  FF FF FF FF FF FF FF FF 3D 40

跟了一下:
004133A2   call    _Printfloat10      //直接NOP这句就不崩溃,但OD的信息窗口不显示浮点结果了。
2006-10-21 20:43
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
3
最初由 kanxue 发布
这个帖http://bbs.pediy.com/showthread.php?s=&threadid=33485提到了OD处理浮点的另一bug

即OD里显示如下浮点指令会崩溃:

004013A0 DB2D A6134000 fld tbyte ptr [4013A6]
........

。。不看源码 看汇编码
/////
2006-10-21 22:17
0
雪    币: 241
活跃值: (21)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
试了下,只要把输出长度改小点好象就不出错了。
比如改成
k=sprintf(s,"%#.17Le",ext);

原因不清楚,在我的机器上管用,别人的不保证。
2006-10-21 23:41
0
雪    币: 241
活跃值: (21)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
再试下,发现好象不能保证100%通过,偶尔还是会挂掉。
新的Themida用HIDEOD后是不是还有个异常必须用SHIFT+F9才能过,我现在对我的机器没有信心。
我在2000下过了那个异常后就没问题了,在XP和2003下面过了以后会有个读写错误始终通不过。是大家都有类似的问题还是我的RPWT。
2006-10-21 23:49
0
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6
最初由 dummy 发布
......
else
{
/* L 前缀只有类型是 f 有效!!! */
/* k=sprintf(s,"%#.19Le",ext); //出错就在这里 */
k = sprintf(s, "%#.19e", ext);
}


能指出该函数传进哪个值的ext时,运行到这个地方会出现类型不是f的情况?
2006-10-22 09:20
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
ollydbg1.1在xp下很容易发现这一BUG,因为会出现错误提示窗口,然后点击详细内容就找到出错地址偏移:000aa2f2即004aa2f2处。
fld tbyte ptr [edx]
fistp qword ptr [eax]   //这里异常。
再上拉就发现比较最高2字节是否为403E,谁能解释一下为什么是403E?如果修改为403D,就不会出错了。但是显示浮点结果可能不对。
2006-10-22 09:33
0
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
对于403D FFFFFFFF FFFFFFFF这个值引起的问题,其实不应该算是ollydbg的bug,应该是borland编译器sprintf的bug

软件在理论上是没错的,实际上被硬件忽悠了
在内存里403D FFFFFFFF FFFFFFFF这个浮点值的整数部分对应于有符号的QWORD最大值:7FFFFFFF FFFFFFFF
fistp qword ptr [xxx]在把浮点转成整数时会自动4舍5入就相当于40 3E 80000000 00000000了
其整数部分已经超出了有符号QWORD的表示范围,在执行fistp qword ptr [xxx]时就会产生异常
2006-10-22 11:58
0
雪    币: 272
活跃值: (143)
能力值: ( LV15,RANK:930 )
在线值:
发帖
回帖
粉丝
9
嗯,
唉,我又犯大错了
没有细考虑
解决办法,太鲁莽了

不好意思,不要有人被我误导了

2006-10-22 12:53
0
雪    币: 303
活跃值: (466)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
行了::::::
拿出最后解决办法吧!
2006-10-22 13:20
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
11
对于OllyIce.exe修改比较容易,前面heXer说的非常清除,这是sprintf函数的bug,而不是OD代码的bug。所以并不打算去纠正这个sprintf的错误,只是简单的将那个403D FFFFFFFF FFFFFFFF数最后一位设置成0,变成403D FFFFFFFF FFFFFFFE。这样做的唯一缺陷是你看到的那个数9.2233720368547758075e18变成9.2233720368547758070e18了,对其他浮点数没有影像,具体修改如下:

OllyIce.exe 打补丁时增加了一个节,将下列代码插入那个节中的空地:

0057F086             loc_57F086:
0057F086 83 7D 0C FF           cmp   dword ptr [ebp+0Ch], 0FFFFFFFFh
0057F08A 75 0A                 jnz   short loc_57F096
0057F08C 83 7D 10 FF           cmp   dword ptr [ebp+10h], 0FFFFFFFFh
0057F090 75 04                 jnz   short loc_57F096
0057F092 80 65 0C FE           and   byte ptr [ebp+0Ch], 0FEh
0057F096
0057F096             loc_57F096:
0057F096 66 8B 45 14           mov   ax, [ebp+14h]
0057F09A 50                    push  eax
0057F09B E9 3C F7 EF+          jmp   loc_47E7DC


0047E7D7             loc_47E7D7:
0047E7D7 E9 AA 08 10+          jmp   loc_57F086
0047E7DC
0047E7DC             loc_47E7DC:
0047E7DC FF 75 10              push  dword ptr [ebp+10h]
0047E7DF FF 75 0C              push  dword ptr [ebp+0Ch]
0047E7E2 68 94 78 4C+          push  offset _19le
0047E7E7 52                    push  edx
0047E7E8 E8 3F 84 02+          call  _sprintf
0047E7ED 83 C4 14              add   esp, 14h
2006-10-22 14:44
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
知道了原因就有很多解决办法,但是要选最好的方法。有的人用改变浮点寄存器的控制寄存器,这个办法不好,影响整个系统的浮点计算精度和浮点异常处理。楼上的方法不能得到该实数的正确值。
下面的方法应该没有什么明显缺陷。
004AA2E0   8B4424 04        MOV EAX,DWORD PTR SS:[ESP+4]
004AA2E4   8B5424 08        MOV EDX,DWORD PTR SS:[ESP+8]
004AA2E8   E9 63530000      JMP OLLYDBG.004AF650    //修改此行
004AA2ED   90               NOP
004AA2EE   74 06            JE SHORT OLLYDBG.004AA2F6
004AA2F0   DB2A             FLD TBYTE PTR DS:[EDX]
004AA2F2   DF38             FISTP QWORD PTR DS:[EAX]
004AA2F4   9B               WAIT
004AA2F5   C3               RETN
004AA2F6   8B0A             MOV ECX,DWORD PTR DS:[EDX]
004AA2F8   8908             MOV DWORD PTR DS:[EAX],ECX
004AA2FA   8B4A 04          MOV ECX,DWORD PTR DS:[EDX+4]
004AA2FD   8948 04          MOV DWORD PTR DS:[EAX+4],ECX
004AA300   C3               RETN
修补代码:
004AF650   66:817A 08 3E40  CMP WORD PTR DS:[EDX+8],403E
004AF656  ^0F84 9AACFFFF    JE OLLYDBG.004AA2F6
004AF65C   833A FF          CMP DWORD PTR DS:[EDX],-1
004AF65F  ^0F85 8BACFFFF    JNZ OLLYDBG.004AA2F0
004AF665   837A 04 FF       CMP DWORD PTR DS:[EDX+4],-1
004AF669  ^0F85 81ACFFFF    JNZ OLLYDBG.004AA2F0
004AF66F   66:817A 08 3D40  CMP WORD PTR DS:[EDX+8],403D
004AF675  ^0F85 75ACFFFF    JNZ OLLYDBG.004AA2F0
004AF67B   FF02             INC DWORD PTR DS:[EDX]
004AF67D   FF42 04          INC DWORD PTR DS:[EDX+4]
004AF680   C642 07 80       MOV BYTE PTR DS:[EDX+7],80
004AF684   66:FF42 08       INC WORD PTR DS:[EDX+8]
004AF688  ^E9 69ACFFFF      JMP OLLYDBG.004AA2F6
2006-10-22 15:50
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
13
请问楼上【下面的方法应该没有什么明显缺陷】是指你的方法能正确的显示 403D FFFFFFFF FFFFFFFF 吗,你测试过了。
用你的方法,将这个数显示成:9.2233720368547758080e+18
而这个数的正确显示应该是:9.2233720368547758075e+18
而用我的方法显示的是:9.2233720368547758070e18
我看不出有什么优点,也不是没有缺陷,缺陷和我的一样大,方法比我的更复杂,这叫100步笑50步,至少我还告诉大家,我的方法有缺陷,而你却一口咬定你的方法没有缺陷。哈哈。
2006-10-22 18:16
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
希望你出理解下面的话:
"把浮点转成整数时会自动4舍5入就相当于40 3E 80000000 00000000了"
你那个纯是自己的臆想,毫无道理可言。而我这个就是依据上述的这点,不是代码多几行就表示比你复杂。
另外你到upack.cn出看正确的是不是9.2233720368547758080e+18。(fly的发贴)
http://www.unpack.cn/viewthread.php?tid=7985&extra=page%3D1
2006-10-22 18:32
0
雪    币: 14950
活跃值: (4733)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
15
弄到个补丁不知道行不行.
修改04aa2e8处为JMP 00552D0C,NOP掉fld tbyte ptr ds:[eax]之前的全部语句.
从00552D0C开始替换成如下语句:
fstcw   word [552D42]
and     word [552D42],-2
or      word [552D42], 400
fldcw   word [552D42]
cmp     word [edx+8], 403E
je      004AA2F6
jmp     004AA2F0
nop
保存文件,用LORDPE设置最后区段(.reloc)的属性为可写.
试试.先声明不是我弄的.不知道说的是不是这个
2006-10-22 18:35
0
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
16
我觉得gkend的方法应该说是理想值了(又分析一下,这句话不对,我收回)

从理论上计算403E 80000000 00000000应该等于2的63次方,即9223372036854775808
403D FFFFFFFF FFFFFFFF应该等于2的63次方减0.5,即9223372036854775807.5
关于自动进位我想应该是在浮点转换成整数时才产生的,在没有转换成整数时应该还是取9223372036854775807.5
2006-10-22 18:41
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
17
我不管你在什么地方看到的,如果这个数的值是:403D FFFFFFFF FFFFFFFF 那么他的正确显示一定是:9.2233720368547758075e+18
如果 fly 认为正确的显示是:9.2233720368547758080e+18 那我可以肯定 fly 看到的这个数是不正确的。这里指 OD 对80位浮点的的显示精度。你将精度减少一位,那我也没有办法。
2006-10-22 18:48
0
雪    币: 47147
活跃值: (20460)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
18
构造一个403D FFFFFFFF FFFFFFFF ,用IDA打开看看应该准确:

.text:004013A0 DB 2D A6 13 40 00                                   fld     ds:tbyte_4013A6
.text:004013A0
.text:004013A0                                     ; ---------------------------------------------------------------------------
.text:004013A6 FF FF FF FF FF FF FF FF 3D 40       tbyte_4013A6    dt 9.2233720368547758075e18
2006-10-22 18:52
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
不是我把精度减少一位,而是ollydbg采用四舍五入取整把小数点抹去了。你在ollydbg中看403d ffffffff fffffffb,403d ffffffff fffffffc,403d ffffffff fffffffd的值,就会发现这3个浮点数得值是一样的。现在既然是给ollydbg打补丁,那么就继续沿用。如果要进一步精确,那么修改就更复杂了。
2006-10-22 20:01
0
雪    币: 254
活跃值: (126)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
20
不必要搞那么精确了,borland有这种80位的long double浮点类型
vc好像只有64位的浮点类型
2006-10-22 21:14
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
21
最初由 LOCKLOSE 发布
弄到个补丁不知道行不行.
修改04aa2e8处为JMP 00552D0C,NOP掉fld tbyte ptr ds:[eax]之前的全部语句.
从00552D0C开始替换成如下语句:
fstcw word [552D42]
and word [552D42],-2
........


LOCKLOSE提出的方法比较简单,虽然精度上可能有点问题,按heXer的意见应该是能够满足使用要求了。我将它略微修改了一下,这样就不用跳到外面又跳回来了,也就是直接修改_fuistq函数,原函数为32个字节,修改后的长度为31个字节。

004AA2E0             __fuistq  proc near
004AA2E0 D9 7D DC              fnstcw word ptr [ebp-24h]
004AA2E3 66 83 65 DC+          and   word ptr [ebp-24h], 0FFFEh
004AA2E8 66 81 4D DC+          or    word ptr [ebp-24h], 400h
004AA2EE D9 6D DC              fldcw word ptr [ebp-24h]
004AA2F1 66 81 78 08+          cmp   word ptr [eax+8], 403Eh
004AA2F7 75 01                 jnz   short loc_4AA2FA
004AA2F9 C3                    retn
004AA2FA
004AA2FA             loc_4AA2FA:
004AA2FA DB 28                 fld   tbyte ptr [eax]
004AA2FC DF 38                 fistp qword ptr [eax]
004AA2FE 9B                    wait
004AA2FF C3                    retn
004AA2FF             __fuistq  endp
2006-10-23 01:06
0
雪    币: 303
活跃值: (466)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
最初由 gzgzlxg 发布
LOCKLOSE提出的方法比较简单,虽然精度上可能有点问题,按heXer的意见应该是能够满足使用要求了。我将它略微修改了一下,这样就不用跳到外面又跳回来了,也就是直接修改_fuistq函数,原函数为32个字节,修改后的长度为31个字节。

[code]
004AA2E0 __fuistq proc near
004AA2E0 D9 7D DC fnstcw word ptr [ebp-24h]
........


改完后总是提示:你作弊了(载入HEXER那个)
怎么办?
2006-10-23 08:41
0
雪    币: 257
活跃值: (369)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
23
最初由 liuyilin 发布
改完后总是提示:你作弊了(载入HEXER那个)
怎么办?


很简单,让HEXER改为“你没有作弊”就OK了:)
VC的确最多就64位精度。
2006-10-23 11:30
0
雪    币: 214
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
24
贴2进制代码,打补丁快点,贴汇编密码还要一行一行复制

补丁前
004AA2E0    8B4424 04           MOV EAX,[ESP+4]
004AA2E4    8B5424 08           MOV EDX,[ESP+8]
004AA2E8    66:817A 08 3E40     CMP WORD PTR [EDX+8],403E
004AA2EE    74 06               JE SHORT 004AA2F6
004AA2F0    DB2A                FLD TBYTE PTR [EDX]
004AA2F2    DF38                FISTP QWORD PTR [EAX]
004AA2F4    9B                  WAIT
004AA2F5    C3                  RETN
004AA2F6    8B0A                MOV ECX,[EDX]
004AA2F8    8908                MOV [EAX],ECX
004AA2FA    8B4A 04             MOV ECX,[EDX+4]
004AA2FD    8948 04             MOV [EAX+4],ECX
004AA300    C3                  RETN

补丁后
004AA2E0    D97D DC             FSTCW [EBP-24]
004AA2E3    66:8165 DC FEFF     AND WORD PTR [EBP-24],0FFFE
004AA2E9    66:814D DC 0004     OR WORD PTR [EBP-24],400
004AA2EF    D96D DC             FLDCW [EBP-24]
004AA2F2    66:8178 08 3E40     CMP WORD PTR [EAX+8],403E
004AA2F8    75 01               JNZ SHORT 004AA2FB
004AA2FA    C3                  RETN
004AA2FB    DB28                FLD TBYTE PTR [EAX]
004AA2FD    DF38                FISTP QWORD PTR [EAX]
004AA2FF    9B                  WAIT
004AA300    C3                  RETN

补丁后2进制
D9 7D DC 66 81 65 DC FE FF 66 81 4D DC 00 04 D9 6D DC 66 81 78 08 3E 40 75 01 C3 DB 28 DF 38 9B

长度刚好 。。。楼下说的是哪个插件?给个名字。。
2006-10-23 12:27
0
雪    币: 14950
活跃值: (4733)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
25
最初由 girl 发布
贴2进制代码,打补丁快点,贴汇编密码还要一行一行复制

可以用OD的那个插件直接把所有代码添加进去的.
就不另回帖了.直接在这写上了.插件文件名NonaWrite.DLL.CC大哥汉化过的.
2006-10-23 12:35
0
游客
登录 | 注册 方可回帖
返回
//