تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
إستخدام الواجهات Interface في إستدعاء الدوال و الروتينات من ملف Dll
#1
مقدمة:

الهدف من هذا الموضوع هو توضيح كيفية استخدام الواجهات Interface في الربط بين ملف Dll و البرنامج الرئيسي
هذه الفكرة تسمح للمبرمج باستخدام الواجهات Interface في اسدعاء الدوال بدون أن يظهر الكود الفعلي في البرنامج الرئيسي
أيضا هذا الأسلوب يسمح للمبرمج بتشقيير ملف او ملفات Dll التي تحتوي علي الكود الفعلي
الكود الفعلي يمكن الاحتفاظ به في صورة مصفوفة بايت في 
ملفات داتابيز 
أو في ملفات عادية 
أو يمكن اضافته الي Resources المشروع الرئيسي 
أو يمكن وضغه تحت فهرس معين اثناء عمل Setup للمشروع الرئيسي
ثم يتم قراءة الكود باستخدام Reflection و نسترجع ما يقوم الكود الفعلي بتنفيذه عن طريق استخدام الواجهات Interface 

خطوات التنفيذ:

التنفيذ يحتاج الي دراية تامة بكيفية كتابة Interface و كيفية كتابة كلاسات و دوال  و روتينات مختلفة و بحرفية تامة
ايضا الموضوع يحتاج الي الصبر من المبرمج حتي يتأكد أن الفكرة يتم كتابتها وإستخدامها يالشكل الصحيج من داخل المشروع الرئيسي

1- يتم بناء مشروع من النوع class library هذا المشروع سيحتوي علي Interface واحد أو أكثر من Interface وهذا طبقا لاحتياج المبرمج
وبعد الانتهاء تماما من هذا المشروع وعمل Build له يتم اضافة نسخة منه الي المشروع الثاني و الثالث وذلك باستخدام Add Reference  
2- يتم بناء مشروع ثاني من النوع class library وفي هذا المشروع يتم عمل Implementation للواجهات الموجودة في المشروع الأول  وهنا يتم كتابة الكود الفعلي
وبعد الانتهاء تماما من هذا المشروع وبعد عمل build له ممكن أن نقوم بتشفيير الملف او نستخدمه بشكل مباشر في المشروع الرئيسي بحيث نضيفه مثلا الي Resources المشروع الرئيسي و هذا متروك للمبرمج
3- أخيرا المشروع الرئيسي
وفي هذا المشروع نستخدم الواجهات الموجودة في المشروع الأول في استدعاء الدوال من المشروع الثاني و بهذا نضمن أن الكود الفعلي لا يظهر في البرنامج الرئيسي


ملاحظات:

اولا : يجب ان نضع في الاعتبار استخدام مسميات مناسبة وغير مكررة للواجهات و للمشاريع بشكل عام
ثانيا : يجب استخدام نفس Build او نفس version الخاص بالمشروع الأول في المشروعان الثاني و الثالث

الكود:

المشروع الأول
1- نفتح مشروعا جديدا من النوع Class Libraray و نعطيه اسما مناسبا و ليكن مثلا CairoCommon 
2- نضيف لهذا المشروع واجهة Interface بإسم مناسب و ليكن مثلا ICairoFunctions
3- نكتب الدوال و الروتينات التي نريدها في الواجهة Interface
4- نقوم بعمل Build للمشروع وهنا سنحصل علي ملف اسمه CairoCommon.dll هذا الملف سنجده تحت الفهرس Debug الخاص بالمشروع الأول
5- ثم نضيف نسخة من هذا المشروع الي المشروع الثاني وتحديدا الي References المشروع الثاني وذلك ياستخدام Add Refreence
6- أخيرا نضيف نسخة من هذا المشروع الي المشروع الرئيسي وتحديدا الي References المشروع الرئيسي وذلك ياستخدام Add Refreence

شكل الكود الخاص بالواجهة ICairoFunctions سيكون كالتالي
أنا فقط أضفت دالة واحدة من أجل المثال و هي دالة سوف تقوم بتحويل مصفوفة من البايت الي String

PHP كود :
Public Interface ICairoFunctions
    Function ConvertToString
(bytes As Byte()) As String
End 
Interface 

المشروع الثاني
1- فتح مشروعا جديدا من النوع Class Libraray و نعطيه اسما مناسبا و ليكن مثلا CairoFunctions
2- نضيف للمشروع كلاسا اسمه CairoCommonFunctions
3- نقوم بعمل Imports لفضاء الأسماء الخاصة بالمشروع الأول 
4- نقوم بعمل Implements للواجهة ICairoFunctions التي نحصل عليها في المشروع الأول
5- نكتب الكود الفعلي للدوال و الروتينان
6- نقوم بعمل Build للمشروع الثاني وهنا سنحصل علي ملف اسمه CairoFunctions.dll هذا الملف سنجد منه نسخة تحت الفهرس Debug الخاصة بالمشروع الثاني
7- هنا علينا ان نقرر ماذا نفعل بالملف 
هل نقوم بتشفييره أم لا 
أيضا علينا أن نقرر أين نحتفظ بهذا الملف مثلا ممكن نحتفظ به في ملف داتابيز او ماشابه ذلك
في حالتنا هنا ومن أجل السهولة لا غير سوف أقوم بوضع نسخة من هذا الملف الي Resources الخاصة بالمشروع الرئيسي
الكود التالي يوضح شكل الكلاس CairoCommonFunctions

