找回密码
 加入
搜索
楼主: cashiba

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

[复制链接]
发表于 7 天前 | 显示全部楼层
本帖最后由 holley 于 2024-11-27 16:48 编辑

借用老大的普适代码,让gpt弄了个GUI,右键图标不知道为什么不生效
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <WinAPIGdi.au3>
#include <WinAPIShellEx.au3>

Opt("MustDeclareVars", 1)

Func IsPEFile64($FilePath)
    Local $hFile = FileOpen($FilePath, 16)
    If $hFile = -1 Then Return "无法打开文件"

    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 "非PE文件"
    EndIf

    If $aBin[$Index + 4] = 100 And $aBin[$Index + 5] = 134 Then
        Return "64位"
    EndIf

    Return "32位"
EndFunc

Func GetFileType($FilePath)
    Local $fileParts = StringSplit($FilePath, ".")
    If @error Then Return "未知文件类型"

    Local $fileExtension = StringLower($fileParts[$fileParts[0]])
    If $fileExtension = "exe" Then
        Return "EXE"
    ElseIf $fileExtension = "dll" Then
        Return "DLL"
    Else
        Return "未知文件类型"
    EndIf
EndFunc

GUICreate("文件位数查看器", 800, 600)
Local $listView = GUICtrlCreateListView("文件名|文件路径|文件位数", 10, 10, 780, 550)
GUICtrlSendMsg($listView, $LVM_SETTEXTBKCOLOR, 0, 0xFFFFFF)
Local $contextMenu = GUICtrlCreateContextMenu($listView)
Local $menuItem1 = GUICtrlCreateMenuItem("添加文件", $contextMenu)
GUICtrlCreateMenuItem("", $contextMenu)
Local $menuItemExit = GUICtrlCreateMenuItem("退出", $contextMenu)

Local $hIcon1 = _WinAPI_LoadIcon(_WinAPI_GetModuleHandle("shell32.dll"), 128)
Local $hIconExit = _WinAPI_LoadIcon(_WinAPI_GetModuleHandle("shell32.dll"), 136)

_SetMenuItemIcon($contextMenu, $menuItem1, $hIcon1)
_SetMenuItemIcon($contextMenu, $menuItemExit, $hIconExit)

GUICtrlSetResizing($listView, 1)

Func AddFilesToList($listView)
    Local $FilePaths = FileOpenDialog("请选择一个或多个可执行文件或 DLL 文件", "", "可执行文件 (*.exe; *.dll)|所有文件 (*.*)", 1 + 4)

    If @error Then Return

    Local $fileArray = StringSplit($FilePaths, "|")
    Local $aItems[UBound($fileArray) - 1][3]
    Local $validItemCount = 0

    For $i = 1 To $fileArray[0]
        Local $filePath = $fileArray[$i]
        If FileExists($filePath) And Not StringRegExp($filePath, "\.exe$|\.dll$", 0) Then
            ContinueLoop
        EndIf

        If FileExists($filePath) Then
            Local $fileName = StringRegExp($filePath, "[^\\]+$", 3)
            Local $fileType = GetFileType($filePath)
            Local $peStatus = IsPEFile64($filePath)

            $aItems[$validItemCount][0] = $fileName[0]
            $aItems[$validItemCount][1] = _WinAPI_GetFullPathName($filePath)
            $aItems[$validItemCount][2] = $fileType & " (" & $peStatus & ")"
            $validItemCount += 1
        EndIf
    Next

    If $validItemCount > 0 Then
        ReDim $aItems[$validItemCount][3]
        _GUICtrlListView_AddArray($listView, $aItems)
        For $j = 0 To 2
            DllCall("user32.dll", "int", "SendMessage", "hwnd", $listView, "int", $LVM_SETCOLUMNWIDTH, "int", $j, "int", $LVSCW_AUTOSIZE)
        Next
    EndIf
EndFunc

AddFilesToList($listView)
GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $menuItem1
            AddFilesToList($listView)
        Case $menuItemExit
            Exit
    EndSwitch
WEnd

