Consider, for example, the instructions at 00403448 and 0040344E. Both
instructions load a value into EAX, which is used in instructions that follow. It
would be quite easy to modify these instructions so that the first uses one reg-
ister and the second uses another register. It is even quite easy to change the
base stack frame pointer (EBP) to use another general-purpose register.
Of course, you could change way more than just registers (see the following
section on metamorphism), but by restricting the magnitude of the modifica-
tion to something like register usage you’re enabling the creation of fairly triv-
ial routines that would simply know in advance which bytes should be
modified in order to alter register usage—it would all be hard-coded, and the
specific registers would be selected randomly at runtime.
0040343B 8B 57 CC MOV EDX,[EDI-34]
0040343E 8B 02 MOV EAX,[EDX]
00403440 33 47 D8 XOR EAX,[EDI-28]
00403443 8B5FCC MOV EBX,[EDI-34]
00403446 89 03 MOV [EBX],EAX
00403448 8B 77 D4 MOV ESI,[EDI-2C]
0040344B 89 77 D8 MOV [EDI-28],ESI
0040344E 8B4FDC MOV ECX,[EDI-24]
00403451 334FD4 XOR ECX,[EDI-2C]
00403454 894FDC MOV [EDI-24],ECX
This code provides an equivalent-functionality alternative to the original
sequence. The emphasized bytecodes represent the bytecodes that have
changed from the original representation. To simplify the implementation of
such transformation, it is feasible to simply store a list of predefined bytes that
could be altered and in what waythey can be altered. The program could then
randomly fiddle with the available combinations during the self-replication
process and generate a unique machine code sequence. Because this kind of
implementation requires the creation of a table of hard-coded information
regarding the specific code bytes that can be altered, this approach would only
be feasible when most of the program is encrypted or encoded in some way, as
described earlier. It would not be practical to manually scramble an entire pro-
gram in this fashion. Additionally, it goes without saying that all registers
must be saved and restored before entering a function that can be polymor-
phed in this fashion.
Metamorphism
Because polymorphism is limited to very superficial modifications on the mal-
ware’s decryption code, there are still plenty of ways for antivirus programs to
identify polymorphed code by analyzing the code and extracting certain high-
level information from it.
Reversing Malware 283