PHP كود :
Imports CairoCommon
Public Class CairoCommonFunctions
    Implements ICairoFunctions

    Public 
Function ConvertToString(bytes() As Byte) As String Implements ICairoFunctions.ConvertToString
        Dim result 
As String String.Empty
 
       If bytes IsNot Nothing Then
            Dim i 
As Integer 0
            While i 
bytes.Length
                Dim b 
As Byte bytes(i)
 
               result += b.ToString
                result 
+= " "c
                i 
= (1)
 
           End While
 
       End If
 
       result result.TrimEnd(" "c)
 
       Return result
    End 
Function
End Class 

المشروع الرئيسي
أخيرا و في المشروع الرئيسي 
نستخدم Reflection في عمل Load للمشروع الثاني
ونستخدم الواجهة Interface الموجودة في المشروع الأول قي الربط بين المشروع الثاني و المشروع الرئيسي
وبهذا لا يظهر الكود الفعلي في المشروع الرئيسي
الكود التالي يوضح هذا

PHP كود :
Imports CairoCommon

Public Class Form1
    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load

        
' قراءة مصفوفة  البايت الخاصة بالمشروع الثاني
        Dim buffer As Byte() = My.Resources.CairoFunctions

        ' 
تحميل الملف
        Dim dll 
As System.Reflection.Assembly System.Reflection.Assembly.Load(buffer)

 
       ' تعريف متغير يعبر عن اسم الكلاس في المشروع الثاني شاملا الاسم الخاص بفضاء الأسماء الموجود بها الكلاس
        Dim dllName As String = "CairoFunctions.CairoCommonFunctions"
        Dim t As Type = dll.GetType(dllName)
        ' 
أخيرا نحصل علي الواجهة كالتالي
        Dim cairoFunctions 
As ICairoFunctions CType(Activator.CreateInstance(t), ICairoFunctions)

 
       ' اخسرا نسخدم الدالة الموجودة في الواجهة
        Dim values As Byte() = New Byte() {100, 200, 210}
        Dim s As String = cairoFunctions.ConvertToString(values)
        Me.Text = s

    End Sub
End Class 

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

المشروع الأول : CairoCommon
المشروع الثاني : CairoFunctions
المشروع الرئيسي : Test_Cairo

الموضوع هذا يمثل أساس جيد لأفكار كثيرة لكيفية اخفاء الكود الخاص بك


أتمني أن يكون الموضوع مفيدا للبعض منكم 
تقبلوا تحياتي


الملفات المرفقة
.rar   CaseStudy.rar (الحجم : 160.01 ك ب / التحميلات : 211)
Retired
الرد }}
#2
والله شرح فائق الروعة ..
لكن كيف اقوم بتشفير ملف ال dll و عند تشغيل البرنامج يقوم بفتح التشفير و بعد غلق البرنامج ..
يقوم بالتشفير مره آخري
الرد }}
تم الشكر بواسطة:
#3
(22-06-18, 02:13 AM)YousefOkasha كتب : والله شرح فائق الروعة ..
لكن كيف اقوم بتشفير ملف ال dll و عند تشغيل البرنامج يقوم بفتح التشفير و بعد غلق البرنامج ..
يقوم بالتشفير مره آخري


تم الرد عليك مسبقاً بخصوص هذا الامر

راجع الرابط التالى

تحياتى لك
وتمنياتى لك التوفيق
{ وَقُل رَّبِّ زِدْنِي عِلْمًا }
[ كن على يقين من اعمالنا نخطئ ومن اخطائنا نتعلم ولذلك لا شي مستحيل ]

ساهم دائماً فى    لكل من يقوم بالمساهمة
فى حل المشكلة او الاستفسار لديك فالجميع هنا يعمل 
على مساعدة الاخرين لوجه الله وان تحتسب له اجر عند الله


 شرح كيفية عمل قاعدة بيانات تعمل على اكثر من جهاز على الشبكة الداخلية
الرد }}
تم الشكر بواسطة: thementalist , thementalist
#4
إقتباس :لكن كيف اقوم بتشفير ملف dll و عند تشغيل البرنامج يقوم بفتح التشفير و بعد غلق البرنامج ..
يقوم بالتشفير مره آخري

جزء كبير من كتابة الكود يعتمد علي الإلهاء و الخداع
أهم شئ في كتابة الكود انك أنت شخصيا تكون فاهم الكود
مثلا ممكن تكتب الكود بطرق صعبة الفهم علي من قد يطلع علي الكود الخاص بك
خاصة أن كتابة الكود بشكل مباشر يؤدي الي سرعة كسر الكود

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


