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

Assembly 在可执行文件中查找指令,给定其在运行进程中的地址?,assembly,reverse-engineering,memory-address,portable-executable,cheat-engine,Assembly,Reverse Engineering,Memory Address,Portable Executable,Cheat Engine,我正在修改一个旧的弃置软件游戏,让它拥有无限的生命 包含指令dec ecx的地址与其在调试的.exe中的位置不同 我记得有一次我的一位老朋友告诉我,有一个公式可以通过.exe中的指令获得“真实”地址。作弊引擎给了我内存地址。我记得在数学公式中,我需要得到模块,在OllyDbg中我得到了它。但是我不记得公式了。有人知道这个数学公式吗?公式很简单! 还有另一种方法可以获取文件位置以永久修改.exe?当然有一个公式。 我们只需要反转PE加载程序的功能: 找到PE节在文件中的起始位置。 这些数字称为文件

我正在修改一个旧的弃置软件游戏,让它拥有无限的生命

包含指令
dec ecx
的地址与其在调试的.exe中的位置不同

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

当然有一个公式。
我们只需要反转PE加载程序的功能:

  • 找到PE节在文件中的起始位置。
    这些数字称为文件偏移量
  • 定位PE节必须加载到内存中的位置,相对于基址。
    这些地址称为RVA(相对虚拟地址)
  • 选择1个可用的基址并将其添加到RVA。
    这些地址称为VAs(虚拟地址),是文件偏移的最终地址
  • 为了帮助理解以下步骤,请记住每个PE部分都具有以下属性:

    • 起始文件偏移量,其中节在文件中开始
    • 文件中的长度
    • 一个起始内存地址,该段应加载到内存中(相对于基址)
    • 加载到内存中后的长度(可能与文件长度不同)
    因此,对于给定的内存地址X,您必须:

  • 减去基址,对于传统Windows程序,这通常是40 0000h
  • 现在有了一个RVA,找到第一个PE节,它的起始内存地址在RVA下面,结束内存地址在RVA后面
  • 减去段起始内存地址,就得到了段偏移量
  • 添加节起始文件偏移量,现在就有了文件偏移量
  • 有一个名为PEEditor 1.7的工具可以为您做到这一点。
    出于某种原因,现在很难找到它,但它应该仍然存在于互联网上。记住:它是免费的


    找到PE编辑器:,使用密码tuts4you解包RAR存档

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


    1由于分页,这实际上意味着使用PE头中设置的基址。
    2计算为内存起始地址+内存长度-1

    有一个“公式”,但实际上需要查看可执行文件内部(尽管根据某些假设可以简化此公式)

  • 获取您感兴趣的指令/数据的内存地址(虚拟地址)。[VA]
  • 获取指令/数据所在模块的基址。[MODBASE]
  • 从VA中减去MODBASE,您将获得所谓的相对虚拟地址[RVA]:
    • VA-MODBASE=RVA
  • 使用PE文件解析器/编辑器打开二进制文件(例如*.exe或*.dll),并查看节标题
  • 查找您的RVA所在的区域
  • 找到RVA所在的节后,获取该节的相对虚拟地址。[SECRVA]
  • 从RVA中减去SECRVA,然后获得一个[偏移量。
    • RVA-SECRVA=偏移量
  • 获取在5处找到的节的RawAddress[SECRAWADDR]
  • 将[OFFSET]添加到[SECRAWADDR],结果是您正在二进制文件中搜索的指令/数据的偏移量。
    • OFFSET+SECRAWADDR=INSDATAOFFSET(磁盘上文件中的指令或数据的偏移量)
  • 假设

    通常(我坚持认为通常情况下,有时情况并非如此),[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
    
    请注意,指令操作码(字节)为:
    0xE8B304000

  • VA=0x1C34B0
  • 在内存中搜索模块库(使用调试器或ProcessExplorer;此处有趣的列在process explorer中简称为“base”):
    • MODBASE=0x1B0000

    • VA-MODBASE=RVA<代码>0x1C34B0-0x1B0000=0x134B0<代码>RVA=0x134B0

    • 在PE编辑器中打开二进制文件(我使用CFF浏览器):

  • 让我们看看0x134B0位于哪个部分:
  • 第一节是.text,其虚拟地址为0x1000,虚拟大小为0x23E4C(因此节的末尾位于
    0x1000+0x23E4C=0x24E4C

    0x134B0是否在0x1000和0x24E4C之间

    • 0x1000>=0x134B0<0x24E4C
      ->True:因此地址位于.text部分
    注意:对每个部分重复相同的过程,直到找到正确的部分

  • SECRVA=0x1000
    (节虚拟地址)

  • RVA-SECRVA=偏移量<代码>0