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.