Click here to Skip to main content
Click here to Skip to main content

Programming Self-generating Code for Windows Applications

By , 29 Feb 2008
 

Introduction

Self-generating code technology is a very important means to counteract disassembler. You should use this technology to protect your applications although it's a "bad" programming style. There are two documented ways of modifying application code at least. First, kernel32.dll exports the WriteProcessMemory function, intended as follows from its name, for modifying the memory of a process. Second, practically all operating systems, Windows and Linux included, allow the code placed on the stack to be modified. I like the second way, because it is more freedom and less limitation when I try creating self-generating code for Windows applications in VC++ IDE. A FAQ is to cause an exception with the subsequent abnormal termination of the application.

Screenshot - error.jpg

I try to resolve these questions, and get some experience as follows:

The function code must be relocatable code:

  1. Only use local variable, don't use global variable, static variable, and constant string variable.
  2. If the function code wants to invoke another function, the pointer of the function should be passed to it.

Some may have a question about Self-generating code: What's the advantage of it?

The answer is that it can conceal crucial or key information, such as procedures for generating the key or for verifying the serial number.

Using the Code

Step 1: Encrypt My_function Code into a Header File

The following code is my function which I want to execute in the stack. Of course you can modify it, add your own code and test it, then you can get your own experience. If you like, you can share it here or write another article and publish it on The Code Project.

//
void __stdcall my_function( int x,
     int y,
     char* str_a,
     char* str_b,
     void* (__cdecl *_memcpy )( void *dest, const void *src, size_t count ),
     int (__cdecl *_sprintf )( char *buffer, const char *format, ... ),
     void* (__cdecl *_malloc )( size_t size ),
     void (__cdecl *_free )( void *memblock ),
     size_t (__cdecl *_strlen )( const char *string ),
     int (__stdcall* _MessageBox)(HWND hWnd, LPCTSTR lpText, 
     LPCTSTR lpCaption, UINT uType)
)
{
    char* pTemp;
    int str_a_len=_strlen(str_a);
    int str_b_len=_strlen(str_b);   
    pTemp=(char*)_malloc(str_a_len+str_b_len+20);

    if(x>y)
    {
        //_sprintf(pTemp,"%s%s",str_a,str_b);       
        //error:constant string variable
        _memcpy(pTemp,str_a,str_a_len);
        _memcpy(pTemp+str_a_len,str_b,str_b_len);
        pTemp[str_a_len+str_b_len]=0;

        //_MessageBox(NULL,pTemp,"",MB_OK);         
        //error:constant string variable
        _MessageBox(NULL,pTemp,str_a,MB_OK);
    }
    else
    {
        //_sprintf(pTemp,"%s%s",str_b,str_a);
        //error:constant string variable
        _memcpy(pTemp,str_b,str_b_len);
        _memcpy(pTemp+str_b_len,str_a,str_a_len);
        pTemp[str_a_len+str_b_len]=0;

        //MessageBox(NULL,pTemp,"title",MB_OK);
        //error:constant string variable
        _MessageBox(NULL,pTemp,str_b,MB_OK); 
    }

    for(int i=0;i<10;i++)
    {
        int j=1;
        j^=i;
    }

    _free(pTemp);
}  
//

In my_function, I try to invoke some running time library functions and Windows API function, in order to compare parameter X and Y to display different message boxes.

In order to execute this function in the stack, first I should encrypt my_function code. This job is implemented in the project named My_function. If you read it, you can find a function named void __stdcall my_function_END(). In order to calculate the length of my function, my_function_END function must follow on the heels of my_function.

void encrypt_my_function() and bool encrypt_function(BYTE* _my_function,unsigned int n_my_function_size,char* function_name) are used to encrypt my_function code data into a temporary buffer, void build_h(BYTE* pInBuf,int InBufSize,char* function_name) function will write the encrypted code data into a header file.

//
bool encrypt_function(BYTE* _my_function,unsigned int n_my_function_size,
    char* function_name)
{
    BYTE* buff=(BYTE*)malloc(n_my_function_size);
    if(buff==NULL) return false;

    //Note: Here is just a simple encryption algorithm,
    //you should replace it with your own.
    //There are a lot of encryption algorithms which you can get 
    //from the Internet.
    for(UINT i=0;i<n_my_function_size;i++) buff[i]=_my_function[i]^99;

    build_h(buff,n_my_function_size,function_name);
    free(buff);
    return true;
}

