[模块]可以搜索内存中存在的PE结构

此模块可以搜索内存中存在的PE结构~~ 方便抓取内存中的PE文件。

Option Explicit
Private Const FILE_SHARE_READ = &H1
Private Const FILE_MAP_READ = 4
Private Const PAGE_READONLY = &H2
Private Const SYNCHRONIZE As Long = &H100000
Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000

Private Type UNICODE_STRING
    uLength As Integer
    uMaximumLength As Integer
    pBuffer(3) As Byte
End Type

Private Type SYSTEM_HANDLE
    UniqueProcessId As Integer
    CreatorBackTraceIndex As Integer
    ObjectTypeIndex As Byte
    HandleAttributes As Byte
    HandleValue As Integer
    pObject As Long
    GrantedAccess As Long
End Type

Private Type SYSTEM_HANDLE_INFORMATION
    uCount As Long
    aSH() As SYSTEM_HANDLE
End Type

Private Type CLIENT_ID
    UniqueProcess As Long
    UniqueThread  As Long
End Type
                               
Private Enum SYSTEM_INFORMATION_CLASS
    SystemBasicInformation
    SystemProcessorInformation             '// obsolete...delete
    SystemPerformanceInformation
    SystemTimeOfDayInformation
    SystemPathInformation
    SystemProcessInformation
    SystemCallCountInformation
    SystemDeviceInformation
    SystemProcessorPerformanceInformation
    SystemFlagsInformation
    SystemCallTimeInformation
    SystemModuleInformation
    SystemLocksInformation
    SystemStackTraceInformation
    SystemPagedPoolInformation
    SystemNonPagedPoolInformation
    SystemHandleInformation
    SystemObjectInformation
    SystemPageFileInformation
    SystemVdmInstemulInformation
    SystemVdmBopInformation
    SystemFileCacheInformation
    SystemPoolTagInformation
    SystemInterruptInformation
    SystemDpcBehaviorInformation
    SystemFullMemoryInformation
    SystemLoadGdiDriverInformation
    SystemUnloadGdiDriverInformation
    SystemTimeAdjustmentInformation
    SystemSummaryMemoryInformation
    SystemMirrorMemoryInformation
    SystemPerformanceTraceInformation
    SystemObsolete0
    SystemExceptionInformation
    SystemCrashDumpStateInformation
    SystemKernelDebuggerInformation
    SystemContextSwitchInformation
    SystemRegistryQuotaInformation
    SystemExtendServiceTableInformation
    SystemPrioritySeperation
    SystemVerifierAddDriverInformation
    SystemVerifierRemoveDriverInformation
    SystemProcessorIdleInformation
    SystemLegacyDriverInformation
    SystemCurrentTimeZoneInformation
    SystemLookasideInformation
    SystemTimeSlipNotification
    SystemSessionCreate
    SystemSessionDetach
    SystemSessionInformation
    SystemRangeStartInformation
    SystemVerifierInformation
    SystemVerifierThunkExtend
    SystemSessionProcessInformation
    SystemLoadGdiDriverInSystemSpace
    SystemNumaProcessorMap
    SystemPrefetcherInformation
    SystemExtendedProcessInformation
    SystemRecommendedSharedDataAlignment
    SystemComPlusPackage
    SystemNumaAvailableMemory
    SystemProcessorPowerInformation
    SystemEmulationBasicInformation
    SystemEmulationProcessorInformation
    SystemExtendedHandleInformation
    SystemLostDelayedWriteInformation
    SystemBigPoolInformation
    SystemSessionPoolTagInformation
    SystemSessionMappedViewInformation
    SystemHotpatchInformation
    SystemObjectSecurityMode
    SystemWatchdogTimerHandler
    SystemWatchdogTimerInformation
    SystemLogicalProcessorInformation
    SystemWow64SharedInformation
    SystemRegisterFirmwareTableInformationHandler
    SystemFirmwareTableInformation
    SystemModuleInformationEx
    SystemVerifierTriageInformation
    SystemSuperfetchInformation
    SystemMemoryListInformation
    SystemFileCacheInformationEx
    MaxSystemInfoClass  '// MaxSystemInfoClass should always be the last enum
End Enum

Private Enum PROCESSINFOCLASS
    ProcessBasicInformation = 0
    ProcessQuotaLimits
    ProcessIoCounters
    ProcessVmCounters
    ProcessTimes
    ProcessBasePriority
    ProcessRaisePriority
    ProcessDebugPort
    ProcessExceptionPort
    ProcessAccessToken
    ProcessLdtInformation
    ProcessLdtSize
    ProcessDefaultHardErrorMode
    ProcessIoPortHandlers
    ProcessPooledUsageAndLimits
    ProcessWorkingSetWatch
    ProcessUserModeIOPL
    ProcessEnableAlignmentFaultFixup
    ProcessPriorityClass
    ProcessWx86Information
    ProcessHandleCount
    ProcessAffinityMask
    ProcessPriorityBoost
    ProcessDeviceMap
    ProcessSessionInformation
    ProcessForegroundInformation
    ProcessWow64Information
    ProcessImageFileName
    ProcessLUIDDeviceMapsEnabled
    ProcessBreakOnTermination
    ProcessDebugObjectHandle
    ProcessDebugFlags
    ProcessHandleTracing
    ProcessIoPriority
    ProcessExecuteFlags
    ProcessResourceManagement
    ProcessCookie
    ProcessImageInformation
    MaxProcessInfoClass
End Enum

Private Const STATUS_INFO_LENGTH_MISMATCH = &HC0000004

Private Type PROCESS_BASIC_INFORMATION
    ExitStatus As Long 'NTSTATUS
    PebBaseAddress As Long 'PPEB
    AffinityMask As Long 'ULONG_PTR
    BasePriority As Long 'KPRIORITY
    UniqueProcessId As Long 'ULONG_PTR
    InheritedFromUniqueProcessId As Long 'ULONG_PTR
End Type

Private Enum SE_OBJECT_TYPE
    SE_UNKNOWN_OBJECT_TYPE = 0
    SE_FILE_OBJECT
    SE_SERVICE
    SE_PRINTER
    SE_REGISTRY_KEY
    SE_LMSHARE
    SE_KERNEL_OBJECT
    SE_WINDOW_OBJECT
    SE_DS_OBJECT
    SE_DS_OBJECT_ALL
    SE_PROVIDER_DEFINED_OBJECT
    SE_WMIGUID_OBJECT
End Enum

Private Const ERROR_PARTIAL_COPY = 299

Private Declare Function NtQueryInformationProcess Lib "ntdll.dll" (ByVal ProcessHandle As Long, _
                                ByVal ProcessInformationClass As PROCESSINFOCLASS, _
                                ByVal ProcessInformation As Long, _
                                ByVal ProcessInformationLength As Long, _
                                ByRef ReturnLength As Long) As Long
                               
'枚举Kernel Module函数
Private Declare Function NtQuerySystemInformation Lib "ntdll.dll" (ByVal SystemInformationClass As SYSTEM_INFORMATION_CLASS, _
                                ByVal pSystemInformation As Long, _
                                ByVal SystemInformationLength As Long, _
                                ByRef ReturnLength As Long) As Long

Private Declare Function NtDuplicateObject Lib "ntdll.dll" (ByVal SourceProcessHandle As Long, _
                                ByVal SourceHandle As Long, _
                                ByVal TargetProcessHandle As Long, _
                                ByRef TargetHandle As Long, _
                                ByVal DesiredAccess As Long, _
                                ByVal HandleAttributes As Long, _
                                ByVal Options As Long) As Long

Private Const DUPLICATE_CLOSE_SOURCE = &H1

Private Const DUPLICATE_SAME_ACCESS = &H2

Private Const DUPLICATE_SAME_ATTRIBUTES = &H4

Private Declare Function NtOpenProcess Lib "ntdll.dll" (ByRef ProcessHandle As Long, _
                                ByVal AccessMask As Long, _
                                ByRef ObjectAttributes As OBJECT_ATTRIBUTES, _
                                ByRef ClientID As CLIENT_ID) As Long
                                                       
Private Type OBJECT_ATTRIBUTES
    Length As Long
    RootDirectory As Long
    ObjectName As Long
    Attributes As Long
    SecurityDescriptor As Long
    SecurityQualityOfService As Long
End Type

Private Type IO_STATUS_BLOCK
    Status As Long
    uInformation As Long
End Type
Private Const PROCESS_VM_READ = &H10

Private Const PROCESS_QUERY_INFORMATION As Long = (&H400)

Private Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)

Private Const PROCESS_DUP_HANDLE As Long = (&H40)

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
Private Declare Function NtClose Lib "ntdll.dll" (ByVal ObjectHandle As Long) As Long
Private Declare Function ImageRvaToVa Lib "dbghelp" (ByRef NtHeaders As Any, Base As Any, ByVal Rva As Long, ByRef LastRvaSection As Any) As Long
Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, lpFileMappigAttributes As Any, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
Public Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As Any) As Long

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub RtlZeroMemory Lib "kernel32" (Destination As Any, ByVal Length As Long)

Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long


Private Enum ImageSignatureTypes
   IMAGE_DOS_SIGNATURE = &H5A4D     ''\\ MZ
   IMAGE_OS2_SIGNATURE = &H454E     ''\\ NE
   IMAGE_OS2_SIGNATURE_LE = &H454C  ''\\ LE
   IMAGE_VXD_SIGNATURE = &H454C     ''\\ LE
   IMAGE_NT_SIGNATURE = &H4550      ''\\ PE00
End Enum

Private Type IMAGE_DOS_HEADER
    Magic    As Integer
    cblp     As Integer
    cp       As Integer
    crlc     As Integer
    cparhdr  As Integer
    minalloc As Integer
    maxalloc As Integer
    ss       As Integer
    sp       As Integer
    csum     As Integer
    ip       As Integer
    cs       As Integer
    lfarlc   As Integer
    ovno     As Integer
    res(3)   As Integer
    oemid    As Integer
    oeminfo  As Integer
    res2(9)  As Integer
    lfanew      As Long
End Type

Private Type IMAGE_FILE_HEADER
    Machine              As Integer
    NumberOfSections     As Integer
    TimeDateStamp        As Long
    PointerToSymbolTable As Long
    NumberOfSymbols      As Long
    SizeOfOtionalHeader  As Integer
    Characteristics      As Integer  '标志Dll
End Type

Private Type IMAGE_DATA_DIRECTORY
    DataRVA     As Long
    DataSize    As Long
End Type

Private Type IMAGE_OPTIONAL_HEADER
    Magic             As Integer
    MajorLinkVer      As Byte
    MinorLinkVer      As Byte
    CodeSize          As Long
    InitDataSize      As Long
    unInitDataSize    As Long
    EntryPoint        As Long
    CodeBase          As Long
    DataBase          As Long
    ImageBase         As Long
    SectionAlignment  As Long
    FileAlignment     As Long
    MajorOSVer        As Integer
    MinorOSVer        As Integer
    MajorImageVer     As Integer
    MinorImageVer     As Integer
    MajorSSVer        As Integer
    MinorSSVer        As Integer
    Win32Ver          As Long
    ImageSize         As Long
    HeaderSize        As Long
    Checksum          As Long
    Subsystem         As Integer
    DLLChars          As Integer
    StackRes          As Long
    StackCommit       As Long
    HeapReserve       As Long
    HeapCommit        As Long
    LoaderFlags       As Long
    RVAsAndSizes      As Long
    DataEntries(15)   As IMAGE_DATA_DIRECTORY
End Type

Private Type IMAGE_NT_HEADERS
    Signature As Long
    FileHeader As IMAGE_FILE_HEADER
    OptionalHeader As IMAGE_OPTIONAL_HEADER
End Type

Private Type IMAGE_SECTION_HEADER
    SectionName(7)    As Byte
    Address           As Long
    VirtualAddress    As Long
    SizeOfData        As Long
    PData             As Long
    PReloc            As Long
    PLineNums         As Long
    RelocCount        As Integer
    LineCount         As Integer
    Characteristics   As Long
End Type

