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

كلمة Stegnography في مجال البرمجة هي علم أو فن إخفاء المعلومات او البيانات
و في هذا الموضوع سنوضح كيفية اخفاء البيانات و لكن برؤية مختلفة فليلا
وفي النهاية الأمر كله عبارة عن وجهة نظر شخصية

الهدف من الموضوع:

1- إثراء المنتدي بمحاولة عرض موضوعات غير تقليدية وهذا قد يساعد علي جذب المزيد من القراء و الأعضاء للمنتدي
2- طرح موضوعات قد تهم المبرمج العربي في كتابة برامج أفضل

الفكرة:

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

لكن هنا سأطرح فكرة كيفية انشاء الصورة التي تستوعب المعلومات ومن ثم يمكن اخفاء المعلومات بها

خطوات تنفيذ الفكرة:

1- الحصول علي البيانات في صورة مصفوفة بايت
    و البيانات هنا قد تكون صورة او ملف او تكست او ارقام ....الخ
2- التعامل مع تلك المصفوفة و تحويلها الي مصفوفة أخري أو يمكن اعتبارها مصفوفة ألوان او مصفوفة بايت
3- حساب أبعاد الصورة التي تستوعب مصفوفة الألوان
4- بناء الصورة التي نحفظ بها مصفوفة الألوان

تنفيذ الفكرة:
لنفترض اننا نريد إخفاء تكست في صورة
اول شئ نفعله هو تعريف متغير يغبر عن تكست 

PHP كود :
Dim txt As String "visual basic for Arab, Hi ..... World" 
ثانيا تخويل التكست الي مصفوفة بايت 

