一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 20835|回复: 23
收起左侧

[其他综合] Protel 99 SE 'Format '%x' invalid or... 的分析

[复制链接]
发表于 2012-4-11 11:27 | 显示全部楼层 |阅读模式

之前在笔记本上从来没出现过这个问题, 相同的安装文件. 已经打了protel99seservicepack6的补丁. 换了4核的台式机基本每天都有几次...

这个问题在网上搜索, 回答多是不能用太好的机器否则Protel 99 SE 就会有很多问题, 经过分析实际还真是这样的.


Od载入 Client99SE.exe 断点到 Kernel32->RaiseException, 因为这是个delphi未处理异常. 运行进程等待 Client99SE.exe 抛出异常.

当调用RaiseException 时查看调用栈定位到函数

0DF61357    55                   push    ebp

0DF61358    68 9414F60D          push    0DF61494

0DF6135D    64:FF30              push    dword ptr fs:[eax]

0DF61360    64:8920              mov     dword ptr fs:[eax], esp

0DF61363    C606 00              mov     byte ptr [esi], 0

0DF61366    E8 CD03E9FF          call    <jmp.&kernel32.GetTickCount>

0DF6136B    8BD8                 mov     ebx, eax

0DF6136D    8D85 FCFEFFFF        lea     eax, dword ptr [ebp-104]

0DF61373    50                   push    eax

0DF61374    A1 7CF1F70D          mov     eax, dword ptr [DF7F17C]

0DF61379    83C0 11              add     eax, 11

0DF6137C    8985 E4FEFFFF        mov     dword ptr [ebp-11C], eax

0DF61382    C685 E8FEFFFF 04     mov     byte ptr [ebp-118], 4

0DF61389    C685 ECFEFFFF 7E     mov     byte ptr [ebp-114], 7E

0DF61390    C685 F0FEFFFF 02     mov     byte ptr [ebp-110], 2

0DF61397    899D F4FEFFFF        mov     dword ptr [ebp-10C], ebx

0DF6139D    C685 F8FEFFFF 00     mov     byte ptr [ebp-108], 0

0DF613A4    8D95 E4FEFFFF        lea     edx, dword ptr [ebp-11C]

0DF613AA    B9 02000000          mov     ecx, 2

0DF613AF    B8 AC14F60D          mov     eax, 0DF614AC                                 ; ASCII "%s\%s%x.tmp"

0DF613B4    E8 0703E9FF          call    <jmp.&Vcl50.Sysutils::Format>

0DF613B9    8B95 FCFEFFFF        mov     edx, dword ptr [ebp-104]

0DF613BF    8D85 00FFFFFF        lea     eax, dword ptr [ebp-100]

0DF613C5    B9 FF000000          mov     ecx, 0FF

0DF613CA    E8 71FEE8FF          call    <jmp.&Vcl50.System::LStrToString>

0DF613CF    EB 69                jmp     short 0DF6143A

0DF613D1    E8 6203E9FF          call    <jmp.&kernel32.GetTickCount>

0DF613D6    8BD8                 mov     ebx, eax

0DF613D8    8D85 E0FEFFFF        lea     eax, dword ptr [ebp-120]

0DF613DE    50                   push    eax

0DF613DF    A1 7CF1F70D          mov     eax, dword ptr [DF7F17C]

0DF613E4    83C0 11              add     eax, 11

0DF613E7    8985 E4FEFFFF        mov     dword ptr [ebp-11C], eax

0DF613ED    C685 E8FEFFFF 04     mov     byte ptr [ebp-118], 4

0DF613F4    C685 ECFEFFFF 7E     mov     byte ptr [ebp-114], 7E

0DF613FB    C685 F0FEFFFF 02     mov     byte ptr [ebp-110], 2

0DF61402    899D F4FEFFFF        mov     dword ptr [ebp-10C], ebx

0DF61408    C685 F8FEFFFF 00     mov     byte ptr [ebp-108], 0

0DF6140F    8D95 E4FEFFFF        lea     edx, dword ptr [ebp-11C]

0DF61415    B9 02000000          mov     ecx, 2

0DF6141A    B8 C014F60D          mov     eax, 0DF614C0                                 ; ASCII "%s\s%x%.tmp"

0DF6141F    E8 9C02E9FF          call    <jmp.&Vcl50.Sysutils::Format>

0DF61424    8B95 E0FEFFFF        mov     edx, dword ptr [ebp-120]

0DF6142A    8D85 00FFFFFF        lea     eax, dword ptr [ebp-100]

0DF61430    B9 FF000000          mov     ecx, 0FF

0DF61435    E8 06FEE8FF          call    <jmp.&Vcl50.System::LStrToString>

0DF6143A    8D85 DCFEFFFF        lea     eax, dword ptr [ebp-124]

0DF61440    8D95 00FFFFFF        lea     edx, dword ptr [ebp-100]

0DF61446    E8 EDFDE8FF          call    <jmp.&Vcl50.System::LStrFromString>

0DF6144B    8B85 DCFEFFFF        mov     eax, dword ptr [ebp-124]

0DF61451    E8 B201E9FF          call    <jmp.&Vcl50.Sysutils::FileExists>

0DF61456    84C0                 test    al, al

0DF61458  ^ 0F85 73FFFFFF        jnz     0DF613D1

0DF6145E    8BC6                 mov     eax, esi

0DF61460    8D95 00FFFFFF        lea     edx, dword ptr [ebp-100]

0DF61466    E8 2DFCE8FF          call    <jmp.&Vcl50.System::PStrCpy>

0DF6146B    33C0                 xor     eax, eax

0DF6146D    5A                   pop     edx

0DF6146E    59                   pop     ecx

