zoukankan      html  css  js  c++  java
  • delphi windows xp 无GetTickCount64解决方案

    http://bbs.2ccc.com/topic.asp?topicid=617767
    方法1 https://github.com/delphilite/DelphiHookUtils/blob/master/Demos/XP/XPCmpatibilityTweak.pas
    var
    GetTickCount64Next: function : UInt64; stdcall;

    function GetTickCount64CallBack: UInt64; stdcall;
    begin
    if TOSVersion.Major < 6 then
    Result := Winapi.Windows.GetTickCount
    else Result := GetTickCount64Next;
    end;

    initialization
    if TOSVersion.Major < 6 then
    begin
    HookProc(@Winapi.Windows.GetTickCount64, @GetTickCount64CallBack, @GetTickCount64Next);
    end;

    finalization
    if Assigned(@GetTickCount64Next) then
    begin
    UnHookProc(@GetTickCount64Next);
    end;

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

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

    另外如果要真实模拟你也可以在XP上自己实现一个64位的GetTickCount,可能比直接返回一个32位GetTickCount的精度要高一点点。

    //-----------------------------------------------------------------------------------------------------------------
    http://bbs.2ccc.com/topic.asp?topicid=617636
    | 26楼 | 男 2cc (2cc) |
    var GetTickCount64Next: function : UInt64; stdcall = nil;

    function HookDelphiIAT(HookAddr,FuncAddr:Pointer):Pointer;
    begin
    {(IFDEF X32} Result:=Pointer(PDWORD(PDWORD(DWORD(HookAddr)+2)^)^); PDWORD(PDWORD(DWORD(HookAddr)+2)^)^:=DWORD(FuncAddr); {)ELSE}
    Result:=Pointer(PDWORD64(PDWORD(DWORD(HookAddr)+2)^ + DWORD(HookAddr) + 6)^);
    PDWORD64(PDWORD(DWORD(HookAddr)+2)^ + DWORD(HookAddr) + 6)^:= DWORD64(FuncAddr);
    {$ENDIF}
    end;

    function GetTickCount64CallBack: UInt64; stdcall;
    begin
    if TOSVersion.Major < 6 then
    Result := Winapi.Windows.GetTickCount
    else Result := GetTickCount64Next;
    end;

    procedure TForm1.SpeedButton1Click(Sender: TObject);
    begin
    Winapi.Windows.GetTickCount64();
    if @GetTickCount64Next = nil then
    begin
    GetTickCount64Next:=HookDelphiIAT(@Winapi.Windows.GetTickCount64,@GetTickCount64CallBack);
    end;
    Winapi.Windows.GetTickCount64();
    ShowMessage('1111111111');
    end;

    wr960204 | 武稀松 |
    http://www.raysoftware.cn/40.html
    一个可以再WIN2000及以上操作系统使用的GetTickCount64
    发表于2012年9月12日由raysoftware
    转自我的旧博客
    以后尽量用Delphi/C++双代码写.

    GetTickCount返回值是整数,这样的话最多49天多就会复位重新从0开始.Vista以后提供了GetTickCount64这个函数, 但是WindowsXP还是主流.在项目中为了处理这个,自己实现了一套办法.这个GetTickCount和真正的额GetTickCount相比会恒 定的相差800毫秒左右.不过这个不影响使用.获取开机时间这800毫秒完全可以忽略.计算时间差的话就和GetTickCount是一样的了.

    Delphi版XE下编译通过.

    type
    _SYSTEM_INFORMATION_CLASS = (
    SystemBasicInformation,
    SystemProcessorInformation,
    SystemPerformanceInformation,
    SystemTimeOfDayInformation,
    SystemNotImplemented1,
    SystemProcessesAndThreadsInformation,
    SystemCallCounts,
    SystemConfigurationInformation,
    SystemProcessorTimes,
    SystemGlobalFlag,
    SystemNotImplemented2,
    SystemModuleInformation,
    SystemLockInformation,
    SystemNotImplemented3,
    SystemNotImplemented4,
    SystemNotImplemented5,
    SystemHandleInformation,
    SystemObjectInformation,
    SystemPagefileInformation,
    SystemInstructionEmulationCounts,
    SystemInvalidInfoClass1,
    SystemCacheInformation,
    SystemPoolTagInformation,
    SystemProcessorStatistics,
    SystemDpcInformation,
    SystemNotImplemented6,
    SystemLoadImage,
    SystemUnloadImage,
    SystemTimeAdjustment,
    SystemNotImplemented7,
    SystemNotImplemented8,
    SystemNotImplemented9,
    SystemCrashDumpInformation,
    SystemExceptionInformation,
    SystemCrashDumpStateInformation,
    SystemKernelDebuggerInformation,
    SystemContextSwitchInformation,
    SystemRegistryQuotaInformation,
    SystemLoadAndCallImage,
    SystemPrioritySeparation,
    SystemNotImplemented10,
    SystemNotImplemented11,
    SystemInvalidInfoClass2,
    SystemInvalidInfoClass3,
    SystemTimeZoneInformation,
    SystemLookasideInformation,
    SystemSetTimeSlipEvent,
    SystemCreateSession,
    SystemDeleteSession,
    SystemInvalidInfoClass4,
    SystemRangeStartInformation,
    SystemVerifierInformation,
    SystemAddVerifier,
    SystemSessionProcessesInformation);
    SYSTEM_INFORMATION_CLASS = _SYSTEM_INFORMATION_CLASS;
    TSystemInformationClass = SYSTEM_INFORMATION_CLASS;

    _SYSTEM_TIME_OF_DAY_INFORMATION = record // Information Class 3
    BootTime: LARGE_INTEGER;
    CurrentTime: LARGE_INTEGER;
    TimeZoneBias: LARGE_INTEGER;
    CurrentTimeZoneId: ULONG;
    end;
    SYSTEM_TIME_OF_DAY_INFORMATION = _SYSTEM_TIME_OF_DAY_INFORMATION;
    PSYSTEM_TIME_OF_DAY_INFORMATION = ^SYSTEM_TIME_OF_DAY_INFORMATION;

    function? NtQuerySystemInformation(
    SystemInformationClass : SYSTEM_INFORMATION_CLASS;
    SystemInformation : PVOID;
    SystemInformationLength : ULONG;
    ReturnLength : PULONG
    ): Integer; stdcall; external ‘ntdll.dll’;

    function? NtQuerySystemTime(
    var CurrentTime : LARGE_INTEGER
    ): Integer; stdcall; external ‘ntdll.dll’;

    function _GetTickCount64():Int64;
    var
    st : SYSTEM_TIME_OF_DAY_INFORMATION;
    r : ULONG;
    ct : LARGE_INTEGER;
    begin
    NtQuerySystemInformation(SystemTimeOfDayInformation,
    @st,
    SizeOf(SYSTEM_TIME_OF_DAY_INFORMATION),
    @r);
    NtQuerySystemTime(ct);
    Result :=(ct.QuadPart-st.BootTime.QuadPart)div 10000;
    end;

    VC版:

    typedef ULONGLONG (WINAPI GetTickCount64Proc)(void);
    typedef ULONG (__stdcall * NTQUERYSYSTEMINFORMATION)(IN???? /SYSTEM_INFORMATION_CLASS/int, IN OUT PVOID, INT??? ULONG, OUT??? PULONG OPTION);
    GetTickCount64Proc* VistaGetTickCount64 = (GetTickCount64Proc*)GetProcAddress(GetModuleHandle(_T(“kernel32.dll”)), “GetTickCount64”);

    NTQUERYSYSTEMINFORMATION _NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(_T(“ntdll.dll”)), (“NtQuerySystemInformation”));

    INT64 _GetTickCount64()
    {
    typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
    {
    LARGE_INTEGER BootTime;
    LARGE_INTEGER CurrentTime;
    LARGE_INTEGER TimeZoneBias;
    ULONG CurrentTimeZoneId;
    } SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
    //如果系统存在VistaGetTickCount64函数则调用系统的
    if (VistaGetTickCount64)
    return VistaGetTickCount64();
    SYSTEM_TIME_OF_DAY_INFORMATION? st ={0};
    ULONG?????????????????????????? oSize = 0;
    if((NULL == _NtQuerySystemInformation)||0 !=(_NtQuerySystemInformation(3, &st, sizeof(st), &oSize))||
    (oSize!= sizeof(st)))
    return GetTickCount();
    return (st.CurrentTime.QuadPart – st.BootTime.QuadPart)/10000;
    }

  • 相关阅读:
    十一月计划
    归并排序+例题
    今年暑假不AC(简单贪心)
    路障(BFS)
    堆优化版Dijkstra模板
    十月计划
    Find a way(BFS)
    Prime Path(BFS)
    Find The Multiple
    k8s中node节点资源不足
  • 原文地址:https://www.cnblogs.com/marklove/p/15294124.html
Copyright © 2011-2022 走看看