الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ Obfuscated Code الكود الأكثر صعوبه ]

بدأه Wajdy Essam في 3 مارس 2008 · 9 رد · 2,086 مشاهدة · في قسم المواضيع الهامة في قسم السي /سي++
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمه الله وبركاته ،،

مقالنا اليوم يتكلم حول طرق سيئه "للغايه" لكتابه الكود بحيث لن يفهم هذا الكود الا القليل ، وهناك بعض الأسباب لعمل مثل هذه البرامج منها مثلا التسليه Fun ، التحدي ، حمايه كود البرنامج ، الفوز بمسابقه ما (هناك مسابقه عالميه تقام كل سنه حول هذا النوع من البرامج International Obfuscated C Code Contest ) .

أغلب هذه البرامج تكون مكتوبه بسي ، أو بيرل ، ونادرا ما نجد سي++ ، وذلك لأن سي تحتوي بعضا من الأمور قد تم تلافيها في سي++ ، منها مثلا استدعاء الداله main من داخل البرنامج .

أحب أن أذكر أن الطرق الموجوده هنا ، لا ينصح باستخدامها أبدا ، فهي طرق سيئه جدا ، وكما ذكرت فقط الغرض منها هو التشويش ...

ولنأخذ مثال "فاتح للشهيه" قبل أن نبدأ بالطرق ، قم بقرائه المثال ، وفي حال فهمت المثال كاملا وعرفت المخرجات ، فسوف أجزم أنك أحد هؤلاء المجانين :lol: .

#include <stdio.h>
main(t,_,a)char *a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,
main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?
main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-72?main(_,t,
"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+,/+#n+,/#\
;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \
q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# \
){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \
iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \
}'+}##(!!/")
:t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)
  :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,
"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

حاول أن تتخيل ما هي المخرجات قبل أن تقوم بتشغيله ، تخيل فقط :) !!

كيف تكتب برنامج مشوش ؟

هنا علينا أن نرجع الى بدايه تعلمنا للغه ونتذكر ما هي أصعب الأشياء التي واجهتنا في التعلم ، أذكر أنني جلست كم يوم حتى فهمت ما هو المؤشر Pointer ، مممم أيضا الأستدعاء الذاتي مربك أيضا ، أيضا المصفوفات وخاصه عندما نستخدم Pointer Arthmatic ، معامل الفاصله Comma مربك ايضا لان تنفيذه غريب بعض الشيء ، جميع المواضيع السابقه التي كنت تعتبرهاصعبه ، هنا ستكون هي سلاحك الأول :) .

أيضا المتغيرات ذات الشكل المتشابه مثلا الحرف O و الحرف o ( الأول كبير والثاني صغير ) و الرقم 0 ، أيضا الحرف i والحرف l والحرف L الرقم 1 ، هذه المتغيرات تسبب لي التشاؤم من البرنامج ، خاصه عندما كنت أقرأ برنامج أحد الطلاب ، وهذه أحد سطور أحد الطلاب :

char clear,ch,c,bag[100],bag1[10][10],bag2[100];
int n=0,m,x,w=0,aa=0,z,l=0,nn[50],mm[50],qw,az,i,j;

// other code

for(int fg=1;fg<=az;fg+=2)
{
if (nn[fg-1]==nn[fg]){
bag2[fg-1]=bag1[nn[fg-1]][(mm[fg-1]+1)%5];
bag2[fg]=bag1[nn[fg-1]][(mm[fg]+1)%5];
}
else
if(mm[fg-1]==mm[fg]){
bag2[fg-1]=bag1[(nn[fg-1]+1)%5][mm[fg-1]];
bag2[fg]=bag1[(nn[fg]+1)%5][mm[fg]];
}
else
{bag2[fg-1]=bag1[nn[fg-1]][mm[fg]];
bag2[fg]=bag1[nn[fg]][mm[fg-1]];
}}

يبدوا لي أن هذا الطالب يكتب برنامج Obfuscated بالفطره ، وأعتقد أنه سيفوز بمثل هذه المسابقات بكل سهوله . :lol:

نبدأ الأن بقطع من الكود ، ونحاول أن نغيرها من كود عادي الى مشوش ، وبعدها نأخذ مثال Hello World ومن ثم نحوله الى Hello Devil :) .

التلاعب بأسماء المتغيرات :

================

نأخذ مثال لبرنامج يطبع الحروف من A الى Z ، ونقوم ببعض التغيرات عليه في اسامي المتغيرات :

