我正在尝试编写一个命令行应用程序,它可以使用特定地址的十六进制值修改.so文件。
我使用IDA Demo和HxD Hex Editor来获取需要更新的地址,但是,每次我尝试修改文件时,无论我使用哪种语言(bash脚本,php,python)每次我编辑文件时,它都会从我从IDA和HxD Hex Editor中错误的地址偏移进行更新。
我已经看过几篇关于此的帖子,但到目前为止,还没有人能够就如何获得HxD和IDA没有发现问题的地址给出明确的答案:(
在python中,我使用mmap函数尝试使用下面的内容;
import mmap
import contextlib
import os
filesize = os.stat("filetomodify.so").st_size
print int(filesize)
with open("filetomodify.so", 'r+b') as f:
with contextlib.closing(mmap.mmap(f.fileno(), access=mmap.ACCESS_WRITE)) as m:
m[0x173596] = "FF 20"
m[0x18D88E] = "FF 20"
m.close()
这使用os
库来确定作为10025936
返回的文件的大小,但是,每次我在length=filesize
和{之间添加f.fileno()
参数时{1}}我总是收到access=mmap.ACCESS_WRITE
错误消息,但是当我省略该参数时,我得到mmap.error: [Errno 22] Invalid argument
我使用的bash脚本是我在这里找到的,它可以修改文件,但是更新了错误的地址;
m: TypeError: Required argument 'length' (pos 2) not found
如上所述调用该函数会更新文件并将其写入正常,但是当我查找更新的字节字符串时(例如,95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01 - 只需a您不希望在文件中找到的长唯一字符串)它已插入错误的地址,或者它告诉我偏移量超出了文件大小。
最后,我使用的php代码(无论如何我都没有取得多大的成功)是;
#!/bin/bash
# param 1: file
# param 2: offset
# param 3: value
# param 4: Size of Bytes
function replaceByte() {
printf "$(printf '\\x%02X' $3)" | dd of="$1" bs=$4 seek=$2 count=1 conv=notrunc &> /dev/null
}
# Usage:
replaceByte 'filetomod.so' "0x173596" "95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01" 15
但是,不是编辑二进制文件的十六进制值,而是将字符串作为字符串添加到HxD地址<?php
$fp = fopen('binary_file.bin', 'w+b');
fseek($fp, 173596, );
fwrite($fp, '95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01');
fclose($fp);
?>
的二进制文件中,十六进制代码为0002A61C
,其输出为39 35 20 45 35 20 30 41 20 32 46 20 36 36 20 31 45 20 33 32 20 45 45 20 34 43 20 42 38 20 39 41 20 36 45 20 42 44 20 45 43 20 30 31
对此的任何帮助将不胜感激。我对答案的唯一要求是它可以从命令行运行,无论是php,bash,python,java等。
提前谢谢。
答案 0 :(得分:1)
在运行Centos 6.5的虚拟机中进行了一些试验后,我得到了它
function replaceByte() {
printf "$(printf '\\x%02X' $3)" |
dd of="$1" ibs=1 count=1 obs=1 seek="$2" conv=notrunc &> /dev/null
}
问题是seek
参数的单位:BLOCKS,而不是BYTES。
更改默认块大小时,输入块大小和输出块大小都会更改。因此,seek
参数指的是大小为bs
参数值的块。
要解决此问题,您必须设置输入块大小ibs
,因为但输出块大小obs
必须设置为1.否则,输出为在磁盘文件中,obs
值设置为512字节(磁盘块大小)。
您可以尝试以下测试来检查输出块的大小是512,而不是1:
echo -e '\x41' | dd if=file.txt ibs=1 count=1 seek=3 conv=notrunc
(0x41是A的ASCII代码)检查file.txt的大小是否已更改:1537字节(每块512个字节的3个块加上1 - 3 * 512 + 1)
由于file.txt是&#34;已损坏&#34;,请重复步骤1和2.
echo -e '\x41' | dd if=file.txt ibs=1 count=1 obs=1 seek=3 conv=notrunc
最好的问候。
P.D:这个功能replaceByte()
应该可以正常工作一个字节。如果您需要在一次调用中更改多个连续字节,则必须使用循环替换printf
...并使用正确值替换ibs=1
。