当前位置:  开发笔记 > 数据库 > 正文

自修改代码有什么用?

如何解决《自修改代码有什么用?》经验,为你挑选了8个好方法。

自修改代码有什么用途吗?

我知道它们可以用于构建蠕虫/病毒,但我想知道程序员是否有必要使用自修改代码的一些好理由.

有任何想法吗?也是受欢迎的假设情况.



1> Zach Scriven..:

事实证明维基百科关于" 自修改代码 "的条目有一个很好的列表:

    状态相关循环的半自动优化.

    运行时代码生成,或算法在运行时或加载时的特化(例如,在实时图形领域中很流行),例如准备代码以执行特定调用中描述的密钥比较的通用排序实用程序.

    改变对象的内联状态,或模拟闭包的高级构造.

    修补子程序地址调用,通常在动态库的加载时进行,或者,在每次调用时修补子程序对其参数的内部引用,以便使用它们的实际地址.这是否被视为"自修改代码"是一个术语的例子.

    进化计算系统,如遗传编程.

    隐藏代码以防止逆向工程,例如通过使用反汇编程序或调试程序.

    隐藏代码以逃避病毒/间谍软件扫描软件等的检测.

    使用重复操作码的滚动模式填充100%的内存(在某些体系结构中),擦除所有程序和数据,或者老化硬件.

    压缩要在运行时解压缩和执行的代码,例如,当内存或磁盘空间有限时.

    一些非常有限的指令集别无选择,只能使用自修改代码来实现某些功能.例如,只使用减法和分支 - 如果否定"指令"的"一指令集计算机"机器不能进行间接复制(类似于C编程中的"*a =**b")语言)而不使用自修改代码.

    改变容错指令

关于阻止黑客使用自修改代码的观点:

在几次固件更新过程中,DirectTV在他们的智能卡上慢慢组装了一个程序,以销毁被黑客入侵非法接收未付费频道的卡片.有关更多信息,请参阅Black Sunday Hack上的Jeff's Coding Horror文章.



2> Alnitak..:

我见过自修改代码用于:

    速度优化,让程序在运行中为自己编写更多代码

    阻碍,使逆向工程更难



3> Kosi2801..:

在以前RAM有限的时代,自修改代码用于节省内存.现在,例如,在加载应用程序的压缩图像之后,使用诸如UPX之类的应用程序压缩实用程序来解压缩/修改自己的代码.



4> Peter Morris..:

因为Commodore 64没有很多寄存器并且具有1Mhz处理器.当您需要读取值偏移的内存地址时,更容易修改源.

@Reader:
LDA $C000
STA $D020
INC Reader+1
JMP Reader

这是我最后一次编写自修改代码:-)



5> Al Katawazi..:

人工智能?



6> Bruce McGee..:

因为它真的非常酷,有时这就足够了.



7> luser droog..:

20世纪60年代的汇编语言使用自修改代码来实现没有堆栈的函数调用.

Knuth,v1,1ed p.182:

MAX100  STJ   EXIT   ;Subroutine linkage
        ENT3  100    ;M1. Initialize
        JMP   2F
1H      CMPA  X,3    ;M3. Compare
        JGE   *+3
2H      ENT2  0,3    ;M4. Change m
        LDA   X,3    ;(New maximum found)
        DEC3  1      ;M5. Decrease k
        J3P   1B     ;M2. All tested?
EXIT    JMP   *      ;Return to main program

在包含该编码作为子程序的较大程序中,单个指令"JMP MAX100"将使寄存器A设置为位置X + 1到X + 100的当前最大值,并且最大值的位置将出现在rI2中.在这种情况下,子程序链接通过指令"MAX100 STJ EXIT"和后面的"EXIT JMP*"来实现.由于J寄存器的操作方式,退出指令将跳转到MAX100原始引用位置之后的位置.

编辑:可能很难看到发生了什么,即使这里有简短的解释.在行中MAX100 STJ EXIT,MAX100是指令的标签(因此对于整个过程而言),STJ意味着存储跳转寄存器(我们刚刚来自的地方),EXIT意味着标记为"EXIT"的存储器位置是STORE的目标.EXIT,我们后面会看到最后一条指令的标签.所以它覆盖了代码!但是,许多指令(包括STJ此处)仅隐含地覆盖指令字的操作数部分.所以JMP遗体不受影响,而且这*是一个虚拟的标记,因为放在那里真的没什么意义,它只会被覆盖.


自修改代码也用于寄存器间接寻址不可用的地方,但您需要的地址就在寄存器中.PDP-1 LISP:

dap .+1  ;deposit address part of accumulator in (IP+1)
lac xy   ;load accumulator with (ADDRESS) [xy is a dummy symbol, just like * above]

这两条指令ACC := (ACC)通过修改加载指令的操作数来执行.

像这样的修改是相对安全的,在古董架构上,它们是必要的.



8> MarkusQ..:

很多原因.脱离我的头顶:

运行时类构造和元编程.例如,拥有一个类工厂,它连接到SQL表并生成专门用于该表的客户机类(具有列的访问器,查找方法等).

当然还有着名的bitblt示例和正则表达式类比.

基于RT信息动态优化跟踪JIT

在增生环境中ada样式泛型函数的子类型特化.

- MarkusQ

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有