Сейчас на форуме: bartolomeo, vasilevradislav, rmn, Magister Yoda (+7 невидимых)

 eXeL@B —› Программирование —› Работа с ресурсами PE-exe
Посл.ответ Сообщение

Ранг: 11.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 11 декабря 2008 17:33
· Личное сообщение · #1

Просвятите плз, каким макаром программно можно заменять ресурсы существующего ехе-шника. Интересует, в первую очередь, значок и строки. Желательно Delphi.



Ранг: 28.7 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 11 декабря 2008 17:47
· Личное сообщение · #2

С помощью программ: Resource Tuner, Restorator, Resource_Hacker.
Строки - там же,либо в Ольке: Search for->All referenced text strings.




Ранг: 81.7 (постоянный), 10thx
Активность: 0.030
Статус: Участник

Создано: 11 декабря 2008 18:00
· Личное сообщение · #3

Автор видимо сорсы подобного ищет




Ранг: 68.0 (постоянный), 6thx
Активность: 0.060
Статус: Участник

Создано: 11 декабря 2008 18:17
· Личное сообщение · #4

www.delphisources.ru/forum/showthread.php?p=3648



Ранг: 251.3 (наставник), 81thx
Активность: 0.140.11
Статус: Участник

Создано: 11 декабря 2008 18:36
· Личное сообщение · #5

WinAPI UpdateResource(), а там хоть на ассемблере пиши
msdn.microsoft.com/en-us/library/ms648008(VS.85).aspx



Ранг: 11.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 11 декабря 2008 19:01 · Поправил: mindkeeper
· Личное сообщение · #6

Большое спасибо.
Ray, мне нужно именно самостоятельно и программно (AVE прав), не буду вдаваться в подробности почему.
cppasm Сначала попробую эту DLL по ссылке, которую Dr3d дал. Там в форуме есть указание автора, что почему то эта ф-я API отказывалась работать у него из dephi, поэтому он на сях сделал, а из delphi просто вызывал.
О результате отпишусь, мало ли, кому еще пригодится.



Ранг: 11.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 12 декабря 2008 00:19 · Поправил: mindkeeper
· Личное сообщение · #7

Получилось просто отлично, таки пошел по пути самостоятельного внедрения UpdateResource и всего, что к нему причитается. Вобще с ресурсами раньше особо не работал, максимум читал курсоры и строки, а тут оказалось все так просто, правда немного пришлось догадываться что к чему. По итогу: у меня в ресурсах одного EXE сидит другой, и целая куча ресурсов к нему на выбор пользователя... экстрактится "внутренний" EXE (я кго еще и упаковал для экономии места), к нему пришиваются необходимые MAINICON, RCDATA. Вот примерчик замены ресурсов из моей тупенькой прожки:
Code:
  1. procedure UpdateIcons(const FileName, IcoFileName: String);
  2. type
  3.   PIcoItemHeader = ^TIcoItemHeader;
  4.   TIcoItemHeader = packed record
  5.     Width: Byte;
  6.     Height: Byte;
  7.     Colors: Byte;
  8.     Reserved: Byte;
  9.     Planes: Word;
  10.     BitCount: Word;
  11.     ImageSize: DWORD;
  12.   end;
  13.   PIcoItem = ^TIcoItem;
  14.   TIcoItem = packed record
  15.     Header: TIcoItemHeader;
  16.     Offset: DWORD;
  17.   end;
  18.   PIcoHeader = ^TIcoHeader;
  19.   TIcoHeader = packed record
  20.     Reserved: Word;
  21.     Typ: Word;
  22.     ItemCount: Word;
  23.     Items: array [0..MaxInt shr 4 - 1] of TIcoItem;
  24.   end;
  25.   PGroupIconDirItem = ^TGroupIconDirItem;
  26.   TGroupIconDirItem = packed record
  27.     Header: TIcoItemHeader;
  28.     Id: Word;
  29.   end;
  30.   PGroupIconDir = ^TGroupIconDir;
  31.   TGroupIconDir = packed record
  32.     Reserved: Word;
  33.     Typ: Word;
  34.     ItemCount: Word;
  35.     Items: array [0..MaxInt shr 4 - 1] of TGroupIconDirItem;
  36.   end;
  37.   function IsValidIcon(P: Pointer; Size: Cardinal): Boolean;
  38.   var
  39.     ItemCount: Cardinal;
  40.   begin
  41.     Result := False;
  42.     if Size < Cardinal(SizeOf(Word) * 3) then
  43.       Exit;
  44.     if (PChar(P)[0] = 'M') and (PChar(P)[1] = 'Z') then
  45.       Exit;
  46.     ItemCount := PIcoHeader(P).ItemCount;
  47.     if Size < Cardinal((SizeOf(Word) * 3) + (ItemCount * SizeOf(TIcoItem))) then
  48.       Exit;
  49.     P := @PIcoHeader(P).Items;
  50.     while ItemCount > Cardinal(0) do begin
  51.       if (Cardinal(PIcoItem(P).Offset + PIcoItem(P).Header.ImageSize) < Cardinal(PIcoItem(P).Offset)) or
  52.         (Cardinal(PIcoItem(P).Offset + PIcoItem(P).Header.ImageSize) > Cardinal(Size)) then
  53.         Exit;
  54.       Inc(PIcoItem(P));
  55.       Dec(ItemCount);
  56.     end;
  57.     Result := True;
  58.   end;
  59. var
  60.   H: THandle;
  61.   M: HMODULE;
  62.   R: HRSRC;
  63.   Res: HGLOBAL;
  64.   GroupIconDir, NewGroupIconDir: PGroupIconDir;
  65.   I: Integer;
  66.   wLanguage: Word;
  67.   FS:TFileStream;
  68.   Ico: PIcoHeader;
  69.   N: Cardinal;
  70.   NewGroupIconDirSize: LongInt;
  71. begin
  72.   if Win32Platform <> VER_PLATFORM_WIN32_NT then
  73.     ShowMessage('Only supported on Windows NT and above');
  74.   Ico := nil;
  75.   try
  76.     { Load the icons }
  77.     fs:=TFileStream.Create(IcoFileName,fmOpenRead,fmShareDenyWrite);
  78.     try
  79.       N:=fs.Size;
  80.       if Cardinal(N) > Cardinal($100000) then  { sanity check }
  81.         ShowMessage('Icon file is too large');
  82.       GetMem(Ico, N);
  83.       fs.Read(Ico^,N);
  84.     finally
  85.         fs.Free;
  86.     end;
  87.     { Ensure the icon is valid }
  88.     if not IsValidIcon(Ico, N) then
  89.       ShowMessage('Icon file is invalid');
  90.     { Update the resources }
  91.     H := BeginUpdateResource(PChar(FileName), False);
  92.     if H = 0 then
  93.       ShowMessage('BeginUpdateResource failed (1)');
  94.     try
  95.       M := LoadLibraryEx(PChar(FileName), 0, LOAD_LIBRARY_AS_DATAFILE);
  96.       if M = 0 then
  97.         ShowMessage('LoadLibraryEx failed (1)');
  98.       try
  99.         { Load the 'MAINICON' group icon resource }
  100.         R := FindResource(M, 'MAINICON', RT_GROUP_ICON);
  101.         if R = 0 then
  102.           ShowMessage('FindResource failed (1)');
  103.         Res := LoadResource(M, R);
  104.         if Res = 0 then
  105.           ShowMessage('LoadResource failed (1)');
  106.         GroupIconDir := LockResource(Res);
  107.         if GroupIconDir = nil then
  108.           ShowMessage('LockResource failed (1)');
  109.         { Delete 'MAINICON' }
  110.         wLanguage:=GetSystemDefaultLangID;
  111.         //if not GetResourceLanguage(M, RT_GROUP_ICON, 'MAINICON', wLanguage) then
  112.         //  Error('GetResourceLanguage failed (1)');
  113.         if not UpdateResource(H, RT_GROUP_ICON, 'MAINICON', wLanguage, nil, 0) then
  114.           ShowMessage('UpdateResource failed (1)');
  115.         { Delete the RT_ICON icon resources that belonged to 'MAINICON' }
  116.         for I := 0 to GroupIconDir.ItemCount-1 do begin
  117.           wLanguage:=GetSystemDefaultLangID;
  118.           if not UpdateResource(H, RT_ICON, MakeIntResource(GroupIconDir.Items[I].Id), wLanguage, nil, 0) then
  119.             ShowMessage('UpdateResource failed (2)');
  120.         end;
  121.         { Build the new group icon resource }
  122.         NewGroupIconDirSize := 3*SizeOf(Word)+Ico.ItemCount*SizeOf(TGroupIconDirItem);
  123.         GetMem(NewGroupIconDir, NewGroupIconDirSize);
  124.         try
  125.           { Build the new group icon resource }
  126.           NewGroupIconDir.Reserved := GroupIconDir.Reserved;
  127.           NewGroupIconDir.Typ := GroupIconDir.Typ;
  128.           NewGroupIconDir.ItemCount := Ico.ItemCount;
  129.           for I := 0 to NewGroupIconDir.ItemCount-1 do begin
  130.             NewGroupIconDir.Items[I].Header := Ico.Items[I].Header;
  131.             NewGroupIconDir.Items[I].Id := I+1; //assumes that there aren't any icons left
  132.           end;
  133.           { Update 'MAINICON' }
  134.           for I := 0 to NewGroupIconDir.ItemCount-1 do
  135.             if not UpdateResource(H, RT_ICON, MakeIntResource(NewGroupIconDir.Items[I].Id), 1033, Pointer(DWORD(Ico) + Ico.Items[I].Offset), Ico.Items[I].Header.ImageSize) then
  136.               ShowMessage('UpdateResource failed (3)');
  137.           { Update the icons }
  138.           if not UpdateResource(H, RT_GROUP_ICON, 'MAINICON', 1033, NewGroupIconDir, NewGroupIconDirSize) then
  139.             ShowMessage('UpdateResource failed (4)');
  140.           {### myURL ###}
  141.           if not UpdateResource(H,RT_RCDATA,'URL',wLanguage,addr(ch),1024) then
  142.             ShowMessage('Fck... cannot write URL');
  143.         finally
  144.           FreeMem(NewGroupIconDir);
  145.         end;
  146.       finally
  147.         FreeLibrary(M);
  148.       end;
  149.     except
  150.       EndUpdateResource(H, True); { discard changes }
  151.       raise;
  152.     end;
  153.     if not EndUpdateResource(H, False) then
  154.       ShowMessage('EndUpdateResource failed');
  155.   finally
  156.     FreeMem(Ico);
  157.   end;
  158. end;





Ранг: 748.2 (! !), 390thx
Активность: 0.370
Статус: Участник
bytecode!

Создано: 12 декабря 2008 04:22 · Поправил: 4kusNick
· Личное сообщение · #8

Я как-то на сях для себя либу написал для работы с ресурсами и юзаю ее наздоровье откуда угодно, в том числе из-под делфи.

Code:
  1. // ResDll.cpp : Defines the entry point for the DLL application.
  2. //
  3. #include "stdafx.h"
  4. #define WINAPI __stdcall
  5. BOOL APIENTRY DllMain( HANDLE hModule, 
  6.                        DWORD  ul_reason_for_call, 
  7.                        LPVOID lpReserved
  8.                                     )
  9. {
  10.          return TRUE;
  11. }
  12. bool WINAPI ReplaceResource(PCHAR sSource,PCHAR sDest,PCHAR sType,PCHAR sName)
  13. {
  14.          // Переменные для чтения и добавления ресурса
  15.          HANDLE hFile;
  16.          DWORD dwFileSize,      
  17.                  dwBytesRead;
  18.          LPBYTE lpBuffer;
  19.          // Открываем файл для дальнейшего чтения
  20.          hFile = CreateFile(sSource,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NO RMAL,NULL);
  21.          // Если открыть не удалось, то выходим
  22.          if(hFile == INVALID_HANDLE_VALUE) return FALSE;
  23.          // Сохраняем его размер
  24.          dwFileSize = GetFileSize(hFile, NULL);
  25.          // Если не удалось получить размер, то выходим
  26.          if(dwFileSize <= NULL)
  27.          {
  28.                  // Закрываем хендл файла
  29.                  CloseHandle(hFile);
  30.                  return FALSE;
  31.          }
  32.          // Создаём массив для чтения файла
  33.          lpBuffer = new BYTE[dwFileSize];
  34.          if (ReadFile(hFile,lpBuffer,dwFileSize,&dwBytesRead,NULL) != FALSE)
  35.          {
  36.                  HANDLE hResource;
  37.                  hResource = BeginUpdateResource(sDest,FALSE);
  38.                  if (NULL != hResource)
  39.                  {
  40.                         if (UpdateResource(hResource,sType,sName,0,(LPVOID)lpBuffer,dwFileSize)!= FALSE)
  41.                         {
  42.                               EndUpdateResource(hResource, FALSE);
  43.                         }
  44.                  }
  45.          }
  46.          delete [] lpBuffer;
  47.          CloseHandle(hFile);
  48.          return true;
  49. }


Когда пробовал адаптировать код под делфю - выходило херово, в некоторых случаях бились exeшки, а при юзаньи либы - не былись, так и забил переписывать под паскаль.

-----
Флэш, ява, дотнет - на завтрак, обед и ужин. Unity3D на закуску.




Ранг: 11.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 12 декабря 2008 10:31
· Личное сообщение · #9

4kusNick пишет:
Я как-то на сях для себя либу написал для работы с ресурсами и юзаю ее наздоровье откуда угодно, в том числе из-под делфи.
...
Когда пробовал адаптировать код под делфю - выходило херово, в некоторых случаях бились exeшки, а при юзаньи либы - не былись, так и забил переписывать под паскаль.

В том-то и дело - цель была сделать все единым exe и в делфях, без дополнительных dll и вобще файлов любого типа. Поэтому все, что надо, включил в свои ресурсы (строго говоря, и эту dll можно было включить, но так хотелось заставить делфи нормально понимать api). А тупо переписывать из исходника на сях в паскаль не так-то просто, приведение типов и структур до нервного тика может довести (убедился, когда пытался самостоятельно в паскале вкрутить Canon SDK - у них то только 1 пример, и то только с использованием Microsoft Foundation Classes...). В общем, формула msdn+google+brain все же действует



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 12 декабря 2008 12:42 · Поправил: progopis
· Личное сообщение · #10

mindkeeper
Здесь сорцы моего любимого редактора (Delphi 2006).
http://www.wilsonc.demon.co.ukd10resourceeditor.htm http://www.wilsonc.demon.co.uk/d10resourceeditor.htm
Из минусов - отсутствует поиск. Из плюсов - побеждает файлы после распаковки, в то время как тот же ResHack сначала хочет чтобы ресурсы пофиксили.

Да, забыл. XN Resource Editor называется.



Ранг: 28.7 (посетитель)
Активность: 0.020
Статус: Участник

Создано: 12 декабря 2008 15:46
· Личное сообщение · #11

progopis
Resource Tuner тоже вполне неплохо справляется с файлами после распаковки.
Но за XN Resource Editor спасибо.Боекомплект пополнен



Ранг: 41.9 (посетитель), 3thx
Активность: 0.040
Статус: Участник

Создано: 12 декабря 2008 20:07
· Личное сообщение · #12

Меня прёт PE Explorer https://nova-forum.com/topic.cgi?forum=35&topic=2300&glp



Ранг: 11.1 (новичок)
Активность: 0=0
Статус: Участник

Создано: 17 декабря 2008 11:05
· Личное сообщение · #13

Всем спасибо, закрываю.


 eXeL@B —› Программирование —› Работа с ресурсами PE-exe
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати