如何找到IDA的二进制文件中的内存地址偏移(How to find the memory addre

2019-10-21 08:29发布

我试图写一个命令行应用程序,它可以修改使用十六进制值在特定地址的.so文件。

我使用IDA演示和HXD十六进制编辑器才能达到的需要更新的地址,然而,每次我试图修改该文件,不管我用哪种语言(bash的脚本,PHP,Python)的每一次我编辑的文件,它是我从IDA和HXD十六进制编辑器的地址有误补偿更新。

我已经看到了这方面的几个职位,但到目前为止,还没有一个能给出一个明确的答案,如何才能达到的HXD和IDA有没有问题找到地址:(

在蟒蛇我用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()access=mmap.ACCESS_WRITE我总是得到一个mmap.error: [Errno 22] Invalid argument的错误消息,但是当我省略参数,得到了一个m: TypeError: Required argument 'length' (pos 2) not found

我已经使用了bash脚本是一个,我发现在这里,这修改文件不错,但更新了错误的地址;

#!/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

调用上述功能更新的文件,并把它确定,但是当我在更新的字节串做一个查找(例如95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01 - 只需一个长期唯一的字符串你不希望在文件中找到),它在不正确的地址被插入,或者它告诉我,偏移量是文件大小之外。

最后,PHP代码我用(我没想到反正有很大的成功)是;

<?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);
?>

然而,不是编辑二进制文件的十六进制值,该添加的字符串作为一个字符串在HXD地址二进制文件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其具有的输出95 E5 0A 2F 66 1E 32 EE 4C B8 9A 6E BD EC 01

任何帮助,将不胜感激。 我的答案唯一的要求是,它可以从命令行运行,无论是PHP的,bash中,蟒蛇,爪哇等。

先感谢您。

Answer 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参数:块,而不是字节。

当您更改默认的块大小,两个输入块大小和输出块的大小被改变。 因此, seek参数是指块大小为的值bs参数。

为了解决此问题,必须设置输入块大小ibs为你几乎没有,但输出块大小obs必须否则设置为1,作为输出是一个磁盘文件,该obs值被设置为512个字节(磁盘块大小) 。

你可以试试下面的测试,以检查输出块的大小是512,而不是1:

  1. 创建包含整个空行的文本文件(file.txt的)(例如,30个白色空格)
  2. 检查文件的大小为近30个字节。
  3. 运行echo -e '\x41' | dd if=file.txt ibs=1 count=1 seek=3 conv=notrunc echo -e '\x41' | dd if=file.txt ibs=1 count=1 seek=3 conv=notrunc (的0x41为ASCII码)
  4. 检查file.txt的大小发生了变化:1537个字节(3块的每块的512个字节加1 - 3 * 512 + 1)

  5. 如file.txt的是“损坏”,重复步骤1和2。

  6. 运行echo -e '\x41' | dd if=file.txt ibs=1 count=1 obs=1 seek=3 conv=notrunc echo -e '\x41' | dd if=file.txt ibs=1 count=1 obs=1 seek=3 conv=notrunc
  7. 检查file.txt的大小没有改变。
  8. 看文件的内容,并检查是否有一个“A”代替第四空白。

最好的祝福。

PD:此funcion replaceByte()应该工作的罚款只是一个字节。 如果您需要更改几个连续字节的单呼,则必须更换printf ,也许,有一个循环...和ibs=1与应有的价值。



文章来源: How to find the memory address offsets from IDA in binary file