ADVANCED POLYMORPHISM PRIMER

PART THE FIRST

By Dark Angel
Phalcon/Skism

 


 

  •        With the recent proliferation of virus encryption "engines," I was
      inspired to write my own.  In a few short weeks, I was able to construct one
      such routine which can hold its own.  A polymorphic encryption routine is
      nothing more than a complex code generator.  Writing such a routine, while
      not incredibly difficult, requires careful planning and perhaps more than a
      few false starts.
    
           The utility of true polymorphism is, by now, an accepted fact.
      Scanning for the majority of viruses is a trivial task, involving merely the
      identification of a specific pattern of bytes in executable files.  This
      approach is quick and may be used to detect nearly all known viruses.
      However, polymorphism throws a monkey wrench into the works.  polymorphic
      viruses encode each copy of the virus with a different decryption routine.
      Since (theoretically) no bytes remain constant in each generated decryption
      routine, virus detectors cannot rely on a simple pattern match to locate
      these viruses.  Instead, they are forced to use an algorithmic appproach
      susceptible to "false positives," misleading reports of the existence of the
      virus where it is not truly present.  Creating a reliable algorithm to
      detect the polymorphic routine takes far more effort than isolating a usable
      scan string.  Additionally, if a virus detector fails to find even one
      instance of the virus, then that single instance will remain undetected and
      spawn many more generations of the virus.  Survival, of course, is the
      ultimate goal of the virus.
    
           Before attempting to write a polymorphic routine, it is necessary to
      obtain a manual detailing the 80x86 instruction set.  Without bit-level
      manipulation of the opcodes, any polymorphic routine will be of limited
      scope.  The nice rigid structure of the 80x86 instruction set will be
      readily apparent after a simple perusal of the opcodes.  Exploitation of
      this structured instruction set allows for the compact code generation
      routines which lie at the heart of every significant polymorphic routine.
    
           After examining the structure of the opcodes, the basic organisation of
      the polymorphic routine should be laid out.  Here, an understanding of the
      basics behind such routines is required.  The traditional approach treats
      the decryption routine as a simple executable string, such as
      "BB1301B900022E8137123483C302E2F6."  A true (advanced) polymorphic routine,
      by contrast, views the decryption routine as a conceptual algorithm, such
      as, "Set up a 'pointer' register, that is, the register whose contents hold
      a pointer to the memory to be decrypted.  Set up a counter register.  Use
      the pointer register to decrypt one byte.  Update the pointer register.
      Decrement the count register, looping if it is not zero."  Two routines
      which fit this algorithm follow:
    
      Sample Encryption 1
      ------ ---------- -
           mov  bx,offset startencrypt   ; here, bx is the 'pointer' register
           mov  cx,viruslength / 2       ; and cx holds the # of iterations
      decrypt_loop:
           xor  word ptr [bx],12h        ; decrypt one word at a time
           inc  bx                       ; update the pointer register to
           inc  bx                       ; point to the next word
           loop decrypt_loop             ; and continue the decryption
      startencrypt:
    
      Sample Encryption 2
      ------ ---------- -
      start:
           mov  bx,viruslength           ; now bx holds the decryption length
           mov  bp,offset start          ; bp is the 'pointer' register
      decrypt_loop:
           add  byte ptr [bp+0Ch],33h    ; bp+0Ch -> memory location to be
                                         ; decrypted at each iteration
           inc  bp                       ; update the pointer register
           dec  bx                       ; and the count register
           jnz  decrypt_loop             ; loop if still more to decrypt
    
           The number of possibilities is essentially infinite.  Naturally,
      treating the decryption as an algorithm rather than as an executable string
      greatly increases the flexibility in creating the actual routine.  Various
      portions of the decryption algorithm may be tinkered with, allowing for
      further variations.  Using the example above, one possible variation is to
      swap the order of the setup of the registers, i.e.
    
           mov  cx,viruslength
           mov  bx,offset startencrypt
    
      in lieu of
    
           mov  bx,offset startencrypt
           mov  cx,viruslength
    
           It is up to the individual to decide upon the specific variations which
      should be included in the polymorphic routine.  Depending upon the nature of
      the variations and the structure of the polymorphic routine, each increase
      in power may be accompanied with only a minimal sacrifice in code length.
      The goal is for the routine to be capable of generating the greatest number
      of variations in the least amount of code.  It is therefore desirable to
      write the polymorphic routine in a manner such that additional variations
      may be easily accommodated.  Modularity is helpful in this respect, as the
      modest overhead is rapidly offset by substantial space savings.
    
           The first step most polymorphic routines undergo is the determination
      of the precise variation which is to be encoded.  For example, a polymorphic
      routine may decide that the decryption routine is to use word-length xor
      encryption with bx as the pointer register, dx as a container for the
      encryption value, and cx as the counter register.  Once this information is
      known, the routine should be able to calculate the initial value of each
      variable.  For example, if cx is the counter register for a byte-length
      encryption, then it should hold the virus length.  To increase variability,
      the length of the encryption can be increased by a small, random amount.
      Note that some variables, in particular the pointer register, may not be
      known before encoding the rest of the routine.  This detail is discussed
      below.
    
           Of course, selecting the variables and registers will not in and of
      itself yield a valid decryption routine; the polymorphic routine must also
      encode the actual instructions to perform the job!  The cheesiest
      polymorphic routines encode a single "mov" instruction for the assignment of
      a value to a register.  The more complex routines encode a series of
      instructions which are functionally equivalent to the simple three byte
      "mov" statement yet far different in form.  For example,
    
           mov  ax, 808h
    
      could be replaced with
    
           mov  ax, 303h                 ; ax = 303h
           mov  bx, 101h                 ; bx = 101h
           add  ax, bx                   ; ax = 404h
           shl  ax, 1                    ; ax = 808h
    
           Recall that the registers should be encoded in a random order.  The
      counter variable, for example, should not always be the first to be encoded.
      Predictability, the bane of polymorphic routines, must be avoided at all
      costs.
    
           After the registers are encoded, the actual decryption loop should then
      be encoded.  The loop can perform a number of actions, the most significant
      of which should be to manipulate the memory location, i.e. the actual
      decryption instruction, and to update the pointer register, if necessary.
      Finally, the loop instruction itself should be encoded.  This can take many
      forms, including "loop," "loopnz," "jnz," etc.  Possible variations include
      altering the decryption value register and the counter register during each
      iteration.
    
           This is the general pattern of encoding.  By placing garbling, or "do-
      nothing," instructions between the essential pieces of code, further
      variability may be ensured.  These instructions may take many forms.  If the
      encoding routines are well-designed, the garbler can take advantage of the
      pre-existing code to generate null instructions, such as assignments to
      unused registers.
    
           Once the decryption routine has been written, it is necessary to
      encrypt the virus code.  The traditional approach gives the polymorphic
      routine the job of encrypting the code.  The polymorphic routine should
      therefore "remember" how the precise variation used by the decryptor and
      adjust the encryption routine in a complementary fashion.  An alternate
      approach is for the polymorphic routine to simultaneously encode both the
      encryption and decryption routines.  Although it adds overhead to the code,
      it is an extremely flexible approach that easily accommodates variations
      which may be later introduced into the polymorphic routine.
    
           Variable-length decryptors come at a significant trade-off; the exact
      start of the decryption cannot be known before encoding the decryptor.
      There are two approaches to working around this limitation.  The first is to
      encode the pointer register in a single instruction, i.e. mov bx,185h and to
      patch the initial value once it is known.  This is simplistic, though
      undesirable, as it decreases the variability of the routine.  An alternate
      approach is to encode the encryption instruction in the form xor word ptr
      [bx+185h], cx (as in Sample encryption 2, above) instead of xor word ptr
      [bx], cx (as in Sample encryption 1).  This increases the flexibility of the
      routine, as the initial value of the pointer register need not be any fixed
      value; correct decryption may be assured by adjusting the offset in the
      decryption instruction.  It is then possible to encode the pointer register
      with multiple instructions, increasing flexibility.  However, using either
      method alone increases the predictability of the generated code.  A better
      approach would be to incorporate both methods into a single polymorphic
      routine and randomly selecting one during each run.
    
           As an example of a polymorphic routine, I present DAME, Dark Angel's
      Multiple Encryptor and a simple virus which utilises it.  They appear in the
      following article.  DAME uses a variety of powerful techniques to achieve
      full polymorphism.  Additionally, it is easy to enhance; both the encoding
      routines and the garblers can be extended algorithmically with minimal
      effort.  In the next issue, I will thoroughly comment and explain the
      various parts of DAME.
