File Signature
هذا الموضوع الهدف منه توضيح ماهية File Signature الخاصة بجميع الملفات الشهيرة و المعروفة لنظام التشغيل في جهاز الكمبيوتر
ماذا تعني كلمة File Signature
هو عبارة عن خليط من حروف و
أرقام يتم إضافتها في بداية الملف ومن خلاله تستطيع
تحديد هوية الملف و هذا الخليط من الحروف و الأرقام يعمل بمثابة ختم أو Stamp للملف ومنه
يستطيع نظام التشغيل Operating System الموجود
علي جهاز الكمبيوتر الخاص بك
تحديد نوعية البرنامج الذي يصلح لفتح الملف
بشكل عام هذا الخليط من الأرقام و
الحروف يتم كتابته الي الملف علي هيئة بايت Byte أيضا هذا
الخليط غالبا له قيمة ثابتة و في بعض الأحيان تقوم الشركات بتغيير قيمة هذا الخليط طبقا لإحتياجاتها وأيضا كل
شركة شهيرة من شركات الكمبيوتر تستخدم قيمة خاصة
بها حسب نوعية الملفات
وكمثال توضيحي للفكرة لنفترض أنك قمت بتشغيل
برنامج Paint ثم فتحت ملف
جديد من خلال البرنامج و سواء رسمت أو لم ترسم شيئا في الملف ثم قمت بحفظ الملف هنا يقوم برنامج Paint بإضافة قيمة معينة وهذه القيمة ممثلة في الحرفان BM ويتم اضافة هذان الحرفان في بداية الملف بحيث يعمل هذان الحرفان بمثابة التوقيع لهذا الملف و يحلو للبعض أن يطلق علي
هذه القيمة اسم File Signature و البعض الأخر يحلو له أن يطلق عليها الإسم
Magic Number أيضا هناك بعض الشركات قد تضيف هذه القيمة
إما في نفس الملف أو تضيفها
في ملف أخر منفصل
و لكي تتأكد مما أقول
حاول أن تفتح أي ملف يكون امتداه BMP بأي برنامج Hex Editor وحينها ستري شئ مشابه للصورة الموجودة أدناه
ما هي فوائد File Signature
من خلاله يتم تحديد نوع الملف حتي و إن كان الملف لم يكن له أي امتداد
من خلاله يتم تحديد نوع البرنامج الذي يصلح لفتح الملف
من خلاله يتم ربط البرنامج مع الملفات التي لها نفس
الامتداد وهذا الامر مفيد في عمل امتداد خاص ببرنامجك
من خلاله قد تستطيع من تحديد معرفة اسم الشركة المنتجة
للملف
طبعا ربما هناك فوائد أخري و الأمر هنا متروك لمخيلة القارئ للتفكير في فوائد أخري أو التفكير في كيفية اإستفادة من هذا الموضوع في برامجه الخاصة.
الكود
كمثال لنأخذ الملفات التي من النوع PDF وهي ملفات شهيرة و معروفة للجميع و قيم File Signature الخاص بهذا النوع من الملفات تم أخذها من أحد المواقع الشهيرة علي النت و هو موقع WIKI و تم كتابة البيانات علي هيئة كود من اجل التوضيح فقط
Dim pdf_Extension As String = "pdf"
Dim pdf_Description As String = "PDF document"
Dim pdf_Offset As Integer = 0
Dim pdf_Ascii As String = "%PDF"
Dim pdf_HeStrings As String = "25 50 44 46"
بشكل
عام لو حاولت تحويل المتغير
pdf_Ascii من String الي
HexString ستجد أن الناتج يساوي قيمة المتغير
pdf_HexString والكود
التالي يوضح ذلك
Dim sb As New System.Text.StringBuilder
For Each c As Char In pdf_Ascii
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0:X} ", Convert.ToByte(c))
Next
Me.Text = sb.ToString
عموما
يجب أن لا تعتمد كثيرا علي هذا الأسلوب في تحويل البيانات لأننا ستكتشف ان بعض الملفات قد
لا تلتزم بنفس منهج تحويل المتغيرات عند كتابة
File Signature الي الملف كمثال علي ذلك الملفات من النوع PNG
Dim png_Extension As String = "png"
Dim png_Description As String = "Image encoded in the Portable Network Graphics format"
Dim png_Offset As Integer = 0
Dim png_Ascii As String = ".PNG...."
Dim png_HeStrings As String = "89 50 4E 47 0D 0A 1A 0A"
Dim sb As New System.Text.StringBuilder
For Each c As Char In png_Ascii
sb.AppendFormat(System.Globalization.CultureInfo.InvariantCulture, "{0:X} ", Convert.ToByte(c))
Next
Me.Text = sb.ToString
لذلك
لا تنخدع أو لا تتسرع و تقوم بتحويل البيانات عن طريق كتابة دالة لتحويل
الحروف التي تخص File
Signature ASCII الي Hex
String لأنك
قد تحصل علي شئ مختلف أحيانا
ملحوظة هامة
هناك حالات قد تجد
أكثر من قيمة لنفس النوع من الملفات علي سبيل المثال الملفات من النوع CAB لها قيمتان و أيضا الملفات من النوع GIF لها قيمتان أيضا
مثلا الملفات التي
إمتدادها ينتهي بالحروف CAB والخاصة بشركة مايكروسوفت سنجد أن
قيمة File Signature الخاص بها كالتالي
Dim cab_MS_Extension As String = "cab"
Dim cab_MS_Description As String = "Microsoft cabinet file"
Dim cab_MS_Offset As Integer = 0
Dim cab_MS_Ascii As String = "MSCF"
Dim cab_MS_HeStrings As String = "4D 53 43 46"
بينما
نفس الملفات و التي هي من انتاج البرنامج الشهير
Install Shield سنجد أن القيمة لها كالتالي
Dim cab_InstallShield_Extension As String = "cab"
Dim cab_InstallShield_Description As String = "Install Shield compressed file"
Dim cab_InstallShield_Offset As Integer = 0
Dim cab_InstallShield_Ascii As String = "ISc("
Dim cab_InstallShield_HeStrings As String = "49 53 63 28"
مثال أخر الملفات من
النوع GIF لها قيمتان القيمة الأولي كالتالي
Dim gif87a_Extension As String = "gif"
Dim gif87a_Description As String = "Image file encoded in the Graphics Interchange Format"
Dim gif87a_Offset As Integer = 0
Dim gif87a_Ascii As String = "GIF87a"
Dim gif87a_HeStrings As String = "47 49 46 38 37 61"
والقيمة الثانية
للملفات من النوع GIF كالتالي
Dim gif89a_Extension As String = "gif"
Dim gif89a_Description As String = "Image file encoded in the Graphics Interchange Format"
Dim gif89a_Offset As Integer = 0
Dim gif89a_Ascii As String = "GIF89a"
لذلك وعند التأكد من File Signature الخاص بالملفات والتي لها أكثر من Signature يجب علينا دائما أن نتأكد من
جميع القيم كما في حالة الملفات التي لها امتداد GIF يجب هنا ان نتأكد من القيمتان معا
مثال أخر الملفات المضغوطة من النوع RAR لها قيمتان أحدهما تعبر عن الملفات من النسخة Version 1.5 حتي النسخة Version 5 من نفس البرنامج ثم من النسخة Version 5 فيما فوق لها رقم اخر
للأسف وكما تلاحظون أن File Signature هذا غير ثابتة القيمة وقد يتم تغيير تلك القيمة لأي أسباب بواسطة الشركات المنتجة للملفات لذلك و عند التأكد من قيمة File Signature يجب دوما ان نراعي اي تعديلات تقوم بها الشركات المختلفة
مثال أخر الملفات المضغوطة من النوع RAR لها قيمتان أحدهما تعبر عن الملفات من النسخة Version 1.5 حتي النسخة Version 5 من نفس البرنامج ثم من النسخة Version 5 فيما فوق لها رقم اخر
للأسف وكما تلاحظون أن File Signature هذا غير ثابتة القيمة وقد يتم تغيير تلك القيمة لأي أسباب بواسطة الشركات المنتجة للملفات لذلك و عند التأكد من قيمة File Signature يجب دوما ان نراعي اي تعديلات تقوم بها الشركات المختلفة
كيف نقرأ قيمة File Signature
الخطوات
التالية توضح الكيفية
أولا: نحتاج الي حفظ جميع المعلومات عن الملف علي هيئة داتا بيز وهذه المعلومات يتم تجميعها من المواقع المختلفة علي النت أو بأي صورة تجدها مناسبة لك و ما يهمني هنا من تلك البيانات التي يتم تجميعها هي قيمة المتغير HexString الخاصة بكل نوع من الملفات
ثانيا: نقوم بتحويل البيانات الخاصة بالمتغير HexString الي مصفوفة Byte
ثالثا: نقوم بقراءة الملف المطلوب التاكد من Signature الخاص به الي Stream
رابعا: نقوم بقراءة Header الخاص بالملف وهو هنا عبارة عن مصفوفة من Byte
خامسا: نقارن بين تلك القيمة التي نقرأها من File Header مع قيمتها الموجودة في الداتا بيز الخاصة بالملفات فإن تساوت القيمتان هنا نستطيع تحديد نوع الملف
طبعا الكلام النظري قد يكون غير مفهوم قليلا للبعض لذلك لنقوم بصياغته بشكل عملي و تحويله الي أكواد و سنأخذ الملفات من النوع PDF كمثال
أولا: نحتاج الي حفظ جميع المعلومات عن الملف علي هيئة داتا بيز وهذه المعلومات يتم تجميعها من المواقع المختلفة علي النت أو بأي صورة تجدها مناسبة لك و ما يهمني هنا من تلك البيانات التي يتم تجميعها هي قيمة المتغير HexString الخاصة بكل نوع من الملفات
ثانيا: نقوم بتحويل البيانات الخاصة بالمتغير HexString الي مصفوفة Byte
ثالثا: نقوم بقراءة الملف المطلوب التاكد من Signature الخاص به الي Stream
رابعا: نقوم بقراءة Header الخاص بالملف وهو هنا عبارة عن مصفوفة من Byte
خامسا: نقارن بين تلك القيمة التي نقرأها من File Header مع قيمتها الموجودة في الداتا بيز الخاصة بالملفات فإن تساوت القيمتان هنا نستطيع تحديد نوع الملف
طبعا الكلام النظري قد يكون غير مفهوم قليلا للبعض لذلك لنقوم بصياغته بشكل عملي و تحويله الي أكواد و سنأخذ الملفات من النوع PDF كمثال
المرحلة الأولي
' تجميع المعلوامت و البيانات الخاصة بالملف
' ------------------------------------------------تحميع المعلومات عن الملف-----------------------------------
' Adobe PDF File data, collected form WIKI site
Dim pdf_Extension As String = "pdf"
Dim pdf_Description As String = "PDF document"
Dim pdf_publisher As String = "Adobe"
Dim pdf_Offset As Integer = 0
Dim pdf_Ascii As String = "%PDF"
' PDF file signature string
Dim pdf_Sig As String = "25 50 44 46"
' convert PDF File Signature string to hex values
Dim pdf_hexValues As Integer() = New Integer() {&H25, &H50, &H44, &H46}
' المرحلة الثانية
' ---------------------------------------------------Cnvert PDF File hex values to bytes-------------------------
' هذا هو الجزء الذي يهمنا جدا معرفته عن الملف
Dim pdf_bytes As Byte() = New Byte() {37, 80, 68, 70}
' المرحلة الثالثة
' ------------------------------ تعريف و قراءة الملف الموجود علي الكمبيوتر ------------------------------------
' define the location of PDF File
' تم اضافة الملف لفهرس المشروع للإختبار فقط لا غير
Dim filePath As String = ".\Chart.pdf"
' convert the PDF file to stream
Dim dataStream As New IO.FileStream(filePath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
' المرحلة الرابعة
' ----------------------------------------Read File Header--------------------------------------------------------
Dim capacity As Integer = 8
Dim bytes As Byte() = New Byte(capacity - 1) {}
Dim position As Long = dataStream.Position
dataStream.Seek(0, IO.SeekOrigin.Begin)
Dim i As Integer = 0
While i < capacity
pdf_Offset = dataStream.Read(bytes, pdf_Offset, capacity - i)
If pdf_Offset <= 0 Then
Exit While
End If
i += pdf_Offset
End While
' المرحلة الخامسة
'----------------------------- مقارنة المصفوفات ------------------------------------------------------------------
' compare byte arrays
Dim isEqualSig As Boolean = True
If bytes.Length < pdf_bytes.Length Then
isEqualSig = False
End If
For j As Integer = 0 To pdf_bytes.Length - 1
If bytes(j) <> pdf_bytes(j) Then
isEqualSig = False
End If
Next
' المرحلة الأخيرة التأكد من النتائج
' -----------------------------------------------------------------------------------------------------------------
' لو كانت المصفوفتان متساويتان
If isEqualSig Then
' do something
MessageBox.Show(" The File is Adobe PDF File", "Info")
Else
' do something
MessageBox.Show(" The File is NOT Adobe PDF File", "Info")
End If
بالطبع
و من الأفضل تحويل الكود أعلاه الي كلاسات تحتوي علي دوال و اجراءات حتي نستطيع
التعامل مع جميع الملفات المعروفة
كمثال الكود
التالي يوضح شكل الدالة التي من الممكن استخدامها لتحويل بعض البيانات من مصفوفة
من النوع Integer الي مصفوفة من النوع Byte Private Function ToBytes(hexValues As Integer()) As Byte()
Dim bytes As List(Of Byte) = New List(Of Byte)()
For Each i As Integer In hexValues
bytes.Add(System.Convert.ToByte(i))
Next
Return bytes.ToArray
End Function
مثال أخر الكود التالي
يوضح شكل الدالة التي من الممكن استخدامها لقراءة الملف المراد تحديد File Signature الخاص به و تحويله الي Stream
Public Function FileToStream(filePath As String) As IO.FileStream
Dim result As IO.FileStream = Nothing
Try
result = New IO.FileStream(filePath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Catch ex As Exception
End Try
Return result
End Function
مثال أخر الكود التالي
يوضح شكل الدالة التي من الممكن استخدامها للمقارنة بين مصفوفة File Signature والمصفوفة التي نقرأهت من File Header الخاصة بالملف
'''
'''
compare signature
'''
''' <param name="leftSig">represents the file header byte array</param>
''' represent the file signature byte array collected from internet
''' <returns></returns>
Public Function IsSignaturesAreEqual(leftSig As Byte(), rightSig As Byte()) As Boolean
If leftSig.Length < rightSig.Length Then
Return False
End If
For i As Integer = 0 To rightSig.Length - 1
If leftSig(i) <> rightSig(i) Then
Return False
End If
Next
Return True
End Function
لمزيد من التفاصيل عن File Signature يمكنكم زيارة الروابط التالية و الاستفادة من المعلومات الموجودة بها
Comments
Post a Comment