Change Icon of EXE file through code extracting it from other EXE file

Discussion in 'MFC' started by shabbir, Mar 18, 2006.

  1. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    I was a FAN of Resource hacker software and always wanted to create a software like them but one day I just thought lets make a mini version of resource hacker and so wrote a program to change the ICON of an exe or dll file. The idea came to me when I saw programs that can show you the ICONS in an executable files and so I thought if we can see them then definitely we can edit them as well. If we can edit them then there is a way to give them a different ICON to be displayed in the explorer.

    Here is the code for the same
    Code:
    void OnButtonChangeIcon() 
    {
    	CString             lpszFile;
    	CString             lpszSourceFile;
    
    	//In the sample it takes the value from the text box the URL to the source and destination file
    	m_SrcPath.GetWindowText(lpszSourceFile);
    	m_DestPath.GetWindowText(lpszFile);
    
    	HRSRC hRes;         // handle/ptr. to res. info. in hExe 
    	HANDLE hUpdateRes;  // update resource handle 
    	char *lpResLock;    // pointer to resource data 
    	HRSRC hResLoad;     // handle to loaded resource 
    	BOOL result; 
    	HMODULE hSrcExe,hDestExe;
    	int iLoop;
    
    	//Load the source exe from where we need the icon
    	hSrcExe = LoadLibrary(lpszSourceFile);
    	if(hSrcExe == NULL)
    		return;
    
    	// Locate the ICON resource in the .EXE file. 
    	for(iLoop = 1;;iLoop++)
    	{
    		CString str;
    		str.Format("#%d",iLoop);
    		hRes = FindResource(hSrcExe, str, RT_ICON); 
    		if (hRes == NULL) 
    			continue ; 
    		else if(iLoop == 10)
    			return;
    		else
    			break;
    	}
    
    	// Load the ICON into global memory. 
    	hResLoad = (HRSRC)LoadResource(hSrcExe, hRes); 
    	if (hResLoad == NULL) 
    		return ; 
    
    	// Lock the ICON into global memory. 
    	lpResLock = (char*)LockResource(hResLoad); 
    	if (lpResLock == NULL) 
    		return ; 
    
    	hDestExe = LoadLibrary(lpszFile);
    	if(hDestExe == NULL)
    		return;
    	// Locate the ICON resource in the .EXE file. 
    	for(iLoop = 1;;iLoop++)
    	{
    		CString str;
    		str.Format("#%d",iLoop);
    		if (FindResource(hDestExe, str, RT_ICON) == NULL) 
    			continue ; 
    		else if(iLoop == 10)
    			break;
    		else
    			break;
    	}
    	FreeLibrary(hDestExe);
    
    	// Open the file to which you want to add the ICON resource. 
    	hUpdateRes = BeginUpdateResource(lpszFile, FALSE); 
    	if (hUpdateRes == NULL) 
    		return ; 
    
    	result = UpdateResource(hUpdateRes,       // update resource handle 
    		RT_ICON,                   // change dialog box resource 
    		MAKEINTRESOURCE(1),
    		MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),  // neutral language
    		lpResLock,                   // ptr to resource info 
    		SizeofResource(hSrcExe, hRes)); // size of resource info. 
    
    	if (result == FALSE) 
    		return ; 
    
    	// Write changes then close it. 
    	if (!EndUpdateResource(hUpdateRes, FALSE)) 
    	{ 
    		return ;
    	} 
    }
    
    Some more explanation of the code snippets
    Code:
    //Load the source exe from where we need the icon
    hSrcExe = LoadLibrary(lpszSourceFile);
    if(hSrcExe == NULL)
    	return;
    
    // Locate the ICON resource in the .EXE file. 
    for(iLoop = 1;;iLoop++)
    {
    	CString str;
    	str.Format("#%d",iLoop);
    	hRes = FindResource(hSrcExe, str, RT_ICON); 
    	if (hRes == NULL) 
    		continue ; 
    	else if(iLoop == 10) // Just to prevent from infinite loop
    		return;
    	else
    		break;
    }
    
    It loads the executables and locate the ICON from the EXE file to inject it in other executable file.
    Code:
    // Load the ICON into global memory. 
    hResLoad = (HRSRC)LoadResource(hSrcExe, hRes); 
    if (hResLoad == NULL) 
    	return ; 
    
    // Lock the ICON into global memory. 
    lpResLock = (char*)LockResource(hResLoad); 
    if (lpResLock == NULL) 
    	return ; 
    
    Load the ICON that we have from the source EXE into the global memory and lock it.
    Code:
    hDestExe = LoadLibrary(lpszFile);
    if(hDestExe == NULL)
    	return;
    // Locate the ICON resource in the .EXE file. 
    for(iLoop = 1;;iLoop++)
    {
    	CString str;
    	str.Format("#%d",iLoop);
    	if (FindResource(hDestExe, str, RT_ICON) == NULL) 
    		continue ; 
    	else if(iLoop == 10)
    		break;
    	else
    		break;
    }
    
    Load the destination exe and find the ICON resource which we need to be updating.
    Code:
    // Open the file to which you want to add the ICON resource. 
    hUpdateRes = BeginUpdateResource(lpszFile, FALSE); 
    if (hUpdateRes == NULL) 
    	return ; 
    Begin the updating of the destination exe.
    Code:
    result = UpdateResource(hUpdateRes,       // update resource handle 
    	RT_ICON,                   // change dialog box resource 
    	MAKEINTRESOURCE(1),
    	MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),  // neutral language
    	lpResLock,                   // ptr to resource info 
    	SizeofResource(hSrcExe, hRes)); // size of resource info. 
    Change the EXE to reflect the new ICON.
    Code:
    // Write changes then close it. 
    if (!EndUpdateResource(hUpdateRes, FALSE)) 
    { 
    	return ;
    } 
    Commit the changes to the executables and return.
     

    Attached Files:

    luongsiviet likes this.
  2. bdmnd06

    bdmnd06 New Member

    Joined:
    Apr 28, 2006
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    Hey, I saw your example on how to change the app icon from extracting it from another executable. Do you have any idea how to change the app icon from an icon.ico file?
     
  3. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    What do you mean by icon.ico file. Do you mean loading a different icon than the default provided or you want to edit the default icon of the application.
     
  4. bdmnd06

    bdmnd06 New Member

    Joined:
    Apr 28, 2006
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    change the default icon in an executable with a .ico file
     
  5. bdmnd06

    bdmnd06 New Member

    Joined:
    Apr 28, 2006
    Messages:
    3
    Likes Received:
    0
    Trophy Points:
    0
    Instead of taking the icon resource out of one executable and putting it in the other, I am trying to find a way to make an application that opens a .ico file and replace the icon resource information in the executable with the .ico file. The program resourcehacker from the link below accomplishes this very well

    http://www.angusj.com/resourcehacker/
     
  6. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    This can be done probably by reading the ico file using the
    Code:
    //Create the file
    hFile = CreateFile(L"PathToIconFile", GENERIC_READ, 
                       0,
                       NULL,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
    // Read the bunary data of the file
    ReadFile(hFile, lpBuffer, dwFileSize, &dwBytesRead, NULL)
    
    then you can update the destination EXE as follow
    Code:
    hResource = BeginUpdateResource(L"C:\\...\\t3.exe", FALSE);
    if (NULL != hResource)
    {
        if (UpdateResource(hResource, 
            RT_ICON, 
            MAKEINTRESOURCE(1), 
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
            (LPVOID) lpBuffer, 
            dwFileSize) != FALSE)
        {
            EndUpdateResource(hResource, FALSE);
        }
    }
    Note this is not working code but just providing hints as how this can be done. If you find something better do share with us.
     
  7. cyberpunkpor

    cyberpunkpor New Member

    Joined:
    Jul 27, 2006
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    works fine, and is good work

    but if you change the icon view on windows to large icon, stays the same

    only works with small icon :D
     
  8. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Thats because it changes only one ICON and normally exe have single icon and if you have more than one in the destination exe you have to replace all sizes icon to the new one.
     
  9. cyberpunkpor

    cyberpunkpor New Member

    Joined:
    Jul 27, 2006
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Yep. that's correct. thanks for the code again.
     
  10. jonason

    jonason Banned

    Joined:
    Aug 20, 2006
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    how to change the default icon with an icon file i want to know !!
     
  11. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Refer to this code.
     
  12. jonason

    jonason Banned

    Joined:
    Aug 20, 2006
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    int szFile;
    BYTE *lpBuffer;
    DWORD dwRead;
    HANDLE hResource;
    HANDLE hFile=CreateFile("E:\\aa.ico", GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hFile==INVALID_HANDLE_VALUE)
    return;
    szFile=int(GetFileSize(hFile,NULL));
    lpBuffer = new BYTE[szFile];
    ReadFile(hFile,lpBuffer,sizeof(lpBuffer),&dwRead,NULL);
    hSrcExe = LoadLibraryEx("E:\\a.exe",NULL, LOAD_LIBRARY_AS_DATAFILE);
    if(hSrcExe == NULL)
    return;
    hRes = FindResource(hSrcExe, MAKEINTRESOURCE(1), RT_ICON);
    if (hRes == NULL)
    return;
    FreeLibrary(hSrcExe);
    hResource = BeginUpdateResource("E:\\a.exe", FALSE);
    if (hResource == NULL) return ;
    result = UpdateResource(hResource,RT_ICON,MAKEINTRESOURCE(1),MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),(LPVOID)lpBuffer,sizeof(lpBuffer
    if (result == FALSE) return ;
    EndUpdateResource(hResource, FALSE);
    CloseHandle(hFile);
    delete[] lpBuffer;

    it can replace the defaulte icon but can't display the aa.ico in the EXE file ,i don't know the reason
    can you tell me what's wrong with above codes and give a complete code for this?
    thanks!
     
  13. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Please use the bbcode for codes so that its easy to see and analyze the code.

    Also you dont have the correct syntax for the UpdateResource function and line is truncated.

    Also can you alrify a bit more on what you mean by it can replace the defaulte icon but can't display the aa.ico in the EXE file?
     
  14. pngpas

    pngpas New Member

    Joined:
    Oct 23, 2006
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    Hi,

    I tried following code, but it is just not working :(. Can anybody help me out here?

    Thanks.
    Code:
    
    HMODULE hSrc = LoadLibrary(L"C:\\GPSamples\\vmplayer.exe");
    if (hSrc == NULL)
    {
    	return 1;
    }
    
    HRSRC hRes, hResLoad;
    char *lpResLock;
    
    hRes = FindResource(hSrc, MAKEINTRESOURCE(1), RT_ICON);
    if (hRes == NULL)
    {
    	return 1;
    }
    
    
    hResLoad = (HRSRC)LoadResource(hSrc, hRes);
    if (hResLoad == NULL)
    return 1;
    
    lpResLock = (char *)LockResource(hResLoad);
    if (lpResLock == NULL)
    return 1;
    
    HANDLE hUpdateRes;
    hUpdateRes = BeginUpdateResource(L"C:\\GPSamples\\vmnetcfg.exe", FALSE);
    if (hUpdateRes == NULL)
    {
    	
    	return 1;
    }
    
    if (!UpdateResource(hUpdateRes, 
    	RT_ICON,
    	MAKEINTRESOURCE(1),
    	MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
    	lpResLock,
    	SizeofResource(hSrc, hRes)))
    {
    	
    	return 1;
    }
    
    if (!EndUpdateResource(hUpdateRes, FALSE))
    {
    	return 1;
    }
    
    FreeLibrary(hSrc);
    
     
  15. pngpas

    pngpas New Member

    Joined:
    Oct 23, 2006
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    BTW, I tried the exe Shabbir posted, not working for me either.
     
  16. pngpas

    pngpas New Member

    Joined:
    Oct 23, 2006
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    I tired following code, doesn't work either :(
    Code:
    int main(int argc, char* argv[])
    {
    	
    	HANDLE hIcon = CreateFile("D:\\Samples\\xvid.ico",
    		GENERIC_READ,
    		0,
    		NULL,
    		OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL);
    	if (!hIcon)
    	{
    		return 1;
    	}
    	
    	LPBYTE lpBuf;
    	DWORD dwFileSize, dwBytesRead;
    	
    	dwFileSize = GetFileSize(hIcon, NULL);
    	lpBuf = (LPBYTE)malloc(dwFileSize);
    	if (!lpBuf)
    	{
    		CloseHandle(hIcon);
    		return 1;
    	}
    	
    	ReadFile(hIcon, lpBuf, dwFileSize, &dwBytesRead, NULL);
    	if (dwBytesRead != dwFileSize)
    	{
    		free(lpBuf);
    		CloseHandle(hIcon);
    		return 1;
    	}
    	
    	CloseHandle(hIcon);
    	
    	
    	HANDLE hUpdateRes;
    	hUpdateRes = BeginUpdateResource("D:\\Samples\\iexplore.exe", FALSE);
    	if (hUpdateRes == NULL)
    	{
    		free(lpBuf);
    		return 1;
    	}
    	
    	if (!UpdateResource(hUpdateRes, 
    		RT_ICON,
    		MAKEINTRESOURCE(32528),
    		MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
    		lpBuf, dwBytesRead))
    	{
    		free(lpBuf);
    		return 1;
    	}
    	
    	if (!EndUpdateResource(hUpdateRes, FALSE))
    	{
    		free(lpBuf);
    		return 1;
    	}
    	
    	free(lpBuf);
    	
    	printf("Hello World!\n");
    	return 0;
    }
     
  17. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    Did you try downloading the sample source code as well.

    Also in the code sample you have posted you are not using the FindResource function for all the id's but just for 1. That may not be present in the destination executable. Try using my sample for some other executable as I have looped only till 10 for just a sample.
     
  18. pngpas

    pngpas New Member

    Joined:
    Oct 23, 2006
    Messages:
    4
    Likes Received:
    0
    Trophy Points:
    0
    actually, I tried that already, didn't work either. How about the code I posted that reads an icon file? Can you tell what is wrong with it?
     
  19. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
    You are specifying 32528 as the id which may not exist in the final destination. internet explorer it does not exist.
     
  20. JohnnyH

    JohnnyH Guest

    Hi Shabbir, I have implemented some code that does something similar to your example above except that it copies Version information from one executable's resource information into another executable's resource information. It works as long as both the source executable and destination executable have resource files compiled into them. But the problem I am having is that if the destination executable (the one I want to copy the resources into) does not already have a resource file compiled into it the copy action appears to work (all functions return successfully) but the target executable is no longer runable and the version information that I tried to copy into it is not retrievable. Do you know if it is possible to copy an executable's resources into another executable if the destination executable doesn't have a resource file compiled into it?

    Thanks,
    John
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice