السلام عليكم
أنا عضو جديد في هذه المنصة، مشرف سابق في منتديات الفريق العربي للبرمجة و rédacteur أيضاً في Club des développeurs et IT Pro.
أعجبتني فكرة الموقع و أحببت أن أناقش معكم كيفية حماية ملف الـ jar إذا كان المشروع غير مفتوح المصدر.
تحياتي.
فضيحة كبيرة للجافا؟ جميع اللغات يوجد فيها 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 هل يمكنك إرجاع ولو سطر واحد من البرنامج؟
يمكنك تحميله من هذا الرابط:
التعليقات