Private Type IMAGE_IMPORT_DESCRIPTOR
    Characteristics As Long
    TimeDateStamp As Long
    ForwarderChain As Long
    pName As Long
    FirstThunk As Long
End Type

Private Type IMAGE_EXPORT_DIRECTORY
    Characteristics As Long
    TimeDateStamp As Long
    MajorVersion As Integer
    MinorVersion As Integer
    pName As Long
    Base As Long
    NumberOfFunctions As Long
    NumberOfNames As Long
    AddressOfFunctions As Long
    AddressOfNames As Long
    AddressOfNameOrdinals As Long
End Type

Private Type IMAGE_THUNK_DATA32
    AddressOfData As Long 'IMAGE_IMPORT_BY_NAME
End Type

Public Type MAP_INFO
    hFile As Long
    hMap As Long
End Type

'判断Nt系列函数是否调用成功
Private Function NT_SUCCESS(ByVal nStatus As Long) As Boolean
    NT_SUCCESS = (nStatus >= 0)
End Function

'通过进程PID获取进程句柄此方法可以不躲过拦截NtOpenProcess方法获取进程句柄
Public Function GetHandleByProcessId(ByVal dwProcessId As Long) As Long
    Dim ntStatus As Long
    Dim objCid As CLIENT_ID
    Dim objOa As OBJECT_ATTRIBUTES
    Dim lngHandles As Long
    Dim i As Long
    Dim objBasic As PROCESS_BASIC_INFORMATION
    Dim objInfo() As SYSTEM_HANDLE
    Dim hProcessToDup As Long, hProcessHandle As Long
    Dim bytBuffer() As Byte
    Dim nSize As Long
    nSize = 1
    Do
        ReDim bytBuffer(nSize)
        ntStatus = NtQuerySystemInformation(SystemHandleInformation, VarPtr(bytBuffer(0)), nSize, 0&)
        If (Not NT_SUCCESS(ntStatus)) Then
            If (ntStatus <> STATUS_INFO_LENGTH_MISMATCH) Then
                Erase bytBuffer
                Exit Function
            End If
        Else
            Exit Do
        End If
        nSize = nSize * 2
        ReDim bytBuffer(nSize)
    Loop
    objOa.Length = Len(objOa)
    CopyMemory lngHandles, bytBuffer(0), 4
    ReDim objInfo(lngHandles - 1)
    CopyMemory objInfo(0), bytBuffer(4), Len(objInfo(0)) * lngHandles
    Erase bytBuffer
    For i = 0 To lngHandles - 1
        If objInfo(i).ObjectTypeIndex = 5 Then ' And objInfo(i).UniqueProcessId = dwProcessId Then
            objCid.UniqueProcess = objInfo(i).UniqueProcessId
            ntStatus = NtOpenProcess(hProcessToDup, PROCESS_DUP_HANDLE, objOa, objCid)
            If (NT_SUCCESS(ntStatus)) Then
                ntStatus = NtDuplicateObject(hProcessToDup, objInfo(i).HandleValue, -1, hProcessHandle, PROCESS_ALL_ACCESS, 0, DUPLICATE_SAME_ATTRIBUTES)
                If (NT_SUCCESS(ntStatus)) Then
                    ntStatus = NtQueryInformationProcess(hProcessHandle, ProcessBasicInformation, VarPtr(objBasic), Len(objBasic), 0)
                    If (NT_SUCCESS(ntStatus)) Then
                        If (objBasic.UniqueProcessId = dwProcessId) Then
                            GetHandleByProcessId = hProcessHandle
                            NtClose hProcessToDup
                            Exit Function
                        End If
                    End If
                End If
                NtClose hProcessToDup
            End If
        End If
    Next
End Function

Private Sub DumpMemFile(ByVal hProcess As Long, ByVal dwAddr As Long, pNtHeaders As IMAGE_NT_HEADERS, ByVal strDumpFile As String)
    Dim dwImageSize As Long
    Dim bytBuffer() As Byte
    Dim hFile As Long
    dwImageSize = pNtHeaders.OptionalHeader.ImageSize
    ReDim bytBuffer(dwImageSize - 1)
    If ReadProcessMemory(hProcess, ByVal dwAddr, bytBuffer(0), dwImageSize, ByVal 0&) Then
        hFile = CreateFile(ByVal strDumpFile, ByVal &H40000000, 0, ByVal 0&, ByVal 4, ByVal 0&, ByVal 0&)
        If hFile = -1 Then Exit Sub
        Call WriteFile(hFile, bytBuffer(0), dwImageSize, dwImageSize, ByVal 0&)
        NtClose hFile
        Erase bytBuffer
    End If
End Sub

Public Function ScanPeStruct(ByVal dwProcessId As Long) As Boolean
    Dim ntStatus As Long
    Dim objBasic As PROCESS_BASIC_INFORMATION
    Dim objFlink As Long
    Dim objPEB As Long, objLdr As Long
    Dim objBaseAddress As Long
    Dim bytBuffer() As Byte
    Dim strModuleName As String, objName As Long
    Dim objCid As CLIENT_ID
    Dim objOa As OBJECT_ATTRIBUTES
    Dim hProcess As Long
    Dim lngRet As Long
    Dim pNTHeader As IMAGE_NT_HEADERS
    Dim pDosHear As IMAGE_DOS_HEADER
    Dim lngImageSize As Long, i As Long, dwScanBase As Long
    Dim dwStartAddr As Long
    objOa.Length = Len(objOa)
    objCid.UniqueProcess = dwProcessId
    ntStatus = NtOpenProcess(hProcess, PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, objOa, objCid)
    If hProcess = 0 Then
        hProcess = GetHandleByProcessId(dwProcessId)
        If hProcess = 0 Then Exit Function
    End If
    ntStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, VarPtr(objBasic), Len(objBasic), ByVal 0&)
    If (NT_SUCCESS(ntStatus)) Then
        objPEB = objBasic.PebBaseAddress
        lngRet = ReadProcessMemory(hProcess, ByVal objPEB + &HC, objLdr, 4, ByVal 0&)
        If lngRet = 0 Then GoTo RET
        lngRet = ReadProcessMemory(hProcess, ByVal objLdr + &HC, objFlink, 4, ByVal 0&)
        If lngRet = 0 Then GoTo RET
        lngRet = ReadProcessMemory(hProcess, ByVal objFlink + &H18, objBaseAddress, 4, ByVal 0&)
        If lngRet = 0 Then GoTo RET
        If objBaseAddress > 0 Then
            lngRet = ReadProcessMemory(hProcess, ByVal objBaseAddress, pDosHear, LenB(pDosHear), ByVal 0&)
            If lngRet = 0 Then GoTo RET
            If pDosHear.Magic <> &H5A4D Then If lngRet = 0 Then GoTo RET
            lngRet = ReadProcessMemory(hProcess, ByVal objBaseAddress + pDosHear.lfanew, pNTHeader, LenB(pNTHeader), ByVal 0&)
            If lngRet = 0 Then GoTo RET
            If pNTHeader.Signature <> IMAGE_NT_SIGNATURE Then GoTo RET
            lngImageSize = pNTHeader.OptionalHeader.ImageSize
            ReDim bytBuffer(lngImageSize - 1)
            lngRet = ReadProcessMemory(hProcess, ByVal objBaseAddress, bytBuffer(0), lngImageSize, ByVal 0&)
            If lngRet = 0 Then GoTo RET
            dwStartAddr = pNTHeader.OptionalHeader.DataEntries(2).DataRVA
            If dwStartAddr = 0 Then dwStartAddr = 1024
            RtlZeroMemory pDosHear, LenB(pDosHear)
            RtlZeroMemory pNTHeader, LenB(pNTHeader)
            For i = dwStartAddr To lngImageSize - 1024
                If bytBuffer(i) = Asc("M") And bytBuffer(i + 1) = Asc("Z") Then
                    CopyMemory pDosHear, bytBuffer(i), LenB(pDosHear)
                    If pDosHear.Magic = &H5A4D Then
                        If Abs(pDosHear.lfanew) < lngImageSize - 1024 Then
                            CopyMemory pNTHeader, bytBuffer(i + pDosHear.lfanew), LenB(pNTHeader)
                            If pNTHeader.Signature = IMAGE_NT_SIGNATURE Then
                                frmMain.List1.AddItem "地址是:" & Hex(objBaseAddress + i) & "发现PE结构"
                                If objBaseAddress + i <> objBaseAddress Then
                                    DumpMemFile hProcess, objBaseAddress + i, pNTHeader, App.Path & "\" & Hex(objBaseAddress + i)
                                    dwStartAddr = pNTHeader.OptionalHeader.DataEntries(2).DataRVA
                                    If dwStartAddr = 0 Then dwStartAddr = 1024
                                    i = i + dwStartAddr
                                End If
                            End If
                            RtlZeroMemory pNTHeader, LenB(pNTHeader)
                        End If
                    End If
                    RtlZeroMemory pDosHear, LenB(pDosHear)
                End If
            Next
        End If
    End If
