Thread: Modifying info on Exe & Dll's

  1. #1
    Registered User
    Join Date
    Aug 2001
    Posts
    19

    Modifying info on Exe & Dll's

    Could anyone point me to some code on altering fields such as "Company Name" & "File version" for PE format files.

    I am looking to set this information to overcome some short coming in an inventory product, NOT! to do any thing dodgy.

    Thanks..

    JD..

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You could parse the PE file for the resources section.
    Then only within that section you coud search for a known unicode string (the company name) and replace it. This is a hack of course so you'll have to replace it with something of equal size (padded with spaces).

    If you don't do hacks, then go the next step and learn the PE resource format.

    Please re-post if you come up with something (I'd like to know the PE resource format myself).

    gg

  3. #3
    Registered User
    Join Date
    Aug 2001
    Posts
    19
    After researching the Win API and finding on no fucntion to do this, that is exactly what I tried.

    It does not work however as the file is checksummed and complains - "Not a valid win32 application"


    JD...

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Awsome.

    Well, we just need some documentation on the PE resource section format (including the checksum method).

    I'll keep looking later tonight.

    gg

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227

    Re: Modifying info on Exe & Dll's

    Originally posted by johnd
    Could anyone point me to some code on altering fields such as "Company Name" & "File version" for PE format files.
    JD..
    These look to be parts of a VERSIONINFO resource so this msdn page may be of some use to you in that regard.
    Originally posted by Codeplug
    some documentation on the PE resource section format
    The Matt Pietrak msdn article you linked to is pretty good and this article gives details on using IMAGEHLP.DLL functionality ( msdn: imagehlp ) ; CheckSumMappedFile may be of some use regarding the checksum issue.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  6. #6
    .
    Join Date
    Nov 2003
    Posts
    307
    On www.galahtech.com in the VB forums, there is an extensive set of tutorials on PE formats, functions like GetVersionInfo, etc.

    UNfortunately, it is discussed in VB. But it has what you need.

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Well I started digging into PE resource formats and found a PE resource editor implemted in Delphi (with source).
    I also found another MSDN article on the PE format.
    Then after reading more closely, I realized that the structures described here actually describe the binary format of a version resource. It would probably take more research to get anything usefull out of it though.

    Then it smacked me right in the face while I was reading some code online:
    BeginUpdateResource()
    UpdateResource()
    EndUpdateResource()
    (As Ken has already posted.)

    The example code on MSDN shows how to copy resources from one file to another - should work with a version resource too.

    gg

  8. #8
    Registered User
    Join Date
    Aug 2001
    Posts
    19
    Many thanks for the helpful information.

    I have tryed the following code. It does insert the company name into the exe, but also padded the file out with PADDXXPADDEDXX right to the end of the file. The file still runs but all information is lost. I found one other person reporting this problem in google. without any response.

    Code:
    #include "stdafx.h"
    #include "windows.h"
    
    HANDLE hExe;   
    HANDLE hResource;
    BOOL Result;
    WCHAR FIELD;
    LPSTR CompanyName= ("\0\0\0company");
    // also tryed CompanyName=("Company")
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    
    BOOL filecopy = CopyFile("c:\\filever\\orgstring.exe",
    		"c:\\filever\\string.exe",
    		FALSE);
    
    // orgstring.exe in an undamaged file this version info intact
    
    
    hResource = BeginUpdateResource ("c:\\filever\\string.exe", TRUE);
    
    if (hResource == NULL)
    {
    printf("could not open file");
    }
    
    Result = UpdateResource(hResource,					RT_VERSION,
    		"CompanyName",
    		MAKELANGID(LANG_NEUTRAL,
    SUBLANG_NEUTRAL),  
    		CompanyName,
    							
    							32);   //also tryed sizeof(CompanyName) here 
    
    
    
    
    
    
    
    
    	if (Result == 0)
    	{
    		printf("UpdateResource Failed Error -%d ", Result);
    	}
    
    
    
    	Result = EndUpdateResource(hResource, FALSE);
    
    
    
    
    	if (Result == 0)
    	{
    		printf("EndUpdateResource Failed Error -%d ", Result);
    	}
    
    
    	return 0;
    }

  9. #9
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Use of the RT_VERSION flags implies a full VERSIONINFO resource. You should probably load in the existing version information, modify the data you need to (make sure all strings are UNICODE; see lpData description under UpdateResource) , ensure proper alignment and then update the resource with the amended data.

    These structures may give you some ideas on how to make sense of the existing, raw version information:

    VarFileInfo
    VS_VERSIONINFO
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I've always wanted to do this so I'm finally doing it for benefit of everyone.
    I've got the raw version resource format figured out. Here's an application that will dump the contents of a version resource.
    I'll be posting some new code later that will allow you to edit and re-form the version resource so you can use it with UpdateResource().

    You're gonna have to chew slowly to digest this.
    Code:
    //NOTE: link with version.lib
    #include <windows.h>
    
    #include <memory>
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    
    // if x isn't DWORD aligned, this will evaluate to next highest DWORD
    // boundry, otherwise evaluates to x
    #define ALIGN_UP32(x) ((((DWORD)(x)) + 3) & 0xFFFFFFFC)
    
    // cast x to a DWORD
    #define DW(x) ((DWORD)(x))
    
    // is ptr within the range: [base, base+size]
    #define PTR_WITHIN(ptr, base, size) \
        ((DW(ptr) >= DW(base)) && (DW(ptr) < (DW(base) + DW(size))))
    
    
    //-----------------------------------------------------------------------------
    // VersionInfoBase - base class for all structures representing resource 
    //                   memory layout
    //-----------------------------------------------------------------------------
    template<typename child_t>
    struct VersionInfoBase
    {
        WORD wLength; 
        WORD wValueLength; 
        WORD wType; 
        WCHAR szKey[1];
        
        // Tests if the given pointer points into this structures
        bool IsValidPtr(PVOID ptr)
        {
            return PTR_WITHIN(ptr, &wLength, wLength);
        }//IsValidPtr
    
        // Get the next adjacent version info structure. We can put this in the 
        // base class since the wLength field holds the size of the structure.
        child_t* GetNext()
        {
            return (child_t*)ALIGN_UP32((DWORD)&wLength + wLength);
        }//GetNext
    
        // This method is only valid for String_data_t and Var_data_t
        WCHAR* GetValuePtr()
        {
            return (WCHAR*)ALIGN_UP32(szKey + wcslen(szKey) + 1);
        }//GetValuePtr
    };//VersionInfoBase
    
    //-----------------------------------------------------------------------------
    // String (version information) structures
    //-----------------------------------------------------------------------------
    // String memory layout type
    struct String_data_t : public VersionInfoBase<String_data_t>
    { 
        //WCHAR szKey[1] == name of string resource
    };//String_t;
    
    // String instance type
    struct String_t 
    {
        String_data_t *data;
        WCHAR *Value;
    
        String_t(String_data_t *d)
            : data(d), Value(d->GetValuePtr()) {}
    };//String_t
    
    //-----------------------------------------------------------------------------
    // StringTable structures
    //-----------------------------------------------------------------------------
    // StringTable memory layout type
    struct StringTable_data_t : public VersionInfoBase<StringTable_data_t>
    { 
        //WCHAR szKey[9] == hex string of lang_id:code_page (040904B0)
    
        // Get a pointer to the first String child structure
        // Use IsValidPtr() and GetNext() to iterate over all String child
        // structures.
        String_data_t* GetChildrenPtr()
        {
            return (String_data_t*)ALIGN_UP32(szKey + 9);
        }//GetChildrenPtr
    };//StringTable_data_t; 
    
    // StringTable instance type
    struct StringTable_t
    {
        StringTable_data_t *data;
        String_t str;
    
        StringTable_t(StringTable_data_t *d)
            : data(d), str(d->GetChildrenPtr()) {}
    };//StringTable_t
    
    //-----------------------------------------------------------------------------
    // StringFileInfo structures
    //-----------------------------------------------------------------------------
    // StringFileInfo memory layout type
    struct StringFileInfo_data_t : public VersionInfoBase<StringFileInfo_data_t>
    { 
        //WCHAR szKey[15] == "StringFileInfo"
        
        // Is this a valid a valid memory layout for a StringFileInfo struct?
        bool IsValid() {return wcsncmp(szKey, L"StringFileInfo", 14) == 0;}
    
        // Get a pointer to the first StringTable child structure
        // Use IsValidPtr() and GetNext() to iterate over all StringTable child
        // structures.
        StringTable_data_t* GetChildrenPtr()
        {
            return (StringTable_data_t*)ALIGN_UP32(szKey + 15);
        }//GetChildrenPtr
    };//StringFileInfo_data_t; 
    
    // StringFileInfo instance type
    struct StringFileInfo_t
    {
        StringFileInfo_data_t *data;
        StringTable_t strtbl;
    
        StringFileInfo_t(StringFileInfo_data_t *d)
            : data(d), strtbl(d->GetChildrenPtr()) {}
    };//StringFileInfo_t
    
    //-----------------------------------------------------------------------------
    // Var structures
    //-----------------------------------------------------------------------------
    // Var memory layout type
    struct Var_data_t : public VersionInfoBase<Var_data_t>
    {
        //WCHAR szKey[12] == "Translation"
    
        // Is this a valid a valid memory layout for a VarFileInfo struct?
        bool IsValid() {return wcsncmp(szKey, L"Translation", 11) == 0;}
    };//Var_data_t
    
    // Var instance type
    struct Var_t
    {
        Var_data_t *data;
        DWORD *value;
    
        Var_t(Var_data_t *d) 
            : data(d), value((DWORD*)d->GetValuePtr()) {}
    };//Var_t
    
    //-----------------------------------------------------------------------------
    // VarFileInfo structures
    //-----------------------------------------------------------------------------
    // VarFileInfo memory layout type
    struct VarFileInfo_data_t : public VersionInfoBase<VarFileInfo_data_t>
    {
        //WCHAR szKey[12] == "VarFileInfo"
    
        // Is this a valid a valid memory layout for a VarFileInfo struct?
        bool IsValid() {return wcsncmp(szKey, L"VarFileInfo", 11) == 0;}
    
        // Get a pointer to the first Var child structure
        // Use IsValidPtr() and GetNext() to iterate over all Var child
        // structures.
        Var_data_t* GetChildrenPtr()
        {
            return (Var_data_t*)ALIGN_UP32(szKey + 12);
        }//GetChildrenPtr
    };//VarFileInfo_data_t
    
    // VarFileInfo instance type
    struct VarFileInfo_t
    {
        VarFileInfo_data_t *data;
        Var_t var;
    
        VarFileInfo_t(VarFileInfo_data_t *d)
            : data(d), var(d->GetChildrenPtr()) {}
    };//VarFileInfo_t
    
    //-----------------------------------------------------------------------------
    // VS_VERSIONINFO structures
    //-----------------------------------------------------------------------------
    // VS_VERSIONINFO memory layout type
    struct VS_VERSIONINFO_data_t : public VersionInfoBase<VS_VERSIONINFO_data_t>
    { 
        WCHAR pad_szKey[15]; // [1]+[15] == "VS_VERSION_INFO"
        WORD Padding1[1]; // assumes this is DWORD aligned
        VS_FIXEDFILEINFO Value[1]; // may be "empty", check wValueLength
    
        // Is this a valid a valid memory layout for a VS_VERSIONINFO struct?
        bool IsValid() {return wcsncmp(szKey, L"VS_VERSION_INFO", 15) == 0;}
    
        // Get a pointer to the first StringFileInfo child structure
        // Use IsValidPtr() and GetNext() to iterate over all StringFileInfo child
        // structures.
        StringFileInfo_data_t* GetChildrenPtr()
        {
            return (StringFileInfo_data_t*)ALIGN_UP32((DWORD)Value + (DWORD)wValueLength);
        }//GetChildrenPtr
    };//VS_VERSIONINFO_data_t
    
    // VS_VERSIONINFO instance type
    struct VS_VERSIONINFO_t
    {
        VS_VERSIONINFO_data_t *data;
        StringFileInfo_t sfi;
    
        VS_VERSIONINFO_t(PVOID d) 
            : data(reinterpret_cast<VS_VERSIONINFO_data_t*>(d)),
              sfi(data->GetChildrenPtr()) {}
    
        bool IsValid() {return data->IsValid();}
        bool IsValidPtr(PVOID ptr) {return data->IsValidPtr(ptr);}
    };//VS_VERSIONINFO_t
    
    //-----------------------------------------------------------------------------
    
    // Prints the data for a structure derived from VersionInfoBase
    template <typename vs_data_t>
    void print_vs_struct(vs_data_t *data, int tab)
    {
        char indent[32];
        int len = tab * 3;
        memset(indent, ' ', len);
        indent[len] = '\0';
    
        cout << indent << "wLength      = " << data->wLength << endl
             << indent << "wValueLength = " << data->wValueLength << endl
             << indent << "wType        = " << data->wType << endl << indent;
        wcout         << L"szKey        = " << data->szKey << endl;
    }//print_vs_struct
    
    // Helper macro used by print_ffi_struct()
    #define print_ffi_member(member) \
        cout << "   " << setw(19) << #member << "= 0x" << hex << setw(8) \
             << setfill('0') << ffi->member << setfill(' ') << endl
    
    // Print the data members of the given VS_FIXEDFILEINFO
    void print_ffi_struct(VS_FIXEDFILEINFO *ffi)
    {
        cout << "BEGIN VS_FIXEDFILEINFO" << endl;
        ios::fmtflags f = cout.setf(ios::left);
        print_ffi_member(dwSignature);
        print_ffi_member(dwStrucVersion);
        print_ffi_member(dwFileVersionMS);
        print_ffi_member(dwFileVersionLS);
        print_ffi_member(dwProductVersionMS);
        print_ffi_member(dwProductVersionLS);
        print_ffi_member(dwFileFlagsMask);
        print_ffi_member(dwFileFlags);
        print_ffi_member(dwFileOS);
        print_ffi_member(dwFileType);
        print_ffi_member(dwFileSubtype);
        print_ffi_member(dwFileDateMS);
        print_ffi_member(dwFileDateLS);
        cout.flags(f);
        cout << "END VS_FIXEDFILEINFO" << endl;
    }//print_ffi_struct
    
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    
    int main()
    {
        char filename[] = "C:\\WINNT\\system32\\USER32.DLL";
        DWORD dummy;
        DWORD ver_sz = GetFileVersionInfoSize(filename, &dummy);
    
        if (ver_sz == 0)
        {
            cerr << "GetFileVersionInfoSize() failed, error = " << GetLastError() << endl;
            return 1;
        }//if
    
        BYTE *ver_info = new BYTE[ver_sz];
        auto_ptr<BYTE> vi_ap(ver_info); // for auto deletion
    
        if (!GetFileVersionInfo(filename, 0, ver_sz, ver_info))
        {
            cerr << "GetFileVersionInfo() failed, error = " << GetLastError() << endl;
            return 2;
        }//if
    
        // construct a memory layout over the raw data (this is a good place to
        // "step-into" using your debugger)
        VS_VERSIONINFO_t vsvi(ver_info);
    
        // show the VS_FIXEDFILEINFO structure if there is one
        if (vsvi.data->wValueLength != 0)
        {
            print_ffi_struct(vsvi.data->Value);
        }//if
    
        // loop through all the StringFileInfo structures in VS_VERSIONINFO
        StringFileInfo_data_t *sfi = vsvi.sfi.data;
        while (vsvi.IsValidPtr(sfi))
        {
            if (!sfi->IsValid())
            {
                // VS_VERSIONINFO can have children of type StringFileInfo and 
                // VarFileInfo (usually StringFileInfo comes first)
                break;
            }//if
            cout << "BEGIN StringFileInfo" << endl;
            print_vs_struct(sfi, 1);
    
            // loop through all the StringTable structures in this StringFileInfo
            StringTable_data_t *strtbl = sfi->GetChildrenPtr();
            while (sfi->IsValidPtr(strtbl))
            {
                cout << "   BEGIN StringTable" << endl;
                print_vs_struct(strtbl, 2);
    
                // loop through all the String structures in this StringTable
                String_data_t *str = strtbl->GetChildrenPtr();
                while (strtbl->IsValidPtr(str))
                {
                    cout << "      BEGIN String" << endl;
                    print_vs_struct(str, 3);
                    cout << "         Value        = ";
                    if (str->wValueLength == 0) // may be empty string
                        cout << "<EMPTY>" << endl;
                    else
                        wcout << str->GetValuePtr() << endl;
                    cout << "      END String" << endl;
                    str = str->GetNext();
                }//while
    
                cout << "   END StringTable" << endl;
                strtbl = strtbl->GetNext();
            }//while
    
            cout << "END StringFileInfo" << endl;
            sfi = sfi->GetNext();
        }//while
    
        // see if there is a valid VarFileInfo child in VS_VERSIONINFO
        VarFileInfo_data_t *vfi = (VarFileInfo_data_t*)sfi;
        if (vfi->IsValid())
        {
            cout << "BEGIN VarFileInfo" << endl;
            print_vs_struct(vfi, 1);
    
            // loop through all the Var structures in this VarFileInfo
            Var_data_t *var = vfi->GetChildrenPtr();
            while (vfi->IsValidPtr(var))
            {
                cout << "   BEGIN Var" << endl;
                print_vs_struct(var, 2);
                cout << "      Value        = ";
                int len = var->wValueLength >> 2;
                DWORD *p = (DWORD*)var->GetValuePtr();
                for (int n = 0; n < len; n++)
                    cout << "0x" << hex << p[n] << ",";
                cout << endl << "   END Var" << endl;
                var = var->GetNext();
            }//while
    
            cout << "END VarFileInfo" << endl;
        }//if
        
        return 0;
    }//main
    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help displaying info from structure
    By kisiellll in forum C Programming
    Replies: 6
    Last Post: 04-04-2009, 12:51 PM
  2. Some doubts on DLLs
    By BrownB in forum Windows Programming
    Replies: 1
    Last Post: 05-30-2007, 02:25 AM
  3. Question about getting an info class from another Form
    By Joelito in forum C# Programming
    Replies: 0
    Last Post: 10-16-2006, 01:02 PM
  4. standart dlls
    By keeper in forum C++ Programming
    Replies: 3
    Last Post: 07-05-2006, 07:32 PM
  5. Help doing an e-mail program in c...
    By Tyler_Durden in forum C Programming
    Replies: 88
    Last Post: 01-02-2005, 03:12 PM