Thread: Programmatically add resources to exe file

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    244

    Programmatically add resources to exe file

    hi!

    i have a question, which i couldn't get the answer of yet. i have a c# exe with a resource file named file.txt (0 bytes). another executable file should access this file and compile a "file.txt" into the first one programmatically...
    note: this will change the size of the executable, so it must be expanding and not fixed-size...

    does anyone know how to do this?
    thanks in advance

  2. #2
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Exe & data block generation

    It's for C++ but you should get the idea. Read the whole thread.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    i've read it...
    the idea of putting a pattern at the end of the file followed by the data is not bad, but still not satisfying enought tho...
    the other idea was a fixed size resource, but that would limit my app to a specific size...

    the good idea was the "UpdateResource" stuff, but i don't quite get how to use this in C# to set an executable's resource...
    any ideas or references (examples) on that?

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    In C# you use the Platform Invocation Services through PInvoke() to call in WinAPI functions. I'm still learning C# and haven't dabble on this yet. But that's pretty much how you would import these functions.

    There's, I believe, plenty of tutorial material on the web. There's also a centralized resource at pinvoke.net: the interop wiki! where you can get the necessary import declarations to your code. For instance, this is the declaration for UpdateResource: pinvoke.net: UpdateResource (kernel32) (btw, if you ever try their little tool for VS2008 and get it to work, let me know. I cannot seem to get it to work)

    However, let me tell you I solved the problem by simply appending the data to the executable at runtime. The only thing I needed to make sure was that the data had a recognizable header (of which format I defined myself) I could later use for proper unmarshalling. There was no need to get into the WinAPI and depending on your specifics, hardly you will need to do it under C# either.

    Why you feel this is not satisfying?
    Last edited by Mario F.; 12-04-2009 at 01:28 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    Code:
    [DllImport("kernel32.dll", SetLastError=true)]
    static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
    so how do i actually use this? what parameters do i have to pass?

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    The information is there along with links to the respective MSDN documentation. Note you will also need BeginUpdateResource and EndUpdateResource. But that's also described there.

    As for any other specifics, I don't know. Study the documentation and try stuff. That's the way with the WinAPI, i'm afraid.

    IntPtr hUpdate -> handle to a BeginUpdateResource instance.
    string lpType -> Pointer to a C-style string with the name of the resource type, or one of the following constants: Resource Types
    string lpName - > duh! The resource name
    ushort wLanguage -> The language identifier (Language Identifiers (Windows))
    IntPtr lpData -> Pointer to the actual resource
    uint cbData -> Size in bytes of the resource

    Regarding lptype, pass it a c-style string of your own or RT_RCDATA if the resource type is not one of the resources defined in the Resources Types link. Otherwise, the function will try to validate the resource format and will fail.
    Last edited by Mario F.; 12-04-2009 at 03:14 PM.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    i put this together:
    Code:
    private void Form1_Load(object sender, EventArgs e)
    		{
    			File.Copy("test - Kopie.exe", "test.exe", true);
    			IntPtr handle = BeginUpdateResource("test.exe", false);
    			byte[] file = new byte[3]; file[0] = 65; file[1] = 66; file[2] = 67;
    			IntPtr fileptr = ToPtr(file);
    			bool res = UpdateResource(handle, "RT_RCDATA", "test.exe", 0, fileptr, Convert.ToUInt32(file.Length));
    			EndUpdateResource(handle, false);
    		}
    
    		unsafe private IntPtr ToPtr(byte[] buffer)
    		{
    			fixed (byte* ptr = buffer)
    			{
    				return (IntPtr)ptr;
    			}
    		}
    
    		[DllImport("kernel32.dll", SetLastError = true)]
    		static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
    		[DllImport("kernel32.dll", SetLastError = true)]
    		static extern IntPtr BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)]bool bDeleteExistingResources);
    		[DllImport("kernel32.dll", SetLastError = true)]
    		static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
    which creates a file in the resources of test.exe. resource hacker can even find this file, althoug it never finds any .NET assembly resources???
    anyway, it is not beeing recognized by the code of test.exe...
    could it be that resources from executables are different/other than the ones i can define in visual studio? if so, all this was for the toilet... ;(

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    In C# you use the Platform Invocation Services through PInvoke() to call in WinAPI functions. I'm still learning C# and haven't dabble on this yet. But that's pretty much how you would import these functions.
    That's one way of doing it but it is quite clunky. You can also create a C++/CLI ref class that encapsulates some of the API functions you wish to call. The C++/CLI code can talk to both .NET objects and to native objects. This makes it a perfect go-between for native and non-native code.

    Once you have your C++/CLI DLL you simply add it as a reference in your C# app and you can now access the code. To communicate the other way around you can add the C# exe or DLL as a reference to your C++/CLI project and access its code by a using statement. Once everything is in place you can freely communicate back and forth between native and non-native and there are no ugly C DLLs and the code to use it is very simple.

    If you are going to go this route keep in mind you will have to use .NET data types in your C++/CLI interface to talk to C# and you will use native types that will be converted to .NET types for communication the other direction.

    But in C++/CLI you can create any ref class you want and and even return it to C# as a managed pointer (MyObject ^object) provided there are no native objects in it. One big gotcha is you cannot have any STL objects or native data members in the C++/CLI ref class. But this can be worked around easily enough using the PIMPL idiom. There are some other gotchas but overall it's very nice and you can do some very cool things with it. I do not recommend trying to pass native objects to C# or managed objects to native code. Your C++/CLI interface and impl should be the mediator between the two pieces of code. Remember any cool .NET stuff you can access in C# you can also access from C++/CLI. The only difference between the two pieces of code is the syntax of the language that is using .NET. On an interesting side note your C++/CLI DLL can also be accessed from a VB project that is .NET compatible. Essentially any language that supports .NET on the Windows platform will be able to talk to your C++/CLI DLL.

    C# <------> C++/CLI <-------> C/C++
    Last edited by VirtualAce; 12-04-2009 at 05:55 PM.

  9. #9
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    well, i'm not so much into c++ and as you see the code above, i managed to add a resource to the c# exe. unfortunately it seems like PE resources and c#-executable-resources are not the same... resource hacker can't find any c# resources for example...

  10. #10
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by Devils Child View Post
    well, i'm not so much into c++ and as you see the code above, i managed to add a resource to the c# exe. unfortunately it seems like PE resources and c#-executable-resources are not the same... resource hacker can't find any c# resources for example...
    C# executables are not created with the PE format. When you create a C# binary (exe or dll) you define an assembly. Despite sharing the same file extension with regular PE binaries .net assemblies are vastly different. They are composed of CIL code (and not platform specific bytecode as is the case with your regular PE), plus any metadata necessary to describe its contents and itself.

    In order to have access to a .net assembly resources, you'll need to use programs that understand the .net assembly format. The bits of the PE format that remain in a .Net assembly actually could help you locate the resources inside a .net assembly. But its cumbersome. So you can still use a PE reader to find those resources location.

    Asmex claims to be able to locate and extract .net assembly resources. Of course, because your resources were inserted through UpdateResource, instead of normal C# language features, I'm unsure as to what the results will be.

    ...

    Meanwhile, I decided to explore a little more about this (thanks Bubba. C++<->CIL seems a much more elegant solution).

    This is what came up after only a few seconds searching:
    Embedding and Using Resources in C#
    If this doesn't answer your problem, I don't know what will.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  11. #11
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    ok, so it seems i'm not gonna get any further this way. i added a pattern at the end of the file and written the data i nedded after that pattern. not a 100% clean solution, but works.

    edit: if the data is too long, it is recognized as TR/Dropper.Gen , which is not good-.-(thats one of the reasons i want to write it into the resource)
    idea: maybe add it as PE resource and read it from C# somehow (but how??)

    what i also need to do is to change the icon of the executable programmatically, which i tried with the code above but i didn't make any success ;(
    my icon appeared in ResourceHacker as a binary file, but couldnt been displayed and neither did explorer do...
    so how do i use the fortress we made yet to embedd an exe icon?
    Last edited by Devils Child; 12-05-2009 at 10:52 AM.

  12. #12
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    UPDATE:
    i managed to add a PE resource to the file. the resource starts with my secret search pattern and is followed by my data.
    then, instead of reading the PE resource (not c# resource) off the file, i search the pattern inside the resource like i did before and boom - there i have the data and it's not recognized as a trojan dropper anymore!

    thanks so far

    one problem solved, but how do i set the executables icon now with that code?

  13. #13
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Keep in mind that you would probably never want to do this in released code. It is far too prone to hackers and the like. You can officially embed resources into an EXE via the resource editor in Visual Studio and the format is one that Windows API calls understand and can read. This is a perfect way to embed icons, localization text strings, and other simple resources.

  14. #14
    Registered User
    Join Date
    Jan 2008
    Posts
    244
    did you read the first post? it described that one application must embedd an icon and a file into another application. i managed the file via resources that is beeing read by using a unique search pattern. when just adding stuff at the end of the executable, it is beeing recognized as trojan/dropper.gen... so how do i embedd the icon now?

    edit: maybe it's a good idea to just call a specific executable found on the web like
    Code:
    iconbinder.exe -b test.exe test.ico
    does anything like this exists?
    Last edited by Devils Child; 12-06-2009 at 07:33 AM.

  15. #15
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Quote Originally Posted by Devils Child View Post
    did you read the first post?
    I would say he has. But it doesn't seem you have been reading the answers or just don't like to click the links being provided.

    The answer to that was already given in the form of a link. Read the thread again.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM
  5. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM