1

Тема: VBScript & LangMF: исследование Win32 PE файлов

Данное предварительное решение предназначено для отображения в память Win32 PE файлов и получения некоторых характерных для них параметров. В качестве надежды на возможность глубокого изучения Win32 операционных систем, с использованием скриптовых интерфейсов программирования.
Используется библиотека dynwrap.dll, а также библиотека LangMf.dll или установленный LangMF 7.7.
Проверялось на Win98/Millenium/XP.

'---------------------------------------------------------------
'Данный предварительный скрипт предназначен для исследования
'Win32 PE файлов и получения некоторых специфических параметров
'характерных для этих файлов.
'---------------------------------------------------------------
'Language:            VBScript
'Используется             библиотека dynwrap.dll
'Используется             библиотека LangMf.dll
'или установленный LangMF 7.7
'OS Win98/Millenium
'---------------------------------------------------------------
'Дополнительно:
'    http://www.wasm.ru/print.php?article=1001013
'    Справка "Win32 Api Первые Шаги"-WinApi-шаг 23-27
'    Возможно потребуется Hiew
'---------------------------------------------------------------
Set RtlMoveMemoryC    =CreateObject("DynamicWrapper")
RtlMoveMemoryC.Register _
"KERNEL32.DLL","RtlMoveMemory","f=s","i=lll","r=l"
'---------------------------------------------------------------
'Константы CreateFileMapping/
Const PAGE_READONLY         =2
Const PAGE_READWRITE     =4
Const PAGE_WRITECOPY     =8
Const PAGE_EXECUTE         =16
Const PAGE_EXECUTE_READ     =32
Const SEC_IMAGE        =&H1000000

'Константы MapViewOfFile/
Const FILE_MAP_ALL_ACCESS     =&HF0000
Const FILE_MAP_READ         =4

'---------------------------------------------------------------
LMFCode= _
"<#Module=filecr>                         \" & _
";/Константы CreateFile/                                  \" & _
"Const GENERIC_READ          =&H80000000              \" & _
"Const GENERIC_WRITE      =&H40000000                    \" & _
"Const FILE_SHARE_READ      =1                  \" & _
"Const FILE_SHARE_WRITE      =2                 \" & _
"Const CREATE_NEW          =1                  \" & _
"Const CREATE_ALWAYS      =2                          \" & _
"Const OPEN_EXISTING      =3                          \" & _
"Const OPEN_ALWAYS          =4                \" & _
"Const FILE_ATTRIBUTE_NORMAL     =&H80              \" & _
"Const FILE_ATTRIBUTE_READONLY     =&H1              \" & _
";--------------------------------------------------------------\" & _
"Sub Load(cmdstr)                        \" & _
"End Sub                            \" & _
";--------------------------------------------------------------\" & _
";Диалог открытие файла                    \" & _
"Function OpenFileDlg()                        \" & _
"OpenFileDlg=sys.cdlg.showopen(    'Выбор PE файла', _    \" & _
"'Dll files (*.dll)|*.dll|All files (*.*)|*.*', _                                     \" & _
"            Sys.WinInfo('system'), _                      \" & _
"            '.dll')                    \" & _
"End Function                            \" & _
";--------------------------------------------------------------\" & _
"Function OpenPEFile(FilePE)                    \" & _
";Открытие файла                        \" & _
"OpenPEFile=Sys.DynApi.CallFunction( _                \" & _
"        'KERNEL32.DLL','CreateFileA', _            \" & _
"                FilePE, _            \" & _
"                GENERIC_READ, _        \" & _
"                FILE_SHARE_READ, _        \" & _
"                0, _                \" & _
"                OPEN_EXISTING, _        \" & _
"                FILE_ATTRIBUTE_READONLY, _    \" & _
"                0)                \" & _
"End Function                            \" & _
";--------------------------------------------------------------\" & _
"Function GetVarPtr(cVar)                    \" & _
"    GetVarPtr=VarPtr(cVar)                    \" & _
"End Function                            \" & _
"<#Module>"
'---------------------------------------------------------------
Set LMActiveX=CreateObject("Atomix.LangMF")