//
//
void encrypt_my_function()
{
    void ( __stdcall *_my_function)(int x,
        int y,
        char* str_a,
        char* str_b,
        void* (__cdecl *_memcpy )( void *dest, 
        const void *src, size_t count ),
        int (__cdecl *_sprintf )( char *buffer, const char *format, ... ),
        void* (__cdecl *_malloc )( size_t size ),
        void (__cdecl *_free )( void *memblock ),
        size_t (__cdecl *_strlen )( const char *string ),
        int (__stdcall* _MessageBox)(HWND hWnd, LPCTSTR lpText, 
        LPCTSTR lpCaption, UINT uType)
                                    );
    void ( __stdcall *_my_function_END)();
    unsigned int n_my_function_size;
    char* function_name="myfunction";

    _my_function=my_function;
    _my_function_END=my_function_END;
    n_my_function_size=abs((UINT)_my_function_END-(UINT)_my_function)+1;
    //calculate the length of my_function

    if(encrypt_function((BYTE*)_my_function,n_my_function_size,function_name))
    {
        AfxMessageBox(
            "My function is encrypted successfully ! 
            The encrypted code is included in myfunction.h file.");
    }
    else
    {
        AfxMessageBox("My function is encrypted unsuccessfully !");
    }
}
//

Myfunction.h is generated by My_function project.

A header file which includes the encrypted code data would look as follows:

//
//myfunction.h

unsigned char myfunction_00001_code[]="\
\xe8\x27\x47\x6f\x30\x36\x35\xe8\x17\x47\x53\x34\x33\
x9c\xb5\xe8\x0f\x47\x47\xe8\
\x9b\x36\x9c\xb5\xe8\xbb\xee\x2f\x58\x77\x32\x9c\x37\
x47\x5b\xe8\x37\x47\x43\xe8\
\x93\xe8\x27\x47\x47\xe0\xa7\x6f\x58\xb3\x1d\x5f\xe8\
x27\x47\x7f\x34\x33\x35\x9c\
\x37\x47\x53\x30\xee\x6f\x5d\x36\x32\x9c\x37\x47\x5f\
xe8\x27\x47\x57\xe0\xa7\x7b\
\xee\x77\x7d\x09\x63\x33\x35\x09\x63\xa5\x67\x59\x63\
x9c\x37\x47\x2b\x35\x9c\x37\
\x47\x57\xe0\xa7\x67\x3c\x3d\x3e\x38\xa1\x4b\x63\x30\
x36\x35\x9c\x37\x47\x53\xe8\
\x2f\x47\x4b\x60\xbd\x34\x32\x30\x9c\x37\x47\x5f\xe0\
xa7\x7b\xa5\x67\x58\x63\x09\
\x63\x0b\x17\x33\x23\x63\x35\x09\x63\x9c\x76\x1b\x50\
x23\x63\x09\x63\x36\x35\x09\
\x63\x9c\x37\x47\x2b\x35\x9c\x37\x47\x57\xe0\xa7\x67\
x3c\x3d\x3e\x38\xa1\x4b\x63\
\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xf3\xa0";
#define myfunction_00001_code_LEN 193

#define myfunction_ARRAY_NUM 1
#define myfunction_CODE_LEN 193

//

Note: If you want to define an unsigned char variable like unsigned char myfunction_00001_code[], it's maxlength is 2048. This is the limitation of VC++ 6.0 IDE. So, if the function code is too long, I must write the encrypted code data into multi unsigned char variables.This function can be realized in build_h which looks as follows:

//
void build_h(BYTE* pInBuf,int InBufSize,char* function_name)
{
    DWORD syslen=InBufSize;
    BYTE* sysbuffer=pInBuf;

    char hname[MAX_PATH];
    sprintf(hname,"%s%s",function_name,".h");

    HANDLE hHandle=CreateFileA(hname,
        GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);

    SetFilePointer(hHandle,0,0,FILE_BEGIN);

    DWORD RW;
    char _code_end[]="\";
    int l_end=strlen(&_code_end[0]);

    char cname[MAX_PATH];
    char* pszSlash=hname;

    char TX[5];
    int count=0;
    int arrary_num=1;
    int ar_num=0;

    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);

    WriteFile(hHandle,"//",2,&RW,NULL);
    WriteFile(hHandle,hname,strlen(hname),&RW,NULL);
    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);
    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);

    WriteFile(hHandle,
        "//Created by Your Name",strlen("//Created by Your Name"),&RW,NULL);
    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);

    WriteFile(hHandle, "//your email", strlen("//your email"), &RW, NULL);

    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);

    for(UINT i=0;i<syslen;i++){
        if(ar_num==0){
            WriteFile(hHandle,"\r",1,&RW,NULL);
            WriteFile(hHandle,"\n",1,&RW,NULL);

            int ee=sprintf(cname,"%s","unsigned char ");
            ee+=sprintf(cname+ee,"%s",pszSlash);
            ee=ee-2;
            ee+=sprintf(cname+ee,"%s%05d","_",arrary_num);
            ee=sprintf(cname+ee,"%s",_code[]=\"\\\r\n");
            int l=strlen(&cname[0]);
            WriteFile(hHandle,cname,l,&RW,NULL);
        }

        WriteFile(hHandle,"\\x",2,&RW,NULL);
        sprintf(TX,"%02x",sysbuffer[i]);
        WriteFile(hHandle,TX,2,&RW,NULL);
        count++;
        ar_num=ar_num+4;

        if (count==20){
        count=0;
        WriteFile(hHandle,"\\",1,&RW,NULL);
        WriteFile(hHandle,"\r",1,&RW,NULL);
        WriteFile(hHandle,"\n",1,&RW,NULL);
        }

        if(ar_num>2030){

        arrary_num=arrary_num+1;
        WriteFile(hHandle,_code_end,l_end,&RW,NULL);

        WriteFile(hHandle,"\r",1,&RW,NULL);
        WriteFile(hHandle,"\n",1,&RW,NULL);

        char len[MAX_PATH];
        int ee=sprintf(len,"%s","#define ");
        ee+=sprintf(len+ee,"%s",cname+14);
        ee=ee-7;
        ee+=sprintf(len+ee,"%s","_LEN ");
        ee+=sprintf(len+ee,"%d",ar_num/4);
        WriteFile(hHandle,len,ee,&RW,NULL);

        WriteFile(hHandle,"\r",1,&RW,NULL);
        WriteFile(hHandle,"\n",1,&RW,NULL);

        ar_num=0;
        count=0;
        }
    } 

    double yushu=fmod(syslen*1.0,508.0);
    if(yushu!=0){
        WriteFile(hHandle,_code_end,l_end,&RW,NULL);

        WriteFile(hHandle,"\r",1,&RW,NULL);
        WriteFile(hHandle,"\n",1,&RW,NULL);

        char len[MAX_PATH];
        int ee=sprintf(len,"%s","#define ");
        ee+=sprintf(len+ee,"%s",cname+14);
        ee=ee-7;
        ee+=sprintf(len+ee,"%s","_LEN ");
        ee+=sprintf(len+ee,"%d",ar_num/4);
        WriteFile(hHandle,len,ee,&RW,NULL);

        WriteFile(hHandle,"\r",1,&RW,NULL);
        WriteFile(hHandle,"\n",1,&RW,NULL);
    }

    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);

    char lLen[MAX_PATH];
    int ee=sprintf(lLen,"%s","#define ");
    ee+=sprintf(lLen+ee,"%s",cname+14);
    ee=ee-17;
    ee+=sprintf(lLen+ee,"%s","ARRAY_NUM ");
    ee+=sprintf(lLen+ee,"%d",arrary_num);


    WriteFile(hHandle,lLen,ee,&RW,NULL);

    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);


    ee=sprintf(lLen,"%s","#define ");
    ee+=sprintf(lLen+ee,"%s",cname+14);
    ee=ee-17;
    ee+=sprintf(lLen+ee,"%s","CODE_LEN ");
    ee+=sprintf(lLen+ee,"%d",syslen);


    WriteFile(hHandle,lLen,ee,&RW,NULL);

    WriteFile(hHandle,"\r",1,&RW,NULL);
    WriteFile(hHandle,"\n",1,&RW,NULL);
    CloseHandle(hHandle);
}
//

