簡體   English   中英

什么正則表達式字符串可以區分包含“PE null null L”和“PE null null d”的文件

[英]What regex strings can distinguish files containing "PE null null L" from "PE null null d"

我需要一種快速簡便的方法來了解給定目錄中有多少 dll 是 32 位的,有多少是 64 位的。 當我想到一個更簡單的解決方案時,我正准備編寫一個 PowerShell 腳本。 我在下面展示了我的想法可以工作,但我需要一點正則表達式幫助才能使其正常工作。

已經證明可以在記事本中打開 dll 文件,只需檢查第一個“ PE ”之后的字符即可顯示位數(32 或 64)。 字母“ L ”和“ d ”分別表示 32 位和 64 位引用 Notepad++ 或十六進制編輯器會更准確地顯示“ PE ”和下圖中從 Notepad++ 復制的另一個字符之間實際上有 2 個 null 個字符。

Notepad++打開的dll截圖

不幸的是,我的一些目錄包含數百個 dll,因此使用記事本或任何其他實用程序一次打開它們是不切實際的。 但是,有一些功能強大的“支持 grep”的文件搜索實用程序可以在目錄中搜索包含指定搜索字符串的文件。 此外,其中一些可以進行正則表達式(regex) 搜索。 因為我知道區分 32 位和 64 位 dll 的唯一字符串(如上所示),所以這樣的文件搜索實用程序應該能夠快速清點任何目錄中的 dll 類型。 在我看來,最好的此類文件搜索實用程序是grepWin ,它可以免費下載和安裝。

我的第一次嘗試是正則表達式搜索字符串“.PE("\x00")*",它可以分解如下。

正則表達式字符串 ".PE("\x00")*" 的分解

下圖顯示了使用 grepWin 和搜索字符串“.PE("\x00")*”對指定目錄進行的搜索結果,其中包含 276 個 dll 個文件。 它顯示找到的 276 個 dll 中有 276 個包含“ PE ”,后跟多個 null 個字符。 它還顯示實際上找到了數千個匹配項。 這是因為正則表達式搜索在第一次匹配后繼續進行,並在不可避免地“隨機”出現的較大文件中找到了更多匹配項。

在此處輸入圖像描述

下表顯示了OOO提出的正則表達式字符串“ PE.{2}L ”和“ PE.{2}d ”的搜索結果。 這些搜索字符串找到所有文件,但不幸的是,某些 dll 文件被計算了兩次,因為 32 位和 64 位 dll 的總和超過了目錄中 dll 文件的總數。

找到包含“PE.{2}L”和“PE.{2}d”的文件

以下使用“ PE.{2}L ”和“ PE.{2}d ”搜索結果的屏幕截圖顯示匹配項超過了找到的文件數,這意味着正則表達式搜索超出了第一個匹配項。

使用“PE.{2}L”和“PE.{2}d”的 grepWin 詳細信息

所以我只需要知道如何修改這些正則表達式搜索字符串以在找到第一個“ PE ”后停止搜索 3 個字符。 我知道這可以使用“ .*? ”修飾符來完成,但我無法讓它工作。 這是我的問題。

• 如何修改這些搜索字符串以在找到第一個“ PE ”后停止讀取3 個字符?

可以通過使用 grepWin 搜索任何 dll 目錄來驗證任何正則表達式搜索字符串。 為了正確起見,搜索字符串必須產生與文件相同數量的匹配項,這與上面顯示的示例不同。 這將驗證搜索是否在找到第一個匹配項后停止。

這不可能是真的:

  • 正則表達式.PE("\x00")*將搜索:
    1. 任何字符(為什么要排除在文件開頭找到它的權利?)

    2. 角色P

    3. 字符E

    4. 組:

      1. 字符"
      2. 字節值00對應的字符
      3. 字符"

      ...根據*匹配數量從從不到無數(為什么不想要恰好 2 個?)

  • 搜索PE\x00\x00不是更好嗎? 除非grepWin帶有自己的正則表達式風格,其中組中的引號具有特殊含義。 但我對此深表懷疑。
  • 正則表達式PE.{2}LPE.{2}d就像沒有人會使用的短語。 為什么不直接寫PE..L

從技術角度

我們可以進一步限制正則表達式不要過度匹配太多誤報,也不要忽略我們還應該檢查的東西(這有助於了解可移植可執行文件的布局是什么樣的):

  • 每個可執行文件都以DOS header 開頭,它總是 64 字節長並且幾乎總是MZ開頭(在極少數/歷史情況下也是ZMNE ,但不是我們的例子)。

  • NT header始終以PE\0\0 (或十六進制50 45 00 00或正則表達式PE\x00\x00 )開頭,然后\x64\x86 (對於 64 位)或\x4c\x01 (對於 32 位)。 這個 header 可以晚得多開始,但我們可以安全地假設在文件的前 2048 個字節內找到它(很可能已經在 240 個字節之后)。

    同樣在18 個字節之后,我們很可能得到字節\x0b\x01\x0b\x02 (或者在極少數情況下\x07\x01 )。

更好的正則表達式

  • 對於 x64(64 位)搜索^MZ.{62,2046}PE\x00\x00\x64\x86.{18}\x0b[\x01\x02]
  • 對於 x86(32 位)搜索^MZ.{62,2046}PE\x00\x00\x4c\x01.{18}\x0b[\x01\x02]

如果你的目標軟件崩潰了(盡管它贊揚它的正則表達式支持,比如grepWin )那么

  • 要么完全省略匹配 DOS header(刪除^MZ.{62,2046}
  • 或者嘗試將重復減少到更小的重復,fe {62,280}

解釋:

  1. 從文件的開頭開始(實際上只是“行”的開頭)

  2. 字符MZM ark Z bikowski)

  3. 任何字符至少 62 次,但最多 2046 次(像Notepad++這樣的文本編輯器可能會抱怨我們的正則表達式太復雜,這就是我們還定義最大值的原因)

  4. 字符PE移植可執行)

  5. 字節00 00

  6. CPU架構

    • 64 位 (AMD) 的字節\x64\x86 ,或
    • 字節\x4c\x01用於 32 位(Intel 386 或更高版本)。

    不要只依賴光學器件( dL ),因為那樣你會忽略一半的值,只會冒更多誤報的風險)。

  7. 任意字符恰好 18 次

  8. 字節0b

  9. 字節0102

測試成功

  • 使用Notepad++ 8.4.8 x64(確保勾選.匹配換行符
  • C:\Windows\System32\quartz.dll
  • 使用 Windows 7 x64(所以 DLL 應該是 64 位):

Notepad++ 正則表達式匹配 DOS 和 NT 標頭

這里的一大優勢是這個正則表達式很可能只匹配一次而不是多次,尤其是在 DLL 中。 然而,由於可執行文件沒有“結束”標記,它們之后可以攜帶任何格式的數據。 不受意圖的約束(好的 = 自解壓檔案,壞的 = 病毒)幾乎沒有辦法排除這些 - 如果我們幸運的話,我們的^可以幫助我們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM