Embedded Protection - Marks Usage Tips


Embedded Protection Marks Usage Tips

 

Introduction:

Embedded Protection possibly is the most important and efficient protection feature of SDProtector, it allows SDProtector to insert some protection code to your code, mixing your code with protector in source code level. It makes your program hard to dump and reconstruct for crackers.


Notes
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.
CopyRight(C) 2003 SDProtector.com All Rights Reserved