Here you go: (01 March 1998)

	To Jack of Shadows (JS) and +Seniors:

	I'm pleased for many reasons, first, it has been proven that a good 
protection can be written in matter of hours with plain assembly using few 
or none dirty ready-made tricks at all; second, this protection has 
surpassed all my expectations as it was only a game and not a serious 
attempt to protect anything, still, it took 4 hours to be defeated, while it 
just took 2 hours to be created. Many serious protections, with the aid of 
ready-made tricks and hugh amounts of code take fewer time than that to be 
cracked.

	The protection, as I designed it, has many important leads to 
facilitate the cracking process, because as I said, it was not meant to be 
uncrackable, on the contrary, it was weak in many (on purpose) points. Both 
strings: Reg and Unreg, are very close which other and not in any manner 
fragmented or created on the fly. The encryption system used is as simple as 
possible, but it will defeat most of wannabes. It is very easy to neutralize 
if you realize the encryption key changes all the time and it is word sized 
which gives you much more possible encrypted variations than usual (byte 
sized). The whole program ends up encrypted with a different key each time 
it is ran, so the only way to read it is annihilating the encryption system 
or as JS did, creating an ex profeso gadget to do the job.

	With the naked program in hand, there are several additional 
facilities. First let's talk about the Random code generator. It has 6 main 
functions, each one of them is capable of creating perfectly working valid 
"senseless" code. The first function creates paired PUSH and POP 
instructions. That configuration has the advantage to preserve the stack 
pointer unchanged, so the coder can still use the stack without any risk of 
corrupting it or overwriting the main program itself. The second function 
creates MOVE instructions using as source and destination operands any 
REGister except AX or DX because they are needed intact for latter use or 
CS, ES, as it can't be done. The third function mixes all up creating sbb, 
cmp, xor, etc., except it won't execute any DIV instruction, to preserve DX 
as it uses a 16 bits destination operand. The fourth branch creates XCHG 
instructions. The fifth and sixth functions create direct addressing mode 
operations. First, MOV to REG from directly pointed memory location using a 
16 bits random displacement. Notice that this random value could be FFFFh 
producing therefore an error because Intel CPU process a 16 bit addressing 
mode operation pointing to the last byte of any segment, by loading the last 
byte of that segment and the first byte of the following one. The primitive 
intel processors would simply wrap around back to zero and load the last and 
first bytes of the same segment. That's why the code generator will only use 
8 bits registers as destination operand in this function, as it is obvious, 
you cannot control the content of every register at any time during 
execution ending up probably with a general fault protection (win95 will 
snoop that at once). For compatibility reasons the sixth function works 
right the same but using the most complexes Intel architecture addressing 
modes. I was not sure to include this last function because complex memory 
addressing modes like: base plus indexed plus 16 bits displacement are CPU 
intensive operations which probably makes this configuration unpractical if 
we would want to employ it at major scale in a commercial product. All six 
functions are able to create perfectly working code that never touches the 
stack, important registers or any memory location. The code is easy to spot 
because it performs suspicious operations as PUSHing and POPing the same 
register, exchanging values using the same register, etc. It was meant that 
way again just to facilitate the job of the potential cracker, off course, 
with several few additional precautions and another 10 or 11 more functions, 
you could create realistic code hard to fish for the untrained eye.

	JS could not explain why the junk registers are cleaned up, he said 
that it was an unnecessary action; he stated this, because he knew what the 
hell was going on, however, if the potential cracker doesn't understand the 
protection and we pretend (by using random code) to simulate a very complex 
mathematical process, it would be very nice to add a register initialization 
sequence as if the value in these register needed to be cleared before going 
any further. Many instructions in a protection scheme are there just to 
confuse, that's part of the game, isn't it?

	JS could not understand the last segment because it is unfinished, 
two hours was not enough to fix everything, it changes the encryption key at 
random, stores it in memory, encrypts the whole program on memory, saves it 
back on the dead file, decrypts it back to prevent CS:IP from pointing to 
junk and the execution continues cleanly. There's an error recovery addition 
at the end, just in case some wannabe decides he's to clever and tries to 
fools the protection by changing the file name or anything like that, 
however, at the end I decided to leave that door open to ease things. JS 
found it and changed the filename, that was the way to do it.

	The Unreg string is presented using INT 21h, no direct screen write, 
no binary level code generation or complex displacement calculation. All of 
that, guess why? Again, to facilitate the cracker's job.

	Finally, the ultimate code, the one which encodes the meaningful 
instructions provides a subtle randomicity system, preventing the main 
operations from falling in the same offset every time because that would 
make the whole code generator worthless. Still the string displaying 
sequence is nothing more than basic.

	Even with all the facilities named, this baby made your life 
miserable at list for four hours, je, je :-)

	There's no point on which language you use to protect, if you do it 
because you want to earn money or limit people's choice, you'll fail. If you 
do it as an art, you'll succeed. I don't agree with the statement in regard 
to the fact that assembly is only useful if you crack DOS targets. On the 
contrary, it doesn't matter what language you've used to protect, the 
cracker will end up dealing with assembly, I don't have to hook an API using 
assembly to probe my point or Do I? I sincerely wish to see more assembly 
targets out there, or maybe more clever ideas as +RCG's even if they are not 
written in assembly. Remember this, if you program in any language, 
depending on how flexible it is, you can play God, if you master assembly, 
you don't have to play God, coz you're him...


	To JS: You're good, so many years out of the scene and you're not 
rusted at all. I wanna hear more about your ideas, so be good to us an write 
about some protection you like or anything else you think could be helpful 
for us, I'm sure Fravia+ will publish it as he's the best to seize the 
brightest stars out there in the cracking scenario. There are bad news too, 
the baby's little brother will be delivered as soon as I have some spare 
time to code again.

	To the +Seniors: Coding in assembly permits you to downgrade your 
communication with the CPU at the very binary level itself, where there are 
no barriers and all of the CPU's resources respond merely as slaves to your 
will. Experiment the sensation of leaving aside your asm interpreter and 
talk with the CPU in binary is sensational, there's no limit for what you 
can accomplish. +ORC's warned us about junk random generated code being used 
as a a mean of effective protection. Encryption is already being effectively 
used (timelock for instance) to protect. Random code is not yet a 
frequent practice, but we have to teach protectionists to use it, I'm sure 
it'll be great fun to crack their pathetic random code.



						Aesculapius.