View difference between Paste ID: pRWX1Qze and gGELy9Lz
SHOW: | | - or go back to the newest paste.
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