Buscar huecos en ejecutables.

Iniciado por Slasher-K, 20 Agosto 2005, 08:39 AM

0 Miembros y 1 Visitante están viendo este tema.

Slasher-K

Para los que le interese la programación de virus este código sirve para buscar espacios libres en la sección de código del ejecutable para luego poder insertar nuestro código ahi.

Lo bueno de este método es que la sección de código (.text) siempre tiene permiso de ejecución por lo que no nos dará errores de protección.

Necesita agregar como referencia al proyecto win.tlb


'
'Coded by Slasher
'
Option Explicit
Option Base 1

Public Const IMAGE_SIZEOF_SHORT_NAME = 8
Public Const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16

Public Const IMAGE_DOS_SIGNATURE = &H5A4D      ' MZ
Public Const IMAGE_OS2_SIGNATURE = &H454E      ' NE
Public Const IMAGE_OS2_SIGNATURE_LE = &H454C   ' LE
Public Const IMAGE_NT_SIGNATURE = &H4550       ' PE
Public Const IMAGE_FILE_UNKNOWN = &H0          ' Desconocido


Type IMAGE_DOS_HEADER
  e_magic     As Integer
  e_cblp      As Integer
  e_cp        As Integer
  e_crlc      As Integer
  e_cparhdr   As Integer
  e_minalloc  As Integer
  e_maxalloc  As Integer
  e_ss        As Integer
  e_sp        As Integer
  e_csum      As Integer
  e_ip        As Integer
  e_cs        As Integer
  e_lfarlc    As Integer
  e_ovno      As Integer
  e_res(3)    As Integer
  e_oemid     As Integer
  e_oeminfo   As Integer
  e_res2(9)   As Integer
  e_lfanew    As Long
End Type

Type IMAGE_FILE_HEADER
  Magic                 As Long
  Machine               As Integer
  NumberOfSections      As Integer
  TimeDateStamp         As Long
  PointerToSymbolTable  As Long
  NumberOfSymbols       As Long
  SizeOfOptionalHeader  As Integer
  Characteristics       As Integer
End Type

Type IMAGE_DATA_DIRECTORY
  VirtualAddress  As Long
  Size            As Long
End Type

Type IMAGE_OPTIONAL_HEADER
'Campos estándar
'
  Magic                     As Integer
  MajorLinkerVersion        As Byte
  MinorLinkerVersion        As Byte
  SizeOfCode                As Long
  SizeOfInitializedData     As Long
  SizeOfUninitializedData   As Long
  AddressOfEntryPoint       As Long
  BaseOfCode                As Long
  BaseOfData                As Long
 
'Campos adicionales de NT
'
  ImageBase                     As Long
  SectionAlignment              As Long
  FileAlignment                 As Long
  MajorOperatingSystemVersion   As Integer
  MinorOperatingSystemVersion   As Integer
  MajorImageVersion             As Integer
  MinorImageVersion             As Integer
  MajorSubsystemVersion         As Integer
  MinorSubsystemVersion         As Integer
  Reserved1                     As Long
  SizeOfImage                   As Long
  SizeOfHeaders                 As Long
  CheckSum                      As Long
  Subsystem                     As Integer
  DllCharacteristics            As Integer
  SizeOfStackReserve            As Long
  SizeOfStackCommit             As Long
  SizeOfHeapReserve             As Long
  SizeOfHeapCommit              As Long
  LoaderFlags                   As Long
  NumberOfRvaAndSizes           As Long
  DataDirectory(IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1) As IMAGE_DATA_DIRECTORY
End Type

Type HoleInfo
  Offset  As Long
  Size    As Long
End Type

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

Sub Main()
        Dim lpHoles() As HoleInfo
        Dim hMap&, lBase&, lSize&
        Dim lHoles&, i&

  hMap = MapExe("C:\WINDOWS\SYSTEM32\NOTEPAD.EXE")
  lBase = GetCodeOffset(hMap, lSize)
 
  'Busca huecos de 128 bytes como mínimo.
  '
  lHoles = FindHoles(hMap, lBase, lSize, lpHoles, 128)
 
  For i = 1 To lHoles
    Debug.Print "Hueco Nº " & i, "Offset: 0x" & Hex$(lpHoles(i).Offset), _
                "Tamaño: 0x" & Hex$(lpHoles(i).Size)
  Next
 
  Call VirtualFree(hMap, 0&, MEM_RELEASE)

End Sub

Function MapExe(Filename As String) As Long
        Dim hMem&, hFile&
        Dim r&

  hFile = CreateFile(Filename, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&)
 
  If hFile = INVALID_HANDLE_VALUE Then Exit Function
 
  'Asigna memoria.
  '
  hMem = VirtualAlloc(0&, GetFileSize(hFile, 0), MEM_COMMIT, PAGE_READWRITE)
 
  'Lee el archivo a memoria.
  '
  r = ReadFile(hFile, ByVal hMem, GetFileSize(hFile, 0), 0&, ByVal 0&)
 
  MapExe = hMem
End Function

Function GetCodeOffset(hMap As Long, Optional outSize As Long) As Long
        Dim lpDosHdr  As IMAGE_DOS_HEADER
        Dim lpFileHdr As IMAGE_FILE_HEADER
        Dim lpOptHdr  As IMAGE_OPTIONAL_HEADER
        Dim r&

  r = ReadProcessMemory(GetCurrentProcess(), hMap, lpDosHdr, Len(lpDosHdr))
 
  If lpDosHdr.e_magic <> IMAGE_DOS_SIGNATURE Then Exit Function
 
  r = ReadProcessMemory(GetCurrentProcess(), hMap + lpDosHdr.e_lfanew + Len(lpFileHdr), lpOptHdr, Len(lpOptHdr))
 
  outSize = lpOptHdr.SizeOfCode
  GetCodeOffset = lpOptHdr.BaseOfCode
End Function

Function FindHoles(hMap As Long, BaseOfCode As Long, SizeOfCode As Long, outHoles() As HoleInfo, Optional MinSize As Integer) As Long
        Dim btData() As Byte
        Dim lHoleSize&, lCnt&
        Dim r&, i&

  ReDim btData(SizeOfCode) As Byte
 
  r = ReadProcessMemory(GetCurrentProcess(), hMap + BaseOfCode, btData(1), SizeOfCode)
 
  If MinSize <= 0 Then MinSize = 128
 
  Erase outHoles
 
  For i = 1 To SizeOfCode
    If btData(i) <> 0 And lHoleSize > MinSize Then
      lCnt = lCnt + 1
     
      ReDim Preserve outHoles(lCnt) As HoleInfo
     
      outHoles(lCnt).Offset = BaseOfCode + i
      outHoles(lCnt).Size = lHoleSize
     
      lHoleSize = 0
     
    ElseIf btData(i) = 0 Then
      lHoleSize = lHoleSize + 1
    End If
  Next
 
  FindHoles = lCnt
End Function


Saludos.



A la reina de las profundidades que cuida los pasos de una sombra en la noche :*

ArcanuS

Slasher amigo, muy bueno el code, jeje no esperaba menos de ti!
Salu2.
ArcanuS
"Solo el conociemiento te hace libre"

ZEALOT

muy bueno, pero pareciera que está incompleto, WriteProcessMemory se declara pero no se utiliza, quisiera estudiarlo completamente, osea, si esta incompleto, de donde lo sacaste men?

Slasher-K

El código lo escribi yo y no está incompleto, WriteProcessMemory está ahi por costumbre porque la librería win.tlb no trae ni ReadProcessMemory ni WriteProcessMemory y a esas funciones las uso muuuy seguido.

Saludos.



A la reina de las profundidades que cuida los pasos de una sombra en la noche :*