Hola! estuve buscando algun ejemplo o algo pero no encontre ninguno en vb.. alguno tiene por ahi algun ejemplo? o alguien que me guie para iniciar nomas..
salu2! y gracias de antemano!
Es muy simple, lees el archivo, rellenas las estructuras PE y las muestras. Alguna duda concreta?
Cita de: E0N en 28 Septiembre 2008, 01:33 AM
Es muy simple, lees el archivo, rellenas las estructuras PE y las muestras. Alguna duda concreta?
de que manera se abre el archivo para mostrar por ejemplo el imagebase?
y de que manera se guarda el archivo para guardar el imagebase modificado?
salu2!
PD: luego si puedo terminarlo publico el source..
Pues en modo binario, lo lees y rellenas las estructuras con CopyMemory, hay varios ejemplos por el foro ;) Luego guardas las estructuras modificadas y listo (te recomiendo que mapees el archivo)
Salu2
http://rapidshare.com/files/149246470/PE.rar.html
he llegado hasta ahi.. con cosas que encontre y fui modificando.. pero no me guarda bien la modificacion y no logro hacerlo andar bien.. alguno puede ayudarme? puse para probar con imagebase nomas
salu2!
No funciona leyendo el archivo en modo binario, porque si, por ejemplo, queres explorar la estructura del formato PE para acceder a las Tablas de importacion para conocer las direcciones de memoria de las apis que llama el programa no vas a poder. Porque estas direcciones se cargan en memoria antes de que el programa empiece a correr. Para explorarlo y modificarlo hay que hacerlo mienntras el programa esta funcionando.
Te recomiendo este texto:
http://goodfellas.shellcode.com.ar/docz/bof/UN-shellcodes_1.txt
y para explorar la memoria de un programa en funcionamiento hice este codigo de un programa que explora su propia memoria, para no tener que hacer una "DLL Injection" ni nada parecido.
'PEGAR EN UN FORMULARIO Form1
'el proyecto necesita los siguientes componentes:
'un textbox Text1 para ingresar la direccion de memoria que se quiere leer
'(&H400000 seria la Direccion Base de la Imagen)
'un textbox Text2 para ingresar la cantidad de bytes a leer
' " " Text3 para mostrar los bytes en Hexadecimal (Font = Fixedsys)
' (Font = Fixedsys, Multiline = True, ScrollBars = 2-Vertical)
' " " Text4 para mostrar los bytes en Ascii
' (Font = Fixedsys, Multiline = True, ScrollBars = 2-Vertical)
'un boton Comman1 para iniciar la lectura
'
' los bytes en Ascii no se ven bien por los caracteres no imprimibles, como
' el retorno de carro, el tab, y el salto de linea.
Option Explicit
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, _
ByVal lpBaseAddress As Any, _
lpBuffer As Any, _
ByVal nSize As Long, _
lpNumberOfBytesWritten As Long) As Long
Private Sub Command1_Click()
LeerMemoria Text3, Text4, CLng(Trim$(Text1.Text)), CLng(Text2.Text)
End Sub
Private Sub LeerMemoria(T_Hex As TextBox, T_Ascii As TextBox, Direccion As Long, CantidadDeBytes As Long)
Dim PID As Long
Dim hProc As Long
ReDim Buffer(1 To CantidadDeBytes) As Byte
Dim ret As Long
Dim Contador As Long
Dim i As Long
Dim ByteX As String
PID = GetCurrentProcessId
hProc = OpenProcess(PROCESS_ALL_ACCESS, False, PID)
ReadProcessMemory hProc, Direccion, Buffer(1), CantidadDeBytes, ret
T_Hex.Text = vbNullString
T_Ascii.Text = vbNullString
Contador = 0
For i = 1 To CantidadDeBytes
Contador = Contador + 1
ByteX = Hex$(Buffer(i))
If Len(ByteX) = 1 Then ByteX = "0" + ByteX
T_Hex.Text = T_Hex.Text + ByteX + " "
T_Ascii.Text = T_Ascii.Text + Chr$(Buffer(i))
If Contador = 16 Then
T_Hex.Text = T_Hex.Text + vbCrLf
T_Ascii.Text = T_Ascii.Text + vbCrLf
Contador = 0
End If
Next i
End Sub
Private Sub Form_Load()
Text1.Text = "&H400000"
Text2.Text = "100"
Command1.Caption = "Leer Memoria"
Text4.Text = vbNullString
Text5.Text = vbNullString
End Sub
Agregue, en cierta ocacion, una llamada a la api MessageBoxA para ver si podia obtener la direccion de mememoria de la funcion en la tabla de importacion, para poder cambiarla pero ni siquiera la encontré. VB hace cosas que supongo extraña, en la tabla solo encontre librerias de VB y nada mas. ¿Alguien sabe como llegar a obtener esas direcciones? seria una especie de intento por hacer "API Hooking" modificando la tabla de importacion con VB.
Por ahora demoniox12 te adelanto que si lees los primeros bytes a partir de la direccion &H40003c vas a encontrar la direccion de memoria donde empieza la cabecera PE, y 80 bytes mas adelante de la direccion donde empieza la cabecera PE esta almacenada la direccion donde empiezan las iTables (Tablas de Importacion), importantes en temas como Api Hooking y Shellcodes Universales.
Lamentablemente creo que no hay muchos expertos en estos temas en el foro de VB6, no es por ofender a nadie, seguro que hay gente que sabe y mucho de esto, pero no creo que sean muchos por aca. Debe haber mas en los que frecuentan foros de de C o Malware, pero en esos casos vi que a gente que habla de VB los tratan como si habaran de resolver matrices con un ábaco.
CitarNo funciona leyendo el archivo en modo binario, porque si, por ejemplo, queres explorar la estructura del formato PE para acceder a las Tablas de importacion para conocer las direcciones de memoria de las apis que llama el programa no vas a poder.
Si, si que se puede, a ver si te crees que se cargan en posiciones de memoria aleatorias xDD Luego hablamos de eso :P
Primero una demostración de lo que pide el amigo demoniox12:
En un form:
Private Sub Form_Load()
RellenarPE ("C:\pru.exe")
MsgBox Hex(inh.OptionalHeader.ImageBase)
End
End Sub
En un módulo:
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 ''\\ PE\0\0
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 PE\0\0 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
Verás que te muestra en un msgbox el image base del archivo C:\pru.exe, para hacer el editor simplemente muestra los distintos datos en text boxes y luego guarda los valores modificados en un nuevo archivo.
achernar_
CitarAgregue, en cierta ocacion, una llamada a la api MessageBoxA para ver si podia obtener la direccion de mememoria de la funcion en la tabla de importacion, para poder cambiarla pero ni siquiera la encontré. VB hace cosas que supongo extraña, en la tabla solo encontre librerias de VB y nada mas. ¿Alguien sabe como llegar a obtener esas direcciones? seria una especie de intento por hacer "API Hooking" modificando la tabla de importacion con VB.
IAT hooking, un ejemplo en C:
http://hackhound.org/forum/index.php?topic=2726.0
Puedes ver como obtiene las direcciones en la iat y de más, otro ejemplo en C:
http://foro.elhacker.net/programacion_cc/source_recorrer_la_iat-t208200.0.html;msg989316
Si te interesan las shellcodes universales esto te será útil, en mi ejemplo lo uso para demostrar como un virus puede llamar a las apis, pero para el caso es lo mismo (y también ves como obtener la posición en memoria de las apis a partir del formato PE, fasm):
http://foro.elhacker.net/analisis_y_diseno_de_malware/source_asm_asi_llaman_los_virus_a_las_apis-t219982.0.html;msg1044189
Y ahora mismo o caigo en más ejemplos, pero ahí puedes ver como obtener la dirección en memoria de un api a partir del PE (aunque si puedes usar GetProcAddres desde el principio pues eso que te ahorras jajajajaja)
Salu2
Excelente! muchisimas gracias!!!
Salu2!
EON seguro que no se cargan en direcciones aleatorias, pero las direcciones que se cargan en la tabla de importacion (las de las apis que usa el programa) son diferentes en diferentes versiones de windows. Si el mismo programa lo ejecutas en un windows XP sp1 y despues lo ejecutas en un Windows XP sp2 o en español e inglés, la tabla de importacion se va a cargar con diferentes valores, porque en diferentes versiones de windows las direcciones de las apis varian, este es el problema precisamente al intentar encontrar las direccines de las apis cuando se usa una shellcode. Los valores de estas direcciones no pueden ser modificados en el binario, precisamente porque se cargan al ejecutarse el programa, en direcciones, que como dicìs, no son aleatorias.
Con respecto al formato PE y las shelcodes universales lo hice con el masm32 y lo entiendo, con el texto de RaiSe pero la tabla de importacion de los programas en VB son el problema, solo los hechos en VB son como extraños, incluso para hacer practicas de craking son rebuscados, son distintos. Por lo menos asi lo veo yo XDDDD sobre todo por ese modo que tiene de usar las apis, como eso de reventarse cuando usan threads en vb6, evidentemente no hace un uso normal de las apis.
Si los valores (direcciones de las apis) en la tabla de importacion fuesen valores estaticos y se pudiesen leer en el binario directamente, serian como las shellcodes hardcodeadas, no se pordrian "Portar los Ejecutables" a otras versiones de windows.
Ya, ya se todo lo que me estás diciendo y por eso te he puesto los ejemplos que te he puesto, mira mi ejemplo en fasm y pruebalo en distintos windows y verás como no falla y no es hardcode :P haya la dirección de las apis a partir de su posición en la tabla de importaciones (realmente haya la posición de GetProcAddress y de ahñi saca el resto más rápidamente, aunque se podrían sacar todas así ;))
VB lo único raro que puede tener es que aparte de las dll que contienen las apis propias del SO tiene su propia dll de donde saca todas las funciones, ya que un MsgBox no es lo mismo que MessageBoxA :P
Salu2
Hola!! una duda.. que hay que modificar del PE Header para que los datos que se le agregan al final de un exe sean parte de la info del exe, o sea como si fuera parte de la ultima sección... intente modificar unicamente el rawsize de la ultima sección y el imagesize pero me dejo el exe inservible..
Saludos!
PD: yo lo que quiero hacer es meter un exe cifrado dentro del stub, entonces yo lo que hago es:
abro el stub, obtengo rawsize, virtualsize y size of image, luego abro el archivo a cifrar y obtengo los mismos datos entonces sumo el rawsize del stub + el rawsize del archivo y lo pongo como rawsize del archivo final, con virtualsize lo aumento en 1000 hasta que virtualsize < rawsize, y luego con size of image sumo las 2 size of image y se lo pongo al archivo final y listo
pero me deja el archivo inservible..
Hice hace algún tiempo un código en asm para ampliar la última sección, si lo quieres pídelo. El mecanismo es este:
- Le sumas al raw size de la última sección el tamaño que quieres ampliarla.
- Le sumas al virtual size el SectionAlignment.
- Le sumas al SizeOfImage el tamaño que quieres ampliar la última sección y guardas el archivo.
Salu2
Cita de: E0N en 7 Octubre 2008, 15:48 PM
Hice hace algún tiempo un código en asm para ampliar la última sección, si lo quieres pídelo. El mecanismo es este:
- Le sumas al raw size de la última sección el tamaño que quieres ampliarla.
- Le sumas al virtual size el SectionAlignment.
- Le sumas al SizeOfImage el tamaño que quieres ampliar la última sección y guardas el archivo.
Salu2
a ver, adaptando eso a mi necesid, al rawsize del archivo final le sumo el filelen() (2,56 bytes -> 1 del pe header no? o bien le sumo el imagesize del archivo a cifrar?) del archivo a cifrar, al virtual size del archivo final le sumo el section alignment del archivo a cifrar y en sizeofimage, tambien le sumo la misma cantidad que a rawsize.
asi?
Saludos! y muchas gracias!
PD: seria bueno ver el ejemplo que comentas.
A ver, para aclarar conceptos le llamaremos "stub" al stub del crypter y "archivo a cifrar" al archivo que quieres meter a continuación del stub cifrado y listo para que el stub lo desencripte y ejecute ok?
(1) Al raw size de la última sección del stub le sumas el tamaño del archivo a cifrar.
(2) Al virtual size de la última sección del stub le sumas el Section Aligement.
(3) Al size of image del stub le sumas el tamaño del archivo a cifrar.
(4) Pones el archivo a cifrar a continuación del stub y todo listo.
Así tiene que funcionarte perfectamente, luego solo te queda extraer el archivo a cifrar del stub, que puedes saber donde empieza calculando cuanto ocupa el stub a partir del PE, te dejo una función: (No uso las estructuras en esta función por que me la pidieron hace tiempo y no me apetecia postear todo el módulo, pero la puedes adaptar fácilmente si quieres ;))
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Dst As Any, Src As Any, ByVal cLen As Long)
Private Sub Form_Load()
MsgBox "El EOF está en el byte: " & GetEOF("C:\file.exe")
End
End Sub
Function GetEOF(Path As String) As Long
Dim ByteArray() As Byte
Dim PE As Long, NumberOfSections As Integer
Dim BeginLastSection As Long
Dim RawSize As Long, RawOffset As Long
Open Path For Binary As #1
ReDim ByteArray(LOF(1) - 1)
Get #1, , ByteArray
Close #1
Call CopyMemory(PE, ByteArray(&H3C), 4)
Call CopyMemory(NumberOfSections, ByteArray(PE + &H6), 2)
BeginLastSection = PE + &HF8 + ((NumberOfSections - 1) * &H28)
Call CopyMemory(RawSize, ByteArray(BeginLastSection + 16), 4)
Call CopyMemory(RawOffset, ByteArray(BeginLastSection + 20), 4)
GetEOF = RawSize + RawOffset
End Function
En cuanto al ejemplo en ASM que comentaba: (FASM)
; ****************************************************************************
; *** Código que amplía 0xFF bytes la última sección de un ejecutable. ***
; *** ***
; *** -> Le sumamos al raw size de la última sección el tamaño que ***
; *** queremos ampliarla. ***
; *** -> Le sumamos al virtual size el SectionAlignment. ***
; *** -> Le sumamos al SizeOfImage el tamaño que queremos ampliar la ***
; *** última sección y guardamos el archivo. ***
; ****************************************************************************
include 'H:\archivos de programa\fasm\include\win32ax.inc'
.code
start:
; Usamos la pila para gurdar nuestras variables
sub esp, 20
; [esp+0] -> El handle del archivo
; [esp+4] -> Handle del archivo mapeado
; [esp+8] -> Lo que sería el "ImageBase" del archivo proyectado
; [esp+12] -> SectionAligement
; [esp+16] -> NumberOfSections
; Sobran dos bytes por el alineamiento de la pila
; Mapeamos el archivo en memoria con 40 bytes de más
invoke CreateFile, ruta, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_WRITE+FILE_SHARE_READ, 0, OPEN_EXISTING, 0,0
mov dword[esp], eax
invoke GetFileSize, eax, 0
add eax, 0x2600 ; <--- Tamaño a ampliar
mov esi, dword[esp]
invoke CreateFileMapping, esi, 0, PAGE_READWRITE, 0, eax, 0
mov [esp+4], eax
invoke MapViewOfFile, eax, FILE_MAP_ALL_ACCESS, 0, 0, 0
mov [esp+8], eax
; Obtenemos los datos necesarios del PE
mov ebx, dword[eax+0x3C] ; EBX = Signature
mov edi, dword[eax+0x3C] ; Guardamos también en edi la posición del signature para usarla luego
add ebx, eax
add edi, eax
add dword[ebx+0x50], 0xFF ; Le sumamos al SizeOfImage el tamaño a ampliar
mov eax, dword[ebx+0x38]
mov [esp+12], eax
mov ax, word[ebx+0x6]
mov [esp+16], ax
; Obtenemos los datos necesarios de la última sección
mov ax, word[esp+16]
dec eax
mov edx, 0x28
mul edx
add edi, eax
add edi, 248 ; 248 = Tamaño OptionalHeader
add dword[edi+16], 0xFF ; Le sumamos al RawSize el tamaño a ampliar
mov eax, dword[esp+12]
add dword[edi+8], eax ; Le sumamos al VirtualSize el SectionAlignment
; Liberamos memoria, cuadramos la pila y salimos
mov esi, esp
invoke CloseHandle, dword[esi]
invoke CloseHandle, dword[esi+4]
invoke UnmapViewOfFile, dword[esi+8]
add esp, 20
invoke ExitProcess, 0
ruta db 'H:\h.exe', 0 ; La ruta del archivo a tratar
.end start
Salu2
Cita de: E0N en 8 Octubre 2008, 17:07 PM
(1) Al raw size de la última sección del stub le sumas el tamaño del archivo a cifrar.
(2) Al virtual size de la última sección del stub le sumas el Section Aligement.
(3) Al size of image del stub le sumas el tamaño del archivo a cifrar.
(4) Pones el archivo a cifrar a continuación del stub y todo listo.
Muchas gracias, una ultima cosa que no me quedo en claro, yo obtengo el rawsize de la ultima sección del stub, lo paso a hex, y de hexadecimal a decimal y ahi le sumo el filelen() del archivo a cifrar?
Saludos!
Lo que tienes que hacer es sumar o en hexadecimal los dos o en decimal los dos (VB te devuelve los números en decimal, así que súmalos así) recuerda que decimal y hexadecimal no son más que formas de representar números binarios (ceros y unos) :P
RellenarPE (App.Path & "\Stub.exe") 'Relleno PE Stub
rawoffsetS = Hex(ish(UBound(ish)).PointerToRawData) 'raw offset +
rawsizeS = Hex(ish(UBound(ish)).SizeOfRawData) 'raw size = punto que empieza el otro codigo (finaliza el exe)
virtualsizeS = Hex(ish(UBound(ish)).VirtualSize)
sizeofimageS = Hex(inh.OptionalHeader.SizeOfImage)
sectionalignmentS = Hex(inh.OptionalHeader.SectionAlignment)
RellenarPE (Text1.Text) 'Relleno Archivo
sizeofimageA = Hex(inh.OptionalHeader.SizeOfImage)
tamArchivo = FileLen(Text1.Text)
rawsizeM = tamArchivo + HexToDec(rawsizeS)
sizeofimageM = tamArchivo + HexToDec(sizeofimageS)
virtualsizeM = HexToDec(virtualsizeS) + HexToDec(sectionalignmentS)
ish(UBound(ish)).SizeOfRawData = CLng("&H" & DecToHex(rawsizeM))
ish(UBound(ish)).VirtualSize = CLng("&H" & DecToHex(virtualsizeM))
inh.OptionalHeader.SizeOfImage = CLng("&H" & DecToHex(sizeofimageM))
compruebo con el StudPE y se modifican todo bien y el peso queda todo bien pero me sigue dando error win32 aplicacion no valida
Lo primero, por que obtienes los valores en hexadecimal y luego los pasas a decimal con HexToDec para sumarlos?? :xD :xD
Lo segundo, pones el archivo a cifrar a continuación del stub o en su caso rellenas los bytes necesarios?? Por que si no te va a dar error xD
Y bueno no se que más decirte, por el trozo de código que pones parece que está bien, haz pruebas con el código en ensamblador que te he pasado (espero que no se me haya olvidado ningún paso) por que tiene que funcionar ;)
Cita de: E0N en 8 Octubre 2008, 18:19 PM
Lo primero, por que obtienes los valores en hexadecimal y luego los pasas a decimal con HexToDec para sumarlos?? :xD :xD
Lo segundo, pones el archivo a cifrar a continuación del stub o en su caso rellenas los bytes necesarios?? Por que si no te va a dar error xD
Y bueno no se que más decirte, por el trozo de código que pones parece que está bien, haz pruebas con el código en ensamblador que te he pasado (espero que no se me haya olvidado ningún paso) por que tiene que funcionar ;)
jeje bueno pekeño error xD pero igual, si, relleno los bytes necesarios, hago los calculos luego de que ya tengo el archivo final (todo cifrado y el stub) y le cambio el PE Header, he probado restandole 1 byte y con el StudPE me aparece extra dat, sin restarle no aparece o sea que si lo toma todo como la ultima sección. as que no se :S
Saludos!
Pues yo si que no se como no pongas más código jajaja Prueba a hacerlo con el código en ensamblador que te e puesto a ver si también te falla o no, pero no debería. Si mañana saco un rato y no lo has solucionado te hago un ejemplo simple :P
Cita de: E0N en 8 Octubre 2008, 18:53 PM
Pues yo si que no se como no pongas más código jajaja Prueba a hacerlo con el código en ensamblador que te e puesto a ver si también te falla o no, pero no debería. Si mañana saco un rato y no lo has solucionado te hago un ejemplo simple :P
He probado el code en ASM, en ImageSize agranda FF y en la ultima sección tambien agrande FF a RawSize, pero al archivo le agrega 2501 bytes de ceros o sea esos se ven como ExtraDat en el StudPE
Saludos! y agradeceria ese ejemplo simple =), te dejo el code que guarda por si no lo hiciste..
Open "C:\test.exe" For Binary Access Write As #1
Put #1, , idh
a = 0
For e = Len(idh) To idh.e_lfanew - 1 'desde DOS Header hasta PE Header
Put #1, , ByteArray(e)
a = a + 1
Next e
tamaniosSecc = 0
Put #1, , inh
For i = 0 To UBound(ish)
Put #1, , ish(i)
tamaniosSecc = tamaniosSecc + Len(ish(i))
Next i
desde = Len(idh) + a + Len(inh) + tamaniosSecc
For e = desde To UBound(ByteArray) 'desde final de ish hasta final archivo
Put #1, , ByteArray(e)
a = a + 1
Next e
Close #1
Este es un code para visualizar el formato pe (esta hecho todo en vb 6)
aqui esta el codigo:
https://foro.elhacker.net/programacion_vb/formato_portable_ejecutable-t197932.0.html
Se obtiene el manejador del archivo con CreateFileA
Se crea el objeto de mapeo con CreateFileMappingA
Se mapea en memoria con MapViewOfFile
el retorno de esta funcion, deja en el inicio del ejecutable
direccion inicio + IMAGE_DOS_HEADER.e_lfanew= situa al inicio de la cabecera nt
inicio cabecera nt + longuitud de la estructura (cabecera nt)= situa al inicio de la tabla de secciones
y de ahi depende que sección se quiera modificar.
por ejemplo para encontrar el punto de entrada de un api en una dll, seria hacer lo anterior, ir al directorio de exportaciones, luego buscar por el nombre en la tabla funciones exportadas por nombre, y obtener el numero de veces q se ha iterado hasta encontrarla, este numero multiplicarlo por 2 y buscar en la tabla de funciones exportadas por ordinal. el valor que se encuentra ahi multiplicarlo por 4 y buscar el la tabla de funciones exportadas por direcciones, el valor que se encuentra alli sumarle la imagen base y listo ese es el punto de entrada para la api algo parecido a lo que hace GetProcAdressA(se podria hacer lo mismo sin mapealo pero se necesitaria que la dll ya estubiera en memoria y adicionalmente conocer la direccion base).
para escribir en el archivo se usa la api Writefile
BOOL WriteFile(
HANDLE hFile, // manejador del archivo
LPCVOID lpBuffer, // dirección de los datos a escribir
DWORD nNumberOfBytesToWrite, // número de bytes a escribir
LPDWORD lpNumberOfBytesWritten, // en esta variable retorna el numero de bytes escritos
LPOVERLAPPED lpOverlapped // dirección de la estructura necesaria para I/O superpuestas normalmente se le pase un NULL
);
pero especificamente, que es lo que parte del formato pe quieres modificar?.
quiero agrandar la ultima sección
Saludos! y muchas gracias =)!