در توسینسو تدریس کنید

و

با دانش خود درآمد کسب کنید

چگونه برنامه های دات نت کرک (Crack) می شوند؟ راه جلوگیری چیست؟

تمام کامپایلرهای مبتنی بر پلاتفرم دات نت، کد نوشته شده را پس از کامپایل به کدی با نام IL یا Intermediate Language که یک زبان میانی مانند زبان اسمبلی است تبدیل می کنند. این کد توسط کامپایلری به نام JIT یا Just In Time Compiler به کد ماشین تبدیل شده و سپس اجرا می شود.

دلیل استفاده از کد IL امکان اجرای برنامه های نوشته شده مبتنی بر پلاتفرم .NET در سایر پلاتفرم ها مانند MAC و Linux قابل اجرا باشند. همین موضوع دست افراد رو برای کرک کردن برنامه های دات نت باز گذاشته. در این مطلب قصد دارم به شما دو ابزاری که در این کار استفاده می شوند و البته توسط خود مایکروسافت نیز عرضه شدند آموزش بدم.

از این دو ابزار برای استخراج کد IL از فایل های کامپایل شده و همچنین تبدیل مجدد کدهای IL به فایل های exe یا dll استفاده می شوند. برای ادامه کار برنامه ای در محیط کنسول می نویسیم که یک نام کاربری و کلمه عبور از کاربر دریافت کرده و در صورت صحیح بودن کلمه عبور پیغام مناسبی به کاربر نمایش می دهد. سپس با ابزارهای ذکر شده برنامه را کرک خواهیم کرد:

class Program
{
    public static void Main()
    {
        Console.Write("Username: ");
        var username = Console.ReadLine();
        Console.Write("Password: ");
        var password = Console.ReadLine();

        if (username.ToLower().Equals("hossein") && password.Equals("ITPro"))
        {
            Console.WriteLine("Welcome to ITPro.ir!");
        }
        else
        {
            Console.WriteLine("Oops! Username or Password is invalid!");
        }

        Console.ReadKey();
    }
}

بعد از کامپایل کردن برنامه یک فایل اجرایی exe برای ما تولید می شود. در اینجا ما باید شرطی که در متد Main نوشتیم را جوری تغییر بدیم که برنامه با هر ورودی اجرا شود. در ابتدا به ابزار ildasm.exe نیاز داریم. برای اجرای این ابزار، کافیست Developer Command Prompt for VS2015 را اجرا کنید. در صورتی که از نسخه های پایین تر Visual Studio استفاده می کنید محیط Command Prompt مربوطه وجود دارد. پس از اجرا، در خط فرمان عبارت ildasm.exe را تایپ کرده و کلید enter را بزنید تا پنجره ildasm باز شود:

وب سایت توسینسو

از منوی فایل گزینه Open را انتخاب کرده و سپس فایل exe ایجاد شده از پروژه کنسول نوشته شده را انتخاب کنید. این فایل در پوشه پروژه کنسول، پوشه bin\debug وجود دارد. پس از انتخاب فایل لیستی از محتویات فایل انتخابی برای شما نمایش داده می شود:

وب سایت توسینسو

در این پنجره با دوبار کلیک کردن بر روی هر یک از بخش های نمایش داده شده، اطلاعاتی به شما نمایش داده می شود. برای مثال، با دوبار کلیک بر روی متد Main کدهای مربوط به این متد برای شما نمایش داده می شود:

وب سایت توسینسو

کد IL ایجاد شده برای متد Main به صورت زیر است:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       106 (0x6a)
  .maxstack  2
  .locals init ([0] string username,
           [1] string password,
           [2] bool V_2)
  IL_0000:  nop
  IL_0001:  ldstr      "Username: "
  IL_0006:  call       void [mscorlib]System.Console::Write(string)
  IL_000b:  nop
  IL_000c:  call       string [mscorlib]System.Console::ReadLine()
  IL_0011:  stloc.0
  IL_0012:  ldstr      "Password: "
  IL_0017:  call       void [mscorlib]System.Console::Write(string)
  IL_001c:  nop
  IL_001d:  call       string [mscorlib]System.Console::ReadLine()
  IL_0022:  stloc.1
  IL_0023:  ldloc.0
  IL_0024:  callvirt   instance string [mscorlib]System.String::ToLower()
  IL_0029:  ldstr      "hossein"
  IL_002e:  callvirt   instance bool [mscorlib]System.String::Equals(string)
  IL_0033:  brfalse.s  IL_0042
  IL_0035:  ldloc.1
  IL_0036:  ldstr      "ITPro"
  IL_003b:  callvirt   instance bool [mscorlib]System.String::Equals(string)
  IL_0040:  br.s       IL_0043
  IL_0042:  ldc.i4.0
  IL_0043:  stloc.2
  IL_0044:  ldloc.2
  IL_0045:  brfalse.s  IL_0056
  IL_0047:  nop
  IL_0048:  ldstr      "Welcome to ITPro.ir!"
  IL_004d:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0052:  nop
  IL_0053:  nop
  IL_0054:  br.s       IL_0063
  IL_0056:  nop
  IL_0057:  ldstr      "Oops! Username or Password is invalid!"
  IL_005c:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0061:  nop
  IL_0062:  nop
  IL_0063:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
  IL_0068:  pop
  IL_0069:  ret
} // end of method Program::Main

برای درک کدهای IL، می بایست با زبان IL آشنا باشید. برای مرحله بعد می بایست از برنامه باز شده در ildasm خروجی بگیریم. برای اینکار ابتدا در یکی از درایو ها یک پوشه با نام Cracking Source ساخته، سپس از پنجره اصلی ildasm، از منوی فایل گزینه dump را انتخاب کرده، در پنجره Dump Options نیازی به تغییری نیست، بر روی دکمه OK کلیک کنید، در ادامه مسیر پوشه ای که ساختید را انتخاب کنید. بعد از اینکار یک فایل با پسوند il و یک فایل با پسوند res برای شما ساخته می شود. برای کرک کردن برنامه شما باید این فایل il را تغییر دهید. در داخل فایل به دنبال کد مربوط به متد Main گشته و قسمت مربوط به شرطی که نام کاربری و کلمه عبور بررسی می شود را تغییر می دهیم. کد مربوط به قسمت شرط برنامه به صورت زیر است:

IL_0042:  ldc.i4.0
IL_0043:  stloc.2
IL_0044:  ldloc.2
IL_0045:  brfalse.s  IL_0056

در خط 45 ام، گفته می شود اگر شرط صحیح نبود، به خط 56 ام برو که پیغام مربوط به صحیح نبودن نام کاربری و کلمه عبور نمایش داده می شود. کافیست در خط 45 ام، عبارت brfalse.s را brtrue.s تغییر دهیم. یعنی اگر شرط صحیح بود به خط 56 ام برو. کد این بخش را به صورت زیر تغییر می دهیم:

IL_0042:  ldc.i4.0
IL_0043:  stloc.2
IL_0044:  ldloc.2
IL_0045:  brtrue.s  IL_0056

فایل il تغییر داده شده را ذخیره می کنیم. حال باید از روی فایل تغییر داده شده مجدد یک فایل اجرایی ایجاد کنیم. برای اینکار باید از ابزار ilasm.exe استفاده کنیم. این ابزار برای ساختن اسمبلی های دات نت از روی فایل های il استفاده می شود. در همان محیط Developer Command Prompt به پوشه ای می رویم که فایل il را در آن dump کردیم. دستور زیر را در خط فرمان می نویسیم:

ilasm.exe source.il /exe

با این کار، یک فایل اجرایی با نام source.exe برای ما تولید می شود که همان فایل اجرایی ما است، با این تفاوت که این فایل کرک شده و حال با هر نام کاربری و کلمه عبوری (به جز نام کاربری Hossein و کلمه عبور ITPRO) می توان به سیستم وارد شد.

اما راهکار پیش گیری کرک شدن کدهای دات نت چیست؟ نمی توان راهکاری ارائه کرد که صد در صد جوابگو باشد، اما می توان بوسیله ابزارهایی که اصطلاحاً به آن ها Obfuscator گفته می شود، کاری کرد که کدهای IL به راحتی قابل فهم نبوده یا نتوان آن ها را با ابزارهایی مثل ildasm باز کرد. در یک مطلب جداگانه در مورد ابزارهای Obfuscator صحبت خواهیم کرد. امیدوارم که این مطلب مورد توجه شما قرار گرفته باشد. ITPRO باشید

نویسنده: حسین احمدی

انجمن تخصصی فناوری اطلاعات ایران

8 نظر
فرشید علی اکبری

سلام

دوست عزیز، سئوالی که در این زمینه (فی البداهه) به ذهنم رسید اینه که:

فرض کنید شما در دات نت و با زبان سی شارپ چند کامپوننت برای انجام کارهای خاص و سرعت بخشیدن به کارهای حرفه ای خود نوشته اید و تصمیم دارید آنها را در اختیار سایر برنامه نویسان نیز قرار دهید. همونطوریکه می دونید موقعی از یک اسمبلی به کلاسهای سایر اسمبلی های وابسته، دسترسی داریم که در سطح public یاشند و چنانچه بخواهیم از اسمبلی A به کلاس های سایر Assembly هایی که (تمام/یرخی از) کلاسهای آن در سطح Internal هستند، دسترسی داشته باشیم، باید یک کلید مشترک (StrongKey) در کامپیوتری که در حال Develop با آن هستیم تولید کرده و مانند تصویر زیر در بخش Signing از هر پروژه قرار داده و سپس در فایل AssemblyInfo نیز توسط کلاس ()InternalsVisibleTo که در فضای نامی System.Runtime.CompilerServices قرار دارد، (بترتیب و یکی یکی) نام اسمبلی هایی که قرار است از کلاسهای internal اسمبلی جاری، تغذیه شوند را به همراه Public Key (ازStronkKey ایی که روی سیستم خود تولید کرده ایم) بنویسیم و یا در اصل آدرس دهی میکنیم.

Signing Assemblies into DotNet

حال با توجه به ابزارهای مختلف جهت دسترسی به سورس کدهای مختلف از نرم افزارهایی که با دات نت نوشته اندو از طرفی اینکه اکثر برنامه نویسان همیشه ترس از دست دادن سورس کدهای ارزشمند خود را دارند، با توجه به سناریویی که خدمت تون عرض کردم، برای یک چنین اسمبلی هایی امکان Encrypt و ناخوانا کردن کدها توسط نرم افزارهای مختلف وجود ندارد، چرا که پس از آن، امکان دسترسی به کلاسهای Internal در سایر اسمبلی های وابسته را از دست میدهند.

سئوال اینجاست که:

برای یک چنین مواردی که نیاز به محافظت شدید از سورس کدها در مقابل افراد سود جو می باشد، شما چه پیشنهادی دارید؟

حسین احمدی

مبحث Strong Key که شما فرمودید کاربردش برای انتشار Assembly ها، قابلیت Versioning و نصب اسمبلی ها در GAC یا همون Global Assembly Cache هست. در حقیقت SNK ارتباطی به دسترسی به کلاس های internal اسمبلی نداره. موردی که شما بهش اشاره کردید، یعنی استفاده از InternalsVisibleToAttribute، یک Attribute در سطح اسمبلی هست که شما می تونید مشخص کنید که بخش های Internal داخل اسمبلی توسط کدام اسمبلی ها که بهشون Friend Assembly هم گفته میشه قابل دسترس باشند. حالا اگر اسمبلی مورد نظر شما توسط SNK به اصطلاح Sign شده باشه باید Fully Qualified Assembly Name به عنوان ورودی InternalsVisibleTo بنویسید، در غیر اینصورت تنها نام اسمبلی کفایت میکنه. پس در حقیقت الزامی به Sign کردن اسمبلی جهت استفاده در InternalsVisibleTo نیست. اما در مورد جلوگیری از محافظت کدها، مکانیزم Obfuscate کردن کدها به چند صورت انجام میشه:

  1. تغییر در CLR Header که امکان باز شدن فایل توسط ابزارهای Reflector رو میگیره. در حقیقت انگار اسمبلی مورد نظر، یک اسمبلی دات نت نیست
  2. تغییر در نام متغیر ها که نام متغیر ها با نام های جدید و ناخوانا جایگزین میشن
  3. Encrypt کردن رشته ها که در این قسمت، رشته رمز نگاری شده و با یک متد که عملیات رمزگشایی رو انجام میده جایگزین میشه، یعنی هر جایی که رشته ای استفاده شده، یک متد فراخوانی میشه و رشته رمز نگاری شده به عنوان پارامتر به متد پاس داده شده و رشته اصلی برگردانده می شود.

اما نکته ای که وجود داره، تمامی روش های بالا بوسیله Reverse Engineering قابل بازگشته و همانطوری که در متن هم اشاره کردم، هیچ روش صد در صد مطمئنی برای حفاظت از کدها وجود نداره، همین چند وقت پیش بود که نیاز شدید به آخرین نسخه ابزار Janus داشتم و به خاطر عدم امکان خرید اون مجبور به کرک کردن اون شدم. با مکانیزم های مختلفی Obfuscation انجام شده بود، اما باز هم امکان کرک داشت. شما با کارهای ذکر شده تنها عمل کرک رو کند می کنید. ;)

فرشید علی اکبری

بله درسته. منظور منم دقیقاً همین پاراگراف اولی هستش که شما پاسخ دادید( که البته شما کاملاترش کردین) ممنون.

موارد 3و2 را که فرمودید من تا حالا انجام دادم ولی برای تغییر CLR Header چطوری میتونم عمل کنم؟ آموزش ولینک خاصی توی سایت داره؟ یا باید با نرم افزار خاصی اینکار رو انجام بدم؟ در حال حاضر با نرم افزار Crypto Obfuscator برای این منظور کار میکنم ولی برای مورد 1 چیزی توی راهنمای اون ندیدم.

حسین احمدی

من پیشنهاد میکنم که ابزار Secure Team رو هم یه نگاهی بندازید. اگر هم مایل بودید لیستی از Obfuscator های موجود در اختیار داشته باشید، در این لینک این لیست قابل دسترسته.

این نظر توسط حسین احمدی در تاریخ پنجشنبه, 24 تیر 1395 حذف شده است.

دلیل: قرار دادن هر گونه شماره تماس و پست الکترونیکی در مطالب ممنوع می باشد.

فرشید علی اکبری

سلام

دوست عزیز چرا مطلب را در قالب یک پُست آموزشی و یا مقاله در همین سایت در دسترس عموم قرار نمی دین؟ چه نیازی به ارسال ایمیل هست؟

mr-saadi

سلام حتما باید فایل های پروزه رو داشته باشیم ؟

من فایل exe رو باز میکنم با ارور :

error : 'App.exe' has no valid CLR header and cannot be disassembled

مواجه میشم آیا همه برنامه ها رو میشه طبق روشی که گفتید بررسی کرد ؟

حسین احمدی

سلام دوست عزیز، روشی که گفته شده فقط بر روی برنامه های دات نت جواب میده، شما کافیه فایل exe یا dll مورد نظر رو داشته باشید. پیغامی هم که دریافت می کنید به دو دلیل می تونه باشه:

  1. برنامه مبتنی بر دات نت نیست
  2. هدر برنامه مورد نظر بوسیله یکی از ابزارهای Obfuscator تغییر کرده.
نظر شما
برای ارسال نظر باید وارد شوید.
از سرتاسر توسینسو
تنظیمات حریم خصوصی
تائید صرفنظر
×

تو می تونی بهترین نتیجه رو تضمینی با بهترین های ایران بدست بیاری ، پس مقایسه کن و بعد خرید کن : فقط توی جشنواره تابستانه می تونی امروز ارزونتر از فردا خرید کنی ....