PHP كود :
Dim txtBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(txt
ثالثا نأتي الي اهم شئ في تنفيذ الفكرة و هو تحويل هذه المصفوفة الي مصفوفة ألوان
او تحويلها الي مصفو فة بايت بحيث كل اربعة بايت يساوي لون معين
ويمكن تنفيذ ذلك باستخدام دالة مثل هذه

PHP كود :
   Public Iterator Function GetRawBytes(bytes As Byte(), Optional alpha As Byte 128) As IEnumerable(Of Byte)
 
       Dim i As Integer 0
        While i 
bytes.Length
            Yield bytes
(i)
 
           Yield bytes(i)
 
           Yield bytes(i)
 
           Yield alpha
            i 
+= 1
        End 
While
 
       Return
    End 
Function 
وإن كنت لا تريد استخدام Yield
يمكن استخدام دالة مثل هذه

PHP كود :
   Private Function ToRawData(values As Byte(), size As IntegerOptional baseValue As Byte 128) As Byte()
 
       Dim result As Byte() = New Byte(((values.Length size)) - 1) {}
 
       Dim i As Integer 0
        While i 
values.Length
            Dim items 
As Byte() = New Byte(size 1) {}
 
           Dim j As Integer 0
            While j 
size
                items
(j) = values(i)
 
               j += 1
            End 
While
 
           Dim newItems As Byte() = New Byte(items.Length 1) {}
 
           items.CopyTo(newItems1)
 
           newItems(0) = baseValue
            System
.Buffer.BlockCopy(newItems0result, (size), size)
 
           i += 1
        End 
While

 
       Return result
    End 
Function 
أو يمكن استخدام دالة مثل هذه لتكرار البيانات

PHP كود :
  Private Function ToRawData(values As Byte(), size As Integer) As Byte()
 
       Dim result As Byte() = New Byte(((values.Length size)) - 1) {}
 
       Dim i As Integer 0
        While i 
values.Length
            Dim items 
As Byte() = New Byte(size 1) {}
 
           Dim j As Integer 0
            While j 
size
                items
(j) = values(i)
 
               j += 1
            End 
While

 
           System.Buffer.BlockCopy(items0result, (size), size)
 
           i += 1
        End 
While

 
       Return result
    End 
Function 


مثال توضيحي صغير
لنفترض اننا نريد تحويل الخرف "A" الي مصفوفة بايت '
ملحوظة:
طبعا التعامل مع الحروف العربية يختلف قليلا عن التعامل مع الحروف الانجليزية
حيث أن كل حرف عربي وعند تحويله الي مصفوفة بايت فإن كل حرف يعادل 2 بايت و ليس  بايت واحد كما في اللغة الانجليزية

PHP كود :
      Dim a As Char "A"c
        Dim b 
As Byte CByte(AscW(a))
 
       Dim bytes As Byte() = New Byte() {b

ما يجب أن نفعله هو ان نحول مصفوفة البايت للحرف "A" لتكون كالتالي

PHP كود :
Dim colors As Byte() = New Byte() {bbbb
أي اننا و ببساطة شديدة ناخذ قيمة اي بايت و نضاعفها اربعة مرات
او يمكن ان نجعلها كالتالي

PHP كود :
       Dim alpha As Byte 128
        Dim colors 
As Byte() = New Byte() {alphabbb

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

أخيرا حساب أبعاد الصورة

يتم حساب أبعاد الصورة من المعادلة التالية

bytes length =  ( Width in pixels × height in pixels × colour depth ) /8

حيث أن
width           = عرض الصورة
height          = طول الصورة
image pixel format  = pixel format
نصيحة يجب تثبيت قيمةالبكسل فورمات و اجعل هذه القيمة تساوي 32 دائما
يجب ان نضع في اعتبارنا ان اكبر Length لمصفوفة الألوان يجب ان لا يتعدي القيمة (2^32 = 4294967296)

الأن لنكتب الكود كاملا


PHP كود :
       Dim txt As String "visual basic for Arab, Hi ..... World"
 
       Dim txtBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(txt)
 
       Dim colorbytes As Byte() = ToRawData(txtBytes4)

 
       ' حساب ابعاد الصورة
        ' 
نفترض ان طول الصورة يساوي عرض الصورة

        Dim colorDepth 
As Integer 32
        Dim length 
As Long CLng(colorbytes.Length 1)
 
       Dim w As Double Math.Sqrt(length colorDepth

انشاء الصورة و حفظها


كود :
' أخيرا نيني الصورة
       Dim bmp As Bitmap = BytesToBitmap(colorbytes, CInt(w + 1), CInt(w + 1))

       bmp.Save(".\txtImage.jpg")

يمكن استخدام الدالة التالية لتحويل مصفوفة بايت الي صورة

PHP كود :
  Private Function BytesToBitmap(buffer() As Bytewidth As Integerheight As Integer) As Drawing.Bitmap
        Dim bmp 
As New System.Drawing.Bitmap(widthheight)
 
       Dim data As Imaging.BitmapData bmp.LockBits(New Rectangle(00bmp.Widthbmp.Height), Imaging.ImageLockMode.WriteOnlyImaging.PixelFormat.Format32bppArgb)
 
       Runtime.InteropServices.Marshal.Copy(buffer0data.Scan0buffer.Length)
 
       bmp.UnlockBits(data)
 
       Return bmp
    End 
Function 



الكود كاملا

PHP كود :
Public Class Form1
    Private Sub Form1_Load
(sender As ObjectAs EventArgsHandles MyBase.Load
        Dim txt 
As String "visual basic for Arab, Hi ..... World"
 
       Dim txtBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(txt)
 
       Dim colorbytes As Byte() = ToRawData(txtBytes4)

 
       ' حساب ابعاد الصورة
        ' 
نفترض ان طول الصورة يساوي عرض الصورة

        Dim colorDepth 
As Integer 32
        Dim length 
As Long CLng(colorbytes.Length 1)
 
       Dim w As Double Math.Sqrt(length colorDepth)

 
       ' أخيرا نيني الصورة
        Dim bmp As Bitmap = BytesToBitmap(colorbytes, CInt(w + 1), CInt(w + 1))

        bmp.Save(".\txtImage.jpg")
    End Sub

    Private Function ToRawData(values As Byte(), size As Integer) As Byte()
        Dim result As Byte() = New Byte(((values.Length * size)) - 1) {}
        Dim i As Integer = 0
        While i < values.Length
            Dim items As Byte() = New Byte(size - 1) {}
            Dim j As Integer = 0
            While j < size
                items(j) = values(i)
                j += 1
            End While

            System.Buffer.BlockCopy(items, 0, result, (i * size), size)
            i += 1
        End While

        Return result
    End Function

    Private Function BytesToBitmap(buffer() As Byte, width As Integer, height As Integer) As Drawing.Bitmap
        Dim bmp As New System.Drawing.Bitmap(width, height)
        Dim data As Imaging.BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), Imaging.ImageLockMode.WriteOnly, Imaging.PixelFormat.Format32bppArgb)
        Runtime.InteropServices.Marshal.Copy(buffer, 0, data.Scan0, buffer.Length)
        bmp.UnlockBits(data)
        Return bmp
    End Function

End Class 

أتمني أن الموضوع يكون مفيدا للبعض منكم
Retired
الرد }}}
تم الشكر بواسطة: ابو ليلى , محمد كريّم
#2
في المشاركة السابقة تم توضيح كيفية تحويل مصفوفة بايت الي صورة
وفي هذا الجزء من الموضوع سأوضح كيفية استرداد البيانات من الصورة

استرداد البيانات:  

استرجاع البيانات عملية بسيطة و تتلخص في الخطوات التالية:
1- نقرأ الصورة
2- تحويل الصورة الي مصفوفة بايت
3- التعامل مع مصفوفة البايت و استرجاع المعلومات منها

ملحوظة :
في الصور بشكل عام فإن مصفوفة البايت او مصفوفة الألون يتم تخزينها بالشكل {Red Green Blue Alpha} 
لذلك قمت بتعديل بسيط علي الكود السابق حتي اقوم بتحويل كل بايت منفردة الي مصفوفة صغيرة بالشكل  {Red Green Blue Alpha}

الكود:
1- نقرأ الصورة التي تم تخزينها بأي طريقة تريدها

PHP كود :
       Dim file As String ".\stegnoText.jpg" 



PHP كود :
       Dim img As Bitmap Image.FromFile(file


2- باستخدام الدالة التالية نقوم بتحويل الصورة الي مصفوفة بايت

PHP كود :
   Private Function ConvertBitmapToBytes(bmp As Bitmap) As Byte()
 
       Dim data As Imaging.BitmapData bmp.LockBits(New Rectangle(00bmp.Widthbmp.Height), Imaging.ImageLockMode.ReadOnlyImaging.PixelFormat.Format32bppArgb)
 
       Dim buffer As Byte() = New Byte(data.Stride data.Height 1) {}
 
       Runtime.InteropServices.Marshal.Copy(data.Scan0buffer0buffer.Length)
 
       bmp.UnlockBits(data)
 
       Return buffer
    End 
Function 

نحصل علي مصفوفة البايت او مصفوفة الألوان

PHP كود :
Dim buffer As Byte() = ConvertBitmapToBytes(img


لو حاولت ان تفتخ الصورة التي تم بناؤها مسبقا في الجزء الأول بأي برنامج للصور
ستلاحظ ان الصورة بها منطقة بيضاء هذه المنطقة كل بكسل فيها عبارة عن {0 0 0 0} وتلك القيم تعبر عن الجزء الخالي من ألوان في الصورة
لذلك كل ما نحتاجه هو ان نقوم بعمل Loop و نفرأ الألوان التي لها قيمة اكبر من صفر
أو نقرا الألوان التي قيمة Alpha أكبر من صفر
أو نقرأ قيمة الألوان التي لها قيمة Alpha محددة أي نحن قمنا بتحديدها عند بناء الصورة

أحد الأفكار لتنفيذ الكود ستكون كالتالي
PHP كود :
       Dim toRawData As List(Of Byte) = New List(Of Byte)()
 
       Dim i As Integer 0
        
' loop thru byte array and read color values with non zero alpha
        While i < buffer.Length
            Dim alpha As Byte = buffer(i + 3)
            If alpha = 255 Then
                toRawData.Add(buffer(i))
            End If
            i += 4
        End While 

و بما أن مصفوفة البايت الأصلية التي تم تخزينها في الجزء الأول من الموضوع هي عبارة عن مصفوفة بايت خاصة ب تكست
هنا يتبقي فقط تحويل تلك المصفوفة الي تكست مرة ثانية
والكود التالي يوضح ذلك
PHP كود :
     Dim result As String System.Text.Encoding.UTF8.GetString(toRawData.ToArray()) 

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

ملحوظة أخيرة 
تمرين بسيط للقارئ : حاول ان تقرأ ملف dll و تحوله الي صورة لتري ماذا سيحدث معك

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

الكود كاملا بالمرفقات


الملفات المرفقة
.rar   Test_Stegnography_vb4Arab.rar (الحجم : 63.97 ك ب / التحميلات : 44)
Retired
الرد }}}
تم الشكر بواسطة: محمد كريّم , sendbad100 , sniperjawadino , ابو ليلى



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


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