🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

9800閲覧

バイナリファイルからバイナリ列を検索したいです。

flag2

総合スコア5

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/12/20 15:23

編集2019/12/20 15:26

前提・実現したいこと

pythonです。

まず、exeファイルなどをバイナリデータで読み込んで、16進数でダンプした後、
ASCIIコードで表記できる特定の16進数のバイナリ列(RegCreate)が存在するかどうかチェックして知らせてくれるものが作りたいです。

ASCIIコードではRegCreate の文字列は16進数だと52 65 67 43 72 65 61 74 65 4B 65 79
なので、これらとマッチするバイナリ列があるか判定したいんです。
ここを参考にしました。https://qiita.com/taka_baya/items/c22bd5f5e7cb3de90988[16進数でダンプして文字も表記]

文字表記できるものを表示するソースは大体わかったのですが、バイナリサーチする方法がわかりません。
どうしたらいいでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

バイナリデータとして読み込んで、bytes.find() で検索すればよいです。

組み込み型 — Python 3.8.1 ドキュメント

複数ある場合は最初に見つかったインデックス、見つからない場合は -1 を返します。

python

1data = "Hello World!" 2 3with open("sample.bin", "w") as f: 4 f.write(data) 5 6target = b"\x6f\x72\x6c" 7with open("sample.bin", 'rb') as f: 8 s = f.read() 9idx = s.find(target) 10print(idx) # 先頭から 7 bytes 目にある

イメージ説明

追記

リンク先を参考に作ってみました。
リンク先では1バイトずつ読み込んで表示するようになっているので、あとから検索するといったことができません。
なので、read() で中身を全部読み込んでしまって、attribute としてもっておき、あとから参照できるように変更しました。
また一部冗長な箇所も修正しました。

python

1class BinaryViewer: 2 def print_headers(self): 3 """ヘッダーを表示する。 4 """ 5 print("Offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F Encode to ASCII") 6 7 def byte_to_char(self, s): 8 """ascii の英数字及び記号の場合、str に変換して返します。 9 ASCIIコード表 http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html 10 """ 11 if 33 <= s < 126: 12 return chr(s) 13 else: 14 return "." 15 16 def read_file(self, filepath): 17 # ファイルを読み込む。 18 with open(filepath, "rb") as f: 19 self.data = f.read() 20 21 # ヘッダーを表示する。 22 self.print_headers() 23 24 # 1バイトずつ読み込む。 25 ascii_string = "" 26 for offset, byte in enumerate(self.data): 27 ascii_string += self.byte_to_char(byte) 28 29 if offset % 16 == 0: 30 # 先頭の列の場合、その行のオフセットを表示する。 31 print(f"{offset:06X}", end=" ") 32 33 print(f"{byte:02x}", end=" ") 34 35 if offset % 16 == 15: 36 # 末尾の列の場合、その行の ascii 文字列を表示する。 37 print(ascii_string) 38 ascii_string = "" 39 40 def search(self, target): 41 return self.data.find(target) 42 43 44viewer = BinaryViewer() 45viewer.read_file("sample.html") 46 47index = viewer.search(b"html") 48print(index)

投稿2019/12/20 16:25

編集2019/12/20 17:14
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

flag2

2019/12/20 16:32

ありがとうございます。 参考にしてまたやってみます。
tiitoi

2019/12/20 17:15

リンク先のコードだと、画面に出力したらデータは破棄するようになっていたので、回答のコードをそのまま適用できなくなっていました。 なので、リンク先のコードを参考に修正したコードを追記しました。
flag2

2019/12/20 17:39

わかりました。 修正したコードを試させてもらいます。
tiitoi

2019/12/20 17:48 編集

バイナリビューアーを作るのが目的ではなく、バイナリファイルに RegCreate が存在するかどうか調べるだけなら最初に書いた回答と同じですが、以下でいいと思います。 ``` s = open("sample.exe", 'rb').read() exists = s.find(b"RegCreate") != -1 print("存在するかどうか", exists) ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問