After generating myfunction.h which includes the encrypted code data of my_funcion, I create a project named self_engendered_code. In this project, My_function is decrypted and then executed in the stack or any other memory buffer such as heap buffer allocated by malloc although some consider that it is not permitted.

Step 2: Decrypt My_function Code and Execute

First, include myfunction.h in the self_engendered_code project. Second, define some macro in order to load the multi unsigned char variables into one memory buffer.

//
#include "..\\\self_engendered_code\\My_function\\myfunction.h"
#define _founc(x) myfunction_##x##_code
#define _founc_len(x) myfunction_##x##_code_LEN
unsigned char p_my_function[1024];
//

void Load_my_function() can decrypt My_function code into a memory buffer: p_my_function here is a global variable. It can be replaced with a local variable which is defined in the function body, that is the local function stack.

//
void Load_my_function()
{
    int code_len=myfunction_CODE_LEN;
    unsigned char* pcode=
        (unsigned char*)malloc(code_len*sizeof(unsigned char));

    if(pcode==NULL)
    {
        #ifdef _DEBUG
            AfxMessageBox("Memory used up!");
        #endif

        return;
    }

    int p;
    int hp=0;

    for(int k=1;k<=myfunction_ARRAY_NUM;k++)
    {
        switch (k)
        {
        //The number of case equal to myfunction_ARRAY_NUM 
        //defined in myfunction.h.
            case 1:
                for(p=0;p<_founc_len(00001);p++) pcode[hp+p]=_founc(00001)[p];
                hp=hp+p;
                break;
            /*
            case 2:
                for(p=0;p<_founc_len(00002);p++) pcode[hp+p]=_founc(00002)[p];
                hp=hp+p;
                break;
            case 3:
                for(p=0;p<_founc_len(00003);p++) pcode[hp+p]=_founc(00003)[p];
                hp=hp+p;
                break;
            case 4:
                for(p=0;p<_founc_len(00004);p++) pcode[hp+p]=_founc(00004)[p];
                hp=hp+p;
            break;
            .
            .
            .

            */
            default:
            break;
        } 
    }

    //Note: Here is just a simple encryption algorithm, you should 
    //replace it with your own.
    //There are a lot of encryption algorithms which you can get 
    //from the Internet. 
    for(int i=0;i<code_len;i++) p_my_function[i]=pcode[i]^99;
}
//

At last, execute My_function in the STACK.

//
void Run_my_function()
{
    int x=1;//8
    int y=2;
    char str_a[]=" HELLO MY_FOUNCTION ! ";
    char str_b[]=" Hello my_function ! ";

    void* (__cdecl *_memcpy )( void *dest, const void *src, size_t count );
    int (__cdecl *_sprintf )( char *buffer, const char *format, ... );
    void* (__cdecl *_malloc )( size_t size );
    void (__cdecl *_free )( void *memblock );
    size_t (__cdecl *_strlen )( const char *string );
    int (__stdcall* _MessageBox)(HWND hWnd, LPCTSTR lpText, 
        LPCTSTR lpCaption, UINT uType);

    _memcpy=memcpy;
    _sprintf=sprintf;
    _malloc=malloc;
    _free=free;
    _strlen=strlen;
    _MessageBox=MessageBox;

    void ( __stdcall *_my_function)(int x,
        int y,
        char* str_a,
        char* str_b,
        void* (__cdecl *_memcpy )( void *dest, 
        const void *src, size_t count ),
        int (__cdecl *_sprintf )( char *buffer, const char *format, ... ),
        void* (__cdecl *_malloc )( size_t size ),
        void (__cdecl *_free )( void *memblock ),
        size_t (__cdecl *_strlen )( const char *string ),
        int (__stdcall* _MessageBox)(HWND hWnd, LPCTSTR lpText, 
        LPCTSTR lpCaption, UINT uType)
                                    );
    _my_function=(void ( __stdcall *)(int x,
        int y,
        char* str_a,
        char* str_b,
        void* (__cdecl *_memcpy )( void *dest, 
        const void *src, size_t count ),
        int (__cdecl *_sprintf )( char *buffer, const char *format, ... ),
        void* (__cdecl *_malloc )( size_t size ),
        void (__cdecl *_free )( void *memblock ),
        size_t (__cdecl *_strlen )( const char *string ),
        int (__stdcall* _MessageBox)(HWND hWnd, LPCTSTR lpText, 
        LPCTSTR lpCaption, UINT uType)
        )) &p_my_function[0];

    _my_function(x,
                 y,
                 str_a,
                 str_b,
                 _memcpy,
                 _sprintf,
                 _malloc,
                 _free,
                 _strlen,
                 _MessageBox
                 );
}
//

Summary

If you want to conceal crucial information, you shouldn't invoke the MessageBox API function. Certainly, the resistance of this protection is insignificant. However, it may be increased. There are numerous programming tips for this purpose, including dynamic asynchronous decoding, substituting the results of comparison for factors in various expressions, and placing the crucial part of code directly in the key. However self-generating code technology is so important that it has been adopted by Antidebug LIB. The purpose of this article is not to offer ready-to-use protection (which hackers could study), but to prove and show that it is possible theoretically to create self-generating code under the control of Windows. How to make use of this possibility is your task.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Jim Charles
Engineer AntiDebugLIB Inc
United States United States
Member
There are so many hackers all over the world that no software can escape the doom of being cracked.And even almost everybody believe that it is impossible to protect the applications through the technology means.But we still work hard to find applications protection solution [32-bit] [64-bit] in order to protect our works.
 
Homepage:

http://www.antidebuglib.com/

http://www.wintsd.com/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionVisual Studio 2010memberMystery12316 Dec '11 - 4:45 
Is anybody able to make it work under VS2010? I still get access violation exception.
Michal

AnswerRe: Visual Studio 2010memberMystery12316 Dec '11 - 5:02 
So I've found the problem - there is a new option in Linker settings->Advanced called Data Execution Prevention (DEP). This one must be set to No to make it work (which is quite logical, but new). Blush | :O
Michal

GeneralRe: Visual Studio 2010memberJim Charles16 Dec '11 - 5:54 
Yes,Set "Data Execution Prevention(DEP)" to "Default".
More settings may refer to antidebug_demo. Smile | :)
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

QuestionCould it work in Ubuntu Linux ?memberXie Jinghui30 Jun '11 - 17:41 
Thank you, Jim Charles! I did really appreciate this artical.
I'm learning linux programming, so I port the code to Ubuntu Linux, complie with G++;
Unfortunately, I cannot run the function, and I just copy the function's memory into allocated memory with no encryption involed. Sigh | :sigh:
 
any suggestion ?
Rose | [Rose]
AnswerRe: Could it work in Ubuntu Linux ?memberJim Charles24 Nov '11 - 5:13 
I think that is feasible. But I have not done experiments.
 
Must ensure that the function code must be relocatable code:
 
1.Only use local variable, don't use global variable, static variable, and constant string variable.
2.If the function code wants to invoke another function, the pointer of the function should be passed to it.
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralFunction size ??memberNicolas Dorier29 Apr '11 - 1:14 
I don't understand why you add +1 to calculate the function size
 
n_my_function_size=abs((UINT)_my_function_END-(UINT)_my_function)+1;
 
If _my_function begin at 0x10 and _my_function_END at 0x14, then the size of _my_function is 4 (0x10,0x11,0x12,0x13), not 5.
GeneralRe: Function size ??memberJim Charles29 Apr '11 - 15:03 
Nicolas Dorier wrote:
I don't understand why you add +1 to calculate the function size
 
