Scott Knight
6 min read

Categories

Tags

In my previous post I covered my “Classic” Mac OS emulator set up. One of my goals of getting the emulator set up was to be able to look at and analyze viruses that affected older versions of Mac OS. I think taking a look at old viruses is interesting for two reasons. First, it provides a good overview of 68k assembly. Second, it provides an interesting perspective on the history of malicious software. The first virus I decided to look at is called INIT 29.

Overview

The Disinfectant 3.7.1 help file has a good short description of the virus:

The INIT 29 virus first appeared in late 1988. We do not know much about its origin. A second minor variant appeared in March, 1994. There are no significant difference between the two strains. The original strain is called “INIT 29 A”. The variant is called “INIT 29 B”.

INIT 29 is extremely virulent. It spreads very rapidly. Unlike Scores and nVIR, you do not have to run an application for it to become infected. Also, unlike Scores and nVIR, INIT 29 can and will infect almost any file, including applications, system files, and document files. Document files are infected, but they are not contagious. The virus can only spread via system files and application files.

Infected application

An application infected with the INIT 29 virus can be easily identified using ResEdit. See an example in the screenshot below:

App Jump Table

The first indicator is a CODE resource of exactly 712 bytes. The second indicator can be seen in the jump table. Each executable has a CODE resource with ID 0 that contains the jump table. If it’s a small application it might only have one or two entries in the table. Normally when the compiler builds an application it would create CODE resources sequentially and similarly the jump table would also be laid out in a linear fashion. The first entry in the jump table points to the main entry point for the executable. In the case of the jump table above, the first entry in the jump table actually points to the CODE resource with ID 3. You can see based on the resource names that ID 1 has a name of “Main” and is the largest section of code. This should be the entry point to the application but the INIT 29 virus has modified the jump table entry to point to itself instead.

The image below shows a section of the virus code. You can see how it has saved the original jump table entry to the CODE resource with ID 1.

App Virus CODE Resource

When an infected application is run it will call UseResFile passing in a refNum value of zero. This will retrieve the System resource file. It will then create a new entry in the INIT resource section with an ID of 29. This is where the name of the virus comes from. The virus copies all 712 bytes of itself into this INIT resource. This code will then be executed when the system starts up next.

Infected system file

An infected System file is also easy to identify using ResEdit. We can run an infected application in our emulator and then use ResEdit to compare the system file before and after detonation.

System File Infection

The left side of the image above is before running the infected application and the right side is after. You can see that after the infected application is run there is now a new INIT resource with the ID 29 and a size of exactly 712 bytes. If we disassemble the virus code we can see the following:

INIT 29 Code

The INIT code is fairly short. It calls GetTrapAddress passing in $A997 to get the address of the current OpenResFile function. It checks to see if it’s already been patched and if it hasn’t it will save a pointer to the original function. Then it allocates 712 bytes on the system heap and makes a copy of itself there. Finally it calls SetTrapAddress to install itself as the new OpenResFile function.

Hijacked OpenResFile

OpenResFile is an important system API. Any time the Finder has to open a file or run an executable it will make use of OpenResFile to find out information about the file. Since it’s used so often it makes a great hook point for the virus to infect other files. The hijacked version of OpenResFile first calls into the original operating system version of the function. This will load the resource file and set it as the current resource. The virus then looks to see if the file has any CODE resources or not. If the file doesn’t have any CODE resources then the virus creates an INIT resource with ID 29 and copies it’s 712 bytes into it. This results in document files that contain the virus code but can’t infect anything else. If the opened resource does have a CODE resource then the virus attempts to find a free ID to use. It will use the lowest free ID to create a new resource entry and copy it’s 712 bytes into it. After that it opens the CODE resource with ID 0 and patches the jump table to point to the new resource that it just created. This results in the application running the virus code the next time it starts attempting to infect the System file.

Conclusion

With the INIT 29 virus attempting to infect every single resource file opened it’s easy to see why the Disinfectant help file called the virus “extremely virulent”. For the most part the virus is harmless and simply infects files. However, since it does hijack the startup of applications it is possible to notice a slow down when launching programs. It’s especially interesting to see just how much the virus accomplishes using only 712 bytes of code.

IOCs

Indicator Type Context
36ff546b093706c98524657e69b124b4bb8ff763b02ee5a7df3281d5ff7a8d91 SHA256 Init29.A
b40e63e0ae669ed362370e0b05e20067c1e3d285f2532927ee58a5dea275571a SHA256 Init29.C
b0318fa75edd599ca739e774fe7a4dcacd2b5e60bcf7830ed45adbbaaacad83a SHA256 Init29.C
2c08b750c30cbd36827f2ccc01546e4fe3aa5ef86b4fd7a9b65038540849feb8 SHA256 Init29.C