内容概要:本文围绕列车-轨道-桥梁交互仿真研究,基于Matlab平台构建数值模型,系统分析列车运行过程中轨道与桥梁结构间的动态相互作用机制。研究涵盖多体动力学建模、耦合系统运动方程求解、边界条件设定及仿真结果可视化等关键环节,重点揭示高速行车条件下基础设施的振动传递规律与力学响应特征。该仿真方法可有效评估结构安全性、舒适性指标及疲劳寿命,为轨道交通工程的设计优化与运维管理提供理论支撑和技术路径。文中配套提供了完整的Matlab代码实现方案及操作说明,便于用户复现、验证和拓展相关研究。; 适合人群:具备Matlab编程基础和结构动力学、车辆动力学等相关专业知识的研究生、科研人员及从事铁路工程、桥梁工程与交通系统安全评估的工程技术人才,尤其适合开展轨道交通耦合振动课题的研究者。; 使用场景及目标:①用于高校与科研机构进行列车-轨道-桥梁耦合系统动力学特性的教学演示与科学研究;②支撑高速铁路桥梁的设计优化、运营安全性评估与减振降噪方案验证;③为复杂交通基础设施的多物理场耦合仿真提供建模思路与代码参考。; 阅读建议:建议读者结合所提供的Matlab代码逐模块深入研读,重点关注系统建模假设、质量-刚度-阻尼矩阵构建方法及数值积分算法的实现细节,同时可通过调整参数进行敏感性分析,进一步掌握仿真模型的适用范围与优化方向。
内容概要:本文系统研究了非线性薛定谔方程的物理信息神经网络(PINN)求解方法,提出一种将物理规律嵌入深度学习模型的科学计算新范式。通过构建全连接神经网络架构,将非线性薛定谔方程及其初始/边界条件作为损失函数的核心组成部分,实现了在无须大量标注数据的前提下对复值偏微分方程的高精度数值求解。该方法充分利用自动微分技术精确计算方程残差,有效融合了数据驱动与模型驱动的优势,在光学孤子传播、量子系统演化等典型场景中展现出优异的逼近能力与泛化性能。文中配套提供了完整的Python实现代码,涵盖网络搭建、损失定义、训练优化与结果可视化全流程。; 适合人群:具备Python编程能力与深度学习基础知识,熟悉偏微分方程理论及科学计算的理工科研究生、科研人员,以及从事光学、量子物理、流体力学等领域建模与仿真的工程技术人员。; 使用场景及目标:① 掌握PINN方法的基本原理与实现技巧;② 学习如何将复杂物理方程转化为可训练的神经网络损失项;③ 应用于非线性光学、玻色-爱因斯坦凝聚、水波动力学等问题的仿真与预测;④ 为相关科研课题提供可复现的算法原型与代码参考。; 阅读建议:建议读者结合所提供的Python代码进行动手实践,重点理解神经网络对微分算子的近似机制、损失函数的多任务加权策略以及训练过程中的超参数调优方法,进而可迁移至其他非线性偏微分方程的求解任务,拓展其在交叉学科中的应用边界。
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 微软推出的【AZ-900微软认证】是一项针对初学者的基础级云服务资格认证,其目的在于帮助学习者掌握云概念、微软Azure服务的运作机制以及云解决方案的核心知识。获得这一认证后,考生将能够清晰地理解云计算领域的基础术语、服务模式(包括IaaS、PaaS、SaaS等)以及这些服务在Azure平台上的实际应用方式。 在【必过考题】部分,我们可以观察到两个重点议题,它们分别聚焦于PaaS(平台即服务)的概念阐释和云成本的计算方式。 在第一个议题中,考生被要求辨别关于PaaS的正确性描述。PaaS平台提供了一个开发环境,但并不允许用户直接访问操作系统(Box 1: No)。比如,Azure Web Apps服务可以用来部署web应用,但用户无法直接管理虚拟机或IIS系统。另一方面,PaaS确实具备自动扩展的功能(Box 2: Yes),这表示可以根据实际需求自动增加负载均衡的虚拟机以支持web应用的运行。PaaS框架还为开发人员提供了构建和调整云端应用的工具,预置的应用组件能够有效缩短新应用的编程周期(Box 3: Yes)。 第二个议题同样关注云计算理念的理解,尤其强调IT支出从资本性支出(CapEx)向运营性支出(OpEx)的转型思想。传统的IT投资通常被视为CapEx,而云计算的按需付费机制使企业能够将这部分开支转化为OpEx,从而在财务规划上获得更大的自由度。 在为AZ-900考试做准备时,考生需要特别关注以下几个核心知识点: 1. **云服务模式**:深入理解IaaS(基础设施即服务)、PaaS和SaaS(软件即服务)之间的差异及其各自的应用情境。 2. **Azure服务*...
源码下载地址: https://pan.quark.cn/s/239a0d536a1e 依据所提供的文件资料,可以归纳出以下核心内容:由清华大学计算机系邓俊辉教授精心编纂的算法训练营题目合集,对于CSP(中国软件专业人才设计与创业大赛)及PAT(程序设计能力测试)这类编程竞赛具有极高的参考价值,堪称一份极具价值的参考资料。此类竞赛普遍对参赛者的算法功底和编程技巧提出严苛要求。该合集中的题目与算法领域紧密相连,其中包含了“最大红矩形”这一典型题目。所谓最大红矩形题目,其核心任务是针对一个由红色与绿色方格构成的棋盘,寻觅出最大的纯红矩形区域。要攻克这一问题,必须运用数据结构与算法的相关知识,特别是栈这一数据结构的应用。 “最大红矩形”问题能够被抽象转化为“直方图最大面积”问题。具体转化方法是将棋盘的每一列视为一个独立的直方图单元,其中红色方格的贡献体现为当前位置与前一个绿色方格所在行数的差值,从而保证每个直方图的基宽恒定为1。随后,借助扫描直方图的技术手段来探寻最大矩形面积。这一过程需要对每个直方图进行系统性遍历,并利用栈来记录各直方图的下标信息。一旦检测到当前直方图的高度小于栈顶元素所记录的高度,则意味着遭遇了一个“高点”,此时需计算以该“高点”为右边界条件的最大矩形面积。 在编程实践环节,必须高度关注栈的操作细节,以及如何精确地初始化和操纵栈来应对直方图问题。代码实现中,通常配置两个栈,一个用于储存直方图的高度值,另一个用于标记直方图的下标位置。当面对新高度时,需审慎判断当前高度与栈顶高度的相对关系,并据此抉择是执行入栈操作还是计算面积。针对“低点”(即当前高度小于栈顶),应直接将当前高度纳入栈中;而对于“高点”,则需执行弹出栈顶元素的操作,并基于该栈顶元素的高...
源码链接: https://pan.quark.cn/s/3af847fbbec7 在计算机科学与编程领域中,十六进制(Hexadecimal)以及二进制(Binary)是两种关键性的数值表示方法。十六进制属于一种基于16的计数系统,它运用0至9的数字以及字母A至F(分别象征10至15的数值)来呈现数值,与此同时,二进制则是一种基于2的计数系统,仅采用0和1两个符号。掌握这两种进制之间的相互转换对于深入理解计算机内部运作机制具有决定性意义,因为计算机在底层数据的存储与处理环节通常都是以二进制的形式来进行的。将十六进制转换成二进制的过程可以通过以下几个环节得以完成: 1. **单个十六进制符号的转换**:每一个十六进制符号对应着4位二进制序列。具体而言: - 十六进制中的`0`在二进制表达为`0000` - 十六进制中的`1`在二进制表达为`0001` - 十六进制中的`2`在二进制表达为`0010` - 依此类推 - 十六进制中的`9`在二进制表达为`1001` - 十六进制中的`A`或`a`在二进制表达为`1010` - 十六进制中的`B`或`b`在二进制表达为`1011` - 十六进制中的`C`或`c`在二进制表达为`1100` - 十六进制中的`D`或`d`在二进制表达为`1101` - 十六进制中的`E`或`e`在二进制表达为`1110` - 十六进制中的`F`或`f`在二进制表达为`1111` 2. **多位十六进制符号的转换**:针对一个由多个十六进制符号组成的数值,我们可以逐个符号进行转换,并将得到的二进制序列依次拼接。例如,十六进制数`3F`转换成二进制形式为`00111111`。 3. **编程实现方法**:在编程实践过程中,众多编程语言提...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值