n_my_function_size=abs((UINT)_my_function_END-(UINT)_my_function)+1;
 
If
_my_function begin at 0x10 and _my_function_END at 0x14, then the size of
_my_function is 4 (0x10,0x11,0x12,0x13), not 5.

 

You are right.
 
You can calculate the function size as follow.
n_my_function_size=abs((UINT)_my_function_END-(UINT)_my_function);
 
You are very careful,thanks.
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralMy vote of 5memberXie Jinghui24 Mar '11 - 20:21 
excellent
QuestionPortable solution?memberSpaceSoft5 Dec '10 - 5:23 
Is there anyway to make the code portable?
AnswerRe: Portable solution?memberJim Charles5 Dec '10 - 14:30 
SpaceSoft wrote:
Is there anyway to make the code portable?

 
Can you tell me more detail about "the code portable"?
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: Portable solution?memberSpaceSoft6 Dec '10 - 5:03 
Make the code cross-platform, running on different system like Linux or Mac Os X.
I'm going to make a shareware, cross-platform program that needs that code, so I'm Looking to a cross-platform solution Wink | ;)
GeneralRe: Portable solution?memberJim Charles6 Dec '10 - 19:07 
SpaceSoft wrote:
Make the code cross-platform, running on different system like Linux or Mac Os X.
I'm going to make a shareware, cross-platform program that needs that code, so I'm Looking to a cross-platform solution

 
I think the principle is same. But c language is a better choice rather than c + +.
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: Portable solution?memberSpaceSoft8 Dec '10 - 0:16 
You're using a lot of functions made by microsoft..so, how can I make this code portable?
GeneralRe: Portable solution?memberJim Charles8 Dec '10 - 5:28 
SpaceSoft wrote:
You're using a lot of functions made by microsoft..so, how can I make this code portable?

 
Roll eyes | :rolleyes:
Please tell me what kinds of software you want to write , maybe I can do it for you. Big Grin | :-D
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: Portable solution?memberSpaceSoft17 Dec '10 - 7:32 
sorry for my delay in response.
I want to do a software that modify itself to increase its security, because I need to store a crypted password in the compiled files, then decrypt it "on the fly" using self-modifying code to make it more complex to disassembly
GeneralRe: Portable solution?membergrilialex30 May '11 - 5:00 
Very nice article. Just for completeness:
One thing you have to have in mind, is that portability to other processor architectures may be problematic. ie. in case of ARM processors the architecture is Harvard (vs von Neumann) where data and program memories are separate. In this case you cannot execute (program code) directly from the stack (data section), unless there is a hardware provision. This is not a concern for x86 CPUs but if you need to port your software to mobile devices this could be a problem.
GeneralMy vote of 5memberKanasz Robert2 Dec '10 - 5:36 
Good job
GeneralMy vote of 5membernhjhkhkjhk17 Nov '10 - 4:21 
ok
GeneralMy vote of 5memberbfbgggggggg17 Nov '10 - 4:15 
Excellent
GeneralMy vote of 5membervnvbbmnmn17 Nov '10 - 4:11 
excellent
GeneralAny possibility of porting to kernel modememberuityuiyiy25 Jun '10 - 10:16 
Hi Jim,
 
If i want to employ Self modifying code (smc) in a kernel mode driver, is it possible to execute code from stack in the kernel mode too? Does your code directly portable to kernel mode? Is there any other method to execute smc say by chaning page protections in kernel mode? I am looking for something like VirtualProtect() equivalent in kernel mode but could not find one.....
GeneralRe: Any possibility of porting to kernel modememberJim Charles25 Jun '10 - 17:34 
Q1:It is possible to execute code from stack in the kernel mode !
Q2:My code can portable to kernel mode,but you must use kernel mode functions.
Q3:Should be possible.
 
Moreover, the definition of the stack, I think that is the local variable, instead of malloc() function, but malloc's effect is better,because the memory location is random.In kernel mode, you should use the corresponding function with malloc.
I hope you are satisfied with my answer. Big Grin | :-D
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: Any possibility of porting to kernel modememberuityuiyiy26 Jun '10 - 7:42 
Thanks Jim for your help, specially Q2
Generalcode in _my_function never executes for mememberDeepika Mulani10 Nov '09 - 15:14 
Hi,
A very good article.
I'm checking the self_engendered_code after the first project has created the myfunction.h
But somehow on debugging I see that the Load_my_function works fine but in Run_my_function() exactly at the point where the function pointer is used to invoke the function through the data present in p_my_function I get this error.
Unhandled exception at 0x0042a8f2 in self_engendered_code.exe: 0xC0000005: Access violation writing location 0x7689d3bd.
I'm actually wondering does this code even work ? As there is nothing that the function is writing and I've replaced my_function with:
void __stdcall my_function()
{
MessageBox(NULL,"Hello","MyFunction",MB_OK);
}
 
