Ya estoi aqui de nuevo, esta vez e intentado agregar una nueva sección a un ejecutable, sin exito :xD
este es el código que tengo:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
IMAGE_DOS_HEADER dh;
IMAGE_NT_HEADERS nth;
IMAGE_SECTION_HEADER * sección;
IMAGE_SECTION_HEADER nSeccion;
// char * stub_dos -> Datos del STUB_DOS
// char * dSecciones -> Datos de las secciones
FILE * archivo = fopen("c:\\windows\\system32\\calc.exe","r+b");
if (archivo == NULL)
{
printf("Error al leer el archivo\n");
system("PAUSE");
return 1;
}
fread(&dh,sizeof(dh),1,archivo); // Rellenamos IMAGE_DOS_HEADER
char * stub_dos = (char*)malloc(dh.e_lfanew-0x40);
fread(stub_dos,1,dh.e_lfanew-0x40,archivo); // Leemos el Stub DOS
fread(&nth,sizeof(nth),1,archivo); // leemos nt headers
sección = (IMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER)*nth.FileHeader.NumberOfSections);
fread(sección,sizeof(IMAGE_SECTION_HEADER),nth.FileHeader.NumberOfSections,archivo);
char * dSecciones = (char*)malloc(nth.OptionalHeader.SizeOfImage);
fread(dSecciones,nth.OptionalHeader.SizeOfImage,1,archivo); //leo todos los datos de las secciones.
fclose(archivo); // terminamos de leer
ZeroMemory(&nSeccion,sizeof(IMAGE_SECTION_HEADER));
int A = sección[nth.FileHeader.NumberOfSections-1].VirtualAddress;
int B = sección[nth.FileHeader.NumberOfSections-1].Misc.VirtualSize;
int C = nth.OptionalHeader.SectionAlignment;
strcpy((char*)nSeccion.Name,".fary"); // nombre de la nueva sección: .fary
nSeccion.VirtualAddress = ((A+B)/C)*C+C;// direccion Virtual
nSeccion.SizeOfRawData = 0x64; // tamaño de la sección: 100
nSeccion.PointerToRawData = sección[nth.FileHeader.NumberOfSections-1].PointerToRawData + 0x64; // direccion fisica
nSeccion.Characteristics = 0x10000020;
nSeccion.Misc.VirtualSize = 0x64;
//nSeccion.VirtulSize
nth.FileHeader.NumberOfSections += 1; // sumamos la nueva sección
nth.OptionalHeader.SizeOfImage += 0x64;
FILE * nuevo = fopen("NuevaCalc.exe","wb+");
fwrite(&dh,sizeof(dh),1,nuevo);
fwrite(stub_dos,dh.e_lfanew-0x40,1,nuevo);
fwrite(&nth,sizeof(nth),1,nuevo);
fwrite(sección,sizeof(IMAGE_SECTION_HEADER)*nth.FileHeader.NumberOfSections,1,nuevo);
fwrite(&nSeccion,sizeof(IMAGE_SECTION_HEADER),1,nuevo);
fwrite(dSecciones,nth.OptionalHeader.SizeOfImage,1,nuevo);
char * DatosSeccion = (char*)malloc(0x64);
ZeroMemory(DatosSeccion,0x64);
fwrite(DatosSeccion,0x64,1,nuevo);
fclose(nuevo);
system("PAUSE");
return 0;
}
Genera bien el nuevo archivo pero no pone bien los datos de la sección y ni que decir de ejecutarse (peta) XD. Así es como salen los datos de mi sección desde el lordPE:
(http://img444.imageshack.us/img444/2459/mirrror.png)
haber si aguien sabe que ago mal...
saludos.
Yo tengo este codigo el cual no lo he podido revisar aun pero si lo probe y es funcional ,,ve este codigo capaz puedes sacar en donde te equivocaste :
Option Explicit
Const IMAGE_DOS_SIGNATURE As Integer = &H5A4D
Const IMAGE_NT_SIGNATURE As Long = &H4550
Private 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_onvo As Integer
e_res(0 To 3) As Integer
e_oemid As Integer
e_oeminfo As Integer
e_res2(0 To 9) As Integer
e_lfanew As Long
End Type
Private Type IMAGE_FILE_HEADER
Machine As Integer
NumberOfSections As Integer
TimeDataStamp As Long
PointerToSymbolTable As Long
NumberOfSymbols As Long
SizeOfOptionalHeader As Integer
Characteristics As Integer
End Type
Private Type IMAGE_DATA_DIRECTORY
VirtualAddress As Long
isize As Long
End Type
Private Type IMAGE_OPTIONAL_HEADER32
Magic As Integer
MajorLinkerVersion As Byte
MinorLinkerVersion As Byte
SizeOfCode As Long
SizeOfInitalizedData As Long
SizeOfUninitalizedData As Long
AddressOfEntryPoint As Long
BaseOfCode As Long
BaseOfData As Long
ImageBase As Long
SectionAlignment As Long
FileAlignment As Long
MajorOperatingSystemVer As Integer
MinorOperatingSystemVer 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
LoaerFlags As Long
NumberOfRvaAndSizes As Long
DataDirectory(1 To 16) As IMAGE_DATA_DIRECTORY
End Type
Private Type IMAGE_SECTION_HEADER
Name As String * 8
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
Private Type IMAGE_NT_HEADERS
Signature As Long
FileHeader As IMAGE_FILE_HEADER
OptionalHeader As IMAGE_OPTIONAL_HEADER32
End Type
Private Function Align(ByVal dwValue As Long, ByVal dwAlign As Long) As Long
If dwAlign <> 0 Then
If dwValue Mod dwAlign <> 0 Then
Align = (dwValue + dwAlign) - (dwValue Mod dwAlign)
Exit Function
End If
End If
Align = dwValue
End Function
Private Function LastSectionRaw(Sections() As IMAGE_SECTION_HEADER) As Long
Dim i As Integer
Dim ret As Long
For i = LBound(Sections) To UBound(Sections)
If Sections(i).SizeOfRawData + Sections(i).PointerToRawData > ret Then
ret = Sections(i).SizeOfRawData + Sections(i).PointerToRawData
End If
Next i
LastSectionRaw = ret
End Function
Private Function LastSectionVirtual(Sections() As IMAGE_SECTION_HEADER) As Long
Dim i As Integer
Dim ret As Long
For i = LBound(Sections) To UBound(Sections)
If Sections(i).VirtualSize + Sections(i).VirtualAddress > ret Then
ret = Sections(i).VirtualSize + Sections(i).VirtualAddress
End If
Next i
LastSectionVirtual = ret
End Function
Public Function AddSection(ByVal szFile As String, ByVal NewSectionName As String, _
ByVal NewSectionSize As Long, ByVal NewSectionCharacteristics As Long, _
ByRef dwNewSectionRVA As Long, ByVal FailIfExists As Boolean) As Long
Dim hFile As Long, hMap As Long, lpMap As Long, x As Long
Dim i As Integer, k As Integer, FF As Integer
Dim DOSHeader As IMAGE_DOS_HEADER
Dim NTHeader As IMAGE_NT_HEADERS
Dim SectionHeader() As IMAGE_SECTION_HEADER
If Len(NewSectionName) < 1 Then Exit Function
If Len(NewSectionName) > 8 Then
NewSectionName = Left$(NewSectionName, 8)
Else
NewSectionName = NewSectionName & String(8 - Len(NewSectionName), Chr$(0))
End If
FF = FreeFile
Open szFile For Binary As #FF
Get #FF, , DOSHeader
If DOSHeader.e_magic = IMAGE_DOS_SIGNATURE Then
Get #FF, 1 + DOSHeader.e_lfanew, NTHeader
If NTHeader.Signature = IMAGE_NT_SIGNATURE Then
ReDim SectionHeader(0 To NTHeader.FileHeader.NumberOfSections - 1) As IMAGE_SECTION_HEADER
k = NTHeader.FileHeader.NumberOfSections - 1
x = DOSHeader.e_lfanew + 24 + NTHeader.FileHeader.SizeOfOptionalHeader
For i = LBound(SectionHeader) To UBound(SectionHeader)
Get #FF, 1 + x, SectionHeader(i)
If SectionHeader(i).Name = NewSectionName And FailIfExists = True Then Exit Function
x = x + Len(SectionHeader(i))
Next i
If NTHeader.OptionalHeader.SizeOfHeaders >= x + Len(SectionHeader(0)) Then
NTHeader.FileHeader.NumberOfSections = NTHeader.FileHeader.NumberOfSections + 1
ReDim Preserve SectionHeader(0 To NTHeader.FileHeader.NumberOfSections - 1) As IMAGE_SECTION_HEADER
With SectionHeader(NTHeader.FileHeader.NumberOfSections - 1)
.Name = NewSectionName
.Characteristics = NewSectionCharacteristics
.PointerToRawData = Align(LastSectionRaw(SectionHeader), NTHeader.OptionalHeader.FileAlignment)
.SizeOfRawData = Align(NewSectionSize, NTHeader.OptionalHeader.FileAlignment)
.VirtualAddress = Align(LastSectionVirtual(SectionHeader), NTHeader.OptionalHeader.SectionAlignment)
.VirtualSize = NewSectionSize
End With
'write new section
NTHeader.OptionalHeader.DataDirectory(12).VirtualAddress = 0
NTHeader.OptionalHeader.DataDirectory(12).isize = 0
NTHeader.OptionalHeader.SizeOfImage = NTHeader.OptionalHeader.SizeOfImage + SectionHeader(k + 1).VirtualSize
Put #FF, 1 + DOSHeader.e_lfanew, NTHeader
Put #FF, 1 + x, SectionHeader(k + 1)
Put #FF, SectionHeader(k + 1).PointerToRawData + SectionHeader(k + 1).SizeOfRawData, Chr$(0)
AddSection = SectionHeader(k + 1).PointerToRawData
End If
End If
End If
Close #FF
End Function
Function AddFile2File(File2BeAdded As String, File2Add2 As String, SectionName As String)
Dim dwSettingsRVA As Long, dwSettingsRaw As Long
Dim Settings As String
Settings = (ReadFile(File2BeAdded))
dwSettingsRaw = AddSection(File2Add2, SectionName, Len(Settings), &HC0000040, dwSettingsRVA, True)
Open File2Add2 For Binary Access Write As #1
Put #1, dwSettingsRaw + 1, Settings
Close #1
End Function
Para llamarlo usa
Call AddFile2File(Text1.Text, App.Path & "\salida.exe", ".comoquieras")
Suerte...
Cita de: lucasluks1004 en 18 Septiembre 2011, 18:54 PM...
pffff... es qeu mi problema creo que esta en cosa de punteros o algo así :-\ y no lo logro encontrar.
saludos.
Tras seguir intentando y intentando no logro arreglarlo del todo (aunque lo otro ya lo arregle), aora parece que todo esta bien pero ejecuto el exe y no me funciona :S de seguro es un error tonto y minúsculo pero no logro dar con él.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
DWORD align(DWORD number, DWORD alignment)
{
if(number % alignment == 0)
return number;
else
return (number / alignment) * alignment + alignment;
}
int main()
{
IMAGE_DOS_HEADER dh;
IMAGE_NT_HEADERS nth;
IMAGE_SECTION_HEADER * sección;
IMAGE_SECTION_HEADER nSeccion;
// char * stub_dos -> Datos del STUB_DOS
// char * dSecciones -> Datos de las secciones
long TamanoSecciones = 0;
int i;
FILE * archivo = fopen("c:\\Mad.exe","r+b");
if (archivo == NULL)
{
printf("Error al leer el archivo\n");
system("PAUSE");
return 1;
}
fread(&dh,sizeof(dh),1,archivo); // Rellenamos IMAGE_DOS_HEADER
char * stub_dos = (char*)malloc(dh.e_lfanew-0x40);
fread(stub_dos,1,dh.e_lfanew-0x40,archivo); // Leemos el Stub DOS
fread(&nth,sizeof(nth),1,archivo); // leemos nt headers
sección = (IMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER)*nth.FileHeader.NumberOfSections);
fread(sección,sizeof(IMAGE_SECTION_HEADER),nth.FileHeader.NumberOfSections,archivo);
for (i=0;i<=nth.FileHeader.NumberOfSections-1;i++)
{
printf("%i\n",sección[i].SizeOfRawData);
TamanoSecciones += sección[i].SizeOfRawData;
}
printf("%i\n",TamanoSecciones);
char * dSecciones = (char*)malloc(TamanoSecciones);
fread(dSecciones,TamanoSecciones,1,archivo); //leo todos los datos de las secciones.
fclose(archivo); // terminamos de leer
strcpy((char*)nSeccion.Name,".fary"); // nombre de la nueva sección: .fary
nSeccion.VirtualAddress = align(sección[nth.FileHeader.NumberOfSections-1].VirtualAddress + sección[nth.FileHeader.NumberOfSections-1].Misc.VirtualSize, nth.OptionalHeader.SectionAlignment);
nSeccion.SizeOfRawData = align(0x50, nth.OptionalHeader.FileAlignment);
nSeccion.PointerToRawData = sección[nth.FileHeader.NumberOfSections-1].PointerToRawData + sección[nth.FileHeader.NumberOfSections-1].SizeOfRawData;//align(0x50,nth.OptionalHeader.FileAlignment);
nSeccion.Characteristics = 0x60000020;
nSeccion.Misc.VirtualSize = 0x50;
nth.FileHeader.NumberOfSections += 1; // sumamos la nueva sección
nth.OptionalHeader.SizeOfImage = align(0x50+nSeccion.VirtualAddress,nth.OptionalHeader.SectionAlignment);
nth.OptionalHeader.SizeOfHeaders += 0x28;
FILE * nuevo = fopen("Nuevo.exe","wb+");
fwrite(&dh,sizeof(dh),1,nuevo);
fwrite(stub_dos,dh.e_lfanew-0x40,1,nuevo);
fwrite(&nth,sizeof(nth),1,nuevo);
nth.FileHeader.NumberOfSections -= 1;
fwrite(sección,sizeof(IMAGE_SECTION_HEADER)*nth.FileHeader.NumberOfSections,1,nuevo);
fwrite(&nSeccion,sizeof(IMAGE_SECTION_HEADER),1,nuevo);
fwrite(dSecciones,TamanoSecciones,1,nuevo);
if (fseek(nuevo,0,SEEK_END) != 0)
{
printf("error\n");
}
char DatosSeccion[] = "Hola yo soy la sección de prueba, y ocupo exactamente la cantidad de 0x50 bytes.";
fwrite(DatosSeccion,0x50,1,nuevo);
fclose(nuevo);
system("PAUSE");
return 0;
}
Si alguien es tan amable de hecharle un ojo y explicarme porque no anda le estaría muy agradecido ;)
saludos.
qué error te sale ahora?
Cuando añades una nueva sección, en la misma no añades ningún byte, entonces no entiendo por qué pones:
nSeccion.SizeOfRawData = align(0x50, nth.OptionalHeader.FileAlignment);
alinearlo a filealignement se hace si realmente tienes bytes. Ponlo a cero directamente. (no he revisado completamente tu código, pero creo que no añades bytes, si me equivoco dímelo)
Además cuando añades una sección, realmente lo que haces es modificar los bytes en el encabezado pero no añades ninguno a no ser que lo hagas de verdad, como hago con Add PE bytes.
Mi código es muy diferente al tuyo y me lo tengo que leer entero para saber dónde has cometido el error.
Haz pruebas con tu programa y con LordPE y examinando los datos de la sección añadida verifica dónde está el error.
Si añado datos... añado una pequeña cadena :P. el problema está en que genera el ejecutable con menos peso y cambia datos de las secciones (osea el contenido) pero nose porque lo hace :-\
saludos.
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
DWORD align(DWORD number, DWORD alignment)
{
if(number % alignment == 0)
return number;
else
return (number / alignment) * alignment + alignment;
}
int main()
{
IMAGE_DOS_HEADER dh;
IMAGE_NT_HEADERS nth;
IMAGE_SECTION_HEADER * sección;
IMAGE_SECTION_HEADER nSeccion;
// char * stub_dos -> Datos del STUB_DOS
// char * dSecciones -> Datos de las secciones
long TamanoSecciones = 0;
int i;
FILE * archivo = fopen("c:\\Mad.exe","r+b");
if (archivo == NULL)
{
printf("Error al leer el archivo\n");
getchar();
return 1;
}
fread(&dh,sizeof(dh),1,archivo); // Rellenamos IMAGE_DOS_HEADER
char * stub_dos = (char*)malloc(dh.e_lfanew-0x40);
fread(stub_dos,1,dh.e_lfanew-0x40,archivo); // Leemos el Stub DOS
fread(&nth,sizeof(nth),1,archivo); // leemos nt headers
sección = (IMAGE_SECTION_HEADER*)malloc(sizeof(IMAGE_SECTION_HEADER)*nth.FileHeader.NumberOfSections);
fread(sección,sizeof(IMAGE_SECTION_HEADER),nth.FileHeader.NumberOfSections,archivo);
/*for (i=0;i<=nth.FileHeader.NumberOfSections-1;i++)
{
printf("%i\n",sección[i].SizeOfRawData);
TamanoSecciones += sección[i].SizeOfRawData;
}*/
TamanoSecciones = (sección[nth.FileHeader.NumberOfSections-1].PointerToRawData + sección[nth.FileHeader.NumberOfSections-1].SizeOfRawData) - sección[0].PointerToRawData;
fseek(archivo, dh.e_lfanew + 248 + (nth.FileHeader.NumberOfSections * 0x28)+0x28, SEEK_SET);
char * dSecciones = (char*)malloc(TamanoSecciones + (nth.OptionalHeader.SizeOfHeaders - ftell(archivo)));
int HeaderSize = nth.OptionalHeader.SizeOfHeaders - ftell(archivo);
char * Header = (char*) malloc(HeaderSize);
memset(Header,0, HeaderSize);
memset(dSecciones, 0, TamanoSecciones);
fread(Header, HeaderSize,1, archivo);
fread(dSecciones,TamanoSecciones,1,archivo); //leo todos los datos de las secciones.
fclose(archivo); // terminamos de leer
memset(&nSeccion,0, 0x28);
strncpy((char*)nSeccion.Name,".fary",5); // nombre de la nueva sección: .fary
nSeccion.VirtualAddress = align(sección[nth.FileHeader.NumberOfSections-1].VirtualAddress + sección[nth.FileHeader.NumberOfSections-1].Misc.VirtualSize, nth.OptionalHeader.SectionAlignment);
nSeccion.SizeOfRawData = align(0x50, nth.OptionalHeader.FileAlignment);
nSeccion.PointerToRawData = sección[nth.FileHeader.NumberOfSections-1].PointerToRawData + sección[nth.FileHeader.NumberOfSections-1].SizeOfRawData;//align(0x50,nth.OptionalHeader.FileAlignment);
nSeccion.Characteristics = 0x60000020;
nSeccion.Misc.VirtualSize = 0x50;
nth.FileHeader.NumberOfSections += 1; // sumamos la nueva sección
nth.OptionalHeader.SizeOfImage = align(0x50+nSeccion.VirtualAddress,nth.OptionalHeader.SectionAlignment);
//nth.OptionalHeader.SizeOfHeaders += 0x28;
FILE * nuevo = fopen("Nuevo.exe","wb+");
fwrite(&dh,sizeof(dh),1,nuevo);
fwrite(stub_dos,dh.e_lfanew-0x40,1,nuevo);
fwrite(&nth,sizeof(nth),1,nuevo);
nth.FileHeader.NumberOfSections -= 1;
fwrite(sección,sizeof(IMAGE_SECTION_HEADER)*nth.FileHeader.NumberOfSections,1,nuevo);
fwrite(&nSeccion,sizeof(IMAGE_SECTION_HEADER),1,nuevo);
fwrite(Header, HeaderSize,1, nuevo);
fwrite(dSecciones,TamanoSecciones,1,nuevo);
if (fseek(nuevo,0,SEEK_END) != 0)
{
printf("error\n");
}
int Size = nSeccion.SizeOfRawData;
char DatosSeccion[0x1000] = "Hola yo soy la sección de prueba, y ocupo exactamente la cantidad de 0x50 bytes.\0"; //Debe tener la cantidad de bytes del SizeOfRawData
fwrite(DatosSeccion,nSeccion.SizeOfRawData,1,nuevo);
fclose(nuevo);
system("PAUSE");
return 0;
}
Tu primer error estaba a la hora de leer el resto de la cabecera, posterior no agregabas el tamaño del SizeOfRawData completo, de lo contrario se corrompe el exe.
Si es un ejecutable VB solo bastaría dejar BoundImport a 0 o moverlo más abajo.