找回密码
 加入
搜索
查看: 244|回复: 18

[AU3基础] 判断dll或exe文件是32位还是64位的函数[已解决]

[复制链接]
发表于 2024-11-22 10:59:21 | 显示全部楼层 |阅读模式
本帖最后由 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。
期待高手完善或创新....

发表于 2024-11-22 12:52:14 | 显示全部楼层
试试 _WinAPI_GetBinaryType
发表于 2024-11-22 19:30:31 | 显示全部楼层
早前我自己写的。大家讨论,共同进步!
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

发表于 2024-11-22 19:33:18 | 显示全部楼层
补充:主要是针对 SnapShot 备份还原软件
 楼主| 发表于 2024-11-22 20:00:20 | 显示全部楼层
afan 发表于 2024-11-22 12:52
试试 _WinAPI_GetBinaryType

原来早就有现成的api原型函数了,A大博闻强识,啥都知道,强!
 楼主| 发表于 2024-11-22 20:02:03 | 显示全部楼层
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就太简单了,还很详细
 楼主| 发表于 2024-11-22 20:08:03 | 显示全部楼层
chishingchan 发表于 2024-11-22 19:30
早前我自己写的。大家讨论,共同进步!

这个用了汇编方法?....厉害!

点评

非汇编,是流  发表于 2024-11-22 20:26
 楼主| 发表于 2024-11-22 20:18:11 | 显示全部楼层
GetBinaryTypeW好像只针对可执行文件(exe),对dll没效果...

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2024-11-22 20:28:29 | 显示全部楼层
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
发表于 2024-11-23 11:03:32 | 显示全部楼层
凑个热闹

Func IsPEFile64($FilePath)
        Local $hFile = FileOpen($FilePath, 16)
        Local $Bin = FileRead($hFile, 1024)
        FileClose($hFile)
        Local $aBin[BinaryLen($Bin)]
        For $i = 0 To UBound($aBin) - 1
                $aBin[$i] = Number(BinaryMid($Bin, $i + 1, 1))
        Next
        Local $Index = $aBin[60] + $aBin[61] * 256 + $aBin[62] * 65536 + $aBin[63] * 16777216
        If $aBin[0] <> 77 Or $aBin[1] <> 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  


 楼主| 发表于 2024-11-24 09:53:55 | 显示全部楼层
本帖最后由 cashiba 于 2024-11-24 09:55 编辑

------>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

 楼主| 发表于 2024-11-24 10:08:59 | 显示全部楼层
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   ;==>_UPX
chishingchan 班主的代码改了一下(如上,不知道改得对不对)
再次测试了一下,结果如下:

------>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'):



发表于 2024-11-24 10:57:38 | 显示全部楼层
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

发表于 2024-11-24 10:58:56 | 显示全部楼层
此方法是根據 PE 頭的特徵,使用流對象對其讀取進行判斷。
发表于 2024-11-24 12:43:22 | 显示全部楼层
cashiba 发表于 2024-11-24 09:53
------>IsPEFile('C:\Program Files (x86)\Windows Media Player\setup_wm.exe'):
32
-->FileCheckBit('C: ...

必须普适啊,这个如果不适用,我想那就没有适用的了吧
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-7 18:53 , Processed in 0.079880 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表