I'm compiling the code on VS2008 and I'm using Vista. Should any of these be reason for this problem.
AnswerRe: code in _my_function never executes for mememberJim Charles17 Nov '09 - 2:26 
The function code must be relocatable code:
1. Only use local variable, don't use global variable, static variable, and constant string variable.
2. If the function code wants to invoke another function, the pointer of the function should be passed to it.
 
I rewrite your code as follow:
 
char str_a[]="Hello ";
char str_b[]="MyFunction";
 
void __stdcall my_function(
char* str_a,
char* str_b,
int (__stdcall* _MessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType))
{
_MessageBox (NULL, str_a, str_b,MB_OK);
}
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

Generalthankss adminmemberseninleyim20 Jul '09 - 7:42 
We're really <b><a href="http://www.zampara.org" title="porno">porno</a></b>not talking <b><a href="http://www.xixipet.com" title="porno izle">porno izle</a></b> about <b><a href="http://www.zampara.org" title="porno izle">porno izle</a></b>art here; although <b><a href="http://www.zampara.org" title="sikiş">sikiş</a></b>everyone uses <b><a href="http://www.pornosikisleri.com" title="porno">porno</a></b> the word.
It's <b><a href="http://www.zampara.org" title="sex izle">sex izle</a></b>more of a<b><a href="http://www.sexpornosikis.com" title="porno">porno</a></b> craft<p>Craftsmen tend <b><a href="http://www.sexpornosikis.com" title="porno izle">porno izle</a></b>to lack inspiration <b><a href="http://www.sexpornosikis.com" title="sikiş">sikiş</a></b>and <b><a href="http://www.pornosikisleri.com" title="full porno">full porno</a></b>creativity,
they<b><a href="http://www.sexpornosikis.com" title="sex izle">sex izle</a></b> can only make <b><a href="http://www.xixipet.com" title="porn">porn</a></b>inferior <b><a href="http://www.sexpornosikis.com" title="sikiş izle">sikiş izle</a></b>reproductions. Artists <b><a href="http://www.kocayanak.com" title="oyun oyna">oyun oyna</a></b>lack the tools <b><a href="http://www.kocayanak.com" title="oyunlar">oyunlar</a></b>to create,
that <b><a href="http://www.mydanoz.net" title="porno">porno</a></b>is why such a <b><a href="http://www.mydanoz.net" title="porno izle">porno izle</a></b>thing as guilds existed. <b><a href="http://www.mydanoz.net" title="sikiş">sikiş</a></b>The ideal partnership <b><a href="http://www.mydanoz.net" title="sex izle">sex izle</a></b>should be learn how <b><a href="http://www.videotuba.org" title="porno izle">porno izle</a></b>to develop <b><a href="http://www.karabatak.net" title="porno izle">porno izle</a></b>lucrative<b><a href="http://www.videotuba.org" title="porno">porno</a></b> business relationships, <b><a href="http://www.karabatak.net" title="sikiş">sikiş</a></b>value and price your work so you don't lose money, and create ongoing streams of clients willing to pay you what you're worth.
one of<b><a href="http://www.suskundunya.com" title="mp3 indir">mp3 indir</a></b> equality.</div> <b><a href="http://www.pornosikisleri.com" title="porno izle">porno izle</a></b> - <b><a href="http://www.pornosikisleri.com" title="sex izle">sex izle</a></b>
Generalthank youmemberdesirejoy18 May '09 - 12:55 
This is a great article,
thanks to you i learn a lot form your article.
 
youpornporn starsporno izlehealth insurancefree porn
QuestionA problem similar with the top picturememberdabang19 Mar '09 - 5:29 
Hi:
Glad to see this article and Thank you Smile | :) .
I have a program, when I close the relevant process, the similar error dialog pop up ,The instruction at [address A]referenced memory at [address A]. The memeory could not be "read"!,and I use the Procmon.exe,find the address A is close to a dll's address ,i.e.The dll's address is ([address A] - x, [address A] + y).Can I say the dll has problem?
And please tell me How can this happen?
Waiting for.
GeneralRe: A problem similar with the top picturememberJim Charles28 Mar '09 - 22:16 
I guess address A the dll wants to read belongs to the process.
The reason maybe the closure of the process.
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralAbout FileSystemWatcher improvement.memberfiratsarlar3 Mar '09 - 11:05 
Instead of fs watcher, keeping latest image(s) hash (crc,md5, etc) and comparing it on Application Start may be usefull.
Not sure fs wathcer could be supported every hosting platform.
GeneralRe: About FileSystemWatcher improvement.memberfiratsarlar3 Mar '09 - 11:06 
sorry I send this wrong article (multi tab issue ).
Generalchanging value by referencememberchernobyl23 Feb '09 - 11:07 
Hello!
 
Thanks for an inspiring articles!
 
I have a question, I got that 'FAQ-error' message everytime I tried to create a function that tries to change variable value by reference.
 
For example,
 
void __stdcall foo(&int a){
  a = 3;
} 
void __stdcall foo_end(){}
 
void main(){
  int b;
  
...
  //after loading and decrypt the encrypted function
  foo_decrypted(b); 
 
}
 
It will give me error message.
 
