相关疑难解决方法(0)

我如何修补delphi类的私有方法?

我已经阅读了这些问题和答案

如何更改外部声明的函数的实现(绕行)

在delphi中调用例程调用

但我不能弄清楚如何修补位于其他单元中的类的私有方法.

检查此示例我想修补Bar程序.

Unit ThidParty;
Interface
   Type
      TFoo =Class
        private
           procedure Bar;
       end;
Run Code Online (Sandbox Code Playgroud)

我认为关键是找到一种方法来获取私有方法的地址.

那么,我如何修补delphi类的私有方法?

delphi delphi-xe2

15
推荐指数
1
解决办法
4780
查看次数

用于Win64 Release Target的Delphi 10.2下的FillChar和StringOfChar

我对Delphi 10.2 Pascal编程语言中的特定编程问题有疑问.

StringOfChar和FillChar在2012年之前发布的CPU上的Win64 Release版本下无法正常工作.

  • FillChar的预期结果只是在给定的内存缓冲区中重复8位字符的简单序列.

  • StringOfChar的预期结果是相同的,但结果存储在字符串类型中.

但实际上,当我在10.2版本的Delphi中编译我们在10.2之前的Delphi中运行的应用程序时,我们为Win64编译的应用程序在2012年之前发布的CPU上停止正常工作.

StringOfChar和FillChar不能正常工作 - 它们返回一串不同的字符,虽然是重复的模式 - 而不仅仅是它们应该具有相同字符的序列.

这是足以证明问题的最小代码.请注意,序列的长度应至少为16个字符,并且字符不应为nul(#0).代码如下:

procedure TestStringOfChar;
var
  a: AnsiString;
  ac: AnsiChar;
begin
  ac := #1;
  a := StringOfChar(ac, 43);
  if a <> #1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1 then
  begin
    raise Exception.Create('ANSI StringOfChar Failed!!');
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我知道StackOverflow上有很多Delphi程序员.你遇到同样的问题吗?如果是,您如何解决?解决办法是什么?顺便说一句,我已经联系了Delphi的开发人员,但到目前为止他们还没有确认也没有否认这个问题.我正在使用Embarcadero Delphi 10.2版本25.0.26309.314.

更新:

如果您的CPU是在2012年或之后生产的,则在调用StringOfChar之前还要包含以下行以重现该问题:

const
  ERMSBBit    = 1 shl 9; //$0200
begin
  CPUIDTable[7].EBX := CPUIDTable[7].EBX and not ERMSBBit;
Run Code Online (Sandbox Code Playgroud)

至于2017年4月的RAD Studio 10.2工具链问题修补程序 - 尝试过它而没有它 - 它没有帮助.无论Hotfix如何,问题都存在.

windows delphi x86-64

14
推荐指数
1
解决办法
825
查看次数

如何更改外部声明的函数的实现(绕行)

我有第三方功能

function DataCompare(const S1, S2: string; APartial: Boolean): Boolean;
begin
   ...
end;
Run Code Online (Sandbox Code Playgroud)

它用于另一个第三方单元.

我希望在运行时用另一个新实现替换函数体.

这可能吗?我想需要一些黑客(ala VirtualMemoryUnprotect).非汇编解决方案非常受欢迎.

delphi implementation replace function delphi-xe

12
推荐指数
1
解决办法
2723
查看次数

FileExists和修改日期的问题

在我的服务器上有几个文件的修改日期31/DEC/1979(不要问我原因).所以FileExists返回false.

Sysutils.FileExists 看起来像这样:

function FileAge(const FileName: string): Integer;
var
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
begin
  Handle := FindFirstFile(PChar(FileName), FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
        LongRec(Result).Lo) then Exit;
    end;
  end;
  Result := -1;
end;

function FileExists(const FileName: string): Boolean;
begin
  Result := FileAge(FileName) <> -1;
end;
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么功能首先取决于FileAge?以下行不够吗?:

if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
  // Yes the file exists!
Run Code Online (Sandbox Code Playgroud)

甚至基于文件属性:

function …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-7

12
推荐指数
1
解决办法
2665
查看次数

我如何解决Delphi无法准确处理日期时间操作的问题?

我是Delphi的新手(现在已经编程了大约6个月).到目前为止,这是一次非常令人沮丧的经历,其中大部分来自Delphi处理日期和时间的糟糕程度.也许我认为这很糟糕,因为我不知道如何正确使用TDate和TTime,我不知道.以下是我现在正在发生的事情:

// This shows 570, as expected
ShowMessage(IntToStr(MinutesBetween(StrToTime('8:00'), StrToTime('17:30'))));

// Here I would expect 630, but instead 629 is displayed. WTF!?
ShowMessage(IntToStr(MinutesBetween(StrToTime('7:00'), StrToTime('17:30'))));
Run Code Online (Sandbox Code Playgroud)

这不是我使用的确切代码,一切都在变量中并在另一个上下文中使用,但我认为你可以看到问题.为什么这个计算错了?我怎么想解决这个问题?

delphi time delphi-2010

12
推荐指数
2
解决办法
3272
查看次数

如何检测整个应用程序中的表单是否被销毁?

我们的应用程序中有很多表单,我需要一个全局事件处理程序来检测其中一个表单何时被销毁(然后采取一些操作).

ps:我想避免向每个表单添加代码,这些表单需要在主表单即将销毁时向主表单发送消息.此外,大多数表单都是在运行时动态创建和销毁的.

我在考虑使用全球TApplicationEvents.

对此最好的方法是什么?

delphi delphi-7

8
推荐指数
4
解决办法
3455
查看次数

解释GetKeyState/GetCursorPos中的错误

有时我会收到客户的错误报告,我无法解释.在Delphi中的Application.Run()之后,我收到以下错误:

 EOSError: System error: Code:_5 Access denied

 Call Stack Information:
-------------------------------------------------------------------
|Address |Module     |Unit       |Class |Procedure       |Line    |
-------------------------------------------------------------------
|Running Thread: ID=4352; Priorität=0; Klasse=; [Main Thread]     |
|-----------------------------------------------------------------|
|772B291F|USER32.dll |           |      |GetKeyState     |        |
|772B7B96|USER32.dll |           |      |GetPropA        |        |
|772B7B5A|USER32.dll |           |      |GetPropA        |        |
|772A7BC5|USER32.dll |           |      |DispatchMessageA|        |
|772A7BBB|USER32.dll |           |      |DispatchMessageA|        |
|00A6D804|Program.exe|Program.dpr|      |                |803[369]|  // Application.Run
-------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

EOsError: A call to an OS function failed

Call Stack Information:
-------------------------------------------------------------------
|Address |Module     |Unit       |Class |Procedure …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-2006

6
推荐指数
1
解决办法
1334
查看次数

Delphi - 尝试使用DLL注入覆盖指令时发生访问冲突

早上好.我正在尝试学习DLL注入,所以我写了一个小软件,它只获取一个String,与StrCmp()进行比较,如果输入等于"Winner",则该软件会给出一个好男孩消息,学习DLL注入的porpouse.所以我写了一个DLL,它在注入时加载一个Form,porpouse正在使用DLL注入,修改比较指令(JNZ(74)到JMP(EB)),然后制作软件,接受任何字符串.我的DLL代码是:

library Project2;
uses
  SysUtils,
  Windows,
  Classes,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}
