#_Trong forum có cái software do bác Hiếu và NMG : FileInfo viết bằng VC++/API dùng để nhận biết một file có đuôi thực là gì nên mình cũng mạo muội làm thử một ví dụ mới học được viết = C#

_Mỗi loại file đều có một cấu trúc đặc trưng để nhận dạng tại đoạn đầu Bây giờ để nhận dạng thì đơn giản kiểm tra cấu trúc của một file có thỏa mãn cấu trúc đó không thôi

_Làm luôn một chú nha. thí nghiệm anh .exe ^^. Mà cái loại exe này mình biết có 2 phát là .exe Win32 PE và .exe .NET assembly <có gì sai pro sửa hộ em>
-> Bây giờ em muốn nhận biết thằng cu .exe .NET Assembly (tớ khoái công nghệ .NET của anh Gates ) thì làm thế nào ? (nếu kiểm tra không phải thằng này thì nó là thằng kia thôi )
< Vào MSDN download cái này về : ECMA Specifications Partition II – Metadata ... Để làm gì ? - Để xem cấu trúc PE của cu .exe .NET Asm thế nào >

__Trích ra một đoạn trong đó nè :
a separate CLI Header in the PE Format. It is the 15th data directory in the PE Optional Headers.
--> vậy thì kiểm tra đến vị trí thứ 15 của PE OH , nếu nó = 0 thì không phải là .exe .NET asm rồi.
==>> CODE nha ^^

Visual C# Code:
  1. private void GetHeaders()
  2. {
  3.     uint peHeader;
  4.     uint peHeaderSignature;
  5.     ushort machine;
  6.     ushort sections;
  7.     uint timestamp;
  8.     uint pSymbolTable;
  9.     uint noOfSymbol;
  10.     ushort optionalHeaderSize;
  11.     ushort characteristics;
  12.     ushort dataDictionaryStart;
  13.  
  14.     uint[] dataDictionaryRVA = new uint[16] ;
  15.     uint[] dataDictionarySize = new uint[16];
  16.     // Đọc file dưới dạng Bin : file có tên : Test.exe
  17.     Stream fs = new FileStream(@"D:\Test.exe", FileMode.Open, fileAccess.Read);
  18.      BinaryReader reader = new BinaryReader(fs);
  19.      //PE Header luôn bắt đầu tại vị trí 60 (0x3C) kích thước 4 byte
  20.      fs.Position = 0x3C; // Lấy vị trí header luôn tại đây
  21.      peHeader = reader.ReadUInt32();
  22.      //Chuyển tới vị trí khởi tạo của PE Header
  23.      fs.Position = peHeader;
  24.      peHeaderSignature = reader.ReadUInt32();
  25.      machine = reader.ReadUInt16();
  26.      sections = reader.ReadUInt16();
  27.      timestamp = reader.ReadUInt32();
  28.      pSymbolTable = reader.ReadUInt32();
  29.      noOfSymbol = reader.ReadUInt32();  
  30.      optionalHeaderSize = reader.ReadUInt16();
  31.      characteristics = reader.ReadUInt16();
  32. /*
  33. Kết thúc phần đầu khai báo và thông tin của PE rùi
  34. Đoạn này thì PE OH (Optional Header) xuất hiện đây...
  35.       To go directly to the datadictionary, we'll increase the      
  36. Giờ thì đi luôn vào trong cái "datadictionary" nha , bây giờ nhẩy luôn đến vị trí 96 ( 0x60 ). Tại sao thế nhỉ ? (:-)??
  37. 28 byte đầu là các trường cơ bản -> bỏ qua . Kiểm tra tiếp tốn mem
  38. 68 byte tiếp là các trường đặc biệt cho hệ NT -> bỏ qua luôn,có xài NT đâu :D
  39. => Tổng cộng là 96 byte.
  40. Bây giờ là đoạn gốc của DataDictionary...có tất cả 128 byte , trong tổng số 16 nhóm directories.
  41. Làm phép tính đơn giản : 128/16 = 8
  42. Thế thì mỗi Directory có 8 byte -> Check thế này quét byte cho nhanh chứ quét từ đầu tồn mem thêm :D
  43. Chú ý lun : trong 8 byte đó thì 4 byte đầu là RVA ( nhớ ảo ) còn 4 byte sau là kich thước.
  44. Vậy thôi, việc bây giờ là kiểm tra thằng số 15 chứa CLR header, nếu mà = 0 thì nó không chứa, nếu chứa thì != 0 .
  45. À quên , 1 file .NET asm thì tại vị trí Dir 15 nó có CLR đó khi load vào OS . */
  46.            
  47. // Lấy vị trí
  48. dataDictionaryStart = Convert.ToUInt16 (Convert.ToUInt16 (fs.Position) + 0x60);          
  49. fs.Position = dataDictionaryStart;
  50.             // Lấy thông tin tất cả Dir
  51.             for (int i = 0; i < 15; i++)
  52.             {
  53.                 dataDictionaryRVA[i] = reader.ReadUInt32();
  54.                 dataDictionarySize[i] = reader.ReadUInt32();
  55.             }
  56.             // Quan trọng đây :D  : Kiểm tra thằng số 15 có = 0 hay != 0
  57.             if (dataDictionaryRVA[14] == 0)
  58.             {
  59.                 Console.WriteLine("Đây không phải File .NET Asm rồi!!");
  60.             }
  61.             else
  62.             {
  63.                 Console.WriteLine("Đây là File .NET Asm đó..");
  64.             }
  65.             fs.Close();
  66. }

__ Đây là một ví dụ để kiểm tra một file thuộc loại gì .
__ Tham khảo cấu trúc các PE Header của các file tại : http://wosit.org/ ->Trang này hay thật ..Không nhớ lần trước ông nào trên forum mình giới thiệu nhỉ ^^! Cảm ơn luôn.
__ Các bạn có thể tham khảo bài này để viết chương trình nhận biết file nha .. Yêu cầu biết chút kiến thức về PE Header và ASM một tí ..Biết dùng thêm cả OllyDbg hoặc SoftICE để check PE Header thì quá tuyệt

__Tham khảo thêm :
Ref Links Code: