判断dll或exe文件是32位还是64位的函数[已解决]
本帖最后由 cashiba 于 2024-11-25 23:59 编辑Func FileCheckBit($file)
Local $b = ""
Local $f = StringLeft($file, StringInStr($file, "", 0, -1)) & "bitchk"
If FileCopy($file, $f, 9) Then
Local $h = FileOpen($f, 16)
If $h <> -1 Then
Local $s = FileRead($h)
If StringInStr($s, "504500004C") Then
$b = "x86"
ElseIf StringInStr($s, "5045000064") Then
$b = "x64"
EndIf
EndIf
FileDelete($f)
EndIf
Return $b
EndFunc
有时某些dll或exe文件不知道是32位或64位的,跟系统不一致会导致出错或没反应,需要提前判断一下
搜了一下没找到类似的主题或函数(可能检索词没选好),有的话请给个链接
用这个来检测某些dll文件或exe文件是64位还是32位,简单测了一下sqlite3.dll可行。
原理参照:https://www.cnblogs.com/God4/articles/11721559.html之第三个方法
感觉上面的写法还不太严谨, 比喻说32位或64位系统都可用的dll或exe。
期待高手完善或创新....
试试 _WinAPI_GetBinaryType 早前我自己写的。大家讨论,共同进步!
Func _UPX($File) ;获取文件架构,压缩状态,版本日期
Local $PE_Header, $Return, $Bit, $UPX0
$ADODB_Stream = ObjCreate("ADODB.Stream") ;创建流对象
$ADODB_Stream.Type = 1 ;数据类型
$ADODB_Stream.Open ;打开流
$ADODB_Stream.LoadFromFile($File) ;以流方式加载文件
$ADODB_Stream.Position = 0x3C ;PE..
$PE_Header = $ADODB_Stream.Read(4) ;=0xF0970000
$ADODB_Stream.Position = _H2L($PE_Header) + 0x14 ;0x000097F0 + 0x00000014 = 0x00009804
$Bit = StringTrimRight($ADODB_Stream.Read(2), 2) ;=0xE000=0xE0
If $File <> $setup_exe Then
If $Bit = 0xE0 Then ;如果等于 0xE0
;$Bit = "X86" ;是32位程序
$ADODB_Stream.Position = _H2L($PE_Header) + 0xF8 ;32位 UPX0 的地址偏移量
$UPX0 = BinaryToString($ADODB_Stream.Read(4)) ;读取4个字节并转换为字符串
Else ;如果不等于 0xE0
;$Bit = "X64" ;是64位程序
$ADODB_Stream.Position = _H2L($PE_Header) + 0x108 ;64位 UPX0 的地址偏移量
$UPX0 = BinaryToString($ADODB_Stream.Read(4)) ;读取4个字节并转换为字符串
EndIf
$ADODB_Stream.Close ;关闭流
If $UPX0 = "UPX0" Then
$UPX = True
Else
$UPX = False
EndIf
Return $UPX
EndIf
EndFunc
补充:主要是针对 SnapShot 备份还原软件 afan 发表于 2024-11-22 12:52
试试 _WinAPI_GetBinaryType
原来早就有现成的api原型函数了,A大博闻强识,啥都知道,强!
{:1_206:} chishingchan 发表于 2024-11-22 19:33
补充:主要是针对 SnapShot 备份还原软件
#include <APIFilesConstants.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>
Local $sText, $sPath = @MyDocumentsDir & '\'
While 1
$sPath = FileOpenDialog(''选择文件', _WinAPI_PathRemoveFileSpec($sPath), '所有文件 (*.*)', 1 + 2)
If $sPath Then
If _WinAPI_GetBinaryType($sPath) Then
Switch @extended
Case $SCS_32BIT_BINARY
$sText = ' 32 位 Windows 应用程序.'
Case $SCS_64BIT_BINARY
$sText = ' 64 位 Windows 应用程序.'
Case $SCS_DOS_BINARY
$sText = ' MS-DOS 应用程序.'
Case $SCS_OS216_BINARY
$sText = ' 16 位 OS/2 应用程序.'
Case $SCS_PIF_BINARY
$sText = ' MS-DOS 应用程序的 PIF 文件.'
Case $SCS_POSIX_BINARY
$sText = ' POSIX 应用程序.'
Case $SCS_WOW_BINARY
$sText = ' 16 位 Windows 应用程序.'
Case Else
$sText = ' 未知类型的可执行文件.'
EndSwitch
Else
$sText = ' 不是可执行文件.'
EndIf
MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL), '_WinAPI_GetBinaryType()', '"' & _WinAPI_PathStripPath($sPath) & '" 是 ' & $sText & ".")
Else
ExitLoop
EndIf
WEnd
有这个API就太简单了,还很详细 chishingchan 发表于 2024-11-22 19:30
早前我自己写的。大家讨论,共同进步!
这个用了汇编方法?....厉害!
{:1_206:} GetBinaryTypeW好像只针对可执行文件(exe),对dll没效果... cashiba 发表于 2024-11-22 20:08
这个用了汇编方法?....厉害!
补充一个函数:
Func _H2L($Binary) ;十六进制字符串高低位转换
Local $L2H
For $i = 1 To StringLen(Hex($Binary)) Step 2
$L2H = StringMid(Hex($Binary), $i, 2) & $L2H
Next
$L2H = "0x" & $L2H
Return $L2H
EndFunc ;==>_H2L 凑个热闹
Func IsPEFile64($FilePath)
Local $hFile = FileOpen($FilePath, 16)
Local $Bin = FileRead($hFile, 1024)
FileClose($hFile)
Local $aBin
For $i = 0 To UBound($aBin) - 1
$aBin[$i] = Number(BinaryMid($Bin, $i + 1, 1))
Next
Local $Index = $aBin + $aBin * 256 + $aBin * 65536 + $aBin * 16777216
If $aBin <> 77 Or $aBin <> 90 Or $aBin[$Index] <> 80 Or $aBin[$Index + 1] <> 69 Then Return 0
If $aBin[$Index + 4] = 100 And $aBin[$Index + 5] = 134 Then Return 64
Return 32
EndFunc ;==>IsPEFile64
Local $FilePath = "D:\autoit3\AutoIt3_x64.exe" ; 替换为你的文件路径
Switch IsPEFile64($FilePath)
Case 64
ConsoleWrite("64位程序" & @CRLF)
Case 32
ConsoleWrite("32位程序" & @CRLF)
Case Else
ConsoleWrite("非可执行文件" & @CRLF)
EndSwitch
本帖最后由 cashiba 于 2024-11-24 09:55 编辑
haijie1223 发表于 2024-11-23 11:03
凑个热闹
------>IsPEFile('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
-->FileCheckBit('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
------>IsPEFile('C:\Program Files\Windows Media Player\setup_wm.exe'):
64
-->FileCheckBit('C:\Program Files\Windows Media Player\setup_wm.exe'):
64
------>IsPEFile('C:\Program Files (x86)\Windows Media Player\WMPDMCCore.dll'):
32
-->FileCheckBit('C:\Program Files (x86)\Windows Media Player\WMPDMCCore.dll'):
------>IsPEFile('C:\Program Files\Windows Media Player\WMPDMCCore.dll'):
64
-->FileCheckBit('C:\Program Files\Windows Media Player\WMPDMCCore.dll'):
拿一般系统中都有的程序文件左了测试如上。
发哥这个比较普适,优于_WinAPI_GetBinaryType
Func _UPX($file)
Local $Bit = ""
$ADODB_Stream = ObjCreate("ADODB.Stream")
$ADODB_Stream.Type = 1
$ADODB_Stream.Open
$ADODB_Stream.LoadFromFile($file)
$ADODB_Stream.Position = 0x3C
$Bit = StringTrimRight($ADODB_Stream.Read(2), 2)
If $Bit = 0xE0 Then
$Bit = "64"
Else
$Bit = "32"
EndIf
$ADODB_Stream.Close
Return $Bit
EndFunc ;==>_UPXchishingchan 班主的代码改了一下(如上,不知道改得对不对)
再次测试了一下,结果如下:
------>IsPEFile('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
---------->_UPX('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
-->FileCheckBit('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
------>IsPEFile('C:\Program Files\Windows Media Player\setup_wm.exe'):
64
---------->_UPX('C:\Program Files\Windows Media Player\setup_wm.exe'):
64
-->FileCheckBit('C:\Program Files\Windows Media Player\setup_wm.exe'):
64
------>IsPEFile('C:\Program Files (x86)\Windows Media Player\WMPDMCCore.dll'):
32
---------->_UPX('C:\Program Files (x86)\Windows Media Player\WMPDMCCore.dll'):
32
-->FileCheckBit('C:\Program Files (x86)\Windows Media Player\WMPDMCCore.dll'):
------>IsPEFile('C:\Program Files\Windows Media Player\WMPDMCCore.dll'):
64
---------->_UPX('C:\Program Files\Windows Media Player\WMPDMCCore.dll'):
32
-->FileCheckBit('C:\Program Files\Windows Media Player\WMPDMCCore.dll'):
cashiba 发表于 2024-11-24 10:08
chishingchan 班主的代码改了一下(如上,不知道改得对不对)
再次测试了一下,结果如下:
連函數名稱也一并改了吧!
Func _Bit($file)
Local $Bit = ""
$ADODB_Stream = ObjCreate("ADODB.Stream")
$ADODB_Stream.Type = 1
$ADODB_Stream.Open
$ADODB_Stream.LoadFromFile($file)
$ADODB_Stream.Position = 0x3C
$Bit = StringTrimRight($ADODB_Stream.Read(2), 2)
If $Bit = 0xE0 Then
$Bit = "64"
Else
$Bit = "32"
EndIf
$ADODB_Stream.Close
Return $Bit
EndFunc ;==>_Bit
此方法是根據 PE 頭的特徵,使用流對象對其讀取進行判斷。 cashiba 发表于 2024-11-24 09:53
------>IsPEFile('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
-->FileCheckBit('C: ...
必须普适啊,这个如果不适用,我想那就没有适用的了吧
页:
[1]
2