Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Delete resources of other EXE

Posted on 2002-06-24
18
Medium Priority
?
425 Views
Last Modified: 2010-04-04
Hey all,

I want to build a program that will delete the resources of another EXE file.
Meaning, i want program A to delete program B's resources like cursors(all), Bitmap Folder and String Table numbers like 3851, 4094 and so on.

Like other programs (like Resource Hacker) are doing but i want it to be done automatically.

A. How to do it...?
B. Are the strings in the String Table always the same.
What i mean is if String number 3829 contain "X" - will it ALWAYS contain "X" ?

Please give a good code example.

ThanX
0
Comment
Question by:ebi1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 7
  • 3
  • +1
18 Comments
 
LVL 3

Expert Comment

by:Slavak
ID: 7106709
If you want delete all resources from the file, you can use:
  H := BeginUpdateResource(FileName, True);
  EndUpdateResource(H, False);


 
0
 
LVL 3

Expert Comment

by:smurff
ID: 7107057
listening
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7110467
ebi1,

You can use this code for Win2000/NT/XP:
(place Button and OpenDialog on the form)

procedure TForm1.Button1Click(Sender: TObject);
var
  h: THandle;
  Victim: String;
begin
  // Resource name:
  Victim:='MYBMP';
  OpenDialog1.Filter:='Executible files|*.EXE;*.DLL';
  if not OpenDialog1.Execute then Exit;
  h := BeginUpdateResource(PChar(OpenDialog1.FileName), LongBool(FALSE));
  if h <> 0 then
    if not UpdateResource(h,                // Resource handle
                          RT_BITMAP,        // Resource type
                          PChar(Victim),    // Resource name
                          LANG_NEUTRAL,     // Language
                          nil, 0) then      // Delete resource
       begin
         MessageDlg('Oops: '+IntToStr(GetLastError), mtError, [mbOk], 0);
         EndUpdateResource(h, LongBool(TRUE));
       end
       else EndUpdateResource(h, LongBool(FALSE))
  else EndUpdateResource(h, LongBool(TRUE));
end;



This example is for RT_BITMAP type, but you can
replace it with whatever type you like. Available
types are listed in WinAPI help; search for
UpdateResource function.

Also, if you don't know names of the exe resources,
I can post some code that enumerates resources.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:ebi1
ID: 7119329
Hey there,

sorry about the delay.

can you also answer about question B of the same question?
"
B. Are the strings in the String Table always the same?
What i mean is if String number 3829 contain "X" - will it ALWAYS contain "X" ?
"

Cynna, if RT_BITMAP is for Bitmaps, what are the names for Icons, StringTables and so on...?

ThanX
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119643
What you mean "always"?
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119649
There is constants for starndard resources:


RT_ACCELERATOR     Accelerator table
RT_ANICURSOR     Animated cursor
RT_ANIICON     Animated icon
RT_BITMAP     Bitmap resource
RT_CURSOR     Hardware-dependent cursor resource
RT_DIALOG     Dialog box
RT_FONT             Font resource
RT_FONTDIR     Font directory resource
RT_GROUP_CURSOR     Hardware-independent cursor resource
RT_GROUP_ICON     Hardware-independent icon resource
RT_ICON             Hardware-dependent icon resource
RT_MENU             Menu resource
RT_MESSAGETABLE     Message-table entry
RT_RCDATA     Application-defined resource (raw data)
RT_STRING     String-table entry
RT_VERSION     Version resource
0
 

Author Comment

by:ebi1
ID: 7119726
Hey Slavak,

For example :

Entry 3829 from the String Table (RT_STRING) shows:"
STRINGTABLE
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
{
61254,      "Details"
61255,      "Could not load '%s' library"
61256,      "File specified is not an executable file, dynamic-link library, or icon file"
61257,      "Function not yet implemented"
61258,      "Previous Month|"
61259,      "Previous Year|"
61260,      "Next Month|"
61261,      "Next Year|"
61262,      "Select a Date"
61263,      "All files (*.*)|*.*"
}
"

So will 3829 ALWAYS contain the SAME text?

ThanX
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119728
Always for same executable file.
0
 

Author Comment

by:ebi1
ID: 7119739
I wrote about 3829 but i mean for all other resource types.

Cynna gave the code for Win 2k/NT/XP and for Bitmaps, so what is the code for Win 9x/ME and how do i delete resources for other types like RT_GROUP_CURSOR?
can i delete all RT_GROUP_CURSOR together and not 1 after the other for the same type?

I don't want to delete ALL the resources.

ThanX
0
 

Author Comment

by:ebi1
ID: 7119741
Hey Slavak,

You said :"Always for same executable file"

Does it means that 3829 (for example) will be different in other EXE...?
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119742
If you don't want delete all resources from the file, you should enumerate them and delete one by one like in Cynna comment.

Windows API functions for update file resources works only on Win NT/2000 systems. If you want it on Win 9x system it much more difficult. You can look in Delphi ResExplor example to see, how to READ the resources without API.
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119746
--- Does it means that 3829 (for example) will be different in other EXE...?

Sure, all executables have its own resources. But, for example, if you check programs from same compiler, you can find some common resources.  
0
 

Author Comment

by:ebi1
ID: 7119773
What's with the ResExplor? everytime i try to open a file i get a message "range check error"...
Does it also show how to delete a type in a resouce?

