جستار : کدهای خودنما
درود بر دوستان گرامی
در پس مباحث گذشته در مورد مبهم سازی کدهای نوشته شده ، اکنون مقدمه به شما برای نوشتن کدهای که پس از اجرا به طور کامل برنامه نوشته شده را به عنوان خروجی بیرون میدهند ، ارائه میکنم.بنده نام خود نما را برای این کدها برگزیدم.زیرا پس از اجرا عینا کدهای برنامه را چاپ میکنند.به طور مثال به کدهای زیر دقت کنید :
main(){char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}”;printf(c,34,c,34);}
این کدها اولین کدهای خود نمای نوشته شده به زبان C هستند.پس از کامپایل و اجرای کدهای بالا نتیجه ای مشابه به کدهای زیر دریافت میکنید:
main(){char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}”;printf(c,34,c,34);}
بله ! نتیجه دقیقا مشابه کدهای نوشته شده است.برای دست یابی به این موضوع که کدهای بالا چگونه عمل میکنند ، کدها را تحلیل میکنیم.ابتدا بهتر است با بازگرداندن فاصله ها و خطوط جدید کد را کمی خواناتر کنیم.
main(){
char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}”;
printf(c,34,c,34);
}
در ابتدا تابع main() را میبینیم .سپس یک آرایه اشاره گر به نام c تعریف شده است.و پس از آن تابع printf با تعدادی آرگومان نوشته شده است.اصل برنامه در تابع printf خلاصه شده است.اولین آرگومان این تابع آرایه c است.تابع printf شروع به چاپ این آرایه میکند.نکته همینجاست ، این آرایه به صورت یک رشته به سمت تابع فرستاده نشده است. به طور مثال اگر کدها را به صورت زیر تغییر دهید :
main(){
char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}”;
printf(”%s”,c,34,c,34);
}
تنها مقدار :
main(){char *c=%c%s%c;printf(c,34,c,34);}
را چاپ شده میبینید. پس از اینکه آرایه c به تابع پاس شد ، تابع مقدار زیر را چاپ میکند :
main(){char *c=
سپس به کاراکتر های %c%s%c میرسد.این کاراکتر ها معنای خاصی برای تابع printf دارند.همانطور که مشاهده میکنید ، تابع در برنامه اصلی به صورت printf(c,34,c,34) به کار گرفته شده است.بنابر این مقدار %c ، عدد ۳۴ را دریافت کرده و معادل اسکی آن یعنی ” را چاپ میکند.بنابر این اکنون داریم.
main(){char *c=”
سپس مقدار %s آرایه c را دریافت کرده و داریم.
main(){char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}
پس از آن به وسیله مقدار %c و عدد ۳۴ ، معادل اسکی ۳۴ یعنی ” چاپ میشود.
main(){char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}”
پس از آن نیز باقی مقدار آرایه c یعنی :
;printf(c,34,c,34);}
چاپ شده و به صورت کامل داریم :
main(){char *c=”main(){char *c=%c%s%c;printf(c,34,c,34);}”;printf(c,34,c,34);}
کدهای بالا بسیار ساده هستند.اما الگو و روش اصلی تولید کدهایی خود نما همین است.با استفاده از این روش میتوان کدهای پیچیده تری چون :
char *f=”char *f=%c%s%c;%c#define Q ‘%c’%c#define N ‘%cn’%c#define B ‘%c%c’%c#include <stdio.h>%cvoid main(){printf(f,Q,f,Q,N,Q,N,B,N,B,B,N,N,N);}%c”;
#define Q ‘”‘
#define N ‘\n’
#define B ‘\\’
#include <stdio.h>
void main(){printf(f,Q,f,Q,N,Q,N,B,N,B,B,N,N,N);}
و حتی پیچیده تر چون :
char*a??(??)=??<
“??=include<stdio.h>”,
“??=include<stdlib.h>”,
“??=define o stdout”,
“??=define b break;case”,
“??=define s(p)fputs(p,o);”,
“??=define c(p)fputc(p,o);”,
“void t(p,f)char*p;??<f&&c(’??/”‘)”,
“for(;;p++)??<switch(*p)??<case 0:f&&”,
“s(??/”??/??/??/”,??/”)c(’??/??/n’)return;case”,
“‘??=’:s(??/”???/??/?=??/”)b’??<’:s(??/”???/??/?<??/”)”,
“b’??>’:s(??/”???/??/?>??/”)b’??(’:s(??/”???/??/?(??/”)b’??)’”,
“:s(??/”???/??/?)??/”)b’??/??/??/??/’:f&&s(??/”???/??/?/??/”)”,
“s(??/”???/??/?/??/”)b’??/??/n’:if(f)s(??/”???/??/?/n??/”)”,
“else case’??/”‘:if(f)s(??/”???/??/?/??/??/??/”??/”)”,
“else default:c(*p)??>??>??>main()??<char**p”,
“;t(??/”char*a??(??)=??<??/”,۰);for(p=a;*p”,
“;p++)t(*p,1);t(??/”۰??>;??/”,۰);for(p=a”,
“;*p;p++)t(*p,0);exit(!ferror(o)&&”,
“!fclose(o)?EXIT_SUCCESS”,
“:EXIT_FAILURE);”,
“/*NOTREACHED*/”,
“??>”,
۰??>;
??=include<stdio.h>
??=include<stdlib.h>
??=define o stdout
??=define b break;case
??=define s(p)fputs(p,o);
??=define c(p)fputc(p,o);
void t(p,f)char*p;??<f&&c(’”‘)
for(;;p++)??<switch(*p)??<case 0:f&&
s(”??/”,”)c(’??/n’)return;case
‘??=’:s(”???/?=”)b’??<’:s(”???/?<”)
b’??>’:s(”???/?>”)b’??(’:s(”???/?(”)b’??)’
:s(”???/?)”)b’??/??/’:f&&s(”???/?/”)
s(”???/?/”)b’??/n’:if(f)s(”???/?/n”)
else case’”‘:if(f)s(”???/?/??/””)
else default:c(*p)??>??>??>main()??<char**p
;t(”char*a??(??)=??<”,۰);for(p=a;*p
;p++)t(*p,1);t(”۰??>;”,۰);for(p=a
;*p;p++)t(*p,0);exit(!ferror(o)&&
!fclose(o)?EXIT_SUCCESS
:EXIT_FAILURE);
/*NOTREACHED*/
??>
نوشت.این وب نوشته مقدمه ای بود برای یکی از روش های جالب و لذت بخش که در که در مبهم سازی کدها میتواند مورد استفاده قرار گیرد.
نگارنده ( مولف ) : شهریار جلایری


۳ پاسخ برای “جستار : کدهای خودنما”
توسط siroos در ۴ بهمن ۱۳۸۶ | پاسخ
با سلام”
مورده استفاده قرار گرفت اگه بیشتر در مورد باگهای bof و پشته بگی بیشتر خوشحال می شم (نگی چقدر پرو هستم ها)
خوب برام خیلی گنگ هستش که بخوام تو مدت خیلی کم هم برنامه نویسی C کار کنم هم …..
در کل دستت درد نکنه . unkn0wn یه چیز دیگس .
توسط c0ld.fir3 در ۵ بهمن ۱۳۸۶ | پاسخ
اقا بازم مثل همیشه مقاله ای نوشتی که باید گفت دستت درد نکونه و خسته نباشی
توسط asadhacker در ۱۶ خرداد ۱۳۸۷ | پاسخ
خیلی جالب بود خوشمان آمد