Thank you!
 
Dio
AnswerRe: changing value by referencememberJim Charles23 Feb '09 - 22:57 
chernobyl wrote:
void __stdcall foo(&int a){ a = 3;} void __stdcall foo_end(){}

 
After read your question,I have made a test in antidebug_demo[^]
Try to pass a reference to custom_function,and get success.
	void __stdcall custom_function(int&		x,// :) 
					int		y,
					char*		str_a,
					char*		str_b,
					void*		(__cdecl *_memcpy	)( void *dest, const void *src, size_t count ),
					int 		(__cdecl *_sprintf	)( char *buffer, const char *format, ... ),
					void*		(__cdecl *_malloc	)( size_t size ),
					void		(__cdecl *_free		)( void *memblock ),
									size_t 		(__cdecl *_strlen	)( const char *string ),
					int		(__stdcall* _MessageBox)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
					)
	{
		char* pTemp;
		int str_a_len=_strlen(str_a);
		int str_b_len=_strlen(str_b);
		pTemp=(char*)_malloc(str_a_len+str_b_len+20);
 

		x=100;// :) 
		if(x>y)
		{
			//_sprintf(pTemp,"%s%s",str_a,str_b);	error:constant string variable
			_memcpy(pTemp,str_a,str_a_len);
			_memcpy(pTemp+str_a_len,str_b,str_b_len);
			pTemp[str_a_len+str_b_len]=0;
 
			//_MessageBox(NULL,pTemp,"",MB_OK);		error:constant string variable
			_MessageBox(NULL,pTemp,str_a,MB_OK);
		}
		else
		{
			//_sprintf(pTemp,"%s%s",str_b,str_a);	error:constant string variable
			_memcpy(pTemp,str_b,str_b_len);
			_memcpy(pTemp+str_b_len,str_a,str_a_len);
			pTemp[str_a_len+str_b_len]=0;
 
			//_MessageBox(NULL,pTemp,"",MB_OK);		error:constant string variable
			_MessageBox(NULL,pTemp,str_b,MB_OK); 
		}
 
		for(int i=0;i<10;i++)
		{
			int j=1;
			j^=i;
		}
 
		_free(pTemp);
	}
 
	void __stdcall custom_function_END()//In order to calculate the length of custom function, custom_function_END function must follow on the heels of custom_function.
	{
	}
 

 
May be you should change (&int a) to (int& a).
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: changing value by referencememberchernobyl24 Feb '09 - 2:17 
Thanks!
 
hum -- I should chek it again
 
BTW, that "integral" sign SHOULD BE posted as &
 
Smile | :)
Generalto make it 64 bit friendly...memberumeca7420 Feb '09 - 22:07 
I am using something similar to protect some parts of my program, and I enjoyed the idea of using my_function_END as you propose (don't ask me how I was doing it, very messy Smile | :) )
 
my only comment is that to make your code 64-bit friendly you have to change your UINT casts on function addresses to UINT_PTR. Also as others have mentioned you will be better off to put the final code into memory with PAGE_EXECUTE_READWRITE attributes. I have written a short article on this here:
 
www.zabkat.com/blog/26Oct08-x64-development-with-VS6-and-ATL3.htm[^]
 
other than that thanks for the tip on function_END Smile | :)
GeneralRe: to make it 64 bit friendly...memberJim Charles21 Feb '09 - 23:29 
umeca74 wrote:
my only comment is that to make your code 64-bit friendly

 
I read your article ,and Your quote ' "Noone will ever need more than 640KB RAM" — Bill Gates ' should be cool!
I do not know whether Bill Gates has said "Noone will ever need __asm in 64bit environment".
You and I feel the same thing:"The only thing I couldn't port to x64 was inline assembly __asm statements in C++ source code."
 
We are waiting for... Big Grin | :-D
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: to make it 64 bit friendly...memberumeca7422 Feb '09 - 0:04 
in the meantime i had a look at your protection system (I am searching for something suitable for my xplorer2), and for me it is no-go, due to its lack of 64 bit support. You explicitly disable /NXCOMPAT then have all these _asm stuff... If you ever find a way around this limitation drop me a line!
 
nikos
www.zabkat.com[^]
AnswerRe: to make it 64 bit friendly...memberJim Charles22 Feb '09 - 1:50 
umeca74 wrote:
in the meantime i had a look at your protection system (I am searching for something suitable for my xplorer2), and for me it is no-go, due to its lack of 64 bit support. You explicitly disable /NXCOMPAT then have all these _asm stuff... If you ever find a way around this limitation drop me a line!

 
OK,I will.
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

Generalsourcememberalooya14 Feb '09 - 3:53 
iwant source of visual c++6 the profissional
thank
AnswerRe: sourcememberJim Charles14 Feb '09 - 14:00 
alooya wrote:
iwant source of visual c++6 the profissional

 
You can download the source code at the start of the article after you sign in. Smile | :)
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