LMFCode=Replace(LMFCode,Chr(39),Chr(34))
LMFCode=Replace(LMFCode,"\",vbCRLF)
LMFCode=Replace(LMFCode,";","'")
    
LMActiveX.Command LMFCode
'---------------------------------------------------------------
    'Диалог открытие файла
    FileName=LMActiveX.FuncRun("OpenFileDlg",1)
    If FileName=vbNullString Then
        LMActiveX.Reset
        WScript.Quit
    End If
    FileName1=FileName
    'После пропуска через OpenPEFile значение FileName 
    'теряет читабельность,поэтому заранее сохранено
    'в переменной FileName1
    '-------------------------------------------------------
    'Открытие файла
    hFile=LMActiveX.FuncRun("OpenPEFile",1,FileName)
    If hFile=-1 Or hFile=0 Then
        Msgbox     "Невозможно открыть указанный файл," & _
            "имя задано неверно,либо не задано вовсе.", _
            vbExclamation,"Open File Error"
        LMActiveX.Reset
        WScript.Quit
    End If
'---------------------------------------------------------------
'Отображение файла в память.В отображенном виде PE файл 
'представляет из себя развернутую структуру с базовым адресом hMap,
'содержащую байт-код.Мэппированный файл подобен просмотру в Hiew,
'в режиме дизассемблера.

Set CreateFileMappingAC=CreateObject("DynamicWrapper")
CreateFileMappingAC.Register _
"KERNEL32.DLL","CreateFileMappingA","i=hlllls","f=s","r=l"

hMap=CreateFileMappingAC.CreateFileMappingA( _
        hFile, _
        0, _
        PAGE_READONLY, _
        0, _
        0, _
        "")    
'---------------------------------------------------------------
Set MapViewOfFileC=CreateObject("DynamicWrapper")
MapViewOfFileC.Register _
"KERNEL32.DLL","MapViewOfFile","i=hllll","f=s","r=l"
hView=MapViewOfFileC.MapViewOfFile( _
        hMap, _
        FILE_MAP_READ, _
        0, _
        0, _
        0)

'Дескриптор hView соответствует адресу заголовка IMAGE_DOS_HEADER
'в выделенной области памяти и является базовым адресом 
'структуры отображенного файла

'---------------------------------------------------------------
'Получение сигнатуры заголовка IMAGE_DOS_HEADER
    DOS_SIGN=GetDataDWORD(hView,2,0)
'---------------------------------------------------------------
'Получение адреса структуры заголовка IMAGE_NT_HEADERS
'Этот последний параметр структуры IMAGE_DOS_HEADER соответствует
'смещению 60=0x3C
    IMAGE_NT_HEADERS_ADDR=GetDataDWORD(hView,4,60)
'---------------------------------------------------------------
'Получение сигнатуры заголовка IMAGE_NT_HEADERS
    NT_SIGN=GetDataDWORD(hView,4,IMAGE_NT_HEADERS_ADDR)
    NT_SIGN=InvertDataDWORD(NT_SIGN)
If NT_SIGN<>"50450000" Then  
Msgbox     "Указанный файл не является исполняемым PE файлом для Win32", _
    vbExclamation,"Open File Error"
    ReleaseMapping()
    LMActiveX.Reset
    WScript.Quit()
End If
'---------------------------------------------------------------
'Получение количества секций PE файла из структуры
'IMAGE_FILE_HEADER.Основная тонкость-правильно подобрать 
'смещение и количество перемещаемых байт.
    SNUM=GetDataDWORD(hView,2,IMAGE_NT_HEADERS_ADDR+6)



'---------------------------------------------------------------
WScript.Echo _
"[Имя открываемого файла]"     & vbCR & FileName1 & vbCR & _
"[Дескриптор файла]"         & vbCR & Hex(hFile) & vbCR & _
"[Базовый адрес отображения]" & vbCR & Hex(hMap) & vbCR & _
"[Сигнатура DOS]"          & vbCR & Hex(DOS_SIGN) & vbCR & _
"[Адрес структуры заголовка IMAGE_NT_HEADERS]" _
                & vbCR & Hex(IMAGE_NT_HEADERS_ADDR) & vbCR & _
"[Сигнатура NT]"          & vbCR & NT_SIGN & vbCR & _
"[Количество секций файла]"    & vbCR & SNUM
'---------------------------------------------------------------
'Можно использовать Hiew,чтобы проверить правильнось значения 
'NumberOfSections [количество секций в файле].Откройте заданный
'файл в Hiew и переведите редактор в режим дизассемблера.Нажав 
'кнопку F8 можно усмотреть NumberOfSections и сравнить со значением
'получаемым через скрипт.

ReleaseMapping()

'************ Вспомогательные функции **************************

'[Обьязательное освобождение ресурсов отображения]
'[Закрытие дескрипторов]
'---------------------------------------------------------------
Function ReleaseMapping()

'Внимание!Перед завершением работы скрипта все дескрипторы
'должны быть обьязательно закрыты.В противном случае
'экземпляр мэппированного файла сохранится в памяти
'что приведет к невозможности повторного исполнения
'отображения файла в память.

Set UnmapViewOfFileC=CreateObject("DynamicWrapper")
UnmapViewOfFileC.Register _
        "KERNEL32.DLL","UnmapViewOfFile","i=h","f=s"
UnmapViewOfFileC.UnmapViewOfFile hView 

'---------------------------------------------------------------
Set CloseHandleC=CreateObject("DynamicWrapper")
CloseHandleC.Register _
        "KERNEL32.DLL","CloseHandle","i=h","f=s"

CloseHandleC.CloseHandle hView 
CloseHandleC.CloseHandle hMap
CloseHandleC.CloseHandle hFile

    Set UnmapViewOfFileC    =Nothing
    Set RtlMoveMemoryC    =Nothing
    LMActiveX.Reset
End Function

'[Инвертирование числа DWORD]
'---------------------------------------------------------------
Function InvertDataDWORD(data)
data=CStr(Hex(data))
data=String(8-Len(data),"0") & data
    B1=Mid(data,1,2)
    B2=Mid(data,3,2)
    B3=Mid(data,5,2)
    B4=Mid(data,7,2)

    InvertDataDWORD=B4 & B3 & B2 & B1
End Function

'[Извлечение DWORD данных из отображенного файла]
'---------------------------------------------------------------
Function GetDataDWORD(lpData,iSize,iOffset)
    Dim pDest,tdOffset
    GetDataDWORD=CLng(0)
    pDest=LMActiveX.FuncRun("GetVarPtr",1,GetDataDWORD)
    GetDataDWORD=CLng(0)
    RtlMoveMemoryC.RtlMovememory pDest+8,lpData+iOffset,iSize 
End Function 
'---------------------------------------------------------------
'Poltergeyst

Пример результата работы скрипта:

[Имя открываемого файла]
C:\WINDOWS\notepad.exe
[Дескриптор файла]
580
[Базовый адрес отображения]
5C4
[Сигнатура DOS]
5A4D
[Адрес структуры заголовка IMAGE_NT_HEADERS]
E0
[Сигнатура NT]
50450000
[Количество секций файла]
3

Скрипт должен показывать такое сообщение для DLL и EXE файлов. Если файл не является PE, например текстовый, то будет показано соответствующее оповещение.
Автор скрипта - Poltergeyst.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

2

Re: VBScript & LangMF: исследование Win32 PE файлов

Получение информации о PE файле с помощью объекта JSSys3.dll:

Set pe = CreateObject("JSSys3.Ops").GetPEFile("C:\WINDOWS\notepad.exe")
WScript.Echo pe.CompanyName
WScript.Echo pe.FileVersion
WScript.Echo pe.DateCreated
WScript.Echo pe.DateLastModified
WScript.Echo pe.ProductVersion
WScript.Echo pe.ProductName
WScript.Echo pe.FileDescription
WScript.Echo pe.Size
WScript.Echo pe.Attributes ' combination of: 0 - normal/archive, 1 - ReadOnly, 2 - Hidden, 4 - System
WScript.Echo pe.Name
Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.