Click here to Skip to main content
11,415,074 members (76,826 online)
Click here to Skip to main content

Programming Self-generating Code for Windows Applications

, 29 Feb 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
Executing VC++ codes in STACK or HEAP

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 <span class="code-string">"..\\\self_engendered_code\\My_function\\myfunction.h"</span>
#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)

Share

About the Author

Jim Charles
Engineer AntiDebugLIB Inc
United States United States
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/

Comments and Discussions

 
AnswerRe: code in _my_function never executes for me Pin
Jim Charles17-Nov-09 3:26
memberJim Charles17-Nov-09 3:26 
Generalthankss admin Pin
seninleyim20-Jul-09 8:42
memberseninleyim20-Jul-09 8:42 
QuestionA problem similar with the top picture Pin
dabang19-Mar-09 6:29
memberdabang19-Mar-09 6:29 
GeneralRe: A problem similar with the top picture Pin
Jim Charles28-Mar-09 23:16
memberJim Charles28-Mar-09 23:16 
GeneralAbout FileSystemWatcher improvement. Pin
firatsarlar3-Mar-09 12:05
memberfiratsarlar3-Mar-09 12:05 
GeneralRe: About FileSystemWatcher improvement. Pin
firatsarlar3-Mar-09 12:06
memberfiratsarlar3-Mar-09 12:06 
Generalchanging value by reference Pin
chernobyl23-Feb-09 12:07
memberchernobyl23-Feb-09 12:07 
AnswerRe: changing value by reference Pin
Jim Charles23-Feb-09 23:57
memberJim Charles23-Feb-09 23:57 
GeneralRe: changing value by reference Pin
chernobyl24-Feb-09 3:17
memberchernobyl24-Feb-09 3:17 
Generalto make it 64 bit friendly... Pin
umeca7420-Feb-09 23:07
memberumeca7420-Feb-09 23:07 
GeneralRe: to make it 64 bit friendly... Pin
Jim Charles22-Feb-09 0:29
memberJim Charles22-Feb-09 0:29 
GeneralRe: to make it 64 bit friendly... Pin
umeca7422-Feb-09 1:04
memberumeca7422-Feb-09 1:04 
AnswerRe: to make it 64 bit friendly... Pin
Jim Charles22-Feb-09 2:50
memberJim Charles22-Feb-09 2:50 
Generalsource Pin
alooya14-Feb-09 4:53
memberalooya14-Feb-09 4:53 
AnswerRe: source Pin
Jim Charles14-Feb-09 15:00
memberJim Charles14-Feb-09 15:00 
QuestionQuick question...? Pin
unRheal13-Feb-09 15:09
memberunRheal13-Feb-09 15:09 
AnswerRe: Quick question...? Pin
Jim Charles13-Feb-09 19:05
memberJim Charles13-Feb-09 19:05 
GeneralC# & Malicious Code Pin
MedicinalProgramming27-Oct-08 6:33
memberMedicinalProgramming27-Oct-08 6:33 
GeneralRe: C# & Malicious Code Pin
Jim Charles31-Oct-08 18:33
memberJim Charles31-Oct-08 18:33 
GeneralRe: C# & Malicious Code Pin
Jeffrey Walton24-Jan-09 16:22
memberJeffrey Walton24-Jan-09 16:22 
GeneralC# Implementation Pin
Fco. Javier Marin17-Oct-08 8:59
memberFco. Javier Marin17-Oct-08 8:59 
GeneralYou can do than just decrypt the code in runtime Pin
cppnow15-Oct-08 6:09
membercppnow15-Oct-08 6:09 
GeneralRe: You can do than just decrypt the code in runtime Pin
Jim Charles15-Oct-08 17:54
memberJim Charles15-Oct-08 17:54 
GeneralRe: You can do than just decrypt the code in runtime Pin
chernobyl20-Feb-09 11:41
memberchernobyl20-Feb-09 11:41 
GeneralRe: You can do than just decrypt the code in runtime Pin
Jim Charles20-Feb-09 16:32
memberJim Charles20-Feb-09 16:32 
GeneralWhat's the point? Pin
levicki2-Mar-09 15:35
memberlevicki2-Mar-09 15:35 
GeneralRe: What's the point? Pin
Jim Charles2-Mar-09 19:52
memberJim Charles2-Mar-09 19:52 
GeneralRe: What's the point? Pin
John Crenshaw17-Jun-09 14:24
memberJohn Crenshaw17-Jun-09 14:24 
GeneralRe: What's the point? Pin
Jim Charles17-Jun-09 19:46
memberJim Charles17-Jun-09 19:46 
QuestionWindows Vista ? Pin
Jim Charles19-Sep-08 6:18
memberJim Charles19-Sep-08 6:18 
Generalgreat article creation Pin
Josemaproject24-Aug-08 21:11
memberJosemaproject24-Aug-08 21:11 
General[Message Removed] Pin
MurderDolls16-Jun-08 12:20
memberMurderDolls16-Jun-08 12:20 
QuestionExecuting Function Code in Heap/Stack Memory Pin
maxtheterrible8-Jun-08 19:42
membermaxtheterrible8-Jun-08 19:42 
AnswerRe: Executing Function Code in Heap/Stack Memory Pin
Jim Charles9-Jun-08 7:22
memberJim Charles9-Jun-08 7:22 
QuestionRe: Executing Function Code in Heap/Stack Memory Pin
Max Kukartsev9-Jun-08 12:58
memberMax Kukartsev9-Jun-08 12:58 
AnswerRe: Executing Function Code in Heap/Stack Memory [modified] Pin
Jim Charles9-Jun-08 15:30
memberJim Charles9-Jun-08 15:30 
GeneralRe: Executing Function Code in Heap/Stack Memory Pin
Max Kukartsev10-Jun-08 6:32
memberMax Kukartsev10-Jun-08 6:32 
General[Message Removed] Pin
MurderDolls30-May-08 1:52
memberMurderDolls30-May-08 1:52 
General[Message Removed] Pin
MurderDolls4-Jun-08 14:02
memberMurderDolls4-Jun-08 14:02 
GeneralWindows Vista Error Pin
Roberto Loreto21-Apr-08 12:25
memberRoberto Loreto21-Apr-08 12:25 
GeneralRe: Windows Vista Error Pin
Jim Charles21-Apr-08 20:31
memberJim Charles21-Apr-08 20:31 
GeneralRe: Windows Vista Error Pin
Leonhardt Wille23-Apr-08 7:25
memberLeonhardt Wille23-Apr-08 7:25 
GeneralRe: Windows Vista Error Pin
Mystery12310-Jul-08 22:57
memberMystery12310-Jul-08 22:57 
GeneralRe: Windows Vista Error Pin
Jim Charles11-Jul-08 3:23
memberJim Charles11-Jul-08 3:23 
QuestionCool!! But not work in VISTA...¿?¿? Pin
Roberto Loreto21-Apr-08 12:16
memberRoberto Loreto21-Apr-08 12:16 
AnswerRe: Cool!! But not work in VISTA...¿?¿? Pin
Jim Charles21-Apr-08 20:37
memberJim Charles21-Apr-08 20:37 
GeneralRe: Cool!! But not work in VISTA...¿?¿? Pin
Roberto Loreto22-Apr-08 13:20
memberRoberto Loreto22-Apr-08 13:20 
AnswerRe: Cool!! But not work in VISTA...¿?¿? Pin
Jim Charles19-Sep-08 6:08
memberJim Charles19-Sep-08 6:08 
GeneralDecode and then call a routine! Pin
tydok25-Feb-08 4:48
membertydok25-Feb-08 4:48 
GeneralRe: Decode and then call a routine! Pin
Jim Charles25-Feb-08 5:04
memberJim Charles25-Feb-08 5:04 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

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