RET:
    If hProcess Then NtClose hProcess

    Erase bytBuffer
    If lngRet = 1 Then ScanPeStruct = True
End Function

Public Function DumpMainModuleFile(ByVal dwProcessId As Long) As Boolean
    Dim ntStatus As Long
    Dim objBasic As PROCESS_BASIC_INFORMATION
    Dim objFlink As Long
    Dim objPEB As Long, objLdr As Long
    Dim objBaseAddress As Long
    Dim bytBuffer() As Byte
    Dim strModuleName As String, objName As Long
    Dim objCid As CLIENT_ID
    Dim objOa As OBJECT_ATTRIBUTES
    Dim hProcess As Long
    Dim lngRet As Long
    Dim pNTHeader As IMAGE_NT_HEADERS
    Dim pDosHear As IMAGE_DOS_HEADER
    Dim pSections() As IMAGE_SECTION_HEADER
    Dim hFile As Long, dwWrites As Long
    Dim dwWriteSize As Long
   
    objOa.Length = Len(objOa)
    objCid.UniqueProcess = dwProcessId
    ntStatus = NtOpenProcess(hProcess, PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, objOa, objCid)
    If hProcess = 0 Then
        hProcess = GetHandleByProcessId(dwProcessId)
        If hProcess = 0 Then Exit Function
    End If
    ntStatus = NtQueryInformationProcess(hProcess, ProcessBasicInformation, VarPtr(objBasic), Len(objBasic), ByVal 0&)
    If (NT_SUCCESS(ntStatus)) Then
        objPEB = objBasic.PebBaseAddress
        lngRet = ReadProcessMemory(hProcess, ByVal objPEB + &HC, objLdr, 4, ByVal 0&)
        If lngRet = 0 Then GoTo RET
        lngRet = ReadProcessMemory(hProcess, ByVal objLdr + &HC, objFlink, 4, ByVal 0&)
        If lngRet = 0 Then GoTo RET
        lngRet = ReadProcessMemory(hProcess, ByVal objFlink + &H18, objBaseAddress, 4, ByVal 0&)
        If lngRet = 0 Then GoTo RET
        If objBaseAddress > 0 Then
            lngRet = ReadProcessMemory(hProcess, ByVal objBaseAddress, pDosHear, LenB(pDosHear), ByVal 0&)
            If lngRet = 0 Then GoTo RET
            If pDosHear.Magic <> &H5A4D Then If lngRet = 0 Then GoTo RET
            lngRet = ReadProcessMemory(hProcess, ByVal objBaseAddress + pDosHear.lfanew, pNTHeader, LenB(pNTHeader), ByVal 0&)
            If lngRet = 0 Then GoTo RET
            If pNTHeader.Signature <> IMAGE_NT_SIGNATURE Then GoTo RET
            DumpMemFile hProcess, objBaseAddress, pNTHeader, App.Path & "\" & Hex(objBaseAddress)
        End If
    End If
RET:
    If hProcess Then NtClose hProcess
    Erase bytBuffer
    If lngRet = 1 Then DumpMainModuleFile = True
End Function

 

原文地址:https://www.cnblogs.com/lizunicon/p/1247310.html