Changing a line in an exe resource
How do I change buffer
in the following code, then save the changes to the resource of the executable? I'm looking for something like SetString(handle,index,buffer,size)
.
var
hExe : Cardinal;
buffer : array [0..4097] of ansichar;
begin
hExe:=LoadLibraryEx(PAnsiChar(Edit2.Text),0,LOAD_LIBRARY_AS_DATAFILE);
LoadString(hExe,65300,buffer,SizeOf(buffer));
ShowMessage(buffer);
//need to modify buffer here then I'll unload the resources..
end;
Update: Here's my attempt at UpdateResource
var
hEXE: DWORD;
pData: PAnsiChar;
begin
pData := PAnsiChar(Edit1.Text);
hEXE := BeginUpdateResource(pchar(edit2.text), FALSE);
if hEXE <> 0 then
begin
UpdateResource(hEXE, RT_string, MAKEINTRESOURCE(4082), LANG_NEUTRAL,
@pData, Length(pData)); //if i change 4082 to 65300 it creates another key like 4082
EndUpdateResource(hEXE, FALSE);
end;
This code messes up all the 4082 content. The problem is that the item named 4082 in RT_STRING is a group of rows. When I open the exe in the resource editor, click the line row then 4082 result:
STRINGTABLE
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
{
65296, "Unicode"
65297, "Big Endian Unicode"
65298, "UTF-8"
65299, "UTF-7"
65300, "ABCDE12345"
}
So I either need to parse the string group or I need an API to set the change string with index 65300 in the group. Any ideas?
source to share
I found the answer using google. ( English translation from Chinese ) Thanks anyway everyone!
procedure UpdateResString(AFileName, ANewString: string; AStringIdent: Integer);
procedure WriteToArray(AArray: TByteDynArray; AData: Word; var APos: Integer);
begin
AArray[APos] := Lo(AData);
AArray[APos + 1] := Hi(AData);
Inc(APos, 2);
end;
function ReadFromArray(AArray: TByteDynArray; APos: Integer): Word;
begin
Result := AArray[APos] + AArray[APos + 1] * 16;
end;
var
hModule, hResInfo, hUpdate: THandle;
ResData, TempData: TByteDynArray;
wsNewString: WideString;
iSection, iIndexInSection: Integer;
i, iLen, iSkip, iPos: Integer;
begin
hModule := LoadLibrary(PChar(AFileName));
if hModule = 0 then
raise Exception.CreateFmt('file %s failed to load.', [AFileName]);
// Calculate the resource string area and the string index in that area
iSection := AStringIdent div 16 + 1;
iIndexInSection := AStringIdent mod 16;
// If the resource already exists, then read it out of the original data
hResInfo := FindResource(hModule, MakeIntResource(iSection), RT_STRING);
if hResInfo <> 0 then
begin
iLen := SizeOfResource(hModule, hResInfo);
SetLength(ResData, iLen);
CopyMemory(ResData, LockResource(LoadResource(hModule, hResInfo)), iLen);
end;
// Should first close the file, and then update
FreeLibrary(hModule);
// Calculate the new data is written to location
wsNewString := WideString(ANewString);
iLen := Length(wsNewString);
iPos := 0;
for i := 0 to iIndexInSection do
begin
if iPos > High(ResData) then
SetLength(ResData, iPos + 2);
if i <> iIndexInSection then
begin
iSkip := (ReadFromArray(ResData, iPos) + 1) * 2;
Inc(iPos, iSkip);
end;
end;
// Delete the original data and the data behind the temporary
// storage of data to be added
iSkip := (ReadFromArray(ResData, iPos) + 1) * 2;
TempData := Copy(ResData, iPos + iSkip, Length(ResData) - iSkip);
SetLength(ResData, iPos);
SetLength(ResData, iPos + (iLen + 1) * 2 + Length(TempData));
// Write new data
WriteToArray(ResData, iLen, iPos);
for i := 1 to iLen do
WriteToArray(ResData, Ord(wsNewString[i]), iPos);
// Write back to the original data
for i := 0 to High(TempData) do
ResData[iPos + i] := TempData[i];
// Write the data back to file
hUpdate := BeginUpdateResource(PChar(AFileName), False);
if hUpdate = 0 then
raise Exception.CreateFmt(
'cannot write file %s. Please check whether it is open or set read-only.',
[AFileName]);
UpdateResource(hUpdate, RT_STRING, MakeIntResource(iSection), LANG_NEUTRAL,
ResData, Length(ResData));
EndUpdateResource(hUpdate, False);
end;
source to share
You can see the source code (Delphi 2006) XN Resource Editor (free, powerful, full featured resource editor and PE module explorer for Windows 98, Windows 2000, and Windows XP).
Also, you should check the following functions
Bye.
source to share
I believe you need to replace the entire group with the version containing your modifications. It is not that hard to parse and you can make multiple shortcuts. Load everything into tStringlist and then collapse the list until the string starts with "65300". Replace and store the text portion of the string list as a replacement resource.
source to share