1

プロセスのメモリで特定の文字列を見つけようとしています。具体的には、それが格納されている仮想アドレスを見つけたいです。プロセスを呼び出しgcore、結果のファイルをスキャンしてすべての一致を検索する Python スクリプトを作成しました。次に、そこにあるエントリを呼び出しpmapて反復処理します。私の考えは、各インデックスが対応するメモリのセクションを見つけ、前のセクションのサイズの合計を減算して正しいセクションのオフセットを取得し、それをベースに追加して、仮想アドレスを取得することです。しかし、gdb を使用して計算している仮想アドレスで文字列を検索すると、正しい文字列が見つかりません。私の方法がうまくいかないのはなぜですか?gcore仮想メモリの内容全体を順番にダンプしませんか?

#!/usr/bin/python3
import sys
import ctypes
import ctypes.util
import subprocess
import os
import ptrace
import re

if(len(sys.argv) != 2):
    print("Usage: search_and_replace.py target_pid")
    sys.exit(-1)

pid = sys.argv[1]
if not pid.isdigit():
    print("Invalid PID specified.  Make sure PID is an integer")
    sys.exit(-1)

bash_cmd = "sudo gcore -a {}".format(pid)
os.system(bash_cmd)

with open("core." + sys.argv[1], 'rb') as f:
    s = f.read()
# with open("all.dump", 'rb') as f:
#   s = f.read()

str_query = b'a random string in program\'s memory'
str_replc = b'This is an inserted string, replacing the original.'
indices = []
for match in re.finditer(str_query, s):
    indices.append(match.start())
print("number of indices is " + str(len(indices)))

#index = s.find(str_query)

# print("offset is " + str(index))
# if(index == 0):
#   print("error: String not found")
#   sys.exit(-1)

bash_cmd = "sudo pmap -x {} > maps".format(pid)
print(bash_cmd)
subprocess.call(bash_cmd, shell=True)

with open("maps") as m:
    lines = m.readlines()

#calculate the virtual address of the targeted string the running process via parsing the pmap output
pages = []
v_addrs = []

for index in indices:
    sum = 0
    offset = 0
    v_addr = 0  
    #print(index)
    for i in range(2, len(lines) - 2):
        line = lines[i]
        items = line.split()
        v_addr = int(items[0], 16)
        old_sum = sum
        sum += int(items[1]) * 1024
        if sum > index:
            offset = index - old_sum
            print("max is " + hex(v_addr + int(items[1]) * 1024))
            print("offset is " + str(offset) + " hex " + hex(offset))
            print("final va is " + hex(v_addr + offset))
            pages.append(hex(v_addr) + ", " + hex(v_addr + int(items[1]) * 1024))
            v_addrs.append(hex(v_addr + offset))
            break

print("base va is " + hex(v_addr))
v_addr += offset

for page in set(pages):
    print(page)

for va in v_addrs:
    print(va)

find関連するメモとして、gdb を使用してファイルを手動でスキャンしようとしましたが、そのコマンドを使用して問題のメモリ領域内の文字列をスキャンすると、ほとんど一致するものが見つからないようです(正確な数はさまざまです)。大いに)。何故ですか?

4

1 に答える 1