我已经阅读了这些问题和答案
但我不能弄清楚如何修补位于其他单元中的类的私有方法.
检查此示例我想修补Bar程序.
Unit ThidParty;
Interface
Type
TFoo =Class
private
procedure Bar;
end;
Run Code Online (Sandbox Code Playgroud)
我认为关键是找到一种方法来获取私有方法的地址.
那么,我如何修补delphi类的私有方法?
我对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如何,问题都存在.
我有第三方功能
function DataCompare(const S1, S2: string; APartial: Boolean): Boolean;
begin
...
end;
Run Code Online (Sandbox Code Playgroud)
它用于另一个第三方单元.
我希望在运行时用另一个新实现替换函数体.
这可能吗?我想需要一些黑客(ala VirtualMemoryUnprotect).非汇编解决方案非常受欢迎.
在我的服务器上有几个文件的修改日期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的新手(现在已经编程了大约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)
这不是我使用的确切代码,一切都在变量中并在另一个上下文中使用,但我认为你可以看到问题.为什么这个计算错了?我怎么想解决这个问题?
我们的应用程序中有很多表单,我需要一个全局事件处理程序来检测其中一个表单何时被销毁(然后采取一些操作).
ps:我想避免向每个表单添加代码,这些表单需要在主表单即将销毁时向主表单发送消息.此外,大多数表单都是在运行时动态创建和销毁的.
我在考虑使用全球TApplicationEvents.
对此最好的方法是什么?
有时我会收到客户的错误报告,我无法解释.在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) 早上好.我正在尝试学习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 ...
delphi ×8
delphi-7 ×2
delphi-2006 ×1
delphi-2010 ×1
delphi-xe ×1
delphi-xe2 ×1
dll ×1
function ×1
memory ×1
replace ×1
time ×1
windows ×1
x86-64 ×1