代码之家  ›  专栏  ›  技术社区  ›  David Titarenco

写一个VM格式良好的字节码?

  •  8
  • David Titarenco  · 技术社区  · 16 年前

    我正在用C写一个虚拟机只是为了好玩。跛脚,我知道,但幸运的是我在,所以希望没有人会取笑:)

    我写了一个非常快速的'不'肮脏的虚拟机,读取(我自己的)ASM行和做的东西。现在,我只有3条说明: add , jmp , end . 一切都很好,它实际上是相当酷,能够饲料线(做这样的事情) write_line(&prog[1], "jmp", regA, regB, 0); 然后运行程序:

    while (machine.code_pointer <= BOUNDS && DONE != true)
    {
        run_line(&prog[machine.cp]);
    }
    

    unsigned char[] )执行字节码。我的问题是:确保字节码是虚拟机的工作吗 结构合理的 只是 编译器的任务是确保输出的二进制文件格式正确?

    我之所以问这个问题,是因为如果有人编辑一个二进制文件并把它搞砸了(删除其中任意部分,等等),会发生什么情况。很明显,这个程序有缺陷,可能无法正常运行。这是虚拟机的问题吗?我确信比我聪明得多的人已经找到了解决这些问题的办法,我只是好奇他们是什么!

    6 回复  |  直到 11 年前
        1
  •  15
  •   Norman Ramsey    16 年前

    最佳实践是让VM在执行之前执行一次检查, 成本与程序的大小成比例,这是非常复杂的,足以保证在执行过程中不会发生任何不稳定的事情。然后在字节码的实际执行过程中,运行时不进行任何检查。 然而,运行前检查的想法可能需要一些非常复杂的分析,即使是最注重性能的vm也常常需要这样做 一些 运行时检查(例如:数组边界)。

    对于一个爱好项目,我会保持简单,每次执行指令时都让VM检查是否正常。大多数指令的开销不会太大。

        2
  •  2
  •   David Z    16 年前

    同样的问题也出现在Java中,我记得,在这种情况下,VM必须进行一些检查,以确保字节码格式良好。在这种情况下,这实际上是一个严重的问题,因为存在潜在的安全问题:如果有人可以更改Java字节码文件,使其包含编译器永远不会输出的内容(例如访问 private 变量),它可能会暴露应用程序内存中保存的敏感数据,或者允许应用程序访问不允许访问的网站或其他内容。Java的虚拟机包括一个字节码验证器,以尽可能确保这些事情不会发生。

    现在,在你的情况下,除非你的自制语言开始流行起来,否则安全方面你不必太担心;毕竟,除了你,谁会入侵你的程序?不过,我想说的是,在字节码无效的情况下,确保VM至少有一个合理的失败策略是一个好主意。至少,如果它遇到一些它不理解并且无法处理的东西,它应该检测到这些东西并失败,并显示一条错误消息,这将使您的调试更加容易。

        3
  •  2
  •   Michael Mrozek    16 年前

    然而,这听起来像是在实现一个处理器,而且由于它们的级别往往较低,所以要使事物处于可检测的无效状态的方法就更少了——给它一个未定义的操作码是一个明显的方法。真正的处理器将发出信号,表示进程试图执行非法指令,操作系统将对此进行处理(例如,Linux使用SIGILL杀死它)

        4
  •  1
  •   conrad carter    15 年前

    如果您担心有人编辑了二进制文件,那么您的问题只有一个答案:VM必须进行检查。这是你唯一有机会发现篡改的方法。编译器只是创建二进制文件。它无法检测下游篡改。

        5
  •  0
  •   500 - Internal Server Error    16 年前

    让编译器做尽可能多的健全性检查是有意义的(因为它只需要做一次),但是总有一些问题是静态分析无法检测到的,比如[cough]堆栈溢出、数组范围错误等等。

        6
  •  0
  •   Bernd Jendrissek    16 年前

    我想说,只要虚拟机实现本身不崩溃,虚拟机让模拟处理器着火是合法的。作为虚拟机实现者,您需要设置规则。但是,如果你想让虚拟硬件公司虚拟地购买你的虚拟芯片,你必须做一些更能原谅错误的事情:好的选择可能是引发异常(更难实现)或重置处理器(更容易实现)。或者,您只需将每个操作码定义为有效的,但有些操作码是“未记录的”——它们执行一些未指定的操作,而不是使实现崩溃。理由:如果(!)您的虚拟机实现是同时运行多个客户机实例,如果一个客户机能够导致其他客户机失败,那将是非常糟糕的。

    推荐文章