DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: tanghaoming019
今日帖子: 13
在线用户: 9
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 szyourname (szyourname) ★☆☆☆☆ -
盒子活跃会员
2021/9/15 9:15:24
标题:
[搬运]Delphi 11 Windows XP compatibility tweak 浏览:1044
加入我的收藏
楼主: Delphi 11 Windows XP compatibility tweak
By Michal Mutl

As you likely noticed, Delphi 11 officially does not support Windows XP anymore. You can make your application compatible with XP again by simple set.
In Project Options|Building|Delphi Compiler|Linking set "Set OS Version fields in PE Headers" and "Set SubSystem Version fields in PE Headers" to "5.1".
Unless your application uses System.Threading.pas (TTask etc) you should run it under Windows XP with no problems. But if so, then you have to tweak this unit.
Threading objects actually use in their internals new TThread.GetTickCount64 method, which is hardwired to Windows API GetTickCount64 which is not available in Windows XP API.
Take this unit from "source\rtl\common" folder in Delphi 11 installation. Declare new local function in the beginning of implementation section of this unit like this:
function _GetTickCount64: UInt64;
begin
if TOSVersion.Major<6 then
Result := TThread.GetTickCount
else
Result := TThread.GetTickCount64;
end;
and
replace all occurences of TThread.GetTickCount64 calls with _GetTickCount64.
For Win32 applications then copy this modified unit to \lib\win32\debug and \lib\win32\release folders in Delphi 11 installation and rename original System.Threading.dcu to e.g. _System.Threading.dcu.
Then build your project which uses System.Threading with Debug and Release configuration. New System.Threading.dcu should be created in mentioned folders. After this you should remove modified System.Threading.pas from these folders to prevent its recurrent compilation.
Now your Delphi 11 Win32 applications should run under Windows XP with no External Exception crash.
----------------------------------------------
-
作者:
男 bjlg (蓝天) ★☆☆☆☆ -
盒子活跃会员
2021/9/15 10:12:52
1楼: 其实最好修改system.classes
就一个地方

class function TThread.GetTickCount64: UInt64;
{$IF Defined(MSWINDOWS)}
begin
   if(TOSVersion.Major<6 )then  
  Result := Winapi.Windows.GetTickCount;
  else  
  Result := Winapi.Windows.GetTickCount64;
end;
----------------------------------------------
http://delphi-z.ru>http://delphi.icm.edu.pl/ftp/http://delphi-z.ru
作者:
男 lsuper (lsuper) ★☆☆☆☆ -
盒子活跃会员
2021/9/16 0:07:48
2楼: 兴许更好的方法是动态修补?随手写了个 demo:

https://github.com/delphilite/DelphiHookUtils/blob/master/Demos/XP
https://github.com/delphilite/DelphiHookUtils/blob/master/Demos/XP/XPCmpatibilityTweak.pas

1、在 XP 下通过 ~
2、注意:这个 hook 方案还有些问题:x64 下 HookProc 上了但调用出错,由于这个实现参考的 wr960204 武稀松大哥的 HookUtils,暂时没空调,期待 武稀松 出手、或 欢迎 Github 上提 PR 哈 ~

广告一个,欢迎标星、PR 哈:https://github.com/delphilite/DelphiHookUtils
----------------------------------------------
-
作者:
男 keymark (嬲) ▲▲△△△ -
注册会员
2021/9/16 10:13:10
3楼: to 2楼:
googlecode delphi-hook-library

var
  Old_GetTickCount64: function : UInt64; stdcall;

function _GetTickCount64: UInt64; stdcall;
begin
   ShowMessage('in test!');
  if TOSVersion.Major < 6 then
    Result := Winapi.Windows.GetTickCount
  else Result := Old_GetTickCount64;
end;

procedure TForm4.CheckBox4Click(Sender: TObject);
const
  GetTickCount64Name = 'GetTickCount64';
begin
  if CheckBox4.Checked then
  begin
    if not Assigned(Old_GetTickCount64) then
    begin
      @Old_GetTickCount64 := HookProcInModule(kernel32, GetTickCount64Name, @_GetTickCount64);
    end
    else
    begin
      ShowMessage('钩过了,不需要重复来吧!');
    end;
  end
  else
  begin
    if Assigned(Old_GetTickCount64) then
      UnHook(@Old_GetTickCount64);
    @Old_GetTickCount64 := nil;
  end;
  ShowMessage('TThread.GetTickCount64: ' + IntToStr(TThread.GetTickCount64));
end;
xp我没有.
----------------------------------------------
[alias]  co = clone --recurse-submodules  up = submodule update --init --recursiveupd = pullinfo = statusrest = reset --hard懒鬼提速http://qalculate.github.io/downloads.htmlhttps://www.cctry.com/
作者:
男 lsuper (lsuper) ★☆☆☆☆ -
盒子活跃会员
2021/9/16 13:56:47
4楼: @keymark (嬲):XP 下不存在 GetTickCount64,用 HookProcInModule 会失败(已 XP 实测);XPCmpatibilityTweak.pas 的做法是直接改的延迟导入表,不过对延迟导入表函数 Hook 原做法有问题,有空我调一下 ~
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2021/9/16 14:18:53
5楼: @lsuper

把  
HookProc(@Winapi.Windows.GetTickCount64, @GetTickCount64CallBack, @GetTickCount64Next);
改成
HookProc('kernel32.dll','GetTickCount64', @GetTickCount64CallBack, @GetTickCount64Next);
就可以了。

第一种写法如果函数是Delphi实现的没问题,但是你这个是钩的导入表的跳转函数。
第二种写法是钩的kernel32.dll中函数的本体

另外如果要真实模拟你也可以在XP上自己实现一个64位的GetTickCount,可能比直接返回一个32位GetTickCount的精度要高一点点。
http://www.raysoftware.cn/40.html
----------------------------------------------
武稀松http://www.raysoftware.cn
作者:
男 lsuper (lsuper) ★☆☆☆☆ -
盒子活跃会员
2021/9/17 14:27:36
6楼: @wr960204 (武稀松):武大侠这个 HookProc('kernel32.dll' ... 做法可能也无法解决,因为 XP 下 kernel32.dll 不存在 GetTickCount64 函数,类似

http://bbs.2ccc.com/topic.asp?topicid=617636

26 楼 2cc (2cc) 的  HookDelphiIAT 做法可能是正道

拜读武大侠这个 _GetTickCount64 [赞]!
----------------------------------------------
-
作者:
男 wr960204 (武稀松) ★☆☆☆☆ -
盒子活跃会员
2021/9/17 17:18:45
7楼: @lsuper
我那个回答跟你这个是否XP无关,是回复你说X64下会出错的问题。

因为你原来那种HOOK方式是HOOK的导入表的地址,里面是个代-理,JMP到真正DLL中的函数。是有风险的。
正确做法是HOOK住DLL中的真正的函数。

X64下HOOK调用旧函数出错就是因为这个原因。HOOK的原理是把函数头几个指令拷贝到新地方,变成一个新函数头,再跳回旧地方。
导入表指向的就是一个JMP,X86没问题,JMP是绝对跳转。
X64就会有问题,X64没有绝对跳转,都是相对2GB空间内的相对跳转,指令拷贝到另一处相对跳转就会出错。

正确安全的做法还是HOOK DLL中的真正的函数,而不是导入表
----------------------------------------------
武稀松http://www.raysoftware.cn
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行93.75毫秒 RSS