var
Hproccess:THandle;
Hid:Cardinal;
b:Boolean=false;

       Procedure Chamar;
       begin
        Form1:=TForm1.Create(nil);
       Form1.ShowModal;
       end;
begin
Hproccess:=OpenProcess(PROCESS_ALL_ACCESS,false,GetCurrentProcessID);
CreateRemoteThread(Hproccess,nil,0,@Chamar,@Chamar,0,Hid);
end.
Run Code Online (Sandbox Code Playgroud)

你怎么看,DLL只是创建一个新的线程来加载窗体(Form1).问题是,当我在Memory Addres中写入以覆盖JNZ指令时,Windows不允许我这样做,并在地址005B55A9返回访问冲突消息.我的表单代码也很简单.

    unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button2: TButton;
    procedure Button2Click(Sender: TObject);

  private

  public

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject);
var
Memory:Dword;
begin
Memory:=$005B55A9;
PDWORD(Memory)^:=225; {EB=225}
Free();
end;
end.
Run Code Online (Sandbox Code Playgroud)

我做错了什么?如何在没有访问冲突错误的情况下将JNZ(74)的指令覆盖到JMP(EB)?对不起我的错误,我昨天开始阅读它,这是我的第一个例子.我已经有了Injector(极端注射器).我的疑问只是关于DLL编码.你能帮助我吗?

我忘了说,我使用的是Windows 10 ...

memory delphi dll access-violation dll-injection

0
推荐指数
1
解决办法
299
查看次数