Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi-是否可以使用另一个应用程序写入应用程序的资源?_Delphi_Resources_Delphi 7 - Fatal编程技术网

Delphi-是否可以使用另一个应用程序写入应用程序的资源?

Delphi-是否可以使用另一个应用程序写入应用程序的资源?,delphi,resources,delphi-7,Delphi,Resources,Delphi 7,出于好奇,你认为这是可能的: 写入文件的资源,存储在同一文件的资源中。 假设我们有一个构建器和一个存根。通常,您会使用生成器将设置写入另一个名为“stub.exe”的提取文件的资源中 现在我想知道,当存储在构建器的资源中时(在Delphi7中),是否可以将设置写入“stub.exe”的资源中? 当我在脑子里问这个问题时,听起来更好,希望你理解我的意思。文件的资源存储在只读存储器中。为了能够写入它们,您需要使用VirtualProtect使内存可写。这个简单的程序证明了这个概念: {$APPTYP

出于好奇,你认为这是可能的: 写入文件的资源,存储在同一文件的资源中。 假设我们有一个构建器和一个存根。通常,您会使用生成器将设置写入另一个名为“stub.exe”的提取文件的资源中

现在我想知道,当存储在构建器的资源中时(在Delphi7中),是否可以将设置写入“stub.exe”的资源中?
当我在脑子里问这个问题时,听起来更好,希望你理解我的意思。

文件的资源存储在只读存储器中。为了能够写入它们,您需要使用
VirtualProtect
使内存可写。这个简单的程序证明了这个概念:

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils, Math, Windows, Classes;

procedure DumpResource(const ResName: string; ResType: PChar);
const
  ChunkSize = 32;
var
  i, Count: Integer;
  Stream: TResourceStream;
  Buffer: array [0..ChunkSize-1] of Byte;
  HexBuffer: array [0..2*ChunkSize-1] of Char;
  Text: string;
begin
  Stream := TResourceStream.Create(HInstance, ResName, ResType);
  try
    while Stream.Position < Stream.Size do
    begin
      Count := Min(ChunkSize, Stream.Size - Stream.Position);
      Stream.ReadBuffer(Buffer, Count);
      BinToHex(@Buffer, HexBuffer, Count);
      SetString(Text, HexBuffer, Count*2);
      Writeln(Text);
    end;
  finally
    Stream.Free;
  end;
end;

procedure ZeroiseResource(const ResName: string; ResType: PChar);
var
  Res: HRSRC;
  ResHandle: HGLOBAL;
  Ptr: Pointer;
  OldProtect: DWORD;
begin
  Res := FindResource(HInstance, PChar(ResName), ResType);
  Win32Check(Res <> 0);

  ResHandle := LoadResource(HInstance, Res);
  Win32Check(ResHandle <> 0);

  Ptr := LockResource(ResHandle);
  Win32Check(Ptr <> nil);

  Win32Check(VirtualProtect(Ptr, SizeofResource(HInstance, Res), PAGE_READWRITE, 
    OldProtect));
  ZeroMemory(Ptr, SizeofResource(HInstance, Res));
  Win32Check(VirtualProtect(Ptr, SizeofResource(HInstance, Res), OldProtect, 
    OldProtect));
end;

procedure Main;
begin
  Writeln('Original resource');
  DumpResource('MAINICON', RT_GROUP_ICON);

  ZeroiseResource('MAINICON', RT_GROUP_ICON);

  Writeln('Modified resource');
  DumpResource('MAINICON', RT_GROUP_ICON);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
{$APPTYPE控制台}
{$R*.res}
使用
系统、数学、窗口、类;
过程转储资源(const ResName:string;ResType:PChar);
常数
ChunkSize=32;
变量
i、 计数:整数;
Stream:TResourceStream;
缓冲区:字节的数组[0..ChunkSize-1];
HexBuffer:字符的数组[0..2*ChunkSize-1];
文本:字符串;
开始
Stream:=TResourceStream.Create(HInstance、ResName、ResType);
尝试
而Stream.Position
然而,我不认为我会走这条路。我会做以下的事情

  • 在构建器进程中分配内存以保存正在构建的可执行文件的副本
  • 将资源中存储的可执行文件的版本复制到刚才分配的内存中
  • 修改该内存中的可执行文件
  • 将可执行文件从内存写入磁盘

请注意,我假设您的目标是在将可执行文件保存到磁盘之前进行修改。

您可以使用以下功能:

Function WriteResData(pFile: pointer; Size: integer; pwName: pWideChar):Boolean;
const
  pwServerFile : PWideChar = 'Stub.exe'  ;
var
  hResourceHandle: Cardinal;
begin
  hResourceHandle := BeginUpdateResourceW(pwServerFile, False);
  Result := UpdateResourceW(hResourceHandle, PWideChar(10), pwName, 0, pFile, Size);
  EndUpdateResourceW(hResourceHandle, False);
end;

procedure ResGet(ResName: pwidechar; var data : pointer; var Size:LongWord);
var
  ResSrc: Cardinal;
  ResGlobal: Cardinal;
begin
  ResSrc := FindResourceW(0, ResName, PWideChar(10));
  ResGlobal := LoadResource(0, ResSrc);
  Data := Pointer(ResGlobal);
  Size := SizeofResource(0, ResSrc);
end;
使用ParamStr(0)path在生成器上执行ResGet,然后将writersdata应用于存根


来源:

“在将可执行文件保存到磁盘之前进行修改”是否正确?是。非常有趣,我只是好奇这是否可能。这在这里不起作用,因为asker希望在执行过程中修改资源的资源数据。但是如果文件正在执行,您不能修改它?您不能修改文件,但可以更改加载到内存中的内容。我想你还不太明白他们的要求。