Sign in to follow this  
Followers 0
Jos

AutoIt3Wrapper Resource Update

87 posts in this topic

#1 ·  Posted (edited)

There is a Bugreport for AutoIt3Wrapper indicating problems updating the program resources for X64 compiled scripts.

It looks like ResHacker doesn't support X64 program resource updates which disables many of the AutoIt3Wrapper functions.

Does anybody know a good/free resource update program that could replace ResHacker, which can be used in batch type operations ?

UPDATE: There is now a AutoIt3Wrapper Beta version available here that has build in support to update the program resources instead of requiring RC.exe and Reshacker. Its does all the DllStruct building and needed DllCalls to update the programs Resources.

Edited by Jos

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I am doing some initial testing with NTCore - CFF Explorer, which can update Program resource and has a nice Scripting extention based on LUA.

Edited by Jos

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I am doing some initial testing with NTCore - CFF Explorer, which can update Program resource and has a nice Scripting extention based on LUA.

Jos have you looked at Resource Tweaker by NTCore?

http://www.ntcore.com/restweaker.php

It's an extension that works with ResHacker


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Jos have you looked at Resource Tweaker by NTCore?

http://www.ntcore.com/restweaker.php

It's an extension that works with ResHacker

mmm .. looks promising.. not sure yet how that works ... :D Edited by Jos

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

mmm .. looks promising.. not sure yet how that works ... :D

I think I figured out how it works. It converts the resources to a 32bit temp file and places it in the temporary folder. You can then edit the resources with Resource Hacker. Once you finish editing the resources with Resource Hacker, it takes the edited resources of the temp file and places them into the 64bit file's resources using its own resource engine.

Maybe we are at this point that we can realize it with Autoit itself:

http://msdn2.microsoft.com/en-us/library/m...004(VS.85).aspx

I love this method. I am going to see if I can get it to work.

- The Kandie Man ;-)

EDIT:

I have been playing with the Kernel32 functions Holger brought up. I have been having problems, but i finally just got it to take the data without erroring.

- The Kandie Man ;-)

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

I have the Resource Update Dllcalls working and am able to load the Raw Binary information into the RT_VERSION resources with an AutoIt3Script, But the main challenge at the moment is how to generate the proper binary format to load.

The output file generated by RC.exe, that I use to load normally with resHacker, looks close but isn't the same and doesn't produce the correct format.

Ideas are welcome :D

Testscript thus far:

#include<winapi.au3>
;
$ExeFilename = "test.exe"
;
FileCopy("testsave.exe",$ExeFilename,1)
;
$ExeFilename = "test.exe"
;
FileCopy("testsave.exe",$ExeFilename,1)
;
$RSection = 16  ; RT_VERSION
_UpdateResources($ExeFilename,"version.res",16,1,2057); Update RT_VERSION
_UpdateResources($ExeFilename,"Manifest.res",24,1,2057); Update RT_MANIFEST
;

Func _UpdateResources($Filename,$InpResFile,$RSection,$RType=1,$RLanguage=2057)
    $hDll = DllOpen("kernel32.dll")
