feedburner
Enter your email address:

Delivered by FeedBurner

Programación VB. EXE file scanner !

CATEGORIAS: , ,


Rasgos Generales de file scanner en VB. Explicando método de funcionamiento

¿Qué es eso? - esto es un programa que define con que está compilado o empaquetado un fichero ejecutable.
Uno de los mas populares de este tipo de programas es PEID.Pues ahora analizaremos ciertos códigos necesarios para scanear ejecutables.

Formato de archivo

En breve explicando DOS-Headers: DOS-Headers comprueba, si el programa se ejecuta por DOS o no, y se lanza DOS stub el cual mostrará siguiente línea
"This рrogram cannot run in DOS mode". Aquí usaremos siguientes campos:
Magic – debe contener "4D5Ah" que equivale "MZ";lfanew – longitud de DOS header, para saber donde se encuentra PE-Header

Option Explicit

'DOS Header

Public 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

РE-Header – contiene muchos campos importantes. Lo que necesitamos son siguientes: Signature – debe ser PE al cual le siguen dos ceros, en caso contrario no lo será ; NumObjects – cantidad de secciones en archivo; EntryPointRVA – dirección, relacionado con Image Base por el cual pasa el proceso del manipulación al ejecutar el programa; ImageBase – dirección inicial virtual de ejecución del programa

'PE Header
Public Type PE_HEADER
Signature As String * 4
CPU_Type As Integer ´tipo de procesor
'CPU Type tiene siguientes valores:
'14Ch -i386
'014Dh - i486
'014Eh - i586
'0162h - MIPS Mark I (R2000, R3000)
'0163h - MIPS Mark II (R6000)
'0166h - MIPS Mark III (R4000)
NumObjects As Integer ´cantidad de secciones
TimeDateStamp As Long
pCOFFTable As Long
COFFTableSize As Long
NTHeaderSize As Integer
Flags As Integer
Magic As Integer
LinkMajor As Byte
LinkMinor As Byte
SizeOfCode As Long
SizeOfInitData As Long
SizeOfUnInitData As Long
EntryPointRVA As Long
BaseOfCode As Long
BaseOfData As Long
ImageBase As Long
ObjectAlign As Long
FileAlign As Long
OSMajor As Integer
OSMinor As Integer
USERMajor As Integer
USERMinor As Integer
SubSysMajor As Integer
SubSysMinor As Integer
Reserved1 As Long
ImageSize As Long
HeaderSize As Long
FileCheckSum As Long
SubSytem As Integer
'SubSystem tiene siguientes valores:
'0001h - Native
'0002h - Windows GUI
'0003h - Windows Character
' (console aplication)
'0005h - OS/2 Character
'0007h - Posix Character
DLLFlags As Integer
StackReserveSize As Long
StackCommitSize As Long
HeapReserveSize As Long
HeapComitSize As Long
LoaderFlags As Long
NumOfRVAandSizes As Long
ExportTableRVA As Long
ExportDataSize As Long
ImportTableRVA As Long
ImportDataSize As Long
ResourceTableRVA As Long
ResourceDataSize As Long
ExceptionTableRVA As Long
ExceptionDataSize As Long
SecurityTableRVA As Long
SecurityDataSize As Long
FixTableRVA As Long
FixDataSize As Long
DebugTableRVA As Long
DebugDataSize As Long
ImageDescriptionRVA As Long
DescriptionDataSize As Long
MachineSpecificRVA As Long
MachnineDataSize As Long
TLSRVA As Long
TLSDataSize As Long
LoadConfigRVA As Long
LoadConfigDataSize As Long
Reserved2(39) As Byte
End Type

Object Table - es una serie de estructuras. La cantidad se define con Num of Objects. El campo SectionName – nombre de sección, maxima longitud 8 bytes; VirtualSize – tamaño virtual de la sección; VirtualAddress – dirección virtual de la sección; PointerToRawData – desplazamiento del fichero al inicio del fichero.

'Object Table
Public Type IMAGE_SECTION_HEADER
SectionName As String * 6
PhisicalAddress As Integer
VirtualSize As Long
VirtualAddress As Long
SizeOfRawData As Long
PointerToRawData As Long
PointerToRelocations As Long
PointerToLinenumbers As Long
NumberOfRelocations As Integer
NumberOfLinenumbers As Integer
Characteristics As Long
End Type

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Public 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

Public Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead _
As Long, lpOverlapped As Any) As Long

Public Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As _
Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal _
dwMoveMethod As Long) As Long

Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Public tDos As IMAGE_DOS_HEADER
Public tFile As PE_HEADER
Public tSection() As IMAGE_SECTION_HEADER

Dim cFileOffset As Long
Dim PackBytes As String

Comprobando es PE (Portable Executable) o no:

Ahora crearemos función que definirá si el fichero es ejecutable o no.

Public Function ChkforPe(hFile As Long) As Boolean
Dim Buffer(4) As Byte
Dim lngBytesRead As Long
Dim tDosHeader As IMAGE_DOS_HEADER

If (hFile > 0) Then
' para leer DOS Header
ReadFile hFile, tDosHeader, ByVal Len(tDosHeader), lngBytesRead, ByVal 0&
CopyMemory Buffer(0), tDosHeader.Magic, 2
If (Chr(Buffer(0)) & Chr(Buffer(1)) = "MZ") Then
SetFilePointer hFile, tDosHeader.lfanew, 0, 0
' salta al final del header y lee 4 bytes en buffer
ReadFile hFile, Buffer(0), 4, lngBytesRead, ByVal 0&
If (Chr(Buffer(0)) = "P") And (Chr(Buffer(1)) = "E") And _
(Buffer(2) = 0) And (Buffer(3) = 0) Then
' debe ser "PE" y dos bytes equivalents a 0
ChkforPe = True ´realmente es un PE (Portable Executable)!
Exit Function
End If
End If
End If
ChkforPe = False
End Function

Bueno, de esta forma comprobamos DOS Header, y si el fichero tiene correcto DOS Header , encontramos PE-Header usando lfanew.

GetFileOffset

Siguiente función encuentra dirección de la sección en archivo por donde debe comenzar.

Public Function GetFileOffset(sFile As String) As String
Dim PointerToRaw As Long
Dim SizeOfRaw As Long
Dim VirtualAdr As Long
Dim EPoint As Long
Dim sTemp As Long
Dim sData() As Byte
Dim sU As Integer

Open sFile For Binary As #1
ReDim sData(LOF(1) - 1)
Get #1, , sData
Close #1

Dim sTemp1 As Long
Dim sTemp2 As Long

cFileOffset = 0 ´pone en zero offset
CopyMemory tDos, sData(sTemp1), Len(tDos)
' llega a tabla de sección del objeto.
' se encuentra después de PE header
CopyMemory tFile, sData(tDos.lfanew), Len(tFile)
sTemp1 = sTemp1 + tDos.lfanew + Len(tFile)
' rellena array de la sección con datos
ReDim tSection(tFile.NumObjects - 1)
For sTemp2 = 0 To UBound(tSection)
CopyMemory tSection(sTemp2), sData(sTemp1), Len(tSection(0))
sTemp1 = sTemp1 + Len(tSection(0))
Next sTemp2
' obtiene "punto de entrada"
EPoint = tFile.EntryPointRVA
For sU = 0 To UBound(tSection)
sTemp1 = tSection(sU).VirtualAddress
sTemp2 = sTemp1 + tSection(sU).VirtualSize
If EPoint >= sTemp1 And EPoint <= sTemp2 Then GoTo sNex Next sU sNex: sTemp = tSection(sU).VirtualAddress - tSection(sU).PointerToRawData cFileOffset = EPoint - sTemp GetFileOffset = cFileOffset End Function GET1stBytes

Esta funcón pasa por cierta cantidad de bytes obtenidos por función GetFileOffset y cuenta en variable PackBytes siguientes 30 bytes.

Public Function Get1stBytes(sFile As String) As String
Dim sX As Integer
Dim sBytes As String * 30
Dim sTemp As String
PackBytes = ""
Open sFile For Binary Access Read As #1
Seek #1, cFileOffset + 1'
Get #1, , sBytes Close #1
For sX = 1 To Len(sBytes)
sTemp = Hex(Asc(Mid(sBytes, sX, 1)))
If sTemp = "0" Then
sTemp = "00"
ElseIf Len(sTemp) = 1 Then
sTemp = "0" & sTemp
End If
PackBytes = PackBytes & sTemp
Get1stBytes = Get1stBytes & sTemp & " "
Next sX

End Function

PakerName

Esta function comprobará los signatures.

Public Function PackerName() As String
Dim sTemp As String
If Trim(PackBytes) Like _
Trim("68????????E8????????0000??00000030000000????????????????????") _
Then
PackerName = "Microsoft Visual Basic v5.0/v6.0"
Else
PackerName = "Nothing found!"
End If
End Function

Bueno, hay varios códigos de este material, y más existe una database grande de los signatures, pero es recomendable usarlo con método Select case.

Saludos
Special thanx to : sl1ppy / arnoldiK


Buscas un programa y no lo encuentras? Pidelo , posteando en blog o en tag y te lo conseguimos!



0 comments:

Post a Comment