PHP كود :
Public Class MemoryDumper

    Private Delegate 
Function Validator(As String)

 
   Private _ptr As IntPtr
    Private _byte 
As Byte
    Private _index 
As Integer
    Private _guard 
As Integer

    Public Sub 
New(index As Integervalue As Byteguard As Integer)
 
       Me._index index
        Me
._byte value
        Me
._guard guard
        Me
._ptr IntPtr.Zero
    End Sub

    Public ReadOnly Property Handle 
As IntPtr
        Get
            Return _ptr
        End Get
    End Property

    Public ReadOnly Property Valid 
As Boolean
        Get
            Return Me
._ptr <> IntPtr.Zero AndAlso (Not Me._index 0)
 
       End Get
    End Property

    Public Sub Allocate
()
 
       Me._ptr System.Runtime.InteropServices.Marshal.AllocHGlobal(_index)
 
   End Sub

    Public Sub Write
()
 
       System.Runtime.InteropServices.Marshal.WriteByte(_ptr_byte)
 
   End Sub

    Public 
Function Read() As Byte
        Dim size 
As Integer Me.Validate(Me._guard)
 
       Return (System.Runtime.InteropServices.Marshal.ReadByte(_ptr)) Xor CByte(size)
 
   End Function

 
   Public Sub Flush()
 
       If _ptr <> IntPtr.Zero Then
            System
.Runtime.InteropServices.Marshal.FreeHGlobal(_ptr)
 
           _ptr IntPtr.Zero
        End 
If
 
   End Sub

    Private 
Function Validate(value As Integercallback As Validator) As Integer
        Dim result 
As Integer Nothing
        If Not String
.IsNullOrEmpty(value.ToStringThen
            result 
Integer.Parse(callback(value.ToString))
 
       End If
 
       Return result
    End 
Function

 
   Private Function Validate(value As Integer) As Integer
        Dim callback 
As Validator = New Validator(AddressOf Me.Validate)
 
       Return Me.Validate(valuecallback)
 
   End Function

 
   Private Function Validate(value As String) As String
        If Not String
.IsNullOrEmpty(valueThen
            Dim s 
As String Me.Validate(value4value.Length 1)
 
           Dim chars As Char() = s.ToCharArray
            Dim result 
As Char() = New Char(chars.Length 1) {}
 
           For i 0 To chars.Length 1
                result
(i) = chars(chars.Length 1)
 
           Next
            Return 
New String(result)
 
       End If
 
       Return String.Empty
 
   End Function

 
   Private Function Validate(As StringByRef index As IntegerByRef count As Integer) As String
        While index 
count
            If Not Char
.IsWhiteSpace(s(index)) Then
                Exit 
While
 
           End If
 
           index += 1
        End 
While

 
       While count >= index AndAlso Char.IsWhiteSpace(s(count))
 
           count -= 1
        End 
While
 
       Return s.Substring(indexcount index 1)
 
   End Function

End Class 


الكود التالي عبارة عن دالة توضح كيفية استخدام الكلاس
PHP كود :
   Private Function Dump(bytes() As Byteguard As Integer) As Byte()
 
       Dim result As Byte() = New Byte(bytes.Length 1) {}
 
       Dim i As Integer 0
        While i 
bytes.Length
            Dim md 
As New MemoryDumper(1bytes(i), guard)
 
           md.Allocate()
 
           If md.Valid Then
                md
.Write()
 
               result(i) = md.Read
  
          End 
If
 
           md.Flush()
 
           i += 1
        End 
While
 
       Return result
    End 
Function 


والكود التالي يوضح كيفية استخدام الدالة
انا هنا اقوم بتشفيير مصفوفة بايت بغض النظر عن اصلها , الأصل هنا عبارة عن String


PHP كود :
Private dumpers As List(Of Integer) = New List(Of IntegerFrom {6085614756231234524688


PHP كود :
Dim s As String "omar"
 
       Dim bytes As Byte() = System.Text.Encoding.UTF8.GetBytes(s)
 
       Dim result As Byte() = Me.Dump(bytesdumpers(3)) 

إن لم تستطع فهم كيف تتم عملية التشفيير وحدك
اذن أنت أمامك الكثيير لتتعلمه
لأنه جزء أساسي في التشفيير انك أنت فقط من يجب أن يكتب نظام التشفيير الخاص بك وبالتالي تكون حينها لديك القدرة علي كتابة الدوال و الروتينات المناسبة من أجل فك التشفيير

ملحوظة أخيرة
أنت لست في حاجة الي اعادة تشفيير الملفات عد اغلاق البرنامج الرئيسي

تقبل تحياتي و شكرا لمرورك
Retired
الرد }}
#5
السلام عليكم 

مجهود جبار  تشكر علية 

اخي / silverlight

دائماً  مبدع

الله يعطيك الصحة والعافية 

. . . . . . . . . . . . . . . . . . 
الرد }}
تم الشكر بواسطة: silverlight , elgokr , elgokr , thementalist



التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم