You need to enable JavaScript to run this app. Delphi中空字符串的汇编字节表示及跨进程写入实现
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中空字符串的汇编字节表示及跨进程写入实现

问题背景

最初提问的备注(Tom Brunberg):尚不明确提问的具体目的与数组的后续使用场景。
本次实际目标为:将空字符串写入目标进程的指定内存地址,实现和已验证C++逻辑一致的写入效果。

参考代码

已验证可用的C++端实现

PVOID hmod = debug_event.u.LoadDll.lpBaseOfDll; 
ULONG op; 
SIZE_T NumberOfBytesWritten; 

if (VirtualProtectEx(pi.hProcess, hmod, 1, PAGE_READWRITE, &op)) 
{ 
 WriteProcessMemory(pi.hProcess, hmod, "", 1, &NumberOfBytesWritten); 
}

待修正的Delphi端写入流程

procedure WriteBytes(hProcess: THandle; Address: pointer; const Buffer: array of byte);
var
  Read: THandle;
  oldprot, tmp: dword;
begin
  if (VirtualProtectEx(hProcess, Address, Length(Buffer), PAGE_EXECUTE_READWRITE, @oldprot)) then
    Writeln('1 - VirtualProtectEx() successfully!');
  
  if (WriteProcessMemory(hProcess, Address, @Buffer, Length(Buffer), Read)) then
    Writeln('2 - WriteProcessMemory() successfully!');

  if (VirtualProtectEx(hProcess, Address, Length(Buffer), oldprot, @tmp)) then
    Writeln('3 - VirtualProtectEx() successfully!');
end;

待初始化的字节数组

已知参考定义为固定长度字节数组:Values : Array[0..4] of byte = ($C2,$00,$00,$90,$90);
需要按相同逻辑初始化长度为1的字节数组:

const
  Values: Array[0..0] of Byte = (???); // 此处需要填入对应空字符串的字节内容

实现方案

1. 字节数组的正确初始化

C++中空字符串""的字节构成就是单个值为$00的空终止符,没有其他字符,和参考的固定字节数组定义逻辑完全匹配。长度为1的字节数组直接填写该字节即可:

const
  Values: Array[0..0] of Byte = ($00);

这个定义生成的内存字节,和C++端传入""时指向的内容完全一致。

2. Delphi写入流程的问题修正

原WriteBytes函数存在两个会导致写入错误的问题,修正后即可完全复刻C++端的运行效果:

  • 数据源传参错误:原代码给WriteProcessMemory传了@Buffer作为数据源地址。对于Delphi的开放数组参数,这个地址是栈上参数变量本身的地址,不是数组实际存储字节的首地址,会把栈上的无关数据写进目标进程。正确写法是直接传PByte(Buffer),Delphi会自动将开放数组隐式转换为指向第一个字节的指针。
  • 变量类型不匹配:原代码里接收写入字节数的变量用了THandle类型,和Windows API要求的SIZE_T类型尺寸不匹配,会引发内存访问异常,需要替换为对应类型的变量。
    修正后的完整可运行代码:
procedure WriteBytes(hProcess: THandle; Address: Pointer; const Buffer: array of Byte);
var
  BytesWritten: SIZE_T;
  oldprot, tmp: DWORD;
begin
  // 调整目标内存保护属性为可写
  if VirtualProtectEx(hProcess, Address, Length(Buffer), PAGE_EXECUTE_READWRITE, @oldprot) then
    Writeln('1 - VirtualProtectEx() 执行成功!');
  
  // 写入目标字节
  if WriteProcessMemory(hProcess, Address, PByte(Buffer), Length(Buffer), BytesWritten) then
    Writeln('2 - WriteProcessMemory() 执行成功!');

  // 还原目标内存的原始保护属性
  if VirtualProtectEx(hProcess, Address, Length(Buffer), oldprot, @tmp) then
    Writeln('3 - VirtualProtectEx() 执行成功!');
end;

调用时直接传入之前定义的Values常量即可,最终写入目标地址的内容和C++端验证通过的逻辑完全一致。

内容的提问来源于stack exchange,提问作者user13342561

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 21:15:06