16

実行可能バイナリから文字列を抽出してファイルに保存するスクリプトを作成しようとしています。文字列自体に改行が含まれている可能性があるため、このファイルを改行で区切ることはできません。ただし、これは、UNIX の「strings」ユーティリティを使用するオプションがないことも意味します。これは、改行で区切られたすべての文字列を出力するだけなので、の出力を見るだけで、どの文字列に改行が含まれているかを知る方法がないことを意味します。 「弦」。したがって、「文字列」と同じ機能を実装するPython関数またはライブラリを見つけたいと思っていましたが、改行の問題を回避できるように、これらの文字列を変数として提供します。

ありがとう!

4

4 に答える 4

24

以下は、 で検出された長さが >= min(デフォルトでは 4)の印刷可能な文字のすべての文字列を生成するジェネレータfilenameです。

import string

def strings(filename, min=4):
    with open(filename, errors="ignore") as f:  # Python 3.x
    # with open(filename, "rb") as f:           # Python 2.x
        result = ""
        for c in f.read():
            if c in string.printable:
                result += c
                continue
            if len(result) >= min:
                yield result
            result = ""
        if len(result) >= min:  # catch result at EOF
            yield result

あなたが繰り返すことができるもの:

for s in strings("something.bin"):
    # do something with s

...またはリストに保存します:

sl = list(strings("something.bin"))

stringsこれを非常に簡単にテストしましたが、選択した任意のバイナリ ファイルに対してUnix コマンドと同じ出力が得られるようです。ただし、これは非常にナイーブで (最初は、ファイル全体を一度にメモリに読み込むため、大きなファイルではコストがかかる可能性があります)、Unixstringsコマンドのパフォーマンスに近づく可能性はほとんどありません。

于 2013-06-19T16:55:46.857 に答える
6

引用するにはman strings

STRINGS(1) GNU 開発ツール STRINGS(1)

名前
       strings - ファイル内の印刷可能な文字列を印刷します。

[...]
説明
       指定されたファイルごとに、GNU 文字列は印刷可能な文字を出力します
       少なくとも 4 文字の長さのシーケンス (または
       以下のオプション)、その後に印刷不能文字が続きます。に
       デフォルトでは、初期化およびロードされた文字列のみを出力します
       オブジェクト ファイルのセクション。他のタイプのファイルの場合は、
       ファイル全体の文字列。

一致する少なくとも 4 つの印刷可能な文字を使用することで、同様の結果を得ることができます。regexそんな感じ:

>>> import re

>>> content = "hello,\x02World\x88!"
>>> re.findall("[^\x00-\x1F\x7F-\xFF]{4,}", content)
['hello,', 'World']

このソリューションでは、ファイル コンテンツ全体をメモリにロードする必要があることに注意してください。

于 2013-06-19T16:28:31.893 に答える
0

文字列コマンドを使用すると、出力セパレータを で変更--output-separatorできるため、改行文字の代わりにカスタム文字列を使用できます (バイナリ ファイルでは見つからないもの)。改行を含めるには、次のようにします--include-all-whitepaces

$ strings --include-all-whitespace --output-separator="YOURSEPARATOR" test.bin

于 2021-12-18T20:50:25.037 に答える