I didn't understand your last comment:
Did you meant that if i see 2 programs made on different compilers but both have resource number 4091(for the example) then 4091 on compiler A will look different then 4091 on compiler B...?

ThanX
0
 
LVL 3

Expert Comment

by:Slavak
ID: 7119776
You can get it on same compiler too.

Generally, different executable files have DIFFERENT
resources.

"ResExplor" delphi demo project that can read and show resources stored in the executable files not using Windows API.

Regards.
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7120231
ebi1,


> B. Are the strings in the String Table always the same?

Yes they are, for the same exe file. Different exe's and dll's have different resources.
If they happen to be the same to a degree, it's a matter of luck, not a rule.




> Cynna gave the code for Win 2k/NT/XP and for Bitmaps, so what is the code for Win 9x/ME...

For Win9x/ME, my advice is: forget it.

Deleting/replacing resources for Win9x/ME requires you to hack into exe file itself.
This requires knowledge of PE file format, which is a whole different story. This
subject is a *much* more complex matter then doing it in NT based systems.




> ... can i delete all RT_GROUP_CURSOR together and not 1 after the other for the same type?

Well, directly (using dedicated API) - no. You can delete only one resource at the time.

But, there is a workaround: you iterate through all resources of the RT_GROUP_CURSOR
type, and delete them. You can use EnumResourceNames() function, with RT_GROUP_CURSOR type.
You'll get the names of all resources of this type in a callback function, one by one.
There you can call code I posted previously, or simply save them and delete them later.
If you get stuck with enumeration, I could write you a simple example.
0
 

Author Comment

by:ebi1
ID: 7120561
Yes Cynna, please give me an example.

Cynna and Slavak you have been VERY helpful so i want to give you both the credit/points

Thank you
0
 
LVL 7

Accepted Solution

by:
Cynna earned 1000 total points
ID: 7121509
OK, I wrote a little example.
Place 2 Buttons and Memo on the form.

Copy/Paste:
----------------------

function EnumResNames(hMod: THandle; ResType, ResName: PChar; MemoLines:TStrings ): BOOL; stdcall;
// Callback function used to store name of each resource in Memo1.
// EnumResourceNames(..) calls this function each time it encounters RT_GROUP_CURSOR.
// We are interested in ResName, because we'll delete them later by name.
begin
  if (ResName<>'') then begin
     MemoLines.Add(ResName); // For now, store name in Memo1
     Result:=TRUE;
  end else Result:=FALSE;
end;

procedure TForm1.Button1Click(Sender: TObject);
// Enumerate resources and place them in Memo1
var ExeName: String;
    ResourceType: PChar;
    h: HModule;
begin
  // For example (adjust these to your needs...):
  ExeName:='C:\Program Files\Delphi5\Projects\testing\General testing\bla.exe';
  ResourceType:=RT_GROUP_CURSOR;
  // Get exe file handle:
  h:=LoadLibrary(PChar(ExeName));
  if h <> 0 then begin
     // Enumerate all resources of type RT_GROUP_CURSOR, and put their names in Memo1:
     Memo1.Clear;
     EnumResourceNames(h, ResourceType, @EnumResNames,Integer(Memo1.Lines));
     FreeLibrary(h);
  end;
end;


procedure TForm1.Button2Click(Sender: TObject);
// Delete all resources named in Memo1
var i,j: Integer;
    h: THandle;
    ExeName: String;
    ResourceType: PChar;
begin
  // For example (adjust these to your needs...):
  ExeName:='C:\Program Files\Delphi5\Projects\testing\General testing\bla.exe';
  ResourceType:=RT_GROUP_CURSOR;
  // Delete them one by one:
  for i:=0 to Memo1.Lines.Count-1 do begin
       h := BeginUpdateResource(PChar(ExeName), LongBool(FALSE));
       if h <> 0 then begin
          // Delete resource with name stored in Memo1.Lines.Strings[i]:
          if not UpdateResource(h,
                             ResourceType,
                             PChar(Memo1.Lines.Strings[i]),
                             LANG_NEUTRAL,
                             nil, 0) then
          begin // Error
             MessageDlg('Oops: '+IntToStr(GetLastError), mtError, [mbOk], 0);
             // Don't write changes:
             EndUpdateResource(h, LongBool(TRUE));
             Memo1.Lines.Strings[i]:=Memo1.Lines.Strings[i]+' - error deleting !'
          end
          else begin // deleted OK
             // Write changes:
             EndUpdateResource(h, LongBool(FALSE));
             Memo1.Lines.Strings[i]:=Memo1.Lines.Strings[i]+' - deleted OK.'
          end;
       end
       else // h=0 - don't write changes:
       EndUpdateResource(h, LongBool(TRUE));
   end;
end;




Notes:
--------------

1. This is just general example, change it to your
   specific needs. As a minimum, you should change ExeName
   variable in both procedures.

2. First click on Button1, to get resource names, and
   then on Button2. This will delete all resources listed
   in Memo1.

3. So, I divided deletion logic in 2 steps. You could
   encapsulate it in one function if it suits you better.
0
 

Author Comment

by:ebi1
ID: 7123631
Thank you Cynna.

You REALY helped me a lot.

Eitan
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question