;
; Begin resource Update
    $result = DllCall($hDll, "ptr", "BeginUpdateResource", "str", $Filename, "int", 0)
    ConsoleWrite('BeginUpdateResources: $result[0] = ' & $result[0] & " - LastError:"  & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
    $rh = $result[0] 
;
; Read file into Struct
    $hFile = _WinAPI_CreateFile($InpResFile, 2, 2)
    $tBuffer = DllStructCreate("char Text[" & FileGetSize($InpResFile)+1 & "]"); Create the buffer.
    $pBuffer = DllStructGetPtr($tBuffer)                                ; Get a pointer to that buffer.
    $bread=0
    _WinAPI_ReadFile($hFile, $pBuffer, FileGetSize($InpResFile), $bread, 0)
;
; Update resources
    $result = DllCall($hDll, "int", "UpdateResource", "ptr", $rh, "Long", $RSection,  "Long", $RType , "short", $RLanguage ,"ptr",$pBuffer,'dword',DllStructGetSize ($tBuffer))
    ConsoleWrite('UpdateResources: $result[0] = ' & $result[0] & " - LastError:"  & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
;
; EndUpdate
    $result = DllCall($hDll, "int", "EndUpdateResource", "ptr", $rh, "int", 0)
    ConsoleWrite('EndUpdateResources: $result[0] = ' & $result[0] & " - LastError:"  & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
;
    DllClose($hdll)
EndFunc

version.res is created by running: rc version.rc

Version.rc:

1 VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1.0.0.0
FILEOS 0x4
FILETYPE 0x0
{
BLOCK "StringFileInfo"
{
    BLOCK "080904b0"
    {
        VALUE "Comments", "test comment"
        VALUE "FileDescription", "Test description"
        VALUE "FileVersion", "0.0.0.0"
     VALUE "LegalCopyright", "test copyrights"
    }
}

BLOCK "VarFileInfo"
{
    VALUE "Translation", 0x0809 0x04B0
}
}

Manifest.res:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<!-- Identify the application security requirements. -->
<!-- level can be "asInvoker", "highestAvailable", or "requireAdministrator" -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel
                level="requireAdministrator"
                  uiAccess="false"/>
              </requestedPrivileges>
    </security>
</trustInfo>
</assembly>
Edited by Jos

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I have the Resource Update Dllcalls working and am able to load the Raw Binary information into the RT_VERSION resources with an AutoIt3Script, But the main challenge at the moment is how to generate the proper binary format to load.

The output file generated by RC.exe, that I use to load normally with resHacker, looks close but isn't the same and doesn't produce the correct format.

Testscript thus far:

#include<winapi.au3>
      ;
       $ExeFilename = "test.exe"
       $VersionResFile = "version.res"
      ;
      ;
       FileCopy("testsave.exe",$ExeFilename,1)
      ;
       $RSection = 16   ; RT_VERSION
       _UpdateResources($ExeFilename,$VersionResFile,$RSection,1,2057)
      ;
       
       Func _UpdateResources($Filename,$InpResFile,$RSection,$RType=1,$RLanguage=2057)
           $hDll = DllOpen("kernel32.dll")
      ;
      ; Begin resource Update
           $result = DllCall($hDll, "ptr", "BeginUpdateResource", "str", $Filename, "int", 0)
           ConsoleWrite('BeginUpdateResources: $result[0] = ' & $result[0] & " - LastError:"  & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
           $rh = $result[0] 
      ;
      ; Read file into Struct
           $hFile = _WinAPI_CreateFile($InpResFile, 2, 2)
           $tBuffer = DllStructCreate("char Text[" & FileGetSize($InpResFile)+1 & "]"); Create the buffer.
           $pBuffer = DllStructGetPtr($tBuffer)                                    ; Get a pointer to that buffer.
           $bread=0
           _WinAPI_ReadFile($hFile, $pBuffer, FileGetSize($InpResFile), $bread, 0)
      ;
      ; Update resources
           $result = DllCall($hDll, "int", "UpdateResource", "ptr", $rh, "Long", $RSection,  "Long", $RType , "short", $RLanguage ,"ptr",$pBuffer,'dword',DllStructGetSize ($tBuffer))
           ConsoleWrite('UpdateResources: $result[0] = ' & $result[0] & " - LastError:"  & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
      ;
      ; EndUpdate
           $result = DllCall($hDll, "int", "EndUpdateResource", "ptr", $rh, "int", 0)
           ConsoleWrite('EndUpdateResources: $result[0] = ' & $result[0] & " - LastError:"  & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
      ;
           DllClose($hdll)
       EndFunc
This is what I came up with. It seems to work. I have an example and 3 UDF's that I made:

Edit_Resources.zip

- The Kandie Man ;-)


"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

This is what I came up with. It seems to work. I have an example and 3 UDF's that I made:

Edit_Resources.zip

- The Kandie Man ;-)

I guess the question is how to generate the proper binary format to import into the programs resources. the outpur from RC.exe looks close but doesn't work...

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I guess the question is how to generate the proper binary format to import into the programs resources. the outpur from RC.exe looks close but doesn't work...

Jos

Yeah, I have been google searching for methods to generate raw binary resources. The resouces have to be in raw binary in order to work. However, one can copy the raw resource information from a 32bit executable to a 64bit executable.

Reshack ==> 32bitexe ==> Resources ==> 64bitexe

That would of course be a last resort.

- The Kandie Man ;-)


"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Update:

Looks like this script is working fine on a regular system but don't know what it does on a x64 machine yet.

I am just stripping the first 64 bytes from the file generated by RC.exe and dump the rest of the file into the RT_VERSION program resource.

This ofcourse only works when only fileversion info is stored in the RC file. Next to figure out how to do the same for adding files and ICO's to the resource.

#include<winapi.au3>
;
$ExeFilename = "test.exe"
;
FileCopy("testsave.exe",$ExeFilename,1)
;
$RSection = 16; RT_VERSION
_UpdateResources($ExeFilename,"version.res",16,1,2057,1); Update RT_VERSION
_UpdateResources($ExeFilename,"Manifest.res",24,1,2057); Update RT_MANIFEST
;

Func _UpdateResources($Filename, $InpResFile, $RSection, $RType = 1, $RLanguage = 2057, $Strip_Version_Header = 0)
    Local $hDll, $result, $rh, $hFile, $tSize, $tBuffer, $pBuffer, $poBuffer, $bread
    $hDll = DllOpen("kernel32.dll")
;
; Begin resource Update
    $result = DllCall($hDll, "ptr", "BeginUpdateResource", "str", $Filename, "int", 0)
    ConsoleWrite('BeginUpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
    $rh = $result[0]
;
; Read file into Struct
    $hFile = _WinAPI_CreateFile($InpResFile, 2, 2)
; Build Structure for data
    $tSize = FileGetSize($InpResFile) - 63
    $tBuffer = DllStructCreate("char Text[64];char Text[" & $tSize & "]"); Create the buffer.
    $pBuffer = DllStructGetPtr($tBuffer)
    If $Strip_Version_Header Then
        $poBuffer = DllStructGetPtr($tBuffer, 2); Skip first 64 bytes for Version structure
        $tSize = FileGetSize($InpResFile) - 63
    Else
        $poBuffer = DllStructGetPtr($tBuffer)
        $tSize = FileGetSize($InpResFile)
    EndIf
    $bread = 0
    _WinAPI_ReadFile($hFile, $pBuffer, FileGetSize($InpResFile), $bread, 0)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bread = ' & $bread & @CRLF & '>Error code: ' & @error & @CRLF);### Debug Console
;
; Update resources
    $result = DllCall($hDll, "int", "UpdateResource", "ptr", $rh, "Long", $RSection, "Long", $RType, "short", $RLanguage, "ptr", $poBuffer, 'dword', $tSize)
    ConsoleWrite('UpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
;
; EndUpdate
    $result = DllCall($hDll, "int", "EndUpdateResource", "ptr", $rh, "int", 0)
    ConsoleWrite('EndUpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
;
    DllClose($hDll)
EndFunc;==>_UpdateResources
Edited by Jos

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

Update:

Looks like this script is working fine on a regular system but don't know what it does on a x64 machine yet.

I am just stripping the first 64 bytes from the file generated by RC.exe and dump the rest of the file into the RT_VERSION program resource.

This ofcourse only works when only fileversion info is stored in the RC file. Next to figure out how to do the same for adding files and ICO's to the resource.

#include<winapi.au3>
  ;
   $ExeFilename = "test.exe"
  ;
   FileCopy("testsave.exe",$ExeFilename,1)
  ;
   $RSection = 16; RT_VERSION
   _UpdateResources($ExeFilename,"version.res",16,1,2057,1); Update RT_VERSION
   _UpdateResources($ExeFilename,"Manifest.res",24,1,2057); Update RT_MANIFEST
  ;
   
   Func _UpdateResources($Filename, $InpResFile, $RSection, $RType = 1, $RLanguage = 2057, $Strip_Version_Header = 0)
       Local $hDll, $result, $rh, $hFile, $tSize, $tBuffer, $pBuffer, $poBuffer, $bread
       $hDll = DllOpen("kernel32.dll")
  ;
  ; Begin resource Update
       $result = DllCall($hDll, "ptr", "BeginUpdateResource", "str", $Filename, "int", 0)
       ConsoleWrite('BeginUpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
       $rh = $result[0]
  ;
  ; Read file into Struct
       $hFile = _WinAPI_CreateFile($InpResFile, 2, 2)
  ; Build Structure for data
       $tSize = FileGetSize($InpResFile) - 63
       $tBuffer = DllStructCreate("char Text[64];char Text[" & $tSize & "]"); Create the buffer.
       $pBuffer = DllStructGetPtr($tBuffer)
       If $Strip_Version_Header Then
           $poBuffer = DllStructGetPtr($tBuffer, 2); Skip first 64 bytes for Version structure
           $tSize = FileGetSize($InpResFile) - 63
       Else
           $poBuffer = DllStructGetPtr($tBuffer)
           $tSize = FileGetSize($InpResFile)
       EndIf
       $bread = 0
       _WinAPI_ReadFile($hFile, $pBuffer, FileGetSize($InpResFile), $bread, 0)
       ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bread = ' & $bread & @CRLF & '>Error code: ' & @error & @CRLF);### Debug Console
  ;
  ; Update resources
       $result = DllCall($hDll, "int", "UpdateResource", "ptr", $rh, "Long", $RSection, "Long", $RType, "short", $RLanguage, "ptr", $poBuffer, 'dword', $tSize)
       ConsoleWrite('UpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
  ;
  ; EndUpdate
       $result = DllCall($hDll, "int", "EndUpdateResource", "ptr", $rh, "int", 0)
       ConsoleWrite('EndUpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
  ;
       DllClose($hDll)
   EndFunc;==>_UpdateResources
Tested. This method works fine for 64bit executables.

Also figured out how to add icons to the files.

This page explains how it is done:

http://www.codeguru.com/cpp/w-p/win32/tuto...cle.php/c12873/

Look at the icon file structure and look at the part where he explains "The Secret" of how this information is used. The key Jos is to get the icon header and structure data from the icon file and place that data into icon group. Then use UpdateResource to add every icon located in the icon file as a resource to the executable.

Sounds tedious, but functions could be made to make it work. I am going to see if I can write functions to read and add icons in the method that is described.

- The Kandie Man ;-)


"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

Tested. This method works fine for 64bit executables.

Also figured out how to add icons to the files.

This page explains how it is done:

http://www.codeguru.com/cpp/w-p/win32/tuto...cle.php/c12873/

Look at the icon file structure and look at the part where he explains "The Secret" of how this information is used. The key Jos is to get the icon header and structure data from the icon file and place that data into icon group. Then use UpdateResource to add every icon located in the icon file as a resource to the executable.

Sounds tedious, but functions could be made to make it work. I am going to see if I can write functions to read and add icons in the method that is described.

- The Kandie Man ;-)

I have read few articles but will looks at this one as well about the Ico adding stuff.

Adding other files in RT_RCDATA is working fine already.

:D


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

I have read few articles but will looks at this one as well about the Ico adding stuff.

Adding other files in RT_RCDATA is working fine already.

:D

EDIT:

Here is what I have. Works with both 64bit and 32bit AutoIt executables:

#include<winapi.au3>

Global Const $RT_CURSOR = 1
Global Const $RT_BITMAP = 2
Global Const $RT_ICON = 3
Global Const $RT_MENU = 4
Global Const $RT_DIALOG = 5
Global Const $RT_STRING = 6
Global Const $RT_FONTDIR = 7
Global Const $RT_FONT = 8
Global Const $RT_ACCELERATORS = 9
Global Const $RT_RCDATA = 10
Global Const $RT_MESSAGETABLE = 11
Global Const $RT_GROUP_CURSOR = 12
Global Const $RT_GROUP_ICON = 14
Global Const $RT_VERSION = 16

Global Const $RT_ANICURSOR = 21
Global Const $RT_ANIICON = 22
Global Const $RT_HTML = 23
Global Const $RT_MANIFEST = 24
;
$ExeFilename = "Test.exe"
;
FileCopy("TestSav.exe", $ExeFilename, 1)
;
$RSection = 16; RT_VERSION
_UpdateResources($ExeFilename, "version.res", 16, 1, 2057, 1); Update RT_VERSION
_UpdateResources($ExeFilename, "Manifest.res", 24, 1, 2057); Update RT_MANIFEST

_RemoveExistingIconResources($ExeFilename);This will remove the default autoit.exe icon from the resources.  This is optional, but will remove unncessary resources that will reduce the exe's final size

_UpdateIcon($ExeFilename, "au3.ico")
;

Func _UpdateResources($Filename, $InpResFile, $RSection, $RType = 1, $RLanguage = 2057, $Strip_Version_Header = 0)
    Local $hDll, $result, $rh, $hFile, $tSize, $tBuffer, $pBuffer, $poBuffer, $bread
    $hDll = DllOpen("kernel32.dll")
    ;
    ; Begin resource Update
    $result = DllCall($hDll, "ptr", "BeginUpdateResource", "str", $Filename, "int", 0)
    ConsoleWrite('BeginUpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
    $rh = $result[0]
    ;
    ; Read file into Struct
    $hFile = _WinAPI_CreateFile($InpResFile, 2, 2)
    ; Build Structure for data
    $tSize = FileGetSize($InpResFile) - 63
    $tBuffer = DllStructCreate("char Text[64];char Text[" & $tSize & "]"); Create the buffer.
    $pBuffer = DllStructGetPtr($tBuffer)
    If $Strip_Version_Header Then
        $poBuffer = DllStructGetPtr($tBuffer, 2); Skip first 64 bytes for Version structure
        $tSize = FileGetSize($InpResFile) - 63
    Else
        $poBuffer = DllStructGetPtr($tBuffer)
        $tSize = FileGetSize($InpResFile)
    EndIf
    $bread = 0
    _WinAPI_ReadFile($hFile, $pBuffer, FileGetSize($InpResFile), $bread, 0)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $bread = ' & $bread & @CRLF & '>Error code: ' & @error & @CRLF);### Debug Console
    ;
    ; Update resources
    $result = DllCall($hDll, "int", "UpdateResource", "ptr", $rh, "Long", $RSection, "Long", $RType, "short", $RLanguage, "ptr", $poBuffer, 'dword', $tSize)
    ConsoleWrite('UpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
    ;
    ; EndUpdate
    $result = DllCall($hDll, "int", "EndUpdateResource", "ptr", $rh, "int", 0)
    ConsoleWrite('EndUpdateResources: $result[0] = ' & $result[0] & " - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
    ;
    DllClose($hDll)
EndFunc   ;==>_UpdateResources

;I added the following to make the UpdateIcon Work - The Kandie Man ;-)
Func _RemoveExistingIconResources($sFile)
    Local $hFile = _BeginUpdateResource($ExeFilename)
    For $iCnt = 1 To 9
        _UpdateResource($hFile, $RT_ICON, $iCnt, 2057, 0, 0)
        If @error Then
            _ResourceUpdateTracelog("!> _RemoveExistingIconResources() Error: _UpdateResource failed.  It is possible that the icon it was trying to remove has already been removed.  Make sure you are editing an unmodified AutoIt Executable.")
            _EndUpdateResource($hFile, 1)
            Return 0
        EndIf
    Next
    _EndUpdateResource($hFile, 0)
    Return 1
EndFunc   ;==>_RemoveExistingIconResources

Func _UpdateIcon($sFile, $sIcon)

    Local $sFileIconGroup = @TempDir & "\IconGroupData.bin"

    FileDelete($sFileIconGroup);Make sure the temp IconGroupData file is gone

    Local $dllICON_HEADER = DllStructCreate("ushort Reserved;ushort Type;ushort ImageCount")
    If @error Then
        _ResourceUpdateTracelog("!> _UpdateIcon () Error: Couldn't create Icon_Header Dll Structure. @error=" & @error)
        Return SetError(2, 0, 0)
    EndIf

    Local $pdllICON_HEADER = DllStructGetPtr($dllICON_HEADER)
    
    Local $dllICON_DIRECTORY_ENTRY = DllStructCreate("ubyte Width;ubyte Height;ubyte Colors;ubyte Reserved;ushort Planes;ushort BitsPerPixel;dword ImageSize;dword ImageOffset")
    If @error Then
        _ResourceUpdateTracelog("!> _UpdateIcon () Error: Couldn't create ICON_DIRECTORY_ENTRY Dll Structure. @error=" & @error)
        Return SetError(2, 0, 0)
    EndIf

    Local $pdllICON_DIRECTORY_ENTRY = DllStructGetPtr($dllICON_DIRECTORY_ENTRY)

    Local $hFileIcon, $bytesRead = 0
    $hFileIcon = _WinAPI_CreateFile($sIcon, 2, 2)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_CreateFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    
    _WinAPI_ReadFile($hFileIcon, $pdllICON_HEADER, DllStructGetSize($dllICON_HEADER), $bytesRead)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_ReadFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    
    Local $iType, $iImageCount
    $iType = DllStructGetData($dllICON_HEADER, "Type")
    If @error Then
        _ResourceUpdateTracelog("!> _UpdateIcon () Error: Couldn't get Type from Icon_Header Dll Structure. @error=" & @error)
        Return SetError(3, 0, 0)
    EndIf
    $iImageCount = DllStructGetData($dllICON_HEADER, "ImageCount")
    If @error Then
        _ResourceUpdateTracelog("!> _UpdateIcon () Error: Couldn't get ImageCount from Icon_Header Dll Structure. @error=" & @error)
        Return SetError(3, 0, 0)
    EndIf
    
    Local $hFileOut, $bytesWritten = 0
    
    $hFileOut = _WinAPI_CreateFile($sFileIconGroup, 1, 4)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_CreateFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    _WinAPI_WriteFile($hFileOut, $pdllICON_HEADER, DllStructGetSize($dllICON_HEADER), $bytesWritten)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_WriteFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    Local $iResourceNumber
    Local $IconArray[$iImageCount][2]
    
    
    For $iCnt = 1 To $iImageCount
        _WinAPI_ReadFile($hFileIcon, $pdllICON_DIRECTORY_ENTRY, DllStructGetSize($dllICON_DIRECTORY_ENTRY), $bytesRead)
        If _WinAPI_GetLastError() Then
            ConsoleWrite("!> _WinAPI_ReadFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
            Return SetError(4, 0, 0)
        EndIf
        If $iCnt < 10 Then;========================Hard coded.  There are two icons 10 and 11 which are icons autoit uses internally.  These icons must therefore be left in tact.
            $iResourceNumber = $iCnt
        Else
            $iResourceNumber = $iCnt + 2;Skip the two icons that autoit uses internally
        EndIf
        $IconArray[$iCnt - 1][0] = $iResourceNumber
        $IconArray[$iCnt - 1][1] = DllStructGetData($dllICON_DIRECTORY_ENTRY, "ImageSize")
        DllStructSetData($dllICON_DIRECTORY_ENTRY, "ImageOffset", $iResourceNumber)
        If @error Then
            _ResourceUpdateTracelog("!> _UpdateIcon () Error. Unable to set DllStructData for dllICON_DIRECTORY_ENTRY ImageOffset. @error=" & @error)
        EndIf
        _WinAPI_WriteFile($hFileOut, $pdllICON_DIRECTORY_ENTRY, DllStructGetSize($dllICON_DIRECTORY_ENTRY) - 2, $bytesWritten)
        If _WinAPI_GetLastError() Then
            ConsoleWrite("!> _WinAPI_WriteFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
            Return SetError(4, 0, 0)
        EndIf
    Next
    
    Local $hUpdate = _BeginUpdateResource($sFile)
    
    Local $dllBuffer
    For $iCnt = 1 To $iImageCount
        $dllBuffer = DllStructCreate("char[" & $IconArray[$iCnt - 1][1] & "]")
        If @error Then
            _ResourceUpdateTracelog("!>Error.  DllStructCreate could not create a buffer. @error=" & @error)
            Return SetError(1, 0, 0)
        EndIf
        $pdllBuffer = DllStructGetPtr($dllBuffer)
        If @error Then
            _ResourceUpdateTracelog("!>Error.  DllStructGetPtr could not create a get a pointer to the buffer. @error=" & @error)
            Return SetError(1, 0, 0)
        EndIf
        _WinAPI_ReadFile($hFileIcon, $pdllBuffer, DllStructGetSize($dllBuffer), $bytesRead)
        If _WinAPI_GetLastError() Then
            ConsoleWrite("!> _WinAPI_ReadFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
            Return SetError(4, 0, 0)
        EndIf
        If _UpdateResource($hUpdate, $RT_ICON, $IconArray[$iCnt - 1][0], 2057, $pdllBuffer, DllStructGetSize($dllBuffer)) = 0 Then
            _ResourceUpdateTracelog("!> _UpdateResource Failed.")
            Return SetError(1, 0, 0)
        EndIf
        $dllBuffer = 0;Free memory
    Next
    
    $dllICON_HEADER = 0;Free memory
    
    $dllICON_DIRECTORY_ENTRY = 0;Free memory
    
    _WinAPI_CloseHandle($hFileIcon)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_CloseHandle  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    
    _WinAPI_CloseHandle($hFileOut)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_CloseHandle  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    
    Local $hFileIconGroupData
    
    $hFileIconGroupData = _WinAPI_CreateFile($sFileIconGroup, 2, 2)
    
    Local $iFileIconSize = FileGetSize($sFileIconGroup)
    
    $dllBuffer = DllStructCreate("char[" & $iFileIconSize & "]")
    
    $pdllBuffer = DllStructGetPtr($dllBuffer)
    
    $bytesRead = 0
    
    _WinAPI_ReadFile($hFileIconGroupData, $pdllBuffer, $iFileIconSize, $bytesRead)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_ReadFile  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    
    _UpdateResource($hUpdate, $RT_GROUP_ICON, 161, 2057, $pdllBuffer, $iFileIconSize)
    
    _EndUpdateResource($hUpdate, 0)
    
    _WinAPI_CloseHandle($hFileIconGroupData)
    If _WinAPI_GetLastError() Then
        ConsoleWrite("!> _WinAPI_CloseHandle  - LastError:" & _WinAPI_GetLastError() & ":" & _WinAPI_GetLastErrorMessage());### Debug Console
        Return SetError(4, 0, 0)
    EndIf
    
    FileDelete($sFileIconGroup);Delete temporary file
    
    $dllBuffer = 0;Free memory
    
    _ResourceUpdateTracelog("+> _UpdateIcon() was successful.")
    
    Return 1
    
EndFunc   ;==>_UpdateIcon

Func _ResourceUpdateTracelog($sText)
    ConsoleWrite($sText & @LF)
EndFunc   ;==>_ResourceUpdateTracelog

Func _UpdateResource($hUpdate, $lpType, $lpName, $wLanguage, $lpData, $cbData);Modified from my previous version

;~ BOOL UpdateResource(
;~     HANDLE hUpdate,
;~     LPCTSTR lpType,
;~     LPCTSTR lpName,
;~     WORD wLanguage,
;~     LPVOID lpData,
;~     DWORD cbData
;~ );
    ;You can replace the two int parameters below with this
;~                                     "str",DllStructGetPtr($DllStructUpdate,"lpType"), _
;~                                     "str",DllStructGetPtr($DllStructUpdate,"lpName"), _
    $aReturn = DllCall("kernel32.dll", "int", "UpdateResource", _
            "hwnd", $hUpdate, _
            "int", $lpType, _
            "int", $lpName, _
            "short", Int($wLanguage), _
            "ptr", $lpData, _
            "dword", $cbData)
    If @error Then
        _ResourceUpdateTracelog("!> Error with _UpdateResource() DllCall.")
        Return SetError(2, 0, 0)
    EndIf
    If $aReturn[0] = 1 Then
        _ResourceUpdateTracelog("+> _UpdateResource() was successful.")
        Return 1
    Else
        Local $aReturn3
        $aReturn3 = DllCall("kernel32.dll", "dword", "GetLastError")
        _ResourceUpdateTracelog("!> Error with _UpdateResource call. GetLastError=" & $aReturn3[0])
        Return SetError(3, 0, 0)
    EndIf
EndFunc   ;==>_UpdateResource


Func _BeginUpdateResource($sFile)
    If Not FileExists($sFile) Then
        _ResourceUpdateTracelog("!> _BeginUpdateResource($sFile): ERROR. $sFile does not exist.")
        Return SetError(1, 0, 0)
    EndIf
    Local $aReturn
    $aReturn = DllCall("kernel32.dll", "hwnd", "BeginUpdateResource", "str", $sFile, "int", 0)
    If @error Then
        _ResourceUpdateTracelog("!> Error with BeginUpdateResource call.")
        Return SetError(2, 0, 0)
    EndIf
    If UBound($aReturn) <> 3 Then
        _ResourceUpdateTracelog("-> Unexpected array size was returned with BeginUpdateResource.  The array has a ubound size of " & UBound($aReturn) & @LF)
        Return SetError(3, 0, 0)
    EndIf
    If $aReturn[0] = 0 Then
        _ResourceUpdateTracelog("!> _BeginUpdateResource($sFile): ERROR.  Function returned NULL")
        Return SetError(4, 0, 0)
    Else
        _ResourceUpdateTracelog("+> _BeginUpdateResource() was successful.")
        Return $aReturn[0]
    EndIf
EndFunc   ;==>_BeginUpdateResource

Func _EndUpdateResource($hResource, $bDiscard = 0)
    Local $aReturn
;~     BOOL EndUpdateResource(
;~     HANDLE hUpdate,
;~     BOOL fDiscard);
    $aReturn = DllCall("kernel32.dll", "int", "EndUpdateResource", _
            "hwnd", $hResource, _
            "int", $bDiscard); False, we do not want to discard our changes(double negative).
    If @error Then
        _ResourceUpdateTracelog("!> EndUpdateResource.")
        Return SetError(1, 0, 0)
    EndIf
    If $aReturn[0] = 1 Then
        _ResourceUpdateTracelog("+> _EndUpdateResource() was successful.")
        Return 1
    Else
        _ResourceUpdateTracelog("!> _EndUpdateResource() errored.")
        Return SetError(1, 0, 0)
    EndIf
EndFunc   ;==>_EndUpdateResource

- The Kandie Man ;-)

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

I am getting :

---------------------------

AutoIt Error

---------------------------

Unable to open the script file.

---------------------------

OK

---------------------------

When I run the script that is updated. :P

I am at the same point with my script. It adds the ICO's and the GroupIcon stuff correctly and Reshacker displays it all nicely but the output file size is different than when I use Reshacker and get this same message.

Still digging :D


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

I am getting :

---------------------------

AutoIt Error

---------------------------

Unable to open the script file.

---------------------------

OK

---------------------------

When I run the script that is updated. :P

I am at the same point with my script. It adds the ICO's and the GroupIcon stuff correctly and Reshacker displays it all nicely but the output file size is different than when I use Reshacker and get this same message.

Still digging :D

This was just a test. If you want the script to work, create a temporary AutoItSC.bin in the temporary files, modify it with the above script, and then use aut2exe to compile the modified AutoItSC.bin. The new generated script will have all the resources and should correctly open the script file inside.

I suspect that modifying an already compiled script messes with a checksum that is generated when the script is compiled into AutoItSC.bin to produce the portable script. Therefore, it errors. Sorry about the confusion.

Here is a complete example that will modify an AutoIt executable:

http://www.thekandieman.com/applications/U...pleteMethod.zip

The modified version should work correcly.

- The Kandie Man ;-)

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

This was just a test. If you want the script to work, create a temporary AutoItSC.bin in the temporary files, modify it with the above script, and then use aut2exe to compile the modified AutoItSC.bin. The new generated script will have all the resources and should correctly open the script file inside.

I suspect that modifying an already compiled script messes with a checksum that is generated when the script is compiled into AutoItSC.bin to produce the portable script. Therefore, it errors. Sorry about the confusion.

Here is a complete example:

http://www.thekandieman.com/applications/U...pleteMethod.zip

- The Kandie Man ;-)

I did the same in the beginning: save the BIN file and update that with ResHacker, but currently ResHacker is updating the EXE from AUT2EXE that is generated without running UPX in aut2exe.

So all I need to figure out now is what ResHacker does extra...


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

I did the same in the beginning: save the BIN file and update that with ResHacker, but currently ResHacker is updating the EXE from AUT2EXE that is generated without running UPX in aut2exe.

So all I need to figure out now is what ResHacker does extra...

Allright. My apologies. I didn't realize that ResHacker updated the compiled .exe. I will try to find the difference between ones that are generated by reshacker and ones that this new version makes.

- The Kandie Man ;-)


"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

Hey... no problem ... I am already happy this is working and its fun stuff to work on ....

Was looking to a nice freeware file compare (hex) utility... do you know any ? (i know I had one on my previous PC but don't recall its name.

I am using HxD and CFF Explorer for normal Hex viewing but they don't do comparing of 2 files afaik.

Thanks for all your efforts

:D


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

Hey... no problem ... I am already happy this is working and its fun stuff to work on ....

Was looking to a nice freeware file compare (hex) utility... do you know any ? (i know I had one on my previous PC but don't recall its name.

I am using HxD and CFF Explorer for normal Hex viewing but they don't do comparing of 2 files afaik.

Thanks for all your efforts

:D

I am using XVI32 as my hex editor as well as CFF Explorer. I am looking for a good free hex file comparing utility as well. Of course, finding good free stuff is hard because it is drowned out by all the expensive proprietary stuff when googling.

EDIT

I also noticed a bug that adds an extra null value to the end of the version resource.

Replace

If $Strip_Version_Header Then
        $poBuffer = DllStructGetPtr($tBuffer, 2); Skip first 64 bytes for Version structure
        $tSize = FileGetSize($InpResFile) - 63oÝ÷ Ùh­Øb±«­¢+Ù%ÀÌØíMÑÉ¥Á}YÉÍ¥½¹}!ÈQ¡¸(ÀÌØíÁ½ ÕÈô±±MÑÉÕÑÑAÑÈ ÀÌØíÑ   ÕȰȤìM­¥À¥ÉÍÐØÐåÑ̽ÈYÉÍ¥½¸ÍÑÉÕÑÕÉ(ÀÌØíÑM¥éô¥±ÑM¥é ÀÌØí%¹ÁIÍ¥±¤´ØÐ

That removes the unneeded null value from the end of the version resource.

- The Kandie Man ;-)

Edited by The Kandie Man

"So man has sown the wind and reaped the world. Perhaps in the next few hours there will no remembrance of the past and no hope for the future that might have been." & _"All the works of man will be consumed in the great fire after which he was created." & _"And if there is a future for man, insensitive as he is, proud and defiant in his pursuit of power, let him resolve to live it lovingly, for he knows well how to do so." & _"Then he may say once more, 'Truly the light is sweet, and what a pleasant thing it is for the eyes to see the sun.'" - The Day the Earth Caught Fire

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0