0DF6146F    59                   pop     ecx

0DF61470    64:8910              mov     dword ptr fs:[eax], edx

0DF61473    68 9B14F60D          push    0DF6149B

0DF61478    8D85 DCFEFFFF        lea     eax, dword ptr [ebp-124]

0DF6147E    BA 02000000          mov     edx, 2

0DF61483    E8 90FDE8FF          call    <jmp.&Vcl50.System::LStrArrayClr>

0DF61488    8D85 FCFEFFFF        lea     eax, dword ptr [ebp-104]

0DF6148E    E8 7DFDE8FF          call    <jmp.&Vcl50.System::LStrClr>

0DF61493    C3                   retn

0DF61494  ^ E9 3FFDE8FF          jmp     <jmp.&Vcl50.System::HandleFinally>

0DF61499  ^ EB DD                jmp     short 0DF61478

0DF6149B    5E                   pop     esi

0DF6149C    5B                   pop     ebx

0DF6149D    8BE5                 mov     esp, ebp

0DF6149F    5D                   pop     ebp

0DF614A0    C3                   retn

堆栈上有一块字符串

0013DD1C   0F817B8C  ASCII "C:\PROGRA~1\DESIGN~1\\System\Temp\~35C52FB.tmp"

问题出在第二个调用format函数时给予的第一个参数 "%s\s%x%.tmp" .

ida插件转换到c代码

int __fastcall sub_571334(int a1)

{

  int v1; // esi@1

  int v2; // ST04_4@1

  DWORD v4; // eax@1

  DWORD v5; // eax@2

  int v6; // [sp+8h] [bp-124h]@1

  int v7; // [sp+Ch] [bp-120h]@1

  int v8; // [sp+28h] [bp-104h]@1

  int v9; // [sp-Ch] [bp-138h]@1

  int v10; // [sp+10h] [bp-11Ch]@1

  char v11; // [sp+14h] [bp-118h]@1

  char v12; // [sp+18h] [bp-114h]@1

  char v13; // [sp+1Ch] [bp-110h]@1

  DWORD v14; // [sp+20h] [bp-10Ch]@1

  char v15; // [sp+24h] [bp-108h]@1

  char v16; // [sp+2Ch] [bp-100h]@1

  v6 = 0;

  v7 = 0;

  v8 = 0;

  v1 = a1;

  v2 = *MK_FP(__FS__, 0);

  *MK_FP(__FS__, 0) = &v9;

  *(_BYTE *)a1 = 0;

  v4 = GetTickCount();

  v10 = dword_58F17C + 17;

  v11 = 4;

  v12 = 126;

  v13 = 2;

  v14 = v4;

  v15 = 0;

  Sysutils__Format(&str__s__s_x_tmp[1], &v10, &v8);

  System____linkproc___LStrToString(&v16, v8);

  while ( 1 )

  {

    System____linkproc___LStrFromString(&v6, &v16);

    if ( !(unsigned __int8)Sysutils__FileExists(v6) )

      break;

    v5 = GetTickCount();

    v10 = dword_58F17C + 17;

    v11 = 4;

    v12 = 126;

    v13 = 2;

    v14 = v5;

    v15 = 0;


Sysutils__Format(&str__s_s_x__tmp[1], &v10, &v7);

    System____linkproc___LStrToString(&v16, v7);

  }

  System____linkproc___PStrCpy(v1, &v16);

  *MK_FP(__FS__, 0) = v2;

  System____linkproc___LStrArrayClr(&v6, 2);

  return System____linkproc___LStrClr(&v8);

}

可以看到这个函数用来完成生成不重复的随机文件名, 当机器太快硬盘太快时GetTickCount返回的值可能在两次调用中相同, 就会调用第二个format发生这个异常 因为Sysutils__Format(&str__s_s_x__tmp[1], &v10, &v7);处参数是错误的.

Ps:我这c盘就一垃圾ssd...

只要补丁字符串 "%s\s%x%.tmp" "%s\%s%x.tmp" 就可以了.

25735C732578252E746D70 -> 25735C257325782E746D70

原来是写 Protel 99 SE 的大神当年没测试到...


protel.99.se.sp6-patch.rar (37.19 KB, 下载次数: 12682)


部分杀软会报毒

发表于 2013-3-8 18:07 | 显示全部楼层
下载不了啊
发表于 2013-3-9 12:46 | 显示全部楼层
我的经常出现pcb库配置文件出错以致无法加载pcb库,只能手动修改配置文件来解决
发表于 2013-3-12 01:53 | 显示全部楼层
牛B啊,LZ就是作者,终于把苦恼的问题解决了!!!
发表于 2013-3-12 08:17 | 显示全部楼层

RE: Protel 99 SE 'Format '%x' invalid or... 的分析

40560335 发表于 2013-3-12 01:53 static/image/common/back.gif
牛B啊,LZ就是作者,终于把苦恼的问题解决了!!!

protel是外国公司的产品吧!
发表于 2013-3-17 15:24 | 显示全部楼层
benli 发表于 2013-3-12 08:17 static/image/common/back.gif
protel是外国公司的产品吧!

那必须的,我说的是,解决这个问题补丁的作者是LZ!~
发表于 2013-3-21 20:10 | 显示全部楼层
观摩~~~~~学习
发表于 2013-5-5 13:28 | 显示全部楼层
楼主太牛了!非常感谢楼主,问题已解决。
发表于 2013-9-28 12:33 来自手机 | 显示全部楼层
怎么样把99改改能用到win7
发表于 2013-9-28 12:33 来自手机 | 显示全部楼层
怎么样把99改改能用到win7

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-3-29 15:49 , Processed in 0.069139 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表