It is safe to execute marked code before and after protection, license
dependent code will be skipped if no valid license is present.
These are some common mistakes when using code encryption, please make
sure to avoid them:
1. In order to encrypt parts of your application,
you need to mark both beginning and end of the code in question, and
you should always use marks in pairs.
for C/C++
// use marks in pairs
{
PATTERN_BLOCK_START <-- Wrong! PATTERN_BLOCK_END is lost, this mark will be ignored!
...
}
for Delphi
// use marks in pairs
begin
{$I PATTERN_BLOCK_START.inc} <-- Wrong! {$I PATTERN_BLOCK_END.inc} is lost, this mark will be ignored!
...
end;
2. Nested marks are not supported and will cause problems.
for C/C++
// Nested marks are not supported
{
PATTERN_BLOCK_START
...
PATTERN_BLOCK_START // <-- Wrong! This mark will be ignored!
...
PATTERN_BLOCK_END // <-- This will become the end mark.
...
PATTERN_BLOCK_END // This mark will be ignored as well!
}
// Calling an encrypted procedure from another encrypted procedure is ok, though.
void foo()
{
PATTERN_BLOCK_START
foo2();
PATTERN_BLOCK_END
}
void foo2()
{
PATTERN_BLOCK_START
...
PATTERN_BLOCK_END
}
for Delphi
// Nested marks are not supported
begin
{$I PATTERN_BLOCK_START.inc}
...
{$I PATTERN_BLOCK_START.inc} // <-- Wrong! This mark will be ignored!
...
{$I PATTERN_BLOCK_END.inc} // <-- This will become the end mark.
...
{$I PATTERN_BLOCK_END.inc} // This mark will be ignored as well!
end;
// Calling an encrypted procedure from another encrypted procedure is ok, though.
procedure foo;
begin
{$I PATTERN_BLOCK_START.inc}
foo2;
{$I PATTERN_BLOCK_END.inc}
end;
procedure foo2;
begin
{$I PATTERN_BLOCK_START.inc}
...
{$I PATTERN_BLOCK_END.inc}
end;
3. Be careful when using recursive call.
for C/C++
// Do not call encrypted code recursively
void foo()
{
PATTERN_BLOCK_START
...
if (x) then
foo(); // Wrong!
...
PATTERN_BLOCK_END
}
// Workaround for above problem
void foo()
{
PATTERN_BLOCK_START
...
PATTERN_BLOCK_END
if (x) then
foo();
PATTERN_BLOCK_START
...
PATTERN_BLOCK_END
}
for Delphi
// Do not call encrypted code recursively
procedure foo;
begin
{$I PATTERN_BLOCK_START.inc}
...
if (x) then
foo; // Wrong!
...
{$I PATTERN_BLOCK_END.inc}
end;
// Workaround for above problem
procedure foo;
begin
{$I PATTERN_BLOCK_START.inc}
...
{$I PATTERN_BLOCK_END.inc}
if (x) then
foo;
{$I PATTERN_BLOCK_START.inc}
...
{$I PATTERN_BLOCK_END.inc}
end;
4. When adding marks to your code, make sure that
both of them will be executed in any case (i.e. don't jump in or out
of protected code, don't mark code inside of try/except statements etc.).
for C/C++
// Do not prematurely exit functions when using code encryption
{
PATTERN_BLOCK_START
do{
...
if(y)
return; // <-- Wrong! Second mark will not be executed!
...
} while (x)
PATTERN_BLOCK_END
}
// Be careful when using exception handling
{
PATTERN_BLOCK_START
__try
{
...
}
__finally
{
...
return; // <-- Second mark will not be executed if an exception occurs!
}
PATTERN_BLOCK_END
}
// Be careful with 'goto'
{
PATTERN_BLOCK_START
...
goto Error; // <-- Wrong! Second mark will not be executed!
PATTERN_BLOCK_END
Error:
}
for Delphi
// Do not prematurely exit functions when using code encryption
begin
{$I PATTERN_BLOCK_START.inc}
while (x) do
begin
...
if (y) then exit; // <-- Wrong! Second mark will not be executed!
...
end;
{$I PATTERN_BLOCK_END.inc}
end;
// Be careful when using exception handling
begin
{$I PATTERN_BLOCK_START.inc}
try
...
finally
... // <-- Second mark will not be executed if an exception occurs!
end;
{$I PATTERN_BLOCK_END.inc}
end;
5. Be careful when protecting a critical function.
for C/C++
// Do not use marks like this
{
PATTERN_BLOCK_START
CheckRegistrationStatus();
PATTERN_BLOCK_END
...
// Because You will encrypt only jump to function and function's code will not
//encrypted. Then is possible for cracker find function and corrected jump.
}
for Delphi
// Do not use marks like this
begin
{$I PATTERN_BLOCK_START.inc}
CheckRegistrationStatus;
{$I PATTERN_BLOCK_END.inc}
...
// Because You will encrypt only jump to function and function's code will not
//encrypted. Then is possible for cracker find function and corrected jump.
end;
6. Efficiency problem.
for C/C++
// Never use marks like this
{
for(int i=0;i<999999;i++)
{
PATTERN_BLOCK_START
...
PATTERN_BLOCK_END
}
// Because code between marks will be encrypted and decrypted 999999 times!
}
// Workaround for above problem
{
PATTERN_BLOCK_START
for(int i=0;i<999999;i++)
{
...
}
PATTERN_BLOCK_END
}
for Delphi
// Never use marks like this
var
I :Integer;
begin
for I:=1 to 999999 do
begin
{$I PATTERN_BLOCK_START.inc}
...
{$I PATTERN_BLOCK_END.inc}
end
// Because code between marks will be encrypted and decrypted 999999 times!
end;
// Workaround for above problem
var
I :Integer;
begin
{$I PATTERN_BLOCK_START.inc}
for I:=1 to 999999 do
begin
...
end
$I PATTERN_BLOCK_END.inc}
end;
7. Code encryption can be used with threads as
well. However, only one thread at a time will have access to an encrypted
section, other threads will have to wait for the first thread to leave
the encrypted section. You should use critical sections/flags for preventing
two or more threads execute protected code at same time.