非典男人 发表于 2010-2-9 17:10:55

编译的时候,用AutoIt编译EXE文件时,您可以嵌入任何二进制数据到EXE文件中

本帖最后由 非典男人 于 2010-2-9 17:13 编辑

(转的帖子)编译的时候,用AutoIt编译EXE文件时,您可以嵌入任何二进制数据到EXE文件中。
除使用用FileInstall()函数直接嵌入数据到文件中外,还可以用#AutoIt3Wrapper的命令来嵌入数据。
下面是一条#AutoIt3Wrapper嵌入文本数据的命令:
#AutoIt3Wrapper_run_after = ResHacker.exe -add %out%, %out%, test_1.txt, rcdata, TEST_TXT_1, 0
这里牵扯到ResHacker.exe软件命令行的用法。可嵌入的数据可为图像、光标、文本、声音、二进制文件等。


在运行时加载/使用数据资源有一个外国人编写的UDF,其中的主要函数有(我没得到详细的说明):

_ResourceGet($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsString($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsStringW($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsBytes($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsImage($ResName, $ResType = $RT_RCDATA, $DLL = -1)
_ResourceGetAsBitmap($ResName, $ResType = $RT_RCDATA, $DLL = -1)
_ResourceSaveToFile($FileName, $ResName, $ResType = $RT_RCDATA, $ResLang = 0, $CreatePath = 0, $DLL = -1)
_ResourceSetImageToCtrl($CtrlId, $ResName, $ResType = $RT_RCDATA, $DLL = -1)
_SetBitmapToCtrl($CtrlId, $hBitmap)
_ResourcePlaySound($ResName, $Flag = 0, $DLL = -1)

以下是必须注意的:

1、必须安装reshacker.exe、upx.exe到Windows搜索路径中或脚本所在的目录。
2、编译时用ACNWrapper(SciTE中Ctrl-F7)
3、必须确保资源数据文件存在,并在相应的目录上,如:在当前脚本目录中
4、要体现效果必须运行编译后的EXE文件
5、当使用#AutoIt3Wrapper_Res_File_Add指令时,AutoIt3Wrapper自动添加UPX的“add --compress-resources=0”开关进行压缩编译。
6、编译时不要再选择UPX压缩,否则编译后的EXE文件不能运行
7、嵌入的资源会被reshacker.exe等工具编辑和替换,所以为保障自己作品的安全性,请另外加个好点的


本用户函数来自英文网站,英文好的可以研究一下这段英文说明:
You can embed any binary data into your AutoIt compiled EXE files in it's resources at compile time.
As opposite to FileInstall() with resources you can use your embedded data directly without any temporary files on disk.
If you wish you can save resources to disk with _ResourceSaveToFile() however.

Adding data to resources can be done simply by #AutoIt3Wrapper directive:
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, test_1.txt, rcdata, TEST_TXT_1, 0

As data can be used for example images,cursors,texts,sounds,binary files etc.
For loading/using data from resources at run time I made this tiny helper resources UDF.
Functions inside UDF:
_ResourceGet($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsString($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsStringW($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsBytes($ResName, $ResType = $RT_RCDATA, $ResLang = 0, $DLL = -1)
_ResourceGetAsImage($ResName, $ResType = $RT_RCDATA, $DLL = -1)
_ResourceGetAsBitmap($ResName, $ResType = $RT_RCDATA, $DLL = -1)
_ResourceSaveToFile($FileName, $ResName, $ResType = $RT_RCDATA, $ResLang = 0, $CreatePath = 0, $DLL = -1)
_ResourceSetImageToCtrl($CtrlId, $ResName, $ResType = $RT_RCDATA, $DLL = -1)
_SetBitmapToCtrl($CtrlId, $hBitmap)
_ResourcePlaySound($ResName, $Flag = 0, $DLL = -1)

Notes:
* to compile all script examples you must have installed Scite4AutoIt3 also with reshacker.exe/upx.exe in "Windows search path" or script directory -> you must compile script by F7 from full Scite
* to compile all script examples must be apropriate resource data files in script directory (from resource_data.zip)
* _ResourceGet() always returns pointer to data (for RT_BITMAP returns hBitmap), returning other types can be done by additional wrapper functions like _ResourceGetAsString() or _ResourceGetAsBytes()
* _ResourceGetAsStringW() is for Unicode strings (Widechar)
* general supported resource types are listed in UDF as constants ($RT_BITMAP, $RT_RCDATA, ...)
* more information/examples about using animated GIFs from resources is here and here thanks smashly/ProgAndy

Known problems/limitations:
* _ResourceGet() returns resource size (in bytes) in @extended macro but not for resource type RT_BITMAP
* _ResourceSetImageToCtrl() works only with static controls (picture,label,icon) - no support of buttons (for upcomming button support look at post #370)
* _ResourcePlaySound() plays only WAV files (not MP3 files)
* _ResourceGetAsBytes() doesn't work for RT_BITMAP type
because _ResourceGet() returns hBitmap instead of memory pointer in this case
there could be used _ResourceGetAsImage() as workaround
* _ResourceGet() has memory leak
releasing of resources UnlockResource,FreeResource (opposite of LoadResource,LockResource) is not done
because it must be done after using of resources at the end and not inside UDF
* _GDIPlus_Startup() is called once at start of whole include --> no _GDIPlus_Shutdown() is called
* don't use #AutoIt3Wrapper_Res_File_Add because of its bug (resources placed at wrong section with wrong name)

下面是一个au3源码例子:
#AutoIt3Wrapper_useupx=n
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, test_1.txt, rcdata, TEST_TXT_1, 0
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, image1.bmp, bitmap, TEST_BMP_1, 0
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, image2.bmp, bitmap, TEST_BMP_2, 0
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, image3.jpg, rcdata, TEST_JPG_3, 0
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, binary1.dat, rcdata, TEST_BIN_1, 0
#AutoIt3Wrapper_run_after=ResHacker.exe -add %out%, %out%, C:\WINDOWS\Media\tada.wav, sound, TEST_WAV_1, 0
#AutoIt3Wrapper_run_after=upx.exe --best --compress-resources=0 "%out%"

#include "resources.au3"

$gui = GUICreate("Data from resources example",820,400)
$pic1 = GUICtrlCreatePic("",0,0,400,300)
$pic2 = GUICtrlCreatePic("",400,0,400,150)
$pic3 = GUICtrlCreatePic("",400,150,400,150)
$pic4 = GUICtrlCreatePic("",600,320,400,100)
$label1 = GUICtrlCreateLabel("",20,320,380,100)
$label2 = GUICtrlCreateLabel("",400,320,200,100)
GUISetState(@SW_SHOW)

; get string from resource
$string = _ResourceGetAsString("TEST_TXT_1")
GUICtrlSetData($label1, $string)

; set BMP image to picture control from resourcebitmap
_ResourceSetImageToCtrl($pic1, "TEST_BMP_1", $RT_BITMAP)

; get bitmap from resource (as pointer)
$hBmp = _ResourceGet("TEST_BMP_2", $RT_BITMAP)
; and use it for whatever you like
_SetBitmapToCtrl($pic2, $hBmp)

; set JPG image to picture control from resource
_ResourceSetImageToCtrl($pic3, "TEST_JPG_3")

; set image to picture control from external DLL resource
_ResourceSetImageToCtrl($pic4, "#14355", $RT_BITMAP, @SystemDir & "\shell32.dll")

; get/use picture from resources as hImage type
$size1 = _ResourceGetImageSize("TEST_BMP_1", $RT_BITMAP)
$size2 = _ResourceGetImageSize("TEST_JPG_3")
GUICtrlSetData($label2, $size1 & @CRLF & $size2)

; save binary data or another type (image) from resource to file and get its size in bytes
$size1 = _ResourceSaveToFile(@ScriptDir & "\binary_data1.dat", "TEST_BIN_1")
$size2 = _ResourceSaveToFile(@ScriptDir & "\binary_data2.bmp", "TEST_BMP_1", $RT_BITMAP)

; save binary data from resource to file (create not existing directory)
_ResourceSaveToFile("C:\Dir1\SubDir2\binary_data1.dat", "TEST_BIN_1", $RT_RCDATA, 0, 1)
_ResourceSaveToFile("C:\Dir1\SubDir2\binary_data2.bmp", "TEST_BMP_1", $RT_BITMAP, 0, 1)

; play WAV from resource (sync/async)
_ResourcePlaySound("TEST_WAV_1")
_ResourcePlaySound("TEST_WAV_1", $SND_ASYNC)

While 1
    If GUIGetMsg() = -3 Then Exit
WEnd

Func _ResourceGetImageSize($ResName, $ResType = 10) ; $RT_RCDATA = 10
    ; get/use picture from resources as hImage type
    $hImage = _ResourceGetAsImage($ResName, $ResType)
    $width =_GDIPlus_ImageGetWidth ($hImage)
    $height = _GDIPlus_ImageGetHeight($hImage)
   
    Return "Size of " & $ResName & " is: " & $width & "x" & $height
EndFunc

guland 发表于 2010-2-9 18:28:53

下来看看

qvvcity 发表于 2010-2-9 21:48:53

看一下,谢谢

benkel 发表于 2010-2-10 10:11:42

最新版本的AU3能用么?

rikthhpgf2005 发表于 2010-2-11 17:52:26

:face (26):

myloveqmx 发表于 2010-2-17 13:53:30

支持一下,以前没注意看帮助文档,原来还可以用命令行的~:face (32):

analyzer 发表于 2010-2-19 18:26:29

看一看,谢谢分享

thealert 发表于 2010-11-27 17:24:17

看一看,谢谢分享

qq342252004 发表于 2010-12-2 14:57:15

不知道怎么用。

shengtools 发表于 2010-12-28 17:28:52

内置运行,很好啊

志义工作室 发表于 2011-3-22 14:04:26

{:face (356):}
好东西..学习了.!

powerofos 发表于 2011-5-14 19:07:18

好像有点。。。麻烦??

haijie1223 发表于 2011-9-6 10:10:13

下载了 谢谢分享 支持了

xms77 发表于 2011-9-6 12:45:11

看一看,谢谢分享

ayumi502 发表于 2011-11-3 17:41:04

学习了 谢谢分享
页: [1] 2
查看完整版本: 编译的时候,用AutoIt编译EXE文件时,您可以嵌入任何二进制数据到EXE文件中