hola compañeros.
Tengo una duda en esta parte del codigo de Karcrack
Call CopyMemory(ish(i), ByteArray(idh.e_lfanew + Len(inh) + Len(ish(i)) * i), Len(ish(i)))
realmente no estoy seguro?
en esta parte lo que hago es pasar a Puntero el offset equivalente a esto
ByteArray(idh.e_lfanew + Len(inh) + Len(ish(i)) * i)
:S estoy medio confundido.
Si no me equivoco esté código no es mío, sino de Cobein. Aún así lo que hace esa linea es rellenar la estructura de la sección ISH(i) con los correspondientes valores de la cabecera PE.
Si ésto te suena a chino mejor será que le eches un ojo al excelente trabajo de The Swash
http://foro.elhacker.net/analisis_y_diseno_de_malware/taller_en_construccionsecciones_en_archivos_pe-t362515.0.html
Saludos
Cita de: Karcrack en 8 Agosto 2012, 16:54 PM
Si no me equivoco esté código no es mío, sino de Cobein. Aún así lo que hace esa linea es rellenar la estructura de la sección ISH(i) con los correspondientes valores de la cabecera PE.
Si ésto te suena a chino mejor será que le eches un ojo al excelente trabajo de The Swash
http://foro.elhacker.net/analisis_y_diseno_de_malware/taller_en_construccionsecciones_en_archivos_pe-t362515.0.html
Saludos
donde lo consegui dice que es tuyo. :S
aqui el codigo completo.
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal L 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
e_magic As Integer ' Magic number
e_cblp As Integer ' Bytes on last page of file
e_cp As Integer ' Pages in file
e_crlc As Integer ' Relocations
e_cparhdr As Integer ' Size of header in paragraphs
e_minalloc As Integer ' Minimum extra paragraphs needed
e_maxalloc As Integer ' Maximum extra paragraphs needed
e_ss As Integer ' Initial (relative) SS value
e_sp As Integer ' Initial SP value
e_csum As Integer ' Checksum
e_ip As Integer ' Initial IP value
e_cs As Integer ' Initial (relative) CS value
e_lfarlc As Integer ' File address of relocation table
e_ovno As Integer ' Overlay number
e_res(0 To 3) As Integer ' Reserved words
e_oemid As Integer ' OEM identifier (for e_oeminfo)
e_oeminfo As Integer ' OEM information; e_oemid specific
e_res2(0 To 9) As Integer ' Reserved words
e_lfanew As Long ' File address of new exe header
End Type
' MSDOS File header
Private Type IMAGE_FILE_HEADER
Machine As Integer
NumberOfSections As Integer
TimeDateStamp As Long
PointerToSymbolTable As Long
NumberOfSymbols As Long
SizeOfOptionalHeader As Integer
characteristics As Integer
End Type
' Directory format.
Private Type IMAGE_DATA_DIRECTORY
VirtualAddress As Long
Size As Long
End Type
' Optional header format.
Const IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16
Private Type IMAGE_OPTIONAL_HEADER
' Standard fields.
Magic As Integer
MajorLinkerVersion As Byte
MinorLinkerVersion As Byte
SizeOfCode As Long
SizeOfInitializedData As Long
SizeOfUnitializedData As Long
AddressOfEntryPoint As Long
BaseOfCode As Long
BaseOfData As Long
' NT additional fields.
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
W32VersionValue 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(0 To IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1) 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
' Section header
Const IMAGE_SIZEOF_SHORT_NAME = 8
Private Type IMAGE_SECTION_HEADER
SecName As String * IMAGE_SIZEOF_SHORT_NAME
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 ByteArray() As Byte ' Byte array del archivo a leer
Public TempArray() As Byte ' Array temporal para reducir el ByteArray
Public Config() As Byte ' La posible configuraci�n del archivo leido
Public idh As IMAGE_DOS_HEADER ' Cabeceras
Public inh As IMAGE_NT_HEADERS
Public ish() As IMAGE_SECTION_HEADER
Sub RellenarPE(Ruta As String)
Open Ruta For Binary As #1
ReDim ByteArray(LOF(1) - 1)
Get #1, , ByteArray
Close #1
' Leemos el MS-DOS stub
CopyMemory idh, ByteArray(0), Len(idh)
If idh.e_magic <> IMAGE_DOS_SIGNATURE Then
MsgBox "Formato PE no v�lido", vbCritical, "Small Crypter"
Exit Sub
End If
' Leemos a partir del PE00 comletando a su vez:
' -> IMAGE_FILE_HEADER (COFF File Header)
' -> IMAGE_OPTIONAL_HEADER (Optional Header)
CopyMemory inh, ByteArray(idh.e_lfanew), Len(inh)
If inh.Signature <> IMAGE_NT_SIGNATURE Then
MsgBox "Formato PE no v�lido", vbCritical, "Small Crypter"
Exit Sub
End If
' Leemos las distintas secciones
Dim i As Integer
ReDim ish(inh.FileHeader.NumberOfSections - 1)
For i = 0 To inh.FileHeader.NumberOfSections - 1
Call CopyMemory(ish(i), ByteArray(idh.e_lfanew + Len(inh) + Len(ish(i)) * i), Len(ish(i)))
Next i
End Sub
lo que me pregunto que si todo esto ByteArray(idh.e_lfanew + Len(inh) + Len(ish(i)) * i) lo podria resumir obteniendo el VirtualAddress.
En realidad gran parte del trabajo de memoria con las estructuras lo puedes obviar y trabajar directamente con los offsets de referencia... Échale un ojo al kRunPE:
http://foro.elhacker.net/programacion_visual_basic/mvb6fud_krunpe_ejecuta_ejecutables_desde_bytearray-t300432.0.html
Ahí hay un bucle que recorre todas las secciones del PE y verás como lo hace con offsets, sin tener que ir copiando estructuras completas.
ByteArray(idh.e_lfanew + Len(inh) + Len(ish(i)) * i)
Te explico más detalladamente: lo que haces ahí es obtener el primer byte de la sección en cuestión, pero como tienes declarado el parámetro de la API como ByRef lo que le pasa es el puntero al primer byte de la sección. Si quieres evitar acceder a "ByteArray" por cuestiones de detección declara el segundo parámetro de CopyMemory() como ByVal y puedes pasarle directamente (idh.e_lfanew + Len(inh) + Len(ish(i)) * i) pero recuerda arreglar el resto de punteros ;)
Un saludo
PD: Según veo en el código lo habrás sacado del SmallCrypter de E0N... Así que si no es de E0N es de Cobein. Quién lo postease pensó que fui yo, pero nope :laugh:
Cita de: Karcrack en 8 Agosto 2012, 17:32 PM
En realidad gran parte del trabajo de memoria con las estructuras lo puedes obviar y trabajar directamente con los offsets de referencia... Échale un ojo al kRunPE:
http://foro.elhacker.net/programacion_visual_basic/mvb6fud_krunpe_ejecuta_ejecutables_desde_bytearray-t300432.0.html
Ahí hay un bucle que recorre todas las secciones del PE y verás como lo hace con offsets, sin tener que ir copiando estructuras completas.
ByteArray(idh.e_lfanew + Len(inh) + Len(ish(i)) * i)
Te explico más detalladamente: lo que haces ahí es obtener el primer byte de la sección en cuestión, pero como tienes declarado el parámetro de la API como ByRef lo que le pasa es el puntero al primer byte de la sección. Si quieres evitar acceder a "ByteArray" por cuestiones de detección declara el segundo parámetro de CopyMemory() como ByVal y puedes pasarle directamente (idh.e_lfanew + Len(inh) + Len(ish(i)) * i) pero recuerda arreglar el resto de punteros ;)
Un saludo
Muchas gracias Ya entiendo. Igual me voy a mirar el kRunPE. saludos Karcrack
De nada, para eso estamos >:D