#include <stdio.h>

int main ()
{
	for (int i='A'; i<='Z'; i++)
		printf("%c",i);

	return 0;
}

الان قمنا بوضع جمله الطباعه في داله ، ومررنا لها الحرف الأول والأخير ، ومن ثم طبعنا الحروف :

#include <stdio.h>

void _(int O , int _O)
{
	for (; O<=_O; O++)
		printf("%c",O);
}

int main ()
{
	// you can change A with 65  in decimal  OR with 0x41 in hex
	// olse you can change Z to 90 in decimal or 0x5A in hex
	_(0x41,90);	

	return 0;
}

لاحظ استخدام الحروف المشابه O و _O ، أيضا ارسال الحرف A بقيمته في النظام Hex ، ويمكن أستخدام أي نظام أخر .

(طبعا عليك بازاله التعليق من البرنامج ، وهو أصلا موضوع لك أنت ، حيث البرنامج المفترض يشوش القارئ وليس يشرح للقارئ).

التلاعب بالمؤشرات والمصفوفات :

====================

مراجعه سريعه للأمر ، تجدها في هذه السطور :

printf("\n\n%d\n",arr[1]);	// print 20
	printf("%d\n",*(arr+1));   // print 20
	printf("%d\n",*(1+arr));   // print 20

	printf("Address = %x\n",&arr[1]);	// print Address for element 1
	printf("Address = %x\n",arr+1);		// print Address for element 1

الأن كيف يمكن أن نتلاعب هنا ، كلنا نعرف أذا أردنا أن نرسل مصفوفه لداله نقوم بارسال عنوانها ، حسنا ، ممكن أن نضع هذا العنوان في متغير int أولا ، ونقوم بارسال هذا العدد (العنوان) ، الان من داخل المصفوفه نقوم بتحويل هذا العدد int الى مؤشر عن طرق الCast .

أنظر الى المثال القادم ، وهو لطباعه الأعداد من 1 الى 10 ، والذي يليه هو بعد التلاعب فيه قليلا :

#include <stdio.h>

void functionOne ( int* array , int size )
{
	for (int i=0; i<size;  i++)
		printf("%d ",array); 	// or *array++	 or   *(array+i) 
}

int main()
{
	int array[] = {1,2,3,4,5,6,7,8,9,10};
	functionOne(array,10);

	return 0;
}

الان النسخه المعدله ، ولاحظ أننا في الداله main قمنا بأخذ عنوان المصفوفه ، وارساله الى الداله functionOne ، وهناك قمنا بعمل cast لهذا الرقم وحولناه الى مؤشر ، بعدها باستخدام pointer arthmatic قمنا بالوصول الى عناصر المصفوفه .

#include <stdio.h>

void functionOne ( int address , int size )
{
	int i=0; 
	for (; i<size;  i++)
		printf("%d ", *((int*)address+i)); 	
}

int main()
{
	int array[] = {1,2,3,4,5,6,7,8,9,10};
	int address = (int)array;	//  (int) &array[0]
	functionOne(address,10);

	return 0;
}

المعامل الشرطي الثلاثي Conditional Operator ومعامل الفاصله Comma Operator :

===================================================

معامل الفاصله يعمل من اليسار الى اليمين ، ومن ثم يسند قيمه المتغير الموجود في الجهه اليمني الى المتغير اذا كان هناك . نأخذ مثال :

int a=0;
int b=3;
a = (b+=3, b-1);

الان عند تنفيذ السطر الثالث ، نقوم بزياده b بمقدار 3 وتصبح 6 ، بعدها نطرح من b واحد وتصبح 5 ، وأخيرا نسند b الى a (اي تصبح قيمه a هي 5 ).

المعامل الشرطي هو بديل لجمله If :

if (<test_condition>) {
	<variable_name> = <value_if_true>;
}
else {
	<variable_name> = <value_if_false>;
}

وباستخدام Conditional Operator :

<variable_name> = (<test_condition>) ? (<value_if_true>) : (<value_if_false>);

في حال كان test_condition صحيح سوف ينفذ value_if_true والا value_if_false .

هذا المعامل له دور كبير جدا في هذه النوعيه من البرامج ، حيث يتم استبدال أي جمله شرطيه بهذا المعامل .

وفي حاله كانت هناك nested if ، يمكن استخدام المعامل الشرطي مع معامل الفاصله لكي يؤدي الغرض :