Func _SetMenuItemIcon($hMenu, $menuItem, $hIcon)
    Local $hBitmap = _ConvertIconToBitmap($hIcon)
    Local $tMii = DllStructCreate("uint;uint;ptr;ptr;uint;int;int;ptr;uint;uint")
    DllStructSetData($tMii, 1, BitOR(0x00000080, 0x00000010))
    DllStructSetData($tMii, 3, $hBitmap)
    DllStructSetData($tMii, 5, $menuItem)
    DllCall("user32.dll", "int", "SetMenuItemInfoW", "hwnd", $hMenu, "uint", $menuItem, "int", 0, "ptr", DllStructGetPtr($tMii))
EndFunc

Func _ConvertIconToBitmap($hIcon)
    Local $hDC = _WinAPI_GetDC(0)
    Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, 16, 16)
    Local $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    _WinAPI_DrawIconEx($hMemDC, 0, 0, $hIcon, 16, 16, 0, 0, 3)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_ReleaseDC(0, $hDC)
    _WinAPI_DeleteDC($hMemDC)
    Return $hBitmap
EndFunc
发表于 6 天前 | 显示全部楼层

发哥的这个估计没几个人能看得懂,应该是解析PE文件的特征吧,我发个大家都能看得懂的
Func _GetArch($sFilePath)
        Local $hFile = FileOpen($sFilePath, 16)
        Local $bBinary = FileRead($hFile)
        FileClose($hFile)
        Local $tBinary = DllStructCreate("byte[" & BinaryLen($bBinary) & "]")
        DllStructSetData($tBinary, 1, $bBinary) ; fill it
        Local $pPointer = DllStructGetPtr($tBinary)
        Local $tIMAGE_DOS_HEADER = DllStructCreate("char Magic[2];" & _
                        "word BytesOnLastPage;" & _
                        "word Pages;" & _
                        "word Relocations;" & _
                        "word SizeofHeader;" & _
                        "word MinimumExtra;" & _
                        "word MaximumExtra;" & _
                        "word SS;" & _
                        "word SP;" & _
                        "word Checksum;" & _
                        "word IP;" & _
                        "word CS;" & _
                        "word Relocation;" & _
                        "word Overlay;" & _
                        "char Reserved[8];" & _
                        "word OEMIdentifier;" & _
                        "word OEMInformation;" & _
                        "char Reserved2[20];" & _
                        "dword AddressOfNewExeHeader", _
                        $pPointer)
        $pPointer += DllStructGetData($tIMAGE_DOS_HEADER, "AddressOfNewExeHeader") ; move to PE file header 移动到PE文件头
        Local $sMagic = DllStructGetData($tIMAGE_DOS_HEADER, "Magic")
        If Not ($sMagic == "MZ") Then
                Return SetError(1, 0, 'unkown') ; MS-DOS header missing. MS-DOS标头丢失。
        EndIf
        Local $tIMAGE_NT_SIGNATURE = DllStructCreate("dword Signature", $pPointer)
        ; Move pointer 移动指针
        $pPointer += 4 ; size of $tIMAGE_NT_SIGNATURE structure $tMAGE_NT_SIGNATURE结构的大小
        ; Check signature 检查签名
        If DllStructGetData($tIMAGE_NT_SIGNATURE, "Signature") <> 17744 Then ; IMAGE_NT_SIGNATURE
                Return SetError(2, 0, 'unkown') ; wrong signature. For PE image should be "PE\0\0" or 17744 dword.签名错误。对于PE,图像应为“PE\0\0”或17744双字。
        EndIf
        $pPointer += 20 ; size of $tIMAGE_FILE_HEADER structure
        Local $tMagic = DllStructCreate("word Magic;", $pPointer)
        Local $iMagic = DllStructGetData($tMagic, 1)
        Select
                Case $iMagic = 267
                        Return 'x86'
                Case $iMagic = 523
                        Return 'x64'
                Case Else
                        Return 'unkown'
        EndSelect
EndFunc   ;==>_GetArch

发表于 5 天前 | 显示全部楼层
tubaba 发表于 2024-11-28 09:32
发哥的这个估计没几个人能看得懂,应该是解析PE文件的特征吧,我发个大家都能看得懂的

被大佬洞悉一切
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-12-4 16:13 , Processed in 0.100445 second(s), 14 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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