السلام عليكم
أنا عضو جديد في هذه المنصة، مشرف سابق في منتديات الفريق العربي للبرمجة و rédacteur أيضاً في Club des développeurs et IT Pro.
أعجبتني فكرة الموقع و أحببت أن أناقش معكم كيفية حماية ملف الـ jar إذا كان المشروع غير مفتوح المصدر.
تحياتي.
اين أجد الجافا Decompiler?
هذه فضيحة كبيرة للجافا!
قمت بفتح عدد كبير من المكتبات والـ JAR والـ CLASS بهذا البرنامج، وقد أظهر كل الكود المكتوب، لم يتبقى إلا التعليقات comments هي التي لم تظهر
أعتقد أن هذا يُثبت أن لغة جافا لا ترقى لأن تكون compiled language لأن من صفات الـ compiled language أن تقوم بإصدار برامج تنفيذية ثُنائية. لكن هذا البرنامج يُثبت أنها ليست برامج ثُنائية حقيقية
سؤال آخر، هل برامج اﻷندرويد المكتوبة بالجافا ايضاً يحدث لها Decompilation? الـ APK
فضيحة كبيرة للجافا؟ جميع اللغات يوجد فيها decompilation. على أية حال، توجد أدوات وبرامج تقوم بتحويل برامج الجافا من byte-code إلى native-code، وبالتالي لن تستطيع إعادة كود الجافا الأصلي، ولكن يمكن الإعادة لكود السي/سي بلص بلص، وأيضاً لن تستطيع تشغيل البرنامج على الأنظمة الأخرى.
هل توجد للغات مثل سي ودلفي إمكانية عمل decomplication دلني على تلك اﻷداة إذا امكن. وماهي البرامج التي تقوم بتحويل كود الجافا إلى native code?
هل توجد للغات مثل سي ودلفي إمكانية عمل decomplication دلني على تلك اﻷداة إذا امكن
بالنسبة لـ C فيوجد[1] لكن المشكلة المترجمات Compilers لا تنتج نفس الكود حتى بدون تحسين الكود(أحد خيارات GCC)
هذا الكود مثالا
-
مترجم MinGW مع Codeblocks ينتج
بداية البرنامج
-
الدالة Main
-
مترجم OpenWatcom مع IDE (يأتي معه في نفس الحزمة)
بداية البرنامج
-
الدالة Main
نرى الاختلاف كبير مع أنه نفس الكود !
-
[1]
الكود الأصلي ترجمته بـ MinGW مع CodeBlocks
-
int main()
{
FILE *fp;
fp = fopen("out.txt","w+");
fprintf(fp,"Hello World!");
fclose(fp);
return 0;
}
-
int __fastcall sub_401010(int a1, char a2)
{
char v2; // ST08_1@1
int v3; // eax@1
int v4; // ecx@1
int v5; // edx@1
v2 = a2;
v3 = sub_4012A0("out.txt", (int)&unk_409004, a1);
sub_4013A0(v4, v3, v3, (int)"Hello World!", v2);
sub_401490(v5);
return 0;
}
ملاحظة:
تجاهلت دوال المكتبة القياسية التي تم توليدها
هذا كود Assembly الذي تم توليد كود C منه
-
sub_401010 proc near
push edx
mov edx, offset unk_409004
mov eax, offset aOut_txt ; "out.txt"
call sub_4012A0
push offset aHelloWorld ; "Hello World!"
push eax
mov edx, eax
call sub_4013A0
add esp, 8
mov eax, edx
call sub_401490
xor eax, eax
pop edx
retn
sub_401010 endp
شكراً لك.
طلب أخير، قمت بعمل برنامج للكتابة في ملف نصي ثم عرضه بواسطة فري باسكال/لازاراس
هل يُمكنك إعادة المصدر ثم عرضه هنا.
البرنامج في هذا الرابط:
هناك أمورا نسيت أن أذكرها
عند توليد كود البرنامج مكتوب بـ C ستحصل على :
كود إبتدئي يحصل على المعلومات التي تحتاجها المكتبات ( ... ,Argc, Argv, stdin, stdout, stderr)
كود المكتبات المدمج مع البرنامج Static Library مثل (printf,fopen, ...)
كود معالج الإستثنائات
كود الذي يكتبه المبرمج
حتى تجد كود المبرمج عليك أن تعرف متى يبدأ كود المكتبة ومتى ينتهي
وهذا يختلف مع كل مترجم لغة(ما يولده MinGW غير الذي يولده ++MVC)
أما في حالة Free Pascal فأنا لا أعرف كيف يولد البرامج وما هي بنية مكتباته
حتى أستطيع الفصل بينه وما كتبت
لكن على كل حالة رفعة لك الكود المولد عن المثال الذي طلبته
والكود المولد عن FileSample
-
صورة توضيحية على ما ذكرتُ
الكود الإبتدائي ما قبل Main
شكراً لك أخ طالب علم
هذا مطمئن بأن البرامج الطبيعية Native لا يمكن إرجاعها إلى مصدرها الأصلي بسهولة. حتى لو تم إرجاعها فلا يمكن تعديلها وإعادة ترجمتها.
ونستخلص من الملف الذي أرسلته اﻵتي:
لم يتم التعرف على لغة البرمجة اﻷصلية التي أنتجت الملف الثُنائي، حيث استخدمت مترجم فري باسكال أما برنامج الـ Decompiler فقط افترض أنها Visual C++, هذا جزء من ترويسة الملف الناتج:
/* This file has been generated by the Hex-Rays decompiler.
Copyright (c) 2007-2011 Hex-Rays <info@hex-rays.com >
Detected compiler: Visual C++
*/
#include <windows.h>
#include <math.h>
#include <defs.h>
أسماء المتغيرات والدوال غير موجودة في البرنامج الناتج.
ليس هُناك علاقة بين حجم البرنامج اﻷصلي والناتج. حيث أن البرنامج اﻷصلي حوالي 50 سطر، أما الناتج فهو 198 ألف سطر!
هذا البرنامج تمت كتابته في حوالي 5 دقائق، لم يستطع الـ Decompiler بإرجاعه بصورة مفهومة، فكيف البرامج التي تحتاج لسنوات للتطوير.
هذا نص البرنامج اﻷصلي:
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
LCLIntf;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
F: TFileStream;
begin
F:= TFileStream.Create('file.txt', fmCreate);
F.WriteAnsiString('Hello there' + #13#10);
F.WriteAnsiString('Today is: ' + DateTimeToStr(Now));
F.Free;
OpenDocument('file.txt');
end;
end.
هل توافق على هذه الاستنتاجات؟ لأني أريد البناء عليها في المستقبل
1)
برنامج Hex-Rays IDA لا يفرق بين المترجمات،
هناك برنامج يسمى Exeinfo PE يستطيع معرفة مترجم الذي ترجم البرنامج
الأخيرة MinGW لم يتعرف عليه بالتفصيل لكنه يبقى GCC
-
2)
صحيح ولن يستطيعوا إيجادها
-
3) السبب هو المكتبة القياسية المدمجة في البرنامج
فالكود المولد هو
كود المبرمج + كود المكتبة القياسية
-
4) IDA هو Disassembly ليس متخصص في Free Pascal أو MinGW أو غيرهما
هناك برامج متخصص مثل Java Decompiler الفرق أن الجافا أسهل من غيرها
-
هل توافق على هذه الاستنتاجات؟ لأني أريد البناء عليها في المستقبل
فيما يتعلق بأسماء المتغيرات والدوال من غير المكتبة القياسية، نعم
أريد أن أضيف كلما زاد تعقيد البرنامج كلما اعتمد على مكتبات إضافية أكثر، بهذه الطريقة يصعب إرجاعه إلى اﻷصل
وايضاً أن لغات البرمجة الـ Native تعتمد على نداء مكتبات موجودة في نظام التشغيل بشكل أساسي
والباسكال لديه مكتبة قياسية ذات حجم كبير، لذلك البرامج التنفيذية المكتوبة بلغة اوبجكت باسكال كبيرة جداً مقارنة بالسي
هذا مثال يرسم شكل معين على الطرفية
أخترته لأنه يحمل خوارزمية أعقد من المقترح
الكود الأصلي
int main()
{
int n, c, k, space = 1;
printf("Enter number of rows\n");
scanf("%d", &n);
space = n - 1;
for (k = 1; k <= n; k++)
{
for (c = 1; c <= space; c++)
printf(" ");
space--;
for (c = 1; c <= 2*k-1; c++)
printf("*");
printf("\n");
}
space = 1;
for (k = 1; k <= n - 1; k++)
{
for (c = 1; c <= space; c++)
printf(" ");
space++;
for (c = 1 ; c <= 2*(n-k)-1; c++)
printf("*");
printf("\n");
}
return 0;
}
int __fastcall sub_401010(int a1, int a2)
{
int v2; // edx@1
int v3; // ecx@1
signed int v4; // edi@1
int v5; // ecx@1
signed int v6; // esi@2
int i; // edx@3
int v8; // edx@4
int v9; // edx@5
int j; // ecx@5
int v11; // edx@6
signed int v12; // ebx@8
int k; // ecx@8
int l; // edx@10
int v15; // edx@11
int v16; // edx@12
int v17; // edx@14
int v18; // ecx@15
int v20; // [sp+0h] [bp-1Ch]@1
sub_401110(a1, a2, (int)"Enter number of rows\n", v20);
sub_4011B0(v3, v2, (int)"%d", (unsigned int)&v20);
v4 = 1;
v5 = v20 - 1;
if ( v20 >= 1 )
{
v6 = 1;
do
{
for ( i = 1; i <= v5; i = v8 + 1 )
sub_401110(v5, i, (int)" ", v20);
v9 = 1;
for ( j = v5 - 1; v9 <= v6; v9 = v11 + 1 )
sub_401110(j, v9, (int)"*", v20);
sub_401110(v5, v9, (int)"\n", v20);
++v4;
v6 += 2;
}
while ( v4 <= v20 );
}
v12 = 1;
for ( k = 1; k <= v20 - 1; k = v18 + 1 )
{
for ( l = 1; l <= v12; l = v15 + 1 )
sub_401110(k, l, (int)" ", v20);
v16 = 1;
++v12;
while ( v16 <= 2 * (v20 - k) - 1 )
{
sub_401110(k, v16, (int)"*", v20);
v16 = v17 + 1;
}
sub_401110(k, v16, (int)"\n", v20);
}
return 0;
}
ملاحظة:
تجاهلت دول المكتبة القياسية التي تم توليدها
لدي برنامج مكتوب بلغة Free Pascal وهي native compiled هل يمكنك إرجاع ولو سطر واحد من البرنامج؟
يمكنك تحميله من هذا الرابط:
أعتقد أن هذا يُثبت أن لغة جافا لا ترقى لأن تكون compiled language
لأن من صفات الـ compiled language أن تقوم بإصدار برامج تنفيذية ثُنائية.
لكن هذا البرنامج يُثبت أنها ليست برامج ثُنائية حقيقية
جربتها على لعبة Minecraft وظهر الكود واضح وصريح لكن لم تكن الاسماء مفهومة كانت على شاكلة a aa ab ac
ربما يكون في المترجم Compiler خيار لتشفير الأسماء
سؤال آخر، هل برامج اﻷندرويد المكتوبة بالجافا ايضاً يحدث لها Decompilation? الـ APK
ربما، لم أجرب فعل ذلك
قد يفيدك هذا الرابط
بنسبة للموضوع الأندريود هناك برامج قامت بDecompilation وأضف إلي ذلك إني تمكنت إضافة سطر إلي لغة جافا أقصد لغة الألة خاصة بجافا إلي لعبة Subway وعمل :) لا أعرف هل لغة جافا ضعيفة إلي هذه الدرجة أو لا وللعلم أنا لأعرف شي عن جافا إلا قليل
ممكن توضيح لهذه النقطة :
أضف إلي ذلك إني تمكنت إضافة سطر إلي لغة جافا أقصد لغة الألة خاصة بجافا إلي لعبة Subway وعمل
أنا أقصد أن أعدل علي ملفات smali,سأعطيك مثال
smali code
const/4 v1, 0x1
if-ne v0, v1, :cond_0
const/4 v2, 0x2
move v0,v2
goto :goto_0
:cond_0
const/4 v2, 0x3
move v0,v2
:goto_0
أوكي اتضحت الفكرة.
لا أعرف هل لغة جافا ضعيفة إلي هذه الدرجة أو لا وللعلم أنا لأعرف شي عن جافا إلا قليل
ماذا كنت تريدها أن تفعل ؟ :)
وماهو الشيء الذي لا أعرفه ؟
في الحقيقة كُنت استخدم جافا لأكثر من ثلاث أعوام. وقد سمعت أنه يمكن إعادة مصدر الكود من البرنامج التنفيذي، لكن لم اكن أتوقع أن يكون الموضوع بهذه السهولة، وحتى أسماء المتغيرات والكلاسات واﻹجراءات و الدوال تظهر بكل سهولة. والمشكلة أن من قام بعمل decomplication هم جهة أخرى أي third party. والمشكلة اﻷكبر أنه لا يمكن الحيلولة دون الـ decomplication على حسب هذه الصفحة:
هذه عبارة عابرة لأني عرفت أنه من موريتانيا
ولي عدد من اﻷصدقاء هُناك، وهم يمتازون باللباقة في الحديث والتواضع
أخي الكريم أنا لا أقلل من علمك و لكن للأسف أنت لا زلت تزيد قناعتي بأنك تتحدث عن موضوع لا تتقنه مع احترامي الشديد لك :)
أعتقد أن هذا يُثبت أن لغة جافا لا ترقى لأن تكون compiled language
من قال بأن جافا compiled language ؟ لو قرأت عن الجافا قليلا لعلمتَ أنها semi-compiled و شتان ما بين الأمرين.
وقد سمعت أنه يمكن إعادة مصدر الكود من البرنامج التنفيذي، لكن لم اكن أتوقع أن يكون الموضوع بهذه السهولة
في الجافا لا يوجد إطلاقا شيء اسمه "ملف تنفيذي" إن كنت تقصد ملف exe لأن بنية ملف الـ jar تختلف تماما عن بنية exe.
أخي الكريم أنا لا أقلل من علمك و لكن للأسف أنت لا زلت تزيد قناعتي بأنك تتحدث عن موضوع لا تتقنه مع احترامي الشديد لك :)
أنت أيضاً تزيد قناعتي أنك لا تعرف الكثير عن الجافا، وانك لم تكتب بها برامج حقيقية مع كامل احترامي لك :)
من قال بأن جافا compiled language ؟ لو قرأت عن الجافا قليلا لعلمتَ أنها semi-compiled و شتان ما بين الأمرين.
التحويل من source code إلى byte code ليتم تنفيذه بواسطة الـ virtual machine هي عملية complition
في الجافا لا يوجد إطلاقا شيء اسمه "ملف تنفيذي" إن كنت تقصد ملف exe لأن بنية ملف الـ jar تختلف تماما عن بنية exe.
ملفات الـ JAR هي ملفات تنفيذية، في نظام لينكس تقوم بإعطاها صلاحية execute حتى يتم تنفيذها مباشرة من الـ file explorer
التحويل من source code إلى byte code ليتم تنفيذه بواسطة الـ virtual machine هي عملية complition
غير صحيح، javac يقوم بتحويل .java إلى .class (هذه العملية تُسمى compilation) بعد ذلك تقوم الـ JVM بتحميل الـ byte code و عمل interpretation له كما يُمكنها أيضاً أن تقوم بعمل JIT.
لهذا قُلت لك أن الجافا ليست compiled language بل هي semi-compiled لأن عملية الترجمة أو التفسير تتم على مرحلتين.
ملفات الـ JAR هي ملفات تنفيذية، في نظام لينكس تقوم بإعطاها صلاحية execute حتى يتم تنفيذها مباشرة من الـ file explorer
أنا كنت أتحدث عن الويندوز و ملفات exe، الـ jar اختصار لـ Java ARchive و هو ليس ملفا تنفيذياً من حيث البنية (كلامي واضح جداً) لأن ملف الـ Jar عبارة عن ملف ZIP و يُمكنك رؤية محتواه باستخدام WinRar مثلا.
التعليقات