Return to Stories

Self-Modifying Code
by Keith Falkner

To make a program inscrutable, write the code so that it modifies itself. The elementary way to do this is to use No-Op/Branch switches. Simply overwrite the B opcode with letter N, and control will continue in line instead of branching. I recall writing some code that would be read only by me, in a situation where economy of memory was vital. I needed to arrange a switch that branched to DETOUR on only the 3rd, 5th, 7th, and successive odd passages through the code. Here is how I handled (or mangled) it:

MODIFY S +1,SWITCH

SWITCH MCE DETOUR

(Here follows code to be executed on the 1st, 2nd, 4th, 6th, and successive even passages.)

DETOUR A SWITCH

(Here follows code to be executed on the 3rd, 5th, 7th, and successive odd passages.)

Now, here is how this economical but obscure code functioned. As written, the instruction labeled SWITCH will cause a process error. The MCE instruction, assembled as letter E, is used to format numeric data, according to the pattern in a receiving field known as an Edit Word. The letter A, at location DETOUR, is acceptable as numeric data, but not as an edit word, for it has no place to receive the one digit being sent.

But one is subtracted from SWITCH by the instruction preceding it, changing the E opcode to D. D is the opcode for MN, the Move Numeric instruction. This instruction moves the numeric portion of DETOUR's opcode A, the digit 1, to itself, accomplishing nothing, after which control continues in-line.

Next time control approaches SWITCH, another 1 is subtracted, changing D to C, after which the letter A is compared to itself, and again control continues in-line.

Next time (this is the third time) control approaches SWITCH, another 1 is subtracted, creating the instruction

B DETOUR

which sends control to that label. The instruction at Detour adds the B to itself, creating D again.

This code accomplishes, in minimum memory, the required sequence of DON’T-BRANCH, DON'T-BRANCH, do-branch, DON'T-BRANCH, do-branch, DON'T-BRANCH …

But wait, there is more. A circumstance arose such that the above alternating cycle had to be cancelled, such that control never again went to DETOUR. How do you think I handled that, bearing in mind that economy of memory use was paramount. Here is the answer:

A MODIFY

This instruction adds the opcode labeled MODIFY to itself. OK, what is the sum of S and S? Well, it is D, so the instruction labeled MODIFY becomes

MODIFY MN +1,SWITCH

so SWITCH becomes

SWITCH A DETOUR

and never again changes. The instruction labeled DETOUR gets corrupted, but that doesn't matter, because it is never executed.

Perhaps diabolical programmers have created worse travesties of self-modifying code, but that was as far as I went!