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:
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.
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.
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:
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 |