Advertisement
Guest User

pe.rs

a guest
Feb 28th, 2015
280
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 8.04 KB | None | 0 0
  1. #![feature(old_io)]
  2. #![feature(old_path)]
  3.  
  4. use std::old_io::{File, Open, Read, Seek, SeekStyle};
  5.  
  6. // Windows 기본 데이터 형 ==============================================
  7. // WinDef.h
  8. type BYTE = u8;
  9. type WORD = u16;
  10. type DWORD = u32;
  11. type LONG = i32;
  12. type ULONGLONG = i64;
  13.  
  14. // PE Headers ==========================================================
  15. // WinNT.h
  16.  
  17. // MZ (Little Endian)
  18. const IMAGE_DOS_SIGNATURE : WORD = 0x5A4D;
  19.  
  20. /// DOS .EXE header
  21. #[allow(dead_code)]
  22. #[allow(non_camel_case_types)]
  23. struct IMAGE_DOS_HEADER {
  24.     e_magic     : WORD,         // Magic number
  25.     e_cblp      : WORD,         // Bytes on last page of file
  26.     e_cp        : WORD,         // Pages in file
  27.     e_crlc      : WORD,         // Relocations
  28.     e_cparhdr   : WORD,         // Size of header in paragraphs
  29.     e_minalloc  : WORD,         // Minimum extra paragraphs needed
  30.     e_maxalloc  : WORD,         // Maximum extra paragraphs needed
  31.     e_ss        : WORD,         // Initial (relative) SS value
  32.     e_sp        : WORD,         // Initial SP value
  33.     e_csum      : WORD,         // Checksum
  34.     e_ip        : WORD,         // Initial IP value
  35.     e_cs        : WORD,         // Initial (relative) CS value
  36.     e_lfarlc    : WORD,         // File address of relocation table
  37.     e_ovno      : WORD,         // Overlay number
  38.     e_res       : [WORD; 4],    // Reserved words
  39.     e_oemid     : WORD,         // OEM identifier (for e_oeminfo)
  40.     e_oeminfo   : WORD,         // OEM information, e_oemid specific
  41.     e_res2      : [WORD; 10],   // Reserved words
  42.     e_lfanew    : LONG,         // File address of new exe header
  43. }
  44.  
  45. /// File header format.
  46. #[allow(dead_code)]
  47. #[allow(non_camel_case_types)]
  48. #[allow(non_snake_case)]
  49. struct IMAGE_FILE_HEADER {
  50.     Machine             : WORD,
  51.     NumberOfSections    : WORD,
  52.     TimeDateStamp       : DWORD,
  53.     PointerToSymbolTable: DWORD,
  54.     NumberOfSymbols     : DWORD,
  55.     SizeOfOptionalHeader: WORD,
  56.     Characteristics     : WORD,
  57. }
  58.  
  59.  
  60. /// Directory format.
  61. #[allow(dead_code)]
  62. #[allow(non_camel_case_types)]
  63. #[allow(non_snake_case)]
  64. struct IMAGE_DATA_DIRECTORY {
  65.     VirtualAddress  : DWORD,
  66.     Size            : DWORD,
  67. }
  68.  
  69. #[allow(dead_code)]
  70. const IMAGE_NUMBEROF_DIRECTORY_ENTRIES : usize = 16;
  71.  
  72. /// Optional header format.
  73. #[allow(dead_code)]
  74. #[allow(non_camel_case_types)]
  75. #[allow(non_snake_case)]
  76. struct IMAGE_OPTIONAL_HEADER32 {
  77.     // STANDARD FIELDS
  78.     Magic                       : WORD,
  79.     MajorLinkerVersion          : BYTE,
  80.     MinorLinkerVersion          : BYTE,
  81.     SizeOfCode                  : DWORD,
  82.     SizeOfInitializedData       : DWORD,
  83.     SizeOfUninitializedData     : DWORD,
  84.     AddressOfEntryPoint         : DWORD,
  85.     BaseOfCode                  : DWORD,
  86.     BaseOfData                  : DWORD,
  87.  
  88.     // NT ADDITIONAL FIELDS
  89.     ImageBase                   : DWORD,
  90.     SectionAlignment            : DWORD,
  91.     FileAlignment               : DWORD,
  92.     MajorOperationSystemVersion : WORD,
  93.     MinorOperatingSystemVersion : WORD,
  94.     MajorImageVersion           : WORD,
  95.     MinorImageVersion           : WORD,
  96.     MajorSubsystemVersion       : WORD,
  97.     MinorSubsystemVersion       : WORD,
  98.     Win32VersionValue           : DWORD,
  99.     SizeOfImage                 : DWORD,
  100.     SizeOfHeaders               : DWORD,
  101.     CheckSum                    : DWORD,
  102.     Subsystem                   : WORD,
  103.     DllCharacteristics          : WORD,
  104.     SizeOfStackReserve          : DWORD,
  105.     SizeOfStackCommit           : DWORD,
  106.     SizeOfHeapReserve           : DWORD,
  107.     SizeOfHeapCommit            : DWORD,
  108.     LoaderFlags                 : DWORD,
  109.     NumberOfRvaAndSizes         : DWORD,
  110.     DataDirectory               : [IMAGE_DATA_DIRECTORY; IMAGE_NUMBEROF_DIRECTORY_ENTRIES],
  111. }
  112.  
  113. #[allow(dead_code)]
  114. #[allow(non_camel_case_types)]
  115. #[allow(non_snake_case)]
  116. struct IMAGE_OPTIONAL_HEADER64 {
  117.     Magic                       : WORD,
  118.     MajorLinkerVersion          : BYTE,
  119.     MinorLinkerVersion          : BYTE,
  120.     SizeOfCode                  : DWORD,
  121.     SizeOfInitializedData       : DWORD,
  122.     SizeOfUninitializedData     : DWORD,
  123.     AddressOfEntryPoint         : DWORD,
  124.     BaseOfCode                  : DWORD,
  125.     ImageBase                   : ULONGLONG,
  126.     SectionAlignment            : DWORD,
  127.     FileAlignment               : DWORD,
  128.     MajorOperationSystemVersion : WORD,
  129.     MinorOperatingSystemVersion : WORD,
  130.     MajorImageVersion           : WORD,
  131.     MinorImageVersion           : WORD,
  132.     MajorSubsystemVersion       : WORD,
  133.     MinorSubsystemVersion       : WORD,
  134.     Win32VersionValue           : DWORD,
  135.     SizeOfImage                 : DWORD,
  136.     SizeOfHeaders               : DWORD,
  137.     CheckSum                    : DWORD,
  138.     Subsystem                   : WORD,
  139.     DllCharacteristics          : WORD,
  140.     SizeOfStackReserve          : ULONGLONG,
  141.     SizeOfStackCommit           : ULONGLONG,
  142.     SizeOfHeapReserve           : ULONGLONG,
  143.     SizeOfHeapCommit            : ULONGLONG,
  144.     LoaderFlags                 : DWORD,
  145.     NumberOfRvaAndSizes         : DWORD,
  146.     DataDirectory               : [IMAGE_DATA_DIRECTORY; IMAGE_NUMBEROF_DIRECTORY_ENTRIES],
  147. }
  148.  
  149. #[allow(dead_code)]
  150. const IMAGE_NT_OPTIONAL_HDR32_MAGIC : WORD = 0x10b; // 32 bit image
  151.  
  152. #[allow(dead_code)]
  153. const IMAGE_NT_OPTIONAL_HDR64_MAGIC : WORD = 0x20b; // 64 bit image
  154.  
  155. #[allow(dead_code)]
  156. const IMAGE_ROM_OPTIONAL_HDR_MAGIC  : WORD = 0x107; // ROM
  157.  
  158.  
  159. // PE00 (Little Endian)
  160. #[allow(dead_code)]
  161. const IMAGE_PE_SIGNATURE : DWORD = 0x004550;
  162.  
  163. /// NT Header
  164. #[allow(dead_code)]
  165. #[allow(non_camel_case_types)]
  166. #[allow(non_snake_case)]
  167. struct IMAGE_NT_HEADERS32 {
  168.     Signature       : DWORD,
  169.     FileHeader      : IMAGE_FILE_HEADER,
  170.     OptionalHeader  : IMAGE_OPTIONAL_HEADER32,
  171. }
  172.  
  173. #[allow(dead_code)]
  174. #[allow(non_camel_case_types)]
  175. #[allow(non_snake_case)]
  176. struct IMAGE_NT_HEADERS64 {
  177.     Signature       : DWORD,
  178.     FileHeader      : IMAGE_FILE_HEADER,
  179.     OptionalHeader  : IMAGE_OPTIONAL_HEADER64,
  180. }
  181.  
  182. // 구현 ================================================================
  183.  
  184. /// 파일에서 DOS 헤더를 읽는다.
  185. fn read_dos_header( pe: &mut  File ) -> IMAGE_DOS_HEADER
  186. {
  187.     let dos_h = IMAGE_DOS_HEADER
  188.     {
  189.         e_magic     : pe.read_le_u16().unwrap(),
  190.         e_cblp      : pe.read_le_u16().unwrap(),
  191.         e_cp        : pe.read_le_u16().unwrap(),
  192.         e_crlc      : pe.read_le_u16().unwrap(),
  193.         e_cparhdr   : pe.read_le_u16().unwrap(),
  194.         e_minalloc  : pe.read_le_u16().unwrap(),
  195.         e_maxalloc  : pe.read_le_u16().unwrap(),
  196.         e_ss        : pe.read_le_u16().unwrap(),
  197.         e_sp        : pe.read_le_u16().unwrap(),
  198.         e_csum      : pe.read_le_u16().unwrap(),
  199.         e_ip        : pe.read_le_u16().unwrap(),
  200.         e_cs        : pe.read_le_u16().unwrap(),
  201.         e_lfarlc    : pe.read_le_u16().unwrap(),
  202.         e_ovno      : pe.read_le_u16().unwrap(),
  203.         e_res       : [
  204.             pe.read_le_u16().unwrap(),
  205.             pe.read_le_u16().unwrap(),
  206.             pe.read_le_u16().unwrap(),
  207.             pe.read_le_u16().unwrap()
  208.         ],
  209.         e_oemid     : pe.read_le_u16().unwrap(),
  210.         e_oeminfo   : pe.read_le_u16().unwrap(),
  211.         e_res2      : [
  212.             pe.read_le_u16().unwrap(),
  213.             pe.read_le_u16().unwrap(),
  214.             pe.read_le_u16().unwrap(),
  215.             pe.read_le_u16().unwrap(),
  216.             pe.read_le_u16().unwrap(),
  217.             pe.read_le_u16().unwrap(),
  218.             pe.read_le_u16().unwrap(),
  219.             pe.read_le_u16().unwrap(),
  220.             pe.read_le_u16().unwrap(),
  221.             pe.read_le_u16().unwrap(),
  222.         ],
  223.         e_lfanew    : pe.read_le_i32().unwrap(),
  224.     };
  225.  
  226.     return dos_h;
  227. }
  228.  
  229. /// 파일에서 IMAGE_FILE_HEADER를 읽는다.
  230. fn read_img_fileheader( pe: &mut File ) -> Option<IMAGE_FILE_HEADER>
  231. {
  232.     let signature = pe.read_le_u32().unwrap();
  233.     if signature != IMAGE_PE_SIGNATURE
  234.     {
  235.         return None;
  236.     }
  237.     else
  238.     {
  239.         let fh = IMAGE_FILE_HEADER
  240.         {
  241.             Machine             : pe.read_le_u16().unwrap(),
  242.             NumberOfSections    : pe.read_le_u16().unwrap(),
  243.             TimeDateStamp       : pe.read_le_u32().unwrap(),
  244.             PointerToSymbolTable: pe.read_le_u32().unwrap(),
  245.             NumberOfSymbols     : pe.read_le_u32().unwrap(),
  246.             SizeOfOptionalHeader: pe.read_le_u16().unwrap(),
  247.             Characteristics     : pe.read_le_u16().unwrap(),
  248.         };
  249.         return Some(fh);
  250.     }
  251. }
  252.  
  253. // EP
  254. fn main()
  255. {
  256.     let myself = Path::new( "./pe.exe" );
  257.     let mut file = match File::open_mode( &myself, Open, Read )
  258.     {
  259.         Ok(f) => f,
  260.         Err(e) => panic!( "file error: {}", e )
  261.     };
  262.  
  263.     let dos_header = read_dos_header( &mut file );
  264.  
  265.     if dos_header.e_magic == IMAGE_DOS_SIGNATURE
  266.     {
  267.         println!( "DOS HEADER." );
  268.         println!( " * EXE Header offset = 0x{:X}\n", dos_header.e_lfanew );
  269.     }
  270.     else
  271.     {
  272.         println!( "MZ를 찾을 수 없음." );
  273.         return;
  274.     }
  275.  
  276.     match file.seek( (dos_header.e_lfanew as i64), SeekStyle::SeekSet )
  277.     {
  278.         Ok(_)=>{},
  279.         Err(e) => panic!("EXE Header Offet으로 Seek 할 수 없음: {}", e)
  280.     }
  281.  
  282.     let fh_res = read_img_fileheader( &mut file );
  283.     match fh_res
  284.     {
  285.         None =>
  286.         {
  287.             println!( "PE Image File Header를 찾을 수 없음." );
  288.             return;
  289.         }
  290.         Some(_)=>{},
  291.     }
  292.  
  293.     let file_header = fh_res.unwrap();
  294.     println!( "PE Image File Header." );
  295.     println!( " * Machine = 0x{:X}", file_header.Machine );
  296.     println!( " * {} Section(s).", file_header.NumberOfSections );
  297. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement