gpt4 book ai didi

delphi - 有没有办法确定程序的大小?

转载 作者:行者123 更新时间:2023-12-03 18:59:46 26 4
gpt4 key购买 nike

我正在使用以下例程来修补RTL中的功能。

procedure PatchCode(const AddrProc: Pointer; const CodeSize: NativeUInt;
const Code: Pointer);
var
OldProtect: Cardinal;
begin
VirtualProtect(AddrProc, CodeSize, PAGE_EXECUTE_READWRITE, OldProtect);
Move(Code^, AddrProc^, CodeSize);
VirtualProtect(AddrProc, CodeSize, OldProtect, OldProtect);
end;


但是,当我调整补丁方法时,它们的大小会发生变化,从而导致如下代码中断:

//PatchRedirect calls PatchCode internally  
PatchRedirect(AddrGetMem,{codesize = }17, @RedirectGetMem, JUMPS_GETMEM);


有没有一种方法可以在编译时或运行时确定方法的大小? (任何一个都可以)。

我希望有一个一般的解决方案,但是
如果它仅适用于asm例程,则对我而言很好。

用例
一个用例是FillChar的更快版本。
99%的时间 FillChar被用作 ZeroMem
所以我用以下命令修补 System.ZeroMem

xor r8,r8
jmp FastFillChar;


然后用 System.FillChar

movzx R8,R8b
mov r9,$0101010101010101
imul r8,r9
jmp FastFillChar


这样,对于这99%的情况,我可以使FillChar快一点。
否则,如果有人不愿意实际使用zeromem

更新资料
感谢Rudy,我想我有一个适用于有限子集的解决方案。

最佳答案

有没有办法确定程序的大小?


如果您有权访问源代码,则可以。
Delphi将生成的例程代码按照在implementation部分中声明的顺序放置。

只要要尝试打补丁的目标代码和要打补丁的源代码都使用相同的{$CODEALIGN n}参数进行编译,就不会有问题。

对于Win32,默认值为4,并且使用对齐方式4编译Win32 RTL。
Win64 RTL的代码对齐方式为{$CodeAlign 16}

只要您代码中的代码对齐方式和补丁接收者匹配,以下代码就可以正常工作:

ProcSize:= NativeInt(@Routine2) - NativeInt(@Routine1);  
PatchCode(@Routine1, ProcSize, @System.Something);


任何对齐nops只会将大小增加到 $CodeAlign的下一个倍数,并且目标代码以相同方式对齐,因此应该没问题。

显然Routine1最好真的很短,否则您会遇到麻烦,也许最好断言@dest在修补 ProcSize > $CodeAlign之前不是其他例程的裸露的jmp。

关于delphi - 有没有办法确定程序的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37720420/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com