刚接触 python 不久,想用 python 直接修改二进制文件中的某段字符串内容,在网上查询使用fopen
然后用seek
定位,write
写入.我测试过确实能达到效果。
但是如果替换的长度不一样,比如本来的字符串为test
,我用上面的方法想替换成mytest
,因为长度比原来的长,就替换不成功,本来我想的是,在内存里找一块空的地址,写入mytest
,然后将地址替换到test
里面,虽然想的很美好,但是实在不会操作,特来请教一下这种替换长度不一致的,该如何操作,提前致谢
1
whileFalse 2020-10-29 09:12:02 +08:00
如果文件不大的话,全部读出-内存替换-全部写回
|
2
fasionchan 2020-10-29 09:12:20 +08:00
文件不大的话可以将整个文件读到内存,在内存中做替换后,再整体覆盖写入
|
3
whileFalse 2020-10-29 09:17:56 +08:00
replace_data = b'mytest'
replace_begin = 3 replace_end = 7 with open('a.txt', 'rb') as f: data = f.read() print(data) print(data[replace_begin:replace_end]) data = data[:replace_begin] + replace_data + data[replace_end:] print(data) with open('b.txt', 'wb') as f: f.write(data) |
4
no1xsyzy 2020-10-29 09:34:50 +08:00
Python 不需要找 “空的地址”,你直接创建对象就会自动分配内存。
f.read() 就会创建 bytes 对象,之后 replace 替换,完了再 f.write() 回去就成 不一样长度的话,除非整 block,并且修改文件系统 metadata,不然从你修改的位置开始后面全部得覆写一遍的。 |
5
lllllliu 2020-10-29 09:41:04 +08:00
难道不是计算修改后的文件长度,修改区段表或者结构段定义头的长度,然后在修改或填充么。。
|
6
zone10 2020-10-29 09:56:54 +08:00 1
新手多找成型的代码看, 按照规范来写代码, 别老是以自己狭隘的思路写, 看多了你就知道有些问题压根不存在
|
7
v2410117 OP @whileFalse 大佬您好,首先感谢您提供的代码,我使用测试后,发现修改后提示`segmentation fault`,无法运行,是还需要修改其他的结构吗?谢谢
|
9
whileFalse 2020-10-29 10:14:32 +08:00
@v2410117 你在代码相同目录下放一个 a.txt 文件,内容是“123test123”试试看
|
10
playniuniu 2020-10-29 10:19:16 +08:00
二进制文件比如 ELF 类型的是有特定格式的,你要是在中间随便增加长度,估计整个程序都运行不了。要增加长度,先确定二进制文件的类型,比如 ELF 格式的,是需要找一片空白区域,把新数据放进去,在把原来读这端程序的地方改成读新的,还是蛮麻烦的。
|
11
v2410117 OP @whileFalse 文本文件是可以,但是二进制执行文件就不行了,应该是如楼上说的那样,还要修改结构啥的吧!
|
12
v2410117 OP @playniuniu 嗯,对,确实如您所说的为 elf 格式,按直接拼接 bytes 的做法确实导致整个程序都无法运行了.我也是想的您后面提到的那个操作,先找个空白区域写好,然后修改读的地址,但是不太会用 python 操作,正在寻找解决办法中
|
13
mumbler 2020-10-29 10:40:57 +08:00 via Android
二进制结构一般会固定字段长度,如果 test 没占满,后面一定会有空字节,就把 mytest 写入前 6 位。归根结底,要了解这种二进制的文件结构
|
14
whileFalse 2020-10-29 10:43:43 +08:00
@v2410117 可执行文件有文件格式啊……你得研究文件格式。修改还是按照我说的方法修改的。但在特定的文件格式下应该怎么修改,那你得自己研究。
|
15
zhyl 2020-10-29 10:46:58 +08:00
如果需要写入后的二进制文件还是正常运行,那么重点不在于如何写入,需要了解对应二进制文件的格式,例如 windows 下 PE 格式以区段划分,代码存放在代码段,数据存放在数据段,如果修改(变长或减短)数据段的内容,那么在代码段中所有这块修改数据之后的数据被引用时,其引用的地址都需要修正。
|
16
belite 2020-10-29 10:54:13 +08:00 via iPhone
我有一个想法 边读边改边写 写到另一个空文件里 完成后替换原文件
|
17
aneostart173 2020-10-29 10:55:27 +08:00
你这个要求对应文本编辑器的插入编辑操作,文本编辑器的实现就很复杂,一两句说不清楚。
|
18
CRVV 2020-10-29 11:07:42 +08:00
@v2410117
如果你连改文件内容都需要来发帖子问,改 ELF 然后还要能跑属于你不可能完成的事情,放弃吧。 https://blog.0patch.com/2017/11/did-microsoft-just-manually-patch-their.html 这是微软做过然后能上新闻的操作。 |
19
playniuniu 2020-10-29 14:55:21 +08:00
@v2410117 这篇文章有关于 Android so 文件 的修改方法 http://www.520monkey.com/archives/561,你可以参考一下,其他 ELF 格式应该差不多
|
20
imn1 2020-10-29 15:05:54 +08:00
1.字节是可以使用 replace 函数的
2.可以前后截取,再用新字节重新拼接 如果二进制文件是某种格式,自然要按那种格式的规范来做,不是这样随意改动,例如 jpg 里面改动 exif,exif 实际只是字节数据,可以改动不影响图像显示,但也是要符合 exif 以及 jpeg 规范的,没有足够知识的话,最好用相关模块辅助完成 |
21
xcai007 2020-10-29 18:05:02 +08:00
用 mmap
import mmap with open('file', 'rb) as f: with mmap.mmap(f.fileno(), length=0, access=mmap.ACCESS_READ) as contents: start = contents.find('test') print(contents[:start]+'mytest'+contents[start+len('test'):] |
22
Owenjia 2020-10-29 23:11:51 +08:00
修改 elf 文件的话可以看下 lief 这个库?
|