|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionSelf-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
I try to resolve these questions, and get some experience as follows: The function code must be relocatable code:
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 CodeStep 1: Encrypt My_function Code into a Header FileThe 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 In order to execute this function in the stack, first I should encrypt
//
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 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 //
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 Step 2: Decrypt My_function Code and ExecuteFirst, include myfunction.h in the //
#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()
{
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 //
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
);
}
//
SummaryIf you want to conceal crucial information, you shouldn't invoke the | ||||||||||||||||||||