gpt4 book ai didi

Python Linux 读取进程内存 - int 太大而无法转换为 C long

转载 作者:太空宇宙 更新时间:2023-11-04 09:45:45 25 4
gpt4 key购买 nike

我有这个片段,它在 Linux 中读取进程内存并搜索字符串,在某些发行版上工作正常,但在其他发行版上出现此错误:

  maps_file = open("/proc/%s/maps"%pid, 'r')
mem_file = open("/proc/%s/mem"%pid, 'r')
for line in maps_file.readlines(): # for each mapped region
m = re.match(r'([0-9A-Fa-f]+)', line)
if m.group(3) == 'r': # if this is a readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region contents
#print chunk, # dump contents to standard output
mem_dump = open(working_dir+"/%s.bin"%pid, "ab")
mem_dump.write(chunk,)
mem_dump.close()
maps_file.close()
mem_file.close()

错误:

scan process: 491
Traceback (most recent call last):
File "./dump.py", line 106, in <module>
MainDump(pid)
File "./dump.py", line 79, in MainDump
mem_file.seek(start) # seek to region start
OverflowError: Python int too large to convert to C long

问题是:

start = int(m.group(1), 16)

mem_file.seek(start)

我应该声明为float吗?有什么想法吗?

也尝试了 long(),结果和错误相同。

编辑:我忘了说的是我在“x64”系统上遇到的错误。

最佳答案

问题是您得到了地址 0xffffffffff600000L。一个(有符号的)C long 只能保存从 -0x80000000000000000x7ffffffffffffffff 的值。所以,这个地址确实“太大了,不能转换成C long”。

如果你看the source ,您可以看到问题很可能是由于某种原因,当在非工作发行版上配置 Python 时,它无法检测到 fseekooff_t 存在.但除非您想重建 Python,否则这对您没有帮助。

那么,您如何解决这个问题呢?有几件事要尝试。


第一种可能是从末尾而不是从头开始寻找。

mem_len = os.fstat(mem_file.fileno()).st_size

if start >= 1<<63L:
mem_file.seek(mem_len - start, os.SEEK_END)
else:
mem_file.seek(start)

你也可以尝试这个可怕的 hack:

if start >= 1<<63L:
start -= 1<<64L

这会将你的 0xffffffffff600000L 转换为 -0xa00000,这正好适合 long ......然后希望 long 实际上被转换为 C 层内的某种无符号 64 位类型,这意味着它会像您希望的那样寻求 0xffffffffff600000L


你也可以通过使用 mmap 来映射你想要的页面来解决这个问题,而不是 seekread.


如果最坏的情况发生,您可以使用 ctypes(或 cffi 或任何您喜欢的)直接在您的文件句柄上调用 fseeko .


最后,确保你真的想阅读这个区域。我可能错了,但我似乎记得 linux 为映射到用户空间的内核页面保留了上层区域。如果我是对的,你要找的字符串不会在这里,所以你可以跳过它们……

要跳过对区域的处理,您可以将处理移到 if 中:

start = int(m.group(1), 16)
end = int(m.group(2), 16)
if start <= sys.maxint:
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region contents
# ...

... 或使用 continue 语句跳到循环的下一次迭代:

start = int(m.group(1), 16)
end = int(m.group(2), 16)
if start > sys.maxint:
continue
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region contents
# ...

如果您知道区域始终按排序顺序排列,则可以使用 break 而不是 continue(因为其余区域也会超出范围)。

但我认为最好的解决方案是尝试,然后处理错误。此 seekread 可能会失败还有其他原因——例如,如果您正在查看的进程在您到达或退出之前取消映射某个区域——并且您宁愿跳过错误并继续而不是退出,对吗?

所以:

if m.group(3) == 'r':  # if this is a readable region
start = int(m.group(1), 16)
end = int(m.group(2), 16)
try:
mem_file.seek(start) # seek to region start
chunk = mem_file.read(end - start) # read region co
except Exception as e:
print('Skipping region {:#018x} because of error {}'.format(start, e))
continue
mem_dump = open(working_dir+"/%s.bin"%pid, "ab")
# ...

关于Python Linux 读取进程内存 - int 太大而无法转换为 C long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16506270/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com