ultimatepp/bazaar/Protect/Protect.h
micio 883a63e29c Bazaar/Protect : reverted useless change
git-svn-id: svn://ultimatepp.org/upp/trunk@6221 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2013-07-31 20:40:51 +00:00

339 lines
8.5 KiB
C++

#ifndef _Protect_h_
#define _Protect_h_
#include <Core/Core.h>
#include <Cypher/Cypher.h>
using namespace Upp;
#define PROTECT_START_MARKER "\xba\xad\xde\xad\xfa\xce"
#define PROTECT_END_MARKER "\xc0\xde\xde\xad\xfe\xed"
#define OBFUSCATE_START_MARKER "\xba\xad\xde\xad\xfa\xde"
#define OBFUSCATE_END_MARKER "\xc0\xde\xde\xad\xfe\xde"
#ifdef flagPROTECT
#ifdef PLATFORM_POSIX
#ifdef flagMT
#define PROTECT_START_FUNC1(decrFunc) \
static volatile bool __decrypted = false; \
INTERLOCKED \
{ \
if(!__decrypted) \
{ \
PROTECT_WRITE_ACCESS((byte *)&&__start, (byte *)&&__end - (byte *)&&__start, true); \
decrFunc((byte *)&&__start, (byte *)&&__end - (byte *)&&__start, (byte *)&&__init + 2, 6 /* sizeof(PROTECT_START_MARK) */); \
PROTECT_WRITE_ACCESS((byte *)&&__start, (byte *)&&__end - (byte *)&&__start, false); \
__decrypted = true; \
asm volatile ( \
"\txor %%eax, %%eax\n" \
"\tcpuid\n" \
: \
: \
: "eax", "ebx", "ecx", "edx" \
); \
} \
}
/* THIS BECAUSE THEIDE HANGS... */
#define PROTECT_START_FUNC2 \
if(__decrypted) \
{ \
if(!__decrypted) \
{ \
__init: \
asm volatile( \
"\tjmp 1f\n" \
"\t.ascii \""PROTECT_START_MARKER"\"\n" \
"1:\n" \
); \
} \
__start:
#define PROTECT_START_FUNC(DecrFunc) PROTECT_START_FUNC1(DecrFunc) PROTECT_START_FUNC2
#else
#define PROTECT_START_FUNC1(decrFunc) \
static volatile bool __decrypted = false; \
if(!__decrypted) \
{ \
PROTECT_WRITE_ACCESS((byte *)&&__start, (byte *)&&__end - (byte *)&&__start, true); \
decrFunc((byte *)&&__start, (byte *)&&__end - (byte *)&&__start, (byte *)&&__init + 2, 6 /* sizeof(PROTECT_START_MARK) */); \
PROTECT_WRITE_ACCESS((byte *)&&__start, (byte *)&&__end - (byte *)&&__start, false); \
__decrypted = true; \
asm volatile ( \
"\txor %%eax, %%eax\n" \
"\tcpuid\n" \
: \
: \
: "eax", "ebx", "ecx", "edx" \
); \
}
/* THIS BECAUSE THEIDE HANGS... */
#define PROTECT_START_FUNC2 \
if(__decrypted) \
{ \
if(!__decrypted) \
{ \
__init: \
asm volatile( \
"\tjmp 1f\n" \
"\t.ascii \""PROTECT_START_MARKER"\"\n" \
"1:\n" \
); \
} \
__start:
#define PROTECT_START_FUNC(DecrFunc) PROTECT_START_FUNC1(DecrFunc) PROTECT_START_FUNC2
#endif
#define PROTECT_END_FUNC \
} \
else \
{ \
__end: \
asm volatile ( \
"\tjmp 2f\n" \
"\t.ascii \""PROTECT_END_MARKER"\"\n" \
"2:\n" \
::: \
); \
goto __start; \
}
#define OBFUSCATE_START_FUNC \
static volatile bool __xxx = false; \
PROTECT_OBFUSCATE((byte *)&&__start, (byte *)&&__end - (byte *)&&__start + 2, (byte *)&&__init + 2, 16 /* sizeof(OBFUSCATE_START_MARKER) + sizeof("0123456789") */); \
asm volatile ( \
"\txor %%eax, %%eax\n" \
"\tcpuid\n" \
: \
: \
: "eax", "ebx", "ecx", "edx" \
); \
__xxx = true; \
if(__xxx) \
{ \
__init: \
asm __volatile__( \
"\tjmp 1f\n" \
"\t.ascii \""OBFUSCATE_START_MARKER"\"\n" \
"\t.ascii \"0123456789\"\n" \
"1:\n" \
); \
} \
__start: \
if(__xxx) \
__xxx++;
#define OBFUSCATE_END_FUNC \
if(__xxx) \
__xxx++; \
__end: \
asm __volatile__( \
"\tjmp 1f\n" \
"\t.ascii \""OBFUSCATE_END_MARKER"\"\n" \
"1:\n" \
); \
PROTECT_OBFUSCATE((byte *)&&__start, (byte *)&&__end - (byte *)&&__start + 2, (byte *)&&__init + 2, 16 /* sizeof(OBFUSCATE_START_MARKER) + sizeof("0123456789") */);
#else
#define _PROTECT_START_MARKER __asm _emit 0xba __asm _emit 0xad __asm _emit 0xde __asm _emit 0xad __asm _emit 0xfa __asm _emit 0xce
#define _PROTECT_END_MARKER __asm _emit 0xc0 __asm _emit 0xde __asm _emit 0xde __asm _emit 0xad __asm _emit 0xfe __asm _emit 0xed
#define _OBFUSCATE_START_MARKER __asm _emit 0xba __asm _emit 0xad __asm _emit 0xde __asm _emit 0xad __asm _emit 0xfa __asm _emit 0xde
#define _OBFUSCATE_END_MARKER __asm _emit 0xc0 __asm _emit 0xde __asm _emit 0xde __asm _emit 0xad __asm _emit 0xfe __asm _emit 0xde
#define _OBFUSCATE_KEYPLACER __asm _emit 0x00 __asm _emit 0x01 __asm _emit 0x02 __asm _emit 0x03 __asm _emit 0x04 __asm _emit 0x05 __asm _emit 0x06 __asm _emit 0x07 __asm _emit 0x08 __asm _emit 0x09
#ifdef flagMT
#define PROTECT_START_FUNC(decrFunc) \
static volatile bool __decrypted = false; \
INTERLOCKED \
{ \
byte *__startPtr, *__endPtr, *__noncePtr; \
if(!__decrypted) \
{ \
__asm \
{ \
__asm push eax \
__asm lea eax, __start \
__asm mov __startPtr, eax \
__asm lea eax, __end \
__asm mov __endPtr, eax \
__asm lea eax, __init \
__asm inc eax \
__asm inc eax \
__asm mov __noncePtr, eax \
__asm pop eax \
}; \
PROTECT_WRITE_ACCESS(__startPtr, __endPtr - __startPtr, true); \
decrFunc(__startPtr, __endPtr - __startPtr, __noncePtr, 6); \
PROTECT_WRITE_ACCESS(__startPtr, __endPtr - __startPtr, false); \
__decrypted = true; \
__asm \
{ \
__asm push eax \
__asm push ebx \
__asm push ecx \
__asm push edx \
__asm xor eax, eax \
__asm cpuid \
__asm pop edx \
__asm pop ecx \
__asm pop ebx \
__asm pop eax \
}; \
} \
} \
if(!__decrypted) \
goto __end; \
__init: \
__asm { \
__asm jmp __next \
_PROTECT_START_MARKER \
__asm __next: \
} \
__start: \
{
#else
#define PROTECT_START_FUNC(decrFunc) \
static bool __decrypted = false; \
byte *__startPtr, *__endPtr, *__noncePtr; \
if(!__decrypted) \
{ \
__asm \
{ \
__asm push eax \
__asm lea eax, __start \
__asm mov __startPtr, eax \
__asm lea eax, __end \
__asm mov __endPtr, eax \
__asm lea eax, __init \
__asm inc eax \
__asm inc eax \
__asm mov __noncePtr, eax \
__asm pop eax \
}; \
PROTECT_WRITE_ACCESS(__startPtr, __endPtr - __startPtr, true); \
decrFunc(__startPtr, __endPtr - __startPtr, __noncePtr, 6); \
PROTECT_WRITE_ACCESS(__startPtr, __endPtr - __startPtr, false); \
__decrypted = true; \
__asm \
{ \
__asm push eax \
__asm push ebx \
__asm push ecx \
__asm push edx \
__asm xor eax, eax \
__asm cpuid \
__asm pop edx \
__asm pop ecx \
__asm pop ebx \
__asm pop eax \
}; \
} \
if(!__decrypted) \
goto __end; \
__init: \
__asm { \
__asm jmp __next \
_PROTECT_START_MARKER \
__asm __next: \
} \
__start: \
{
#endif
#define PROTECT_END_FUNC \
} \
__end: \
__asm { \
__asm jmp __next2 \
_PROTECT_END_MARKER \
__asm __next2: \
};
#define OBFUSCATE_START_FUNC \
byte *__startPtr, *__endPtr, *__keyPtr; \
__asm \
{ \
__asm push eax \
__asm lea eax, __start \
__asm mov __startPtr, eax \
__asm lea eax, __end \
__asm mov __endPtr, eax \
__asm lea eax, __init \
__asm inc eax \
__asm inc eax \
__asm mov __keyPtr, eax \
__asm pop eax \
}; \
PROTECT_OBFUSCATE(__startPtr, __endPtr - __startPtr, __keyPtr, 16); \
__asm \
{ \
__asm push eax \
__asm push ebx \
__asm push ecx \
__asm push edx \
__asm xor eax, eax \
__asm cpuid \
__asm pop edx \
__asm pop ecx \
__asm pop ebx \
__asm pop eax \
}; \
__init: \
__asm { \
__asm jmp __next \
_OBFUSCATE_START_MARKER \
_OBFUSCATE_KEYPLACER \
__asm __next: \
} \
__start: \
#define OBFUSCATE_END_FUNC \
__asm { \
__asm jmp __next2 \
_OBFUSCATE_END_MARKER \
__asm __next2: \
}; \
__end: \
PROTECT_OBFUSCATE(__startPtr, __endPtr - __startPtr, __keyPtr, 16)
#endif
// Check macro for program startup -- executes next statement if invalid key
#define ON_PROTECT_BAD_KEY(decrFunc) \
bool __keyOk; \
{ \
const char *crypted = PROTECT_START_MARKER "abracadabra" PROTECT_END_MARKER; \
const int len = strlen("abracadabra"); \
Buffer<byte>buf(len); \
Buffer<byte>nonce(6); \
/* can't use memcpy, it gets optimized out */ \
for(int i = 0; i < len; i++) buf[i] = crypted[i + 6 /* sizeof(PROTECT_START_MARKER)*/]; \
for(int i = 0; i < 6 /* sizeof(PROTECT_START_MARKER)*/; i++) nonce[i] = crypted[i]; \
decrFunc(buf, len, nonce, 6); \
__keyOk = !memcmp(buf, "abracadabra", len); \
} \
if(!__keyOk)
#else
#define PROTECT_START_FUNC(decrFunc)
#define PROTECT_END_FUNC
#define OBFUSCATE_START_FUNC
#define OBFUSCATE_END_FUNC
#define ON_PROTECT_BAD_KEY(decrFunc) if(false)
#endif
bool PROTECT_WRITE_ACCESS(byte *start, size_t size, bool access);
void PROTECT_DECRYPT(byte *start, size_t size, String const &key, byte const *nonce, size_t nonceLen);
void PROTECT_OBFUSCATE(byte *start, size_t len, byte *key, size_t keyLen);
#endif