PDA

View Full Version : How to execute arbitrary code...


efrost
14th December 2007, 02:27 AM
Dear all,

I want to publish here one very very simple method how you can execute arbitrary code in your applications.

This method can be used to protect your software with runtime decryption\encryption mechanisms.
For example, your license checking function can be stored in the exe-file somehow encrypted and you'll be able to decrypt it in runtime end execute.

Using this method you can even encrypt all your application and decrypt only necessary functions just before you want to execute them. :)

Of course you should understand that any security mechanisms sooner or later will be cracked, but our goal is not to create non-breakable security, but to make cracking process more expensive then buying a license. ;)

So, the idea is simple: we can prepare some buffer in the application and in the runtime copy there code we want to execute.

Here is source code:

/*
After compilation it is necessary to change flags of .mysec
from 60000020 (Code Execute Read) на E0000020 (Code Execute Read Write)

Just open exe-file, search for 0x20 0x00 0x00 0x60 after text ".mysec"
and change it to 0x20 0x00 0x00 0xE0
*/

#include <windows.h>

// turn off optimiztions
#pragma optimize("", off)

// define our code segment
#pragma code_seg(".mysec")

// let's allocate some place in our new segment
__declspec(allocate(".mysec")) BYTE pBUF[100];

// put functions to the new segment (not necessary!)
int func1(int i)
{
return i*2;
}

int func2(void) // just fake function. we'll need it to find size of func1
{
return 5;
}

// turn on optimizations
#pragma optimize("", on)

// switch back to .text segment
#pragma code_seg()

// define pointer to function
typedef int (*pfn_t)(int i);

int _tmain(int argc, TCHAR* argv[])
{
func2(); // not so necessary, but linker might remove unused functions... :-\

// here we're copying code of func1 into the buffer :)
// in fact, here should be some procedure decrypting necessary
// code into our buffer, but to simplify the example, I'll
// just copy one of existing functions int the buffer
// and then execute it
memcpy(pBUF, &func1, (int)&func2 - (int)&func1);

int a = ((pfn_t)(void*)pBUF)(4); // execute

// show result
wchar_t pBuf[20] = {0};
wsprintf(pBuf, L"a = %d", a);
::MessageBoxW(0, pBuf, L"tst1", MB_OK);

return 0;
}

I'll also attach the compiled application for those who think it won't work. :D

Thank you!

Best regards,
efrost