<variable_name> = (<test_condition>) ? (<expression_a1>, ..., <value_if_true>) : (<expression_b1>, ..., <value_if_false>);

مثال :

	int a=1;
	int b=2;
	int c=3;

	if (a<0) {
		b+=3;
		a=b-1;
	}
	else {
		c+=b;
		a=c+2;
	}

الان نحوله الى conditional operator و comma operator :

	int a=1;
	int b, c;
	a=(b=2, c=3, a<0) ? (b+=3, b-1) : (c+=b, c+2);

وهنا أولا سوف يسند 2 الى b ، بعدها 3 الى c ، بعدها يقارن هل a أصغر من 0 ، في حال كان ذلك ، يزيد على b ثلاثه ، ومن ثم يطرح واحد ، ويرجع القيمه ويسندها الى a . اما اذا كان a أكبر من 0 ، سوف يزيد على c مقدار b وهي 2 ، بعدها يزيد على c 2 ويسند الناتج الى a .

الأستدعاء الذاتي Recursion :

==================

الجميع يعلم هذا الموضوع ، وهي داله تنادي نفسها في حال تحقق شرط ما ، وهنا أغلب الأحيان نرسل قيمه وهي التي تدل على نهائيه الأستدعاء ، أو نقوم بعمل متغير static لكن لا يجب أ ن تستخدم هذه الطريقه في حاله استدعيت الداله أكثر من مره .

نأخذ مثال لطباعه الأعداد من 1 - 10 ، وبعدها نحوله الى النداء الذاتي :

#include "stdio.h"

int main() {
	int array[]={0,1,2,3,4,5,6,7,8,9};

	int i;
	for (i=0; i<10; ++i) {
		printf("%d ",array);
	}

	return 0;
}

وها هو البرنامج بعد التعديل :

#include "stdio.h"

void recursiveFunction(int array, int i, int stop) {
	printf("%d ",*((int*)array+i));
	i++;
	if (i < stop) {
		recursiveFunction(array, i, stop);
	}
}

int main() {
	int array[]={0,1,2,3,4,5,6,7,8,9};
	recursiveFunction((int)array, 0, 10);
	return 0;
}

الأن نأخذ مثال شامل لـ Hello World ، المثال هو :

#include "stdio.h"

int main() {
	printf("Hello World!");
	return 0;
}

وبعدها سندخل هذا المثال غرفه العمليات ، للقيام بعمليه تجميل ، ليخرج بالشكل :

#include "stdio.h"
_(__,_0,O_,___){(O_<_0)?printf("%c",(O_==2)
||(O_==3)||(O_==9)?___++,O_++,108:*((int*)__
+O_++-___)),_(__,_0, O_, ___):0;}main(){int array
[]={72,'e',111,040,0127,0x6F,'r',0x64,041 };_(array
,
12
,
0
,
0
)
;
}

جميل أليس كذلك ! :rolleyes:

نبدا الأن .

الخطوه الأولى :

نعمل داله للطباعه ، نرسل اليها المصفوفه ، القيم التي في المصفوفه كتبناها بالنظام العشري .

void myFunction(int array[], int arraySize) {
	int i;
	for (i=0; i<arraySize; ++i) {
		printf("%c", array);
	}
}

int main() {
	int array[]={72,101,108,108,111,32,87,111,114,108,100,33};
	myFunction(array,12);
	return 0;
}

الخطوه الثانيه :

استخدمنا فكره ارسال متغير يحمل العنوان (التي شرحناها في الأعلى) وبعدها نقوم بعمل cast للمتغير ونحوله الى مؤشر :

#include "stdio.h"

void myFunction(int integer, int arraySize) {
	int i;
	for (i=0; i<arraySize; ++i) {
		printf("%c", *((int*)integer+i));
	}
}

int main() {

	int array[]={72,101,108,108,111,32,87,111,114,108,100,33}, integer=(int)array;
	myFunction(integer,12);
	return 0;
}

الخطوه الثالثه :

غيرنا الداله وقمنا بعمل استدعاء ذاتي ، وغيرنا if الى Conditional Operator :

void myFunction(int integer, int arraySize, int i) {
	(i<arraySize) ? printf("%c", *((int*)integer + i++ )), myFunction(integer, arraySize, i) : 0;
}

int main() {

	int array[]={72,101,108,108,111,32,87,111,114,108,100,33};
	myFunction((int)array,12, 0);
	return 0;
}

الخطوه الرابعه :

نتخلص من بعض الحروف المكرره في المصفوفه (وهو الحرف L) يتكرر ثلاث مرات 108 ، في الموقع 2 و 3 و 9 :

#include "stdio.h"

void myFunction(int integer, int arraySize, int i, int k) {
	(i<arraySize) ? 
			(i==2)||(i==3)||(i==9) ?
					k++, i++, printf("%c",108) :
	printf("%c", *((int*)integer + i++ - k)), myFunction(integer,arraySize, i, k) :
			0;
}

int main() {

	int array[]= { 72, 101, 111, 32, 87, 111, 114, 100, 33 };
	myFunction((int)array, 12, 0, 0);
	return 0;
}

الخطوه الخامسه :

نغير من ترتيب معامل الشرط في الداله :

void myFunction(int integer, int arraySize, int i, int k) {
	(i<arraySize) ? 
			printf("%c",(i==2)||(i==3)||(i==9) ?
					k++, i++, 108 :
			*((int*)integer + i++ - k)), myFunction(integer,arraySize, i, k) : 0;
}

int main() {

	int array[]= { 72, 101, 111, 32, 87, 111, 114, 100, 33 };
	myFunction((int)array, 12, 0, 0);
	return 0;
}

الخطوه السادسه :

نغير من أسماء المتغيرات في الداله ، ودائما تغير اسماء المتغيرات يأتي في أخر مرحله حتى لا تضيع أنت وتشوش على نفسك اثناء كتابة البرنامج ، أيضا تغيير القيم في المصفوفه وجعلها بعده أنظمه Hex و octal وdecimal :

#include "stdio.h"

void myFunction(int __, int _0, int O_, int ___) {
	(O_<_0) ? 
			printf("%c",(O_==2)||(O_==3)||(O_==9) ?
					___++, O_++, 108 :
			*((int*)__ + O_++ - ___)), myFunction(__,_0, O_, ___) : 0;
}

int main() {

	int array[]= { 72, 'e', 111, 040, 0127, 0x6F, 'r', 0x64, 041 };
	myFunction((int)array, 12, 0, 0);
	return 0;
}

الخطوه السابعه :

تغير اسم الداله ، حذف القيمه الراجعه ، وسوف يعتبرها المترجم هي int ، أيضا حذف نوع المتغير المرسل في الداله وأيضا سيتعبرها int :

_(__, _0, O_, ___) {
	(O_<_0) ? 
			printf("%c",(O_==2)||(O_==3)||(O_==9) ?
					___++, O_++, 108 :
			*((int*)__ + O_++ - ___)), _(__,_0, O_, ___) : 0;
}

main() {
	int array[]= { 72, 'e', 111, 040, 0127, 0x6F, 'r', 0x64, 041 };
	_(array, 12, 0, 0);
}

الخطوه الأخير :

نقوم بحذف المسافات بين الجمل ، وضغطها :

#include "stdio.h"
_(__,_0,O_,___){(O_<_0)?printf("%c",(O_==2)
||(O_==3)||(O_==9)?___++,O_++,108:*((int*)__
+O_++-___)),_(__,_0, O_, ___):0;}main(){int array
[]={72,'e',111,040,0127,0x6F,'r',0x64,041 };_(array
,
12
,
0
,
0
)
;
}

واوووو ...... من كان يصدق أن هذا البرنامج Hello World !

نقطه أخيره ،

البرنامج السابق هو أسهل برنامج مشوش ، نعم !! هناك بعض البرامج معقده جدا وخاصه عندما يتم استخدام جمل الهاش # أو Preprocessor Direcitve ، وفي المرفقات عده برامج من هذا النوع ....

هناك بعض البرامج ، يمكن أن تقوم بكشفها بسرعه مثل :

_(__,___,____){___/__<=1?_(__,___+1,____):!(___%__)?_(__,___+1,0):___%__==___/
__&&!____?(printf("%d\t",___/__),_(__,___+1,0)):___%__>1&&___%__<___/__?_(__,1+
___,____+!(___/__%(___%__))):___<__*__?_(__,___+1,____):0;}main(){_(100,0,0);}

وهو يطبع الأعداد الأوليه من 1 الى 100 ، وهنا أولا أستعن بخاصيه Find & Replace الموجوده في المترجم أو أي محرر نصوص ، وغير كل : _ بمثلا Function ، وبعدها سوف تصبح النتيجه :

Function(__,___,____){___/__<=1?Function(__,___+1,____):!(___%__)?Function(__,___+1,0):___%__==___/
__&&!____?(printf("%d\t",___/__),Function(__,___+1,0)):___%__>1&&___%__<___/__?Function(__,1+
___,____+!(___/__%(___%__))):___<__*__?Function(__,___+1,____):0;}main(){Function(100,0,0);}

الان غير كل : __ بمثلا varOne وقم بعمل replace All :

Function(

varOne,___,____){___/varOne<=1?Function(varOne,___+1,____):!(___%varOne)?Function(varOne,___+1,0):___%varOne==___/
varOne&&!____?(printf("%d\t",___/varOne),Function(varOne,___+1,0)):___%varOne>1&&___%varOne<___/varOne?Function(varOne,1+
___,____+!(___/varOne%(___%varOne))):___<varOne*varOne?Function(varOne,___+1,____):0;}main(){Function(100,0,0);}

واستمر هكذا الى أن تنتهي من جميع أسماء المتغيرات العجيبه ، وبعدها قم بتنظيم البرنامج ، وهنا ستجد نفسك أمام الكود مباشره !

أخيرا ، لما لا يطرح كل منا كوده الـ Obfuscated ونشاهد من هو صاحب الكود الأكثر تشويشا ؟

أو نضعها في موضوع منفصل ونسميه : ArabTeam Obfuscated C Code Contest :) :) .

تحياتي .

2

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#2

أرجوا المعذره ، لقد نسيت الملف المرفق ، سأرفقه المره القادمه باذن الله ..

أيضا مصدر المقال :

Obfuscated Code - A Simple Introduction

Obfuscated code

:)

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#3

يا ريت على اللى بيعملوه ده يكونوا مجانين بس

دول مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن و مجانيـــــن

:D :D :nose_pick: :nose_pick: :nose_pick: :nose_pick: :nose_pick:

ربنا يشفيهم

ادعولهم يا جماعة و انتم بتصلوا

تم تعديل هذه المشاركة بواسطة Omar Eladel في 3 مارس 2008 في 19:33

#4

فعلا اسلوب جميل وبعدين ما تحتاج للتشفير!

tvquran_6.gif

#6

جميلة جدا هذه المقاله ..

حقيقة نحن من غير تشفير شفرات .. في بعض الاحيان نتلخبط بين اسطر الكود ..

فماذا يحدث لو كان معها مثل هذه الامور .؟؟

اكيد :thumbup:

شكرا مره اخرى اخي الرومانسي ..

تحياتي العطرة ..

يَارَبُ إِن ضَاقَت قُلُوُب الْنَّاسٍ عَنْ مّافِي .. مِنْ خَيْرٍٍ فَعَفْوكَ لَا يَضِيْقْ ..

#7

جدا رائع ^_^

يعني ادخل الامتحان واذا ماعرفت للبرنامج اعرف متغيرات بهالشكل

int _X_X_X_X_X_XX_X____LALALALALAALALALALALALA__________X_X_X_X_X_X_X___DODODODODODO
DODODO_______X_X_X_X_X_XX=10;

بس كيف راح استدعي المتغير ؟ انسخه واللصقه مثلا ؟ :unsure:

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#8

الصراحة المقال اصابني بالتخمة لدرجة اني لم اتناول فطور الصباح :lol:

مقال مثير و لديد جاري التطبيق

مشكور اخي وجدي

ربما استعمل هده الطرق لكتابة برامج مفتوحة المصدر :evil:

العمل كثير و الوقت قليل أعاننا الله

seo zen SEO Enlightment amazon danbo

#9

شكرا لك اخي وجدي

مقالة رائعة

تحياتي

while( "اسلام" )
{
 cout >> "الموت لبني صهيون" >> endl;
}
return "فلسطين";
#10

الله يشفيهم

الصراحة انا كل يوم بدعيلهم بسجود السهو :thumbup: :haha: :haha:

دولة الخلافة الاسلامية في المخاض الاخير وميلادها قريب

حزب التحرير : التزم الطريق الصحيح الشرعي الوحيد لاعادة دولة الخلافة الاسلامية .

الامة الاسلامية متعطشة لقيادة مخلصة لتذوق حلاوة النصر ولن يكون ذلك الا بعودة الخلافة الاسلامية

الامة الاسلامية تحتاج لاحداث تسحقها سحقا وتمعسها معسا لتفكر تفكيرا جماعيا بالتغير لان وحدة المشاعر لوحدها لاتكفي وهذة الاحداث كلها خير

مواضيع مشابهة