QuestionQuick question...?memberunRheal13 Feb '09 - 14:09 
Just reading the first paragraph of your article - particularly the last sentence. What does:
"A FAQ is to cause an exception with the subsequent abnormal termination of the application."
... mean...? Sorry if I seem a bit dense, sometimes I can miss really obvious stuff. Wink | ;)
Cheers
AnswerRe: Quick question...?memberJim Charles13 Feb '09 - 18:05 
unRheal wrote:
Just reading the first paragraph of your article - particularly the last sentence. What does:
"A FAQ is to cause an exception with the subsequent abnormal termination of the application."
... mean...?

 
I mean that when you try to do this job,a common problem is that your programe will often be terminated by an exception. Smile | :)
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralC# & Malicious CodememberMedicinalProgramming27 Oct '08 - 5:33 
First of all, hats off on a really interesting article that I only got to reading today...
 
I have a point to think about and a question for you.
 
1. When I saw this code the first thing that popped into mind is that somebody could easily use such a technique to write malicious code. I don't think that antiviruses today search for malicious code in memory so I don't know how they would be able to prevent it.
 
2. Do you know of similar techniques in c#?
 
http://www.pc-kitchen.com

GeneralRe: C# & Malicious CodememberJim Charles31 Oct '08 - 17:33 
MedicinalProgramming wrote:
1. When I saw this code the first thing that popped into mind is that somebody could easily use such a technique to write malicious code. I don't think that antiviruses today search for malicious code in memory so I don't know how they would be able to prevent it.
 
2. Do you know of similar techniques in c#?

 
First of all,thank you for your interesting.
 
I almost do not know how to answer your question.So,I thought about for several days.
I hope you will be satisfied with the answer.
 
1.Will you give up eating for fear of choking?
2.For now, we still focus on vc + +.Meybe in the future,we'll study c# if we can get more support.
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

GeneralRe: C# & Malicious CodememberJeffrey Walton24 Jan '09 - 15:22 
Hi Jim,
 
> Maybe in the future, we'll study c# if we can get more support.
Managed code does present some issues, but also offers support for the practice. When I was investigating this topic in C#, I found that Reflection was the answer. See DynamicMethod Class[^].
 
There is one shortcoming: suppose you want to build an EXE, then encrypt the method in place (decrypting during runtime). DynamicMethod does not lend itself to the endeavor. In this case, what we want to do is more akin to flushing JIT'd code so that a recompile can occur after decrypting. There is very little reading on flushing JIT'd code. A C++ example can be found here[^].
 
Jeff
GeneralC# ImplementationmemberFco. Javier Marin17 Oct '08 - 7:59 
Good work, would be interesting to implement it in C#
 

GeneralYou can do than just decrypt the code in runtimemembercppnow15 Oct '08 - 5:09 
In principle, myfunction_00001_code can be found in the executable (it's a global), and an attacker can utilize standard cryptoanalysis tools to attempt to decrypt it (for example, C uses a standard function entry and exit blocks).
 
Of course, if the attacker identifies the decryption code itself and disassembles it, the game is over. If references to the encrypted function are found in the executable, the attacker can pinpoint the relevant code (note that this may be done from static analysis - no need to actually run anything, so anti-debugging protection would not help much). Of course, this is easily solved: the pointer to the encrypted function itself must be calculated at runtime.
 
Note that you can do more than just decrypt a function in memory - you could actually construct it in runtime (see this[^]).
GeneralRe: You can do than just decrypt the code in runtimememberJim Charles15 Oct '08 - 16:54 
Hi,cppnow
 
First,thank you for your reading the article carefully.
It is impossible to protect your applications only by this way.It is just a beginning.All the problems you mentioned need you to resolve.And this is the reason why I say "It's easier said than done.".When you start trying to solve them, you will find that the work is very heavy.
My software protection solution almost resolves every possibility of being cracked.Of course includes all the problems you mentioned.And this is the reason why I can say boldly "Nobody can crack the software protected by it".
But still,Even Homer sometimes nods. I hope that everyone can give our team valuable comments and suggestions. Smile | :)
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Jim Charles

GeneralRe: You can do than just decrypt the code in runtimememberchernobyl20 Feb '09 - 10:41 
This is one of the inspiring articles! Super cool!
 
BTW, how the "compile at runtime" could help us to hide the code?
 
OOT, what is the perfect solution to store "private key" (for example if we use the public-private chiper scheme) -- store in the file (saved in the disk)? (I'm thinking to "hard-code" the key in the code and "prevent" the code to be disassembled).
 
Any suggestions should be cool!
 
Thanks!
 
Dio
GeneralRe: You can do than just decrypt the code in runtimememberJim Charles20 Feb '09 - 15:32 
chernobyl wrote:
Any suggestions should be cool!

 
Yes,Any suggestions should be cool!
 
BTW,Can you give us some suggestions about our Software Protection Solution?
We would be grateful.And that maybe answer your question about " how the "compile at runtime" could help us to hide the code ?".
 
Thank you very much !
 
Smooth runs the water where the brook is deep.——Shakespeare
BLOG: Self-generating-code | Software Protection Solution | Homepage| Jim Charles

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 29 Feb 2008
Article Copyright 2007 by Jim Charles
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid