ورود

View Full Version : سوال: جلوگیری از کپی کردن کدهای جاوا



ravand
سه شنبه 08 اردیبهشت 1394, 09:50 صبح
سلام
آیا راهی وجود داره که ما کاری کنیم که کسی نتونه کدهایی که نوشتیم رو کپی برداری کنه؟ من یه بار کدهام رو به فرمت exe تبدیل کردم. آیا میشه با این روش کاری کرد که کسی نتونه کدها رو کپی کنه؟ آیا روش دیگه و روش بهتری هم هست؟
متشکرم.

محمد فدوی
سه شنبه 08 اردیبهشت 1394, 10:06 صبح
سلام.
بعد از کامپایل جاوا به بایت‌کد دیگه امکان کپی برداری کد شما وجود نداره. با این حال می‌شه بایت‌کد جاوا رو Decompile کرد... کد Decompile شده دقیقا کد شما نیست و کلی از جزئیاتش مثل نام متغیرها و... دیگه وجود نداره و فهمش هم بسیار مشکله. با این حال ابزارهایی هست که کد شما رو قبل از کامپایل نامفهوم‌تر می‌کنه تا بازم در صورت Decompile شدن فهمشون سخت‌تر بشه.
راهی که تقریبا این مشکل رو حل می‌کنه و البته کد شما رو وابسته به سکو می‌کنه ترجمه‌ی جاوا به کد دودویی (Binary) یا همون فایل اجراییه، که در این صورت کد شما به صورت محلی (Native) اجرا خواهد شد و طبعا در سیستم‌عامل‌های مختلف کاراییش رو از دست خواهد داد.
در این مورد اطلاعات کافی ندارم و فکر هم نمی‌کنم خیلی کار جالبی باشه. چه از نظر اینکه کد رو وابسته به سکو می‌کنه و چه از نظر سازگاری... به‌هرحال شاید این لینک کمکتون کنه:
http://stackoverflow.com/questions/16360691/compiling-java-into-native-code

موفق باشید.

ravand
سه شنبه 08 اردیبهشت 1394, 10:32 صبح
این تبدیل به فرمت exe باعث جلوگیری از کپی کردن کدها نمیشه؟

محمد فدوی
سه شنبه 08 اردیبهشت 1394, 12:40 عصر
اگه دلیل exe شدن، کامپایل شدن جاوا به کد محلی (Native) باشه باعث می‌شه کد دیگه غیرقابل Decompile و وابسته به سکو بشه.

ravand
سه شنبه 08 اردیبهشت 1394, 13:23 عصر
اگه دلیل exe شدن، کامپایل شدن جاوا به کد محلی (Native) باشه باعث می‌شه کد دیگه غیرقابل Decompile و وابسته به سکو بشه.
شما یه سری اصطلاحات توی حرف هاتون بکار میبرید که من درست متوجه نمیشم.
مثلا Decompile یا سکو
من فقط میخوام بدونم اگه exe کنم کسی بازم میتونه به کدهاش دسترسی پیدا کنه؟ همینو بگید آره یا نه؟
متشکرم.

ahmad.mo74
سه شنبه 08 اردیبهشت 1394, 16:20 عصر
سلام، منظور از سکو که همون platform ه و منظور از decompile هم معکوس compile هست، (در اینجا) یعنی از روی byte code جاوا به source code اش برسیم.

ابزارهای زیادی برای decompile کردن بایت کد جاوا هست و به نظرم قوی ترینش رو intelliJ داره که از ورژن 14.1 به بعد اضافه شده. یعنی هر فایل class. ای رو به راحتی decompile میکنه و تقریبا کدی شبیه به کد اصلی رو بهتون میده.

واقعیت اینه که نمیشه یه jar فایل رو encrypt کرد و از سورسش محافظت کرد. چون بالاخره jvm هم قراره این کدهارو بخونه و اگر قرار باشه روشی برای encrypt کردن byte code وجود داشته پس قطعا برای decrypt کردنش هم باید روشی وجود داشته باشه... پس نمیشه روش حساب باز کرد، چون هم بیخودی یه کار اضافی انجام میشه و هم اینکه شما فکر کن 1 درصد روش decrypt کردنش هک نشه!

تا حالا درباره اینکه مستقیما بشه کد جاوا رو به کد (native (machine code کامپایل کرد نشنیده بودم، و همین الان با GCJ آشنا شدم. اما اونطور که فهمیدم خیلی وقته ازش پشتیبانی نمیشه و ظاهرا تا ورژن 1.6 جاوا هم بیشتر ساپورت نمیکنه.
http://stackoverflow.com/a/3032745/3767784

میشه برای برنامه جاوا فایل exe تولید کرد. ابزار های زیادی براش هست که به نظرم راحت ترینش launch4j (http://launch4j.sourceforge.net/) ه.
اما بازم این روش، روش امنی نیست : http://stackoverflow.com/questions/14879586/decompile-java-application-packed-with-launch4j
به هر حال بازم یک مرحله جلوتر میبره شمارو... ولی اگر صرفا میخواید برای برنامتون فایل exe بسازید خیلی هم خوبه.

بازم سرچ کنید ابزارهای حرفه ای تر (اکثرا پولی) هم پیدا میکنید که شاید مشکل بالا رو نداشته باشن و دیگه به هیچ وجه اجازه دسترسی به jar فایل رو ندن یا ...
اگر زمانی از JavaFX استفاده کردید، درباره JavaFX Packager Tool هم سرچ کنید.

کار دیگه ای که میشه انجام داد اینه که بشه این مهندسی معکوس رو برای هکرها و ... به شدت سخت و هزینه بر کرد.
یعنی ابزاری باشه که فرایند decompile کردن byte code رو به شدت مختل یا حتی غیرممکن کنه و یا حداقل بخشی از byte code رو نشه decompile کرد و اون بخشیش هم که از دستمون در رفته به قدری درهم برهم و نامفهوم باشه که به راحتی نشه ازش سردرآورد.

ابزارهایی که میشه ازشون استفاده کرد :

ProGuard (http://proguard.sourceforge.net/)
yGuard (https://www.yworks.com/en/products_yguard_about.html)

اما یکیش که به نظرم جالب تر اومد و حتی دیدم که یه ویژگی خوب داره که به نحوی jar فایل رو encrypt میکنه که برای jvm قابل فهم باشه!!

JWrapper (http://www.jwrapper.com/)
JWCrypt (http://www.jwrapper.com/guide-jwcrypt-code-protection.html)

من خودم تا حالا از هیچکدوم اینا استفاده نکردم (نیازی نبوده).

به هر حال همه اینا خلاف هدف اصلی جاواست؛ جاوا open-source ه و از اول هدفش این بوده که برنامه جاوا رو همه جا بشه اجرا کرد.

مسئله اصلی به خود شما و به برنامه ای که مینوسید برمیگرده. دیگه توی مقطعی هستیم که همه دارن میرن به سمت سرویس های تحت وب و cloud computing و دیگه معنی نداره که سورس اصلی برنامه سمت کاربر باشه! مگر اینکه واقعا مجبور باشید.

-سیّد-
چهارشنبه 09 اردیبهشت 1394, 10:53 صبح
ضمن تشکر از پاسخ‌های خوب دوستان، یه سری نکات رو اضافه کنم:


کد Decompile شده دقیقا کد شما نیست و کلی از جزئیاتش مثل نام متغیرها و... دیگه وجود نداره

این بخش از صحبتتون درست نیست. bytecode جاوا به صورت پیش‌فرض شامل نام متغیرها و توابع دقیقاً به همون صورتی که نوشتید هست. حتی دیده شده که کامنت هم توش بوده! (نمی‌دونم کامنت چه وقت‌هایی توی bytecode میاد، فقط یادم میاد که دیدم! شایدم خواب دیدم و اشتباه می‌کنم!)


اگه دلیل exe شدن، کامپایل شدن جاوا به کد محلی (Native) باشه باعث می‌شه کد دیگه غیرقابل Decompile و وابسته به سکو بشه.
درسته که کد exe رو نمی‌شه به سورس جاوا decompile کرد، ولی می‌شه dissassemble اش کرد. روی همون کد exe هم قابلیت انجام انواع کارها وجود داره، مانند استخراج الگوریتم‌های استفاده شده، سرورهایی که باهاشون داده رد و بدل می‌کنید، فهمیدن روند اجرای کد و ... (البته که خیلی سخت‌تره، ولی ممکنه).

نکته‌ی دیگه: به پیچوندن کد به نحوی که خوندن و فهمیدنش برای آدم سخت بشه، می‌گن Obfuscate کردن. مثلاً یکی از ساده‌ترین کارهایی که Obfuscator ها می‌کنن، اینه که اسم تمام کلاس‌ها، پکیج‌ها، توابع و متغیرها رو به a و b و c و ... تغییر می‌دن. مثلاً یه نمونه کلاس Obfuscate شده بعد از decompile به این صورت خواهد بود:

package a.a.a.a;

import a.a.a.b;
import a.a.b.c;

public class a implements b extends c {
public static final int a = 10;

private final a.a.a b;

public a(a.a.a a) {
this.b = a;
}

public float a(a.e.a a) {
return c.a.a.a(a.a());
}
}

خوب امیدوارم از خوندن کد بالا لذت ببرید! :لبخند:

اتفاقات مختلف و جالبی هم این وسط می‌افته. مثلاً شما هر چی این خط رو نگاه می‌کنید نمی‌فهمید یعنی چی!

return c.a.a.a(a.a());

منظور این بوده که تابع static‌ با نام a از کلاس a در پکیج c.a فراخوانی بشه، پارامتر a از شیء a هم بهش داده بشه!!!

یه نکته‌ی دیگه‌ای که اتفاق می‌افته اینه که توی یه پکیج، مثلاً a، یه کلاس به نام a وجود داره، و همزمان یه پکیج هم به نام a وجود داره (یعنی a.a هم کلاس هست، هم پکیج!). خوب این باعث می‌شه کد شما کامپایل نشه و خطا بده که این پکیج، هم‌نام با یه کلاس هست.
نکته اینجاس که یه سری مفاهیم موقع کامپایل شدن قابل قبول نیستن، ولی موقع اجرا توسط jvm مشکلی ندارن. یعنی کامپایلر جاوا به این که یه پکیج با یه کلاس همنام باشه گیر می‌ده، ولی jvm موقع اجرا گیر نمی‌ده.

یه کار دیگه‌ای که می‌شه کرد اینه که شما کارهای مخصوصتون رو به صورت native توی یه زبون مثل ++C پیاده‌سازی کنید، و بعد اونها رو با jni به کد جاواتون متصل کنید. با این کار اگه کسی کد رو decompile کنه، فقط به signature اون توابع مخصوص شما توی جاوا دسترسی پیدا می‌کنه و برای بقیه‌اش باید فایل‌های لینک شده (so یا dll) رو dissassemble کنه که همونطور که گفتند و گفتم، سخت‌تره.

یه نکته‌ی کلی توی دنیای رایانه هم بگم: کلاً هر کاری توسط یه بخشی از سیستم شما داره انجام می‌شه، قابل تکرار توسط خود شما خواهد بود (مگر این که همه‌اش توی سیستم شما نباشه و وابستگی به یه سیستم دیگه داشته باشه، مثلاً از یه سروری یه چیزی رو بپرسه). یعنی همونطور که دوستمون اشاره کردن، وقتی jvm می‌تونه کد رو بفهمه و اجرا کنه، پس شما هم می‌تونید کد رو بفهمید (البته در حدی که jvm می‌فهمه، مثلاً jvm کاری به کامنت‌ها و اسم متغیرها نداره و نیازی نداره که اونا رو بفهمه).
یا مثلاً وقتی یه کد exe اجرا می‌کنید، یعنی سیستم عامل متوجه می‌شه توش چیه و اجراش می‌کنه. پس شما هم می‌تونید متوجه بشید توش چیه (البته به زبان ماشین).
پس شما هیچ وقت نمی‌تونید برنامه‌ای که به یه نفر می‌دید رو ازش پنهان کنید! چون بهش دادیدش! منطقی بود نه؟! :لبخند:

مثلاً کدهای جاوااسکریپت تمام سایت‌ها در اختیار تمام کاربران هستند! به عنوان مثال به گوگل مراجعه کنید، می‌بینید که کدهای جاوااسکریپتش رو obfuscate کرده در حد تیم ملی! (البته minify هم کرده)

بنابراین نتیجه‌گیری اخلاقی می‌شه این: شما تلاشتون رو می‌کنید که فهم کد رو برای کاربر سخت کنید، انقدر که براش نصرفه بره تو شیکم کد شما و شروع کنه مهندسی معکوس کردن. یعنی مثلاً هزینه‌اش براش از ساختن همون پروژه از صفر بیشتر بشه!

پ.ن. یه decompiler معروف دیگه برای جاوا هست به نام jd:
http://jd.benow.ca

ravand
چهارشنبه 09 اردیبهشت 1394, 14:27 عصر
خیلی ممنونم.
اینطوری که فهمیدم همه ی این فایل ها بالاخره توسط یه متخصص حرفه ای خونده میشن. ولی حرف من این بود. که من بیام مثلا exe کنم آیا یه فرد معمولی با یه برنامه ای که توی اینترنت پیدا میکنه میتونه کدهای منو در بیاره؟ یا باید حتما خودش تحصصش بالا باشه؟
آخه میدونید من خودم چند تا برنامه توی نت پیدا کردم که راحت کدهای جاوا رو میشد دراورد. برای همین پرسیدم.
گفتم من این همه زحمت بکشم. یه نفر بیاد کدهاش رو در بیاره و ازش استفاده بکنه به نفع خودش. یعنی نقض کپی رایت. خب واقعا حالگیریه.
اصلا برای همین یه مدت از جاوا بدم امده بود.
متشکرم.

dasssnj
چهارشنبه 09 اردیبهشت 1394, 14:34 عصر
این بخش از صحبتتون درست نیست. bytecode جاوا به صورت پیش‌فرض شامل نام متغیرها و توابع دقیقاً به همون صورتی که نوشتید هست. حتی دیده شده که کامنت هم توش بوده! (نمی‌دونم کامنت چه وقت‌هایی توی bytecode میاد، فقط یادم میاد که دیدم! شایدم خواب دیدم و اشتباه می‌کنم!)


این کامنت ها را خود دیکامپایلر برای جاهایی که مشکلی در دیکامپایل وجود داشته یا وقتی ابهاماتی در کد دیکامپایل شده وجود داشته باشه می نویسه . مثلا اگه با jad یا Jd-gui کار کرده باشید از این کامنت ها در بعضی کد ها دیده میشه . فکر نمی کنم هیچ وقت بشه کامنت های برنامه نویس را دیکامپایل کرد چون هنگام کامپایل خود به خود حذف میشن و هیچ اثری ازشون باقی نمی مونه .

http://stackoverflow.com/questions/8798002/can-java-comments-be-seen-by-decompiling