- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在进程的内存中查找特定的字符串。具体来说,我想找到存储它的虚拟地址。我编写了一个 python 脚本来在进程上调用 gcore 并扫描结果文件中的所有匹配项。然后我调用 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)
在相关说明中,我还尝试使用 gdb 手动扫描文件 - 当我使用其 find
命令扫描字符串时,它似乎找不到那么多匹配项在相关内存区域(确切数字差异很大)。这是为什么?
最佳答案
您可以使用Python代码来定位核心文件中的各种内容。 structer包包含一个 elf
模块,其 Elf
类为此提供了方法。 gdb
session 的以下输出包含如何使用该代码的示例。
该 session 的第一个摘录显示 gdb
打开由 gcore
生成的核心文件,并为后续搜索提供一些数据。
18:33:00 $ gdb -q /home/efuller/gnu/bin/gdb core.17856
Reading symbols from /home/efuller/gnu/bin/gdb...done.
[New LWP 17856]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/home/efuller/gnu/bin/gdb /home/efuller/gnu/bin/gdb'.
Program terminated with signal SIGINT, Interrupt.
#0 0x00007ffff62c5660 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) backtrace
#0 0x00007ffff62c5660 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1 0x00005555557f7ea6 in gdb_wait_for_event (block=1) at event-loop.c:772
#2 0x00005555557f7185 in gdb_do_one_event () at event-loop.c:347
#3 0x00005555557f71bd in start_event_loop () at event-loop.c:371
#4 0x00005555557f003a in captured_command_loop (data=0x0) at main.c:324
#5 0x00005555557eb2e9 in catch_errors (func=0x5555557efff8 <captured_command_loop(void*)>, func_args=0x0, errstring=0x555555b4f733 "", mask=RETURN_MASK_ALL) at exceptions.c:236
#6 0x00005555557f16e2 in captured_main (data=0x7fffffffea10) at main.c:1149
#7 0x00005555557f170b in gdb_main (args=0x7fffffffea10) at main.c:1159
#8 0x00005555555f2daa in main (argc=2, argv=0x7fffffffeb18) at gdb.c:32
(gdb) frame 6
#6 0x00005555557f16e2 in captured_main (data=0x7fffffffea10) at main.c:1149
1149 catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
(gdb) info locals
context = 0x7fffffffea10
argc = 2
argv = 0x7fffffffeb18
quiet = 0
set_args = 0
inhibit_home_gdbinit = 0
symarg = 0x7fffffffed8e "/home/efuller/gnu/bin/gdb"
execarg = 0x7fffffffed8e "/home/efuller/gnu/bin/gdb"
pidarg = 0x0
corearg = 0x0
pid_or_core_arg = 0x0
cdarg = 0x0
ttyarg = 0x0
print_help = 0
print_version = 0
print_configuration = 0
cmdarg_vec = 0x0
cmdarg_p = 0x0
dirarg = 0x555555fdeb80
dirsize = 1
ndir = 0
system_gdbinit = 0x0
home_gdbinit = 0x555556174960 "/home/efuller/.gdbinit"
local_gdbinit = 0x0
i = 0
save_auto_load = 1
objfile = 0x0
pre_stat_chain = 0x555555b2c000 <sentinel_cleanup>
(gdb)
下一个摘录显示了 gdb
导入 python 代码,并根据局部变量的值执行两次搜索。第一个搜索显示出现该值的多个地址(symarg
和 execarg
的值就在其中)。 findbytes
方法需要 bytes
对象,而不是 str
对象。第二次搜索仅显示一个地址,其中包含第一次搜索中第一个匹配项的地址,该地址恰好在符号表中具有名称。
(gdb) pi
>>> from structer import memmap, elf
>>> core = elf.Elf(memmap('core.17856'))
>>> from pprint import pprint
>>>
(gdb) python pprint(tuple(hex(a) for a in core.findbytes(b"/home/efuller/gnu/bin/gdb")))
('0x555555fdef30',
'0x55555606fce0',
'0x55555614ff72',
'0x5555562496a0',
'0x55555624b915',
'0x55555625f250',
'0x5555562c6c4b',
'0x55555689f2b5',
'0x7ffff5f2d490',
'0x7fffffffed74',
'0x7fffffffed8e',
'0x7fffffffedf0',
'0x7fffffffefde')
(gdb) python pprint(tuple(hex(a) for a in core.findwords(0x555555fdef30)))
('0x555555faea38',)
(gdb) x/a 0x555555faea38
0x555555faea38 <_ZL16gdb_program_name>: 0x555555fdef30
(gdb)
下一个摘录显示了搜索的其他变体。搜索第一个搜索模式的 dirname
会出现多个命中,其中包括第一次搜索的所有命中。后续搜索通过要求空终止符来过滤掉常见的命中,而之后的搜索则过滤掉不以空终止符开头的命中。最后两个搜索报告相同的结果,尽管地址相差一,因为搜索需要在该前导空值处有一个前导空值点。
(gdb) python pprint(tuple(hex(a) for a in core.findbytes(b"/home/efuller/gnu/bin")))
('0x555555b4f701',
'0x555555bd33f0',
'0x555555fdef30',
'0x55555606fce0',
'0x55555614ff72',
'0x5555562496a0',
'0x55555624b915',
'0x55555625f250',
'0x5555562c6c4b',
'0x55555689f2b5',
'0x7ffff5f2d490',
'0x7fffffffed74',
'0x7fffffffed8e',
'0x7fffffffedf0',
'0x7fffffffefde')
(gdb) python pprint(tuple(hex(a) for a in core.findbytes(b"/home/efuller/gnu/bin\x00")))
('0x555555b4f701', '0x555555bd33f0')
(gdb) python pprint(tuple(hex(a) for a in core.findbytes(b"\x00/home/efuller/gnu/bin\x00")))
('0x555555b4f700', '0x555555bd33ef')
(gdb)
最后的摘录将第一次搜索的命中分为两种情况,即具有前导空值的情况和不具有前导空值的情况。后者使用最通用的搜索类型(findbytes
和 findwords
都依赖的搜索类型),以便它可以包含固定部分之前的非空字符。搜索模式。
(gdb) python pprint(tuple(hex(a) for a in core.findbytes(b"\x00/home/efuller/gnu/bin/gdb")))
('0x555555fdef2f',
'0x55555606fcdf',
'0x55555624969f',
'0x55555625f24f',
'0x7fffffffed73',
'0x7fffffffed8d',
'0x7fffffffefdd')
(gdb) python import re
(gdb) python pprint(tuple(hex(a) for a in core.find(re.compile(rb"\x00[^\x00]+/home/efuller/gnu/bin/gdb"))))
('0x55555614ff6f',
'0x55555624b8ff',
'0x5555562c6c37',
'0x55555689f297',
'0x7ffff5f2d487',
'0x7fffffffeded')
(gdb) x/s 0x55555614ff6f + 1
0x55555614ff70: "_=/home/efuller/gnu/bin/gdb"
(gdb)
最后一个命令中的 + 1
会跳过该搜索命中中的前导 null,尽管它也可以合并到搜索代码中,如下所示。
(gdb) python pprint(tuple(hex(a+1) for a in core.find(re.compile(rb"\x00[^\x00]+/home/efuller/gnu/bin/gdb"))))
('0x55555614ff70',
'0x55555624b900',
'0x5555562c6c38',
'0x55555689f298',
'0x7ffff5f2d488',
'0x7fffffffedee')
(gdb)
structer代码不需要gdb
;它可以在 gdb 之外的 python 解释器中运行。它与 python2 不兼容,因此在 gdb
中运行它需要一个与 python3.5 链接的 gdb
二进制文件。
在核心文件中搜索模式可以报告structer中的搜索方法未报告的结果。代码。原因有两个。 structer代码只搜索load段,因此不会找到note段的内容,其中包含各种与核心中的虚拟地址不对应的东西。 structer如果两个相邻段有间隙(段之间的未映射区域),则代码不会找到跨越多个负载段的结果。该代码组合了虚拟地址空间中连续的相邻段,因此搜索结果不必局限于单个段。
关于python - 如何从核心转储中反转字符串的虚拟地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50845037/
我正在尝试将我在本文档中阅读的内容付诸实践: https://sar.informatik.hu-berlin.de/research/publications/SAR-PR-2006-05/SAR-
我一直在尝试编写一个可以改变这个的 terraform 表达式: subnets = { my_subnet_1 = { nsg = "my_nsg_1", ad
我有一个HashMap,它将两个字符串转换为单词,然后将单词添加到 map 中。我拥有它,以便一个键可以指向多个值。现在我想创建一个循环来反转表,以便所有值都指向键。不要为一个指向多个逆值的键而烦恼。
我对 ~ 运算符有点困惑。代码如下: a = 1 ~a #-2 b = 15 ~b #-16 ~ 是如何工作的? 我想,~a 会是这样的: 0001 = a 1110 = ~a 为什么不呢? 最佳
如果执行 ResourceManager.GetString(Key),您可以获取资源中某个项目的值。有没有一种方法可以进行反向查找以从给定值的资源中获取 key (本质上是反翻译)? 最佳答案 您应
我在 R 中编写了一个代码来反转一个数字。但是我得到了 inf作为输出。 digit0){ rev_num=rev_num*10 + digit %% 10 digit=digit / 10 }
这个问题已经有答案了: Invert keys and values of the original dictionary (3 个回答) 已关闭 9 年前。 我正在寻找在 python 上转置一本字
所以我试图反转我当前制作的形状的输出。我想知道我应该扭转这种情况吗?我尝试更改变量“a”和“c”的值,最终陷入无限循环。 class IRT { public static void main
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: PHP mysql_real_escape_string() -> stripslashes() leavi
从 Wordpress 模板中提取一些预先存在的代码来绘制椭圆阴影。阴影呈椭圆形向下辐射。只有椭圆的下半部分可见,从而形成底部阴影效果。 我只是想“反转”椭圆的“阴影效果”,以便只有阴影的顶部 一半可
我有一个函数应该找到两个弧度的中间 function mrad(rb,ra){return (rb+ra)/2;} 但有时,当我用 Math.sin 和 Math.cos 绘制 x 和 y 时,这两个
给定此代码(http://jsfiddle.net/bzf1mkx5/) .intern { -webkit-animation: in 1s 1 reverse forwards; } .i
我对 ~ 运算符有点困惑。代码如下: a = 1 ~a #-2 b = 15 ~b #-16 ~ 是如何工作的? 我想,~a 会是这样的: 0001 = a 1110 = ~a 为什么不呢? 最佳
我需要以相反的顺序从列表中提取项目(从最后一个条目到第一个)。我设法得到了所有元素,但是,从第一个到最后一个。这是我正在使用的部分代码: 该列表位于不同的网站集上。 using (SPSit
由于一些证书问题,我不得不写 ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chai
是否有一个函数接受一个函数列表和一个输入,并输出一个对输入进行操作的函数列表? 所以像 map,但倒退: >>>map(lambda x: 2*x,[1,2,3,4,5,6,7,8,9]) [2, 4
考虑下表团队消息: 15:10 | Peter | I'm off to the store, call my mobile phone if you need me. 15:11 | Susy |
算法如下: int encryption(int a, int b) { short int c, c2; uint8_t d; c = a ^ b; c2 = c;
我正在寻找一种方法来逆转 a CRC32 checksum .周围有解决方案,但它们要么是 badly written , extremely technical和/或 in Assembly .汇编
使用批处理文件,处理所有在文件名或扩展名中共享字符串的文件就足够简单了,例如: FOR /R %F IN (*.EXE) DO @ECHO %F 但是,如果我想反转文件集的含义怎么办?比如,处理所有不
我是一名优秀的程序员,十分优秀!