在正在运行的进程中给出其地址,在可执行文件中查找指令?

时间:2015-12-04 18:13:30

标签: assembly reverse-engineering memory-address portable-executable cheat-engine

我正在修改一个旧的放弃软件游戏以获得无限生命。

具有指令dec ecx的地址与其在.exe调试中的位置不同。

我记得我的一位老朋友告诉我,有一个公式可以通过.exe中的指令获得“真实”地址。作弊引擎给了我内存地址。我记得在数学公式中,我需要得到模块,在OllyDbg我得到它。但我不记得这个公式。有人知道那个数学公式怎么样?这个公式非常简单! 还有另一种方法可以让文件位置永久修改.exe?

2 个答案:

答案 0 :(得分:10)

有一个"公式"但是你实际上需要查看可执行文件(虽然这个公式可以根据一些假设进行简化)。

  1. 获取您感兴趣的指令/数据的内存地址。[ VA ]
  2. 获取指令/数据所在模块的基址。 [<强> MODBASE
  3. 从VA中减去MODBASE,即可获得所谓的[ RVA ]:
    • VA - MODBASE = RVA
  4. 使用PE文件解析器/编辑器打开二进制文件(例如* .exe或* .dll),然后查看节标题。
  5. 查找您的RVA所在的部分。
  6. 找到RVA所在的部分后,获取VirtualAddress部分。 [<强> SECRVA
  7. 从RVA中减去SECRVA,然后获得[ OFFSET ]
    • RVA - SECRVA = OFFSET
  8. 获取您在5处找到的部分的RawAddress [ SECRAWADDR ]。
  9. 将[ OFFSET ]添加到[ SECRAWADDR ],结果是您在二进制文件中搜索的指令/数据的偏移量
    • OFFSET + SECRAWADDR = INSDATAOFFSET(磁盘上文件中的偏移量)
  10. <强>假设

    通常(我坚持通常,有时情况并非如此),[SECRVA]第一部分为0x1000 - 恰好是代码部分 - 其[SECRAWADDR]将是0x400。

    因此,如果您根据内存中的地址搜索指令的偏移量,通常可以假设:

    • SECRVA = 0x1000
    • SECRAWADDR = 0x400

    示例

    基于cmd.exe的示例。

    我们假设我在程序加载到内存时在0x1C34B0搜索此代码:

    CPU Disasm
    Address   Hex dump          Command                                  Comments
    001C34B0  /$  E8 B3040000   CALL 001C3968
    001C34B5  \.^ E9 2EFEFFFF   JMP 001C32E8
    

    注意指令操作码(字节)是:0xE8B3040000

    1. VA = 0x1C34B0
    2. 在内存中搜索模块库(使用调试器或ProcessExplorer):
    3. CMD Base address

      • MODBASE = 0x1B0000

        1. VA - MODBASE = RVA ; 0x1C34B0 - 0x1B0000 = 0x134B0; RVA = 0x134B0

        2. 在PE编辑器中打开二进制文件(我使用CFF资源管理器):

      Section headers

      1. 让我们看看0x134B0在哪个部分:
      2. 第一部分是.text,其VirtulAddress是0x1000,其VirtualSize是0x23E4C(因此该部分的末尾是0x1000 + 0x23E4C = 0x24E4C)。

        在0x1000和0x24E4C之间是0x134B0吗?

        • 0x1000 >= 0x134B0 < 0x24E4C - &gt;是的:所以地址位于.text部分。

        注意:对每个部分重复相同的过程,直到找到正确的部分。

        1. SECRVA = 0x1000(虚拟地址部分)

        2. RVA - SECRVA = OFFSET ; 0x134B0 - 0x1000 = 0x124B0

        3. SECRAWADDR = 0x400(原始地址部分)

        4. OFFSET + SECRAWADDR = INSDATAOFFSET; 0x124B0 + 0x400 = 0x128B0

        5. 如果我们查看文件中的0x128B0

          Offset in binary file

          因此我们发现文件(0xE8B3040000)中的字节与内存中的字节完全相同。

答案 1 :(得分:1)

当然有一个公式 我们只需要反转PE加载器的作用:

  1. 找到PE部分开始进入文件的位置 这些数字称为文件偏移量。
  2. 找到PE部分必须相对于基地址加载到内存的位置 这些地址称为RVAs(相对虚拟地址)
  3. 选择 1 可用的基地址并将其添加到RVA 这些地址称为VAs(虚拟地址),是文件偏移的最终地址。
  4. 为了帮助理解以下步骤,请记住每个PE部分都包含以下属性:

    • 起始文件偏移量,该部分从文件开始。
    • 文件内的长度。
    • 起始内存地址,其中该部分应加载到内存中(相对于基地址)
    • 一旦加载到内存中的长度(这可能与文件长度不同)。

    因此,对于给定的内存地址X,您必须:

    1. 减去基本地址,对于旧版Windows程序,通常是40 0000h。
    2. 您现在有一个RVA,找到第一个PE部分,其起始内存地址低于RVA,结束内存地址 2
    3. 减去开始记忆地址的部分,你现在有一个部分偏移。
    4. 添加部分起始文件偏移量,您现在有一个文件偏移量。
    5. 有一个名为 PEEditor 1.7 的工具可以为您完成此任务 由于某些原因,它现在更难找到它,但它应该仍然存在于互联网上。记住:它是免费的。

      找到PE编辑器:Here,使用密码tuts4you解压缩RAR存档。

      加载文件(通过拖动到窗口或使用“浏览”按钮),然后点击FLC(文件位置计算器)。在新窗口中,输入地址。

      1 大多数情况下,这实际上意味着使用PE头中设置的基地址,这要归功于分页。
      2 计算为内存起始地址+内存长度-1