Advertisement
coderail

ExecutableReader - VB.NET

May 7th, 2014
1,618
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.55 KB | None | 0 0
  1. Imports System.IO
  2. Imports System.ComponentModel
  3. Imports System.Runtime.InteropServices
  4.  
  5. '------------------
  6. 'Creator: aeonhack
  7. 'Site: nimoru.com
  8. 'Created: 05/06/2014
  9. 'Changed: 05/06/2014
  10. 'Version: 1.0.0.0
  11. '------------------
  12.  
  13. Public NotInheritable Class ExecutableReader
  14. Implements IDisposable
  15.  
  16. #Region " Properties "
  17.  
  18. Private _Is32Bit As Boolean
  19. ReadOnly Property Is32Bit() As Boolean
  20. Get
  21. Return _Is32Bit
  22. End Get
  23. End Property
  24.  
  25. Private _DosHeader As Win32.IMAGE_DOS_HEADER
  26. ReadOnly Property DosHeader As Win32.IMAGE_DOS_HEADER
  27. Get
  28. Return _DosHeader
  29. End Get
  30. End Property
  31.  
  32. Private _Signature As UInteger
  33. ReadOnly Property Signature As UInteger
  34. Get
  35. Return _Signature
  36. End Get
  37. End Property
  38.  
  39. Private _FileHeader As Win32.IMAGE_FILE_HEADER
  40. ReadOnly Property FileHeader As Win32.IMAGE_FILE_HEADER
  41. Get
  42. Return _FileHeader
  43. End Get
  44. End Property
  45.  
  46. Private _OptionalHeader32 As Win32.IMAGE_OPTIONAL_HEADER32
  47. ReadOnly Property OptionalHeader32 As Win32.IMAGE_OPTIONAL_HEADER32
  48. Get
  49. Return _OptionalHeader32
  50. End Get
  51. End Property
  52.  
  53. Private _OptionalHeader64 As Win32.IMAGE_OPTIONAL_HEADER64
  54. ReadOnly Property OptionalHeader64 As Win32.IMAGE_OPTIONAL_HEADER64
  55. Get
  56. Return _OptionalHeader64
  57. End Get
  58. End Property
  59.  
  60. Private _DataDirectory As Win32.IMAGE_DATA_DIRECTORY()
  61. ReadOnly Property DataDirectory As Win32.IMAGE_DATA_DIRECTORY()
  62. Get
  63. Return _DataDirectory
  64. End Get
  65. End Property
  66.  
  67. Private _SectionHeaders As Win32.IMAGE_SECTION_HEADER()
  68. ReadOnly Property SectionHeaders() As Win32.IMAGE_SECTION_HEADER()
  69. Get
  70. Return _SectionHeaders
  71. End Get
  72. End Property
  73.  
  74. Private _IsDisposed As Boolean
  75. ReadOnly Property IsDisposed As Boolean
  76. Get
  77. Return _IsDisposed
  78. End Get
  79. End Property
  80.  
  81. Private _IsLoaded As Boolean
  82. ReadOnly Property IsLoaded As Boolean
  83. Get
  84. Return _IsLoaded
  85. End Get
  86. End Property
  87.  
  88. #End Region
  89.  
  90.  
  91. #Region " Constants "
  92.  
  93. Private Const PROCESS_VM_OPERATION As Integer = 8
  94. Private Const PROCESS_VM_READ As Integer = 16
  95.  
  96. Private Const PAGE_NOACCESS As Integer = 1
  97. Private Const PAGE_EXECUTE_READWRITE As Integer = 64
  98.  
  99. #End Region
  100.  
  101.  
  102. #Region " Members "
  103.  
  104. Private _IsRuntime As Boolean
  105.  
  106. Private _ProcessHandle As IntPtr
  107. Private _FileStream As FileStream
  108.  
  109. Private _Address As IntPtr
  110. Private _BaseAddress As IntPtr
  111.  
  112. #End Region
  113.  
  114.  
  115. #Region " Initialization "
  116.  
  117. Public Sub LoadFromProcess(process As Process)
  118. ThrowOnDisposed()
  119. ThrowOnLoaded()
  120.  
  121. _IsLoaded = True
  122. _IsRuntime = True
  123.  
  124. _BaseAddress = process.MainModule.BaseAddress
  125. _Address = _BaseAddress
  126.  
  127. _ProcessHandle = Win32.OpenProcess(PROCESS_VM_READ Or PROCESS_VM_OPERATION, False, process.Id)
  128.  
  129. If _ProcessHandle = IntPtr.Zero Then
  130. Throw New Win32Exception(Marshal.GetLastWin32Error())
  131. End If
  132.  
  133. ProcessExecutable()
  134. End Sub
  135.  
  136. Public Sub LoadFromFile(fileName As String)
  137. ThrowOnDisposed()
  138. ThrowOnLoaded()
  139.  
  140. _IsLoaded = True
  141. _FileStream = File.OpenRead(fileName)
  142.  
  143. ProcessExecutable()
  144. End Sub
  145.  
  146. #End Region
  147.  
  148.  
  149. #Region " Processing "
  150.  
  151. Private Sub ProcessExecutable()
  152. _DosHeader = Read(Of Win32.IMAGE_DOS_HEADER)()
  153. Seek(_DosHeader.e_lfanew)
  154.  
  155. _Signature = Read(Of UInteger)()
  156. _FileHeader = Read(Of Win32.IMAGE_FILE_HEADER)()
  157. _Is32Bit = (_FileHeader.Machine = 332)
  158.  
  159. If _Is32Bit Then
  160. _OptionalHeader32 = Read(Of Win32.IMAGE_OPTIONAL_HEADER32)()
  161. Else
  162. _OptionalHeader64 = Read(Of Win32.IMAGE_OPTIONAL_HEADER64)()
  163. End If
  164.  
  165. _DataDirectory = New Win32.IMAGE_DATA_DIRECTORY(16 - 1) {}
  166. For I As Integer = 0 To _DataDirectory.Length - 1
  167. _DataDirectory(I) = Read(Of Win32.IMAGE_DATA_DIRECTORY)()
  168. Next
  169.  
  170. SeekToSectionHeaders()
  171.  
  172. _SectionHeaders = New Win32.IMAGE_SECTION_HEADER(_FileHeader.NumberOfSections - 1) {}
  173. For I As Integer = 0 To _FileHeader.NumberOfSections - 1
  174. _SectionHeaders(I) = Read(Of Win32.IMAGE_SECTION_HEADER)()
  175. Next
  176. End Sub
  177.  
  178. Private Function Read(Of T As Structure)() As T
  179. Dim Data As Byte() = Read(Marshal.SizeOf(GetType(T)))
  180.  
  181. Dim Item As New T()
  182. Dim Handle As IntPtr = Marshal.AllocCoTaskMem(Data.Length)
  183.  
  184. Marshal.Copy(Data, 0, Handle, Data.Length)
  185. Item = DirectCast(Marshal.PtrToStructure(Handle, GetType(T)), T)
  186. Marshal.FreeCoTaskMem(Handle)
  187.  
  188. Return Item
  189. End Function
  190.  
  191. Private Function Read(length As Integer) As Byte()
  192. Dim Data(length - 1) As Byte
  193.  
  194. If _IsRuntime Then
  195. Dim BytesRead As Integer
  196.  
  197. If Not Win32.ReadProcessMemory(_ProcessHandle, _Address, Data, Data.Length, BytesRead) Then
  198. Throw New Win32Exception(Marshal.GetLastWin32Error())
  199. End If
  200.  
  201. _Address = New IntPtr(_Address.ToInt64() + Data.Length)
  202. Else
  203. _FileStream.Read(Data, 0, Data.Length)
  204. End If
  205.  
  206. Return Data
  207. End Function
  208.  
  209. Private Sub Seek(offset As Integer)
  210. If _IsRuntime Then
  211. _Address = New IntPtr(_BaseAddress.ToInt64() + offset)
  212. Else
  213. _FileStream.Seek(offset, SeekOrigin.Begin)
  214. End If
  215. End Sub
  216.  
  217. Private Sub SeekToSectionHeaders()
  218. Dim Offset As Integer = _DosHeader.e_lfanew
  219.  
  220. Offset += Marshal.SizeOf(_Signature)
  221. Offset += Marshal.SizeOf(_FileHeader)
  222. Offset += _FileHeader.SizeOfOptionalHeader
  223.  
  224. Seek(Offset)
  225. End Sub
  226.  
  227. #End Region
  228.  
  229.  
  230. #Region " Extraction "
  231.  
  232. Public Function DumpSection(sectionHeader As Win32.IMAGE_SECTION_HEADER) As Byte()
  233. ThrowOnDisposed()
  234. ThrowOnNotLoaded()
  235.  
  236. If _IsRuntime Then
  237. Seek(sectionHeader.VirtualAddress)
  238. Else
  239. Seek(sectionHeader.PointerToRawData)
  240. End If
  241.  
  242. Return GetDump(sectionHeader.VirtualSize)
  243. End Function
  244.  
  245. Public Function DumpDataDirectory(dataDirectory As Win32.IMAGE_DATA_DIRECTORY) As Byte()
  246. ThrowOnDisposed()
  247. ThrowOnNotLoaded()
  248.  
  249. If dataDirectory.VirtualAddress = 0 Then
  250. Return New Byte() {}
  251. End If
  252.  
  253. If _IsRuntime Then
  254. Seek(dataDirectory.VirtualAddress)
  255. Else
  256. Seek(GetPointerToRawData(dataDirectory.VirtualAddress))
  257. End If
  258.  
  259. Return GetDump(dataDirectory.Size)
  260. End Function
  261.  
  262. Public Function DumpUnmappedData() As Byte()
  263. ThrowOnDisposed()
  264. ThrowOnNotLoaded()
  265.  
  266. If _IsRuntime Then
  267. Return New Byte() {}
  268. Else
  269. Dim HighestOffset As Integer
  270.  
  271. For Each Section As Win32.IMAGE_SECTION_HEADER In _SectionHeaders
  272. If Section.PointerToRawData + Section.SizeOfRawData > HighestOffset Then
  273. HighestOffset = Section.PointerToRawData + Section.SizeOfRawData
  274. End If
  275. Next
  276.  
  277. For Each Directory As Win32.IMAGE_DATA_DIRECTORY In _DataDirectory
  278. Dim PointerToRawData As Integer = GetPointerToRawData(Directory.VirtualAddress)
  279.  
  280. If PointerToRawData + Directory.Size > HighestOffset Then
  281. HighestOffset = PointerToRawData + Directory.Size
  282. End If
  283. Next
  284.  
  285. Seek(HighestOffset)
  286.  
  287. Return Read(CInt(_FileStream.Length) - HighestOffset)
  288. End If
  289. End Function
  290.  
  291. Private Function GetPointerToRawData(virtualAddress As Integer) As Integer
  292. For Each Section As Win32.IMAGE_SECTION_HEADER In _SectionHeaders
  293. If (virtualAddress < Section.VirtualAddress) OrElse (virtualAddress > (Section.VirtualAddress + Section.SizeOfRawData)) Then
  294. Continue For
  295. End If
  296.  
  297. Return Section.PointerToRawData + (virtualAddress - Section.VirtualAddress)
  298. Next
  299.  
  300. Return -1
  301. End Function
  302.  
  303. Private Function GetDump(size As Integer) As Byte()
  304. If size = 0 Then
  305. Return New Byte() {}
  306. End If
  307.  
  308. Dim Address As IntPtr = _Address
  309. Dim Protection As Integer = SetMemProtection(Address, size, PAGE_EXECUTE_READWRITE)
  310.  
  311. If Protection = -1 Then
  312. Return New Byte() {}
  313. End If
  314.  
  315. Dim Data As Byte() = Read(size)
  316. SetMemProtection(Address, size, Protection)
  317.  
  318. Return Data
  319. End Function
  320.  
  321. Private Function SetMemProtection(address As IntPtr, size As Integer, protection As Integer) As Integer
  322. If Not _IsRuntime Then Return 0
  323.  
  324. Dim OldProtection As Integer
  325.  
  326. If Win32.VirtualProtectEx(_ProcessHandle, address, size, protection, OldProtection) = 0 Then
  327. If OldProtection = PAGE_NOACCESS Then
  328. Return -1
  329. Else
  330. Throw New Win32Exception(Marshal.GetLastWin32Error())
  331. End If
  332. End If
  333.  
  334. Return OldProtection
  335. End Function
  336.  
  337. #End Region
  338.  
  339.  
  340. #Region " State Handling "
  341.  
  342. Private Sub ThrowOnDisposed()
  343. If _IsDisposed Then
  344. Throw New ObjectDisposedException([GetType]().FullName)
  345. End If
  346. End Sub
  347.  
  348. Private Sub ThrowOnLoaded()
  349. If _IsLoaded Then
  350. Throw New Exception("An executable has already been loaded.")
  351. End If
  352. End Sub
  353.  
  354. Private Sub ThrowOnNotLoaded()
  355. If Not _IsLoaded Then
  356. Throw New Exception("No executable has been loaded.")
  357. End If
  358. End Sub
  359.  
  360. #End Region
  361.  
  362.  
  363. #Region " IDisposable "
  364.  
  365. Protected Sub Dispose(disposing As Boolean)
  366. If Not _IsDisposed Then
  367. If disposing Then
  368.  
  369. If _FileStream IsNot Nothing Then
  370. _FileStream.Close()
  371. End If
  372.  
  373. End If
  374.  
  375. Win32.CloseHandle(_ProcessHandle)
  376. End If
  377.  
  378. _IsDisposed = True
  379. End Sub
  380.  
  381. Protected Overrides Sub Finalize()
  382. Dispose(False)
  383. MyBase.Finalize()
  384. End Sub
  385.  
  386. Public Sub Dispose() Implements IDisposable.Dispose
  387. Dispose(True)
  388. GC.SuppressFinalize(Me)
  389. End Sub
  390.  
  391. Public Sub Close()
  392. Dispose()
  393. End Sub
  394.  
  395. #End Region
  396.  
  397. End Class
  398.  
  399. Public NotInheritable Class Win32
  400.  
  401. #Region " Methods "
  402.  
  403. <DllImport("kernel32.dll", EntryPoint:="OpenProcess", SetLastError:=True)> _
  404. Public Shared Function OpenProcess( _
  405. ByVal access As Integer, _
  406. ByVal inherit As Boolean, _
  407. ByVal processId As Integer) As IntPtr
  408. End Function
  409.  
  410. <DllImport("kernel32.dll", EntryPoint:="VirtualProtectEx", SetLastError:=True)> _
  411. Public Shared Function VirtualProtectEx( _
  412. ByVal handle As IntPtr, _
  413. ByVal address As IntPtr, _
  414. ByVal size As Integer, _
  415. ByVal newProtection As Integer, _
  416. ByRef oldProtection As Integer) As Integer
  417. End Function
  418.  
  419. <DllImport("kernel32.dll", EntryPoint:="ReadProcessMemory", SetLastError:=True)> _
  420. Public Shared Function ReadProcessMemory( _
  421. ByVal handle As IntPtr, _
  422. ByVal address As IntPtr, _
  423. ByVal data As Byte(), _
  424. ByVal dataLength As Integer, _
  425. ByRef length As Integer) As Boolean
  426. End Function
  427.  
  428. <DllImport("kernel32.dll", EntryPoint:="CloseHandle")> _
  429. Public Shared Function CloseHandle( _
  430. ByVal handle As IntPtr) As Boolean
  431. End Function
  432.  
  433. #End Region
  434.  
  435. #Region " Structures "
  436.  
  437. <StructLayout(LayoutKind.Sequential, Pack:=1)> _
  438. Public Structure IMAGE_DOS_HEADER
  439. Public e_magic As UShort
  440. Public e_cblp As UShort
  441. Public e_cp As UShort
  442. Public e_crlc As UShort
  443. Public e_cparhdr As UShort
  444. Public e_minalloc As UShort
  445. Public e_maxalloc As UShort
  446. Public e_ss As UShort
  447. Public e_sp As UShort
  448. Public e_csum As UShort
  449. Public e_ip As UShort
  450. Public e_cs As UShort
  451. Public e_lfarlc As UShort
  452. Public e_ovno As UShort
  453. <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
  454. Public e_res As UShort()
  455. Public e_oemid As UShort
  456. Public e_oeminfo As UShort
  457. <MarshalAs(UnmanagedType.ByValArray, SizeConst:=10)> _
  458. Public e_res2 As UShort()
  459. Public e_lfanew As Integer 'NOTE: Should be unsigned
  460. End Structure
  461.  
  462. <StructLayout(LayoutKind.Sequential, Pack:=1)> _
  463. Public Structure IMAGE_FILE_HEADER
  464. Public Machine As UShort
  465. Public NumberOfSections As UShort
  466. Public TimeDateStamp As Integer
  467. Public PointerToSymbolTable As Integer
  468. Public NumberOfSymbols As Integer
  469. Public SizeOfOptionalHeader As UShort
  470. Public Characteristics As UShort
  471. End Structure
  472.  
  473. <StructLayout(LayoutKind.Sequential, Pack:=1)> _
  474. Public Structure IMAGE_OPTIONAL_HEADER32
  475. Public Magic As UShort
  476. Public MajorLinkerVersion As Byte
  477. Public MinorLinkerVersion As Byte
  478. Public SizeOfCode As Integer
  479. Public SizeOfInitializedData As Integer
  480. Public SizeOfUninitializedData As Integer
  481. Public AddressOfEntryPoint As Integer
  482. Public BaseOfCode As Integer
  483. Public BaseOfData As Integer
  484. Public ImageBase As Integer
  485. Public SectionAlignment As Integer
  486. Public FileAlignment As Integer
  487. Public MajorOperatingSystemVersion As UShort
  488. Public MinorOperatingSystemVersion As UShort
  489. Public MajorImageVersion As UShort
  490. Public MinorImageVersion As UShort
  491. Public MajorSubsystemVersion As UShort
  492. Public MinorSubsystemVersion As UShort
  493. Public Win32VersionValue As Integer
  494. Public SizeOfImage As Integer
  495. Public SizeOfHeaders As Integer
  496. Public CheckSum As Integer
  497. Public Subsystem As UShort
  498. Public DllCharacteristics As UShort
  499. Public SizeOfStackReserve As Integer
  500. Public SizeOfStackCommit As Integer
  501. Public SizeOfHeapReserve As Integer
  502. Public SizeOfHeapCommit As Integer
  503. Public LoaderFlags As Integer
  504. Public NumberOfRvaAndSizes As Integer
  505. End Structure
  506.  
  507. <StructLayout(LayoutKind.Sequential, Pack:=1)> _
  508. Public Structure IMAGE_OPTIONAL_HEADER64
  509. Public Magic As UShort
  510. Public MajorLinkerVersion As Byte
  511. Public MinorLinkerVersion As Byte
  512. Public SizeOfCode As Integer
  513. Public SizeOfInitializedData As Integer
  514. Public SizeOfUninitializedData As Integer
  515. Public AddressOfEntryPoint As Integer
  516. Public BaseOfCode As Integer
  517. Public ImageBase As Long
  518. Public SectionAlignment As Integer
  519. Public FileAlignment As Integer
  520. Public MajorOperatingSystemVersion As UShort
  521. Public MinorOperatingSystemVersion As UShort
  522. Public MajorImageVersion As UShort
  523. Public MinorImageVersion As UShort
  524. Public MajorSubsystemVersion As UShort
  525. Public MinorSubsystemVersion As UShort
  526. Public Win32VersionValue As Integer
  527. Public SizeOfImage As Integer
  528. Public SizeOfHeaders As Integer
  529. Public CheckSum As Integer
  530. Public Subsystem As UShort
  531. Public DllCharacteristics As UShort
  532. Public SizeOfStackReserve As Long
  533. Public SizeOfStackCommit As Long
  534. Public SizeOfHeapReserve As Long
  535. Public SizeOfHeapCommit As Long
  536. Public LoaderFlags As Integer
  537. Public NumberOfRvaAndSizes As Integer
  538. End Structure
  539.  
  540. <StructLayout(LayoutKind.Sequential, Pack:=1)> _
  541. Public Structure IMAGE_DATA_DIRECTORY
  542. Public VirtualAddress As Integer
  543. Public Size As Integer
  544. End Structure
  545.  
  546. <StructLayout(LayoutKind.Sequential, Pack:=1)> _
  547. Public Structure IMAGE_SECTION_HEADER
  548. <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _
  549. Public Name As String
  550. Public VirtualSize As Integer 'NOTE: Alias of Misc
  551. Public VirtualAddress As Integer
  552. Public SizeOfRawData As Integer
  553. Public PointerToRawData As Integer
  554. Public PointerToRelocations As Integer
  555. Public PointerToLineNumbers As Integer
  556. Public NumberOfRelocations As UShort
  557. Public NumberOfLineNumbers As UShort
  558. Public Characteristics As Integer
  559. End Structure
  560.  
  561. #End Region
  562.  
  563.  
  564. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement