// Sencillo Visor PE Consola v0.1
// codigo por Fary
// foro.elhacker.net
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int MostrarSecciones(void * Mapa); // Muestra los datos de las secciones
int MostrarImportaciones(void * Mapa); //Muestra las imports
int MostrarExportaciones(void * Mapa); // Muestra las exports
int RVAToOffset(int IDDVirtual, int ISHVirtual, int ISHRaw); // Convierte direccion virtual en offset fisico
DWORD AltRVAToOffset(DWORD RVA, void *Mapa); // AltRVAToOffset -> Convierte direccion virtual en offset fisico, version mejorada.
HANDLE Consola;
int main()
{
HANDLE archivo;
HANDLE marchivo;
DWORD TamanoArchivo;
LPVOID MapaArchivo;
int Opcion = 0;
char ruta[MAX_PATH] = {0};
Consola = GetStdHandle(STD_OUTPUT_HANDLE);
printf("Indica la ruta del archivo (La Ruta no puede tener espacios): \n");
archivo = CreateFile(ruta, GENERIC_READ | GENERIC_WRITE, 0,0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); // abrimos el archivo EXE
if(archivo == INVALID_HANDLE_VALUE)
{
printf("Error: No se pudo abrir el archivo.\n"); return 1;
}
TamanoArchivo = GetFileSize(archivo,0);
marchivo = CreateFileMappingA(archivo, 0 ,PAGE_READWRITE, 0, TamanoArchivo,0);
if (marchivo == NULL)
{
printf("No se puede abrir el mapeo del archivo\n"); CloseHandle(archivo);
return 1;
}
MapaArchivo = MapViewOfFile(marchivo, FILE_MAP_ALL_ACCESS, 0, 0, 0);
IMAGE_DOS_HEADER * idh = (IMAGE_DOS_HEADER*)&MapaArchivo[0]; // Rellenamos el IMAGE_DOS_HEADER
if (idh->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("No es un PE Valido\n"); CloseHandle(archivo);
CloseHandle(marchivo);
return 0;
}
IMAGE_NT_HEADERS * INTH = (IMAGE_NT_HEADERS*)&MapaArchivo[idh->e_lfanew];
while(1)
{
if(INTH->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) // Mostrador el parametro machine
{
printf("FileHeader->Machine: x86\n"); }else if(INTH->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
{
printf("FileHeader->Machine: x64\n"); }
if (INTH->FileHeader.Characteristics == IMAGE_FILE_EXECUTABLE_IMAGE) // Characteristics
{
printf("FileHeader->Characteristics: EXE"); }else if(INTH->FileHeader.Characteristics == IMAGE_FILE_DLL)
{
printf("FileHeader->Characteristics: DLL"); }else if(INTH->FileHeader.Characteristics == IMAGE_FILE_32BIT_MACHINE)
{
printf("FileHeader->Characteristics: 32-Bit\n"); }
printf("FileHeader->NumberOfSections: 0x%x\n",INTH
->FileHeader.
NumberOfSections);
printf("OptionaHeader->AddressOfEntryPoint: 0x%x\n", INTH
->OptionalHeader.
AddressOfEntryPoint); printf("OptionalHeader->ImageBase: 0x%x\n", INTH
->OptionalHeader.
ImageBase); printf("OptionalHeader->SectionAlignment: 0x%x\n",INTH
->OptionalHeader.
SectionAlignment); printf("OptionalHeader->FileAlignment: 0x%x\n",INTH
->OptionalHeader.
FileAlignment); printf("OptionalHeader->SizeOfImage: 0x%x\n", INTH
->OptionalHeader.
SizeOfImage); printf("OptionalHeader->SizeOfHeaders: 0x%x\n",INTH
->OptionalHeader.
SizeOfHeaders);
printf("\nSelecciona que quieres hacer ahora: \n"); printf("1 - Ver secciones.\n"); printf("2 - Ver Import Table.\n"); printf("3 - Ver Export Table.\n");
switch(Opcion)
{
case 1:
MostrarSecciones(MapaArchivo);
break;
case 2:
MostrarImportaciones(MapaArchivo);
break;
case 3:
MostrarExportaciones(MapaArchivo);
break;
case 4:
CloseHandle(archivo);
CloseHandle(marchivo);
return 0;
}
}
return 0;
}
int MostrarExportaciones(void * Mapa)
{
IMAGE_DOS_HEADER * IDH = (IMAGE_DOS_HEADER*)&Mapa[0];
IMAGE_NT_HEADERS * INTH = (IMAGE_NT_HEADERS*)&Mapa[IDH->e_lfanew];
IMAGE_SECTION_HEADER * ISH;
IMAGE_DATA_DIRECTORY * IDD = (IMAGE_DATA_DIRECTORY*)&(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
if (IDD->VirtualAddress == 0)
{
printf("No hay ExportTable.\n"); return 1;
}
int i;
DWORD exportRaw = AltRVAToOffset(IDD->VirtualAddress, Mapa);
IMAGE_EXPORT_DIRECTORY *IED = (IMAGE_EXPORT_DIRECTORY *)&Mapa[exportRaw];
int a = AltRVAToOffset(IED->AddressOfNames, Mapa);
DWORD * NombreFuncion = &Mapa[a];
int e = AltRVAToOffset(IED->AddressOfFunctions, Mapa);
DWORD * DirFuncion = &Mapa[e];
int z = AltRVAToOffset(IED->AddressOfNameOrdinals, Mapa);
WORD * Ordinal = &Mapa[z];
for (i = 0; i < IED->NumberOfNames; i++)
{
DWORD nameOffset = AltRVAToOffset(NombreFuncion[i], Mapa);
char * funcName = (char*)&Mapa[nameOffset];
DWORD dirfun = DirFuncion[Ordinal[i]];
printf("%s -> 0x%x\n",funcName
, dirfun
); }
return 0;
}
int MostrarImportaciones(void * Mapa)
{
IMAGE_DOS_HEADER * IDH = (IMAGE_DOS_HEADER*)&Mapa[0];
IMAGE_NT_HEADERS * INTH = (IMAGE_NT_HEADERS*)&Mapa[IDH->e_lfanew];
IMAGE_DATA_DIRECTORY * IDD = (IMAGE_DATA_DIRECTORY*)&(INTH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]);
IMAGE_SECTION_HEADER * ISH;
if (IDD->VirtualAddress == 0)
{
printf("No se encontro tabla de importaciones.\n"); return 1;
}
int i;
ISH = IMAGE_FIRST_SECTION(INTH);
for (i = 0; i < INTH->FileHeader.NumberOfSections; i++)
{
//ISH = (IMAGE_SECTION_HEADER*)&Mapa[IDH->e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*i];
if(IDD->VirtualAddress >= ISH[i].VirtualAddress && IDD->VirtualAddress < (ISH[i].VirtualAddress + ISH[i].Misc.VirtualSize))
{
break;
}
}
DWORD Offset = AltRVAToOffset(IDD->VirtualAddress, Mapa);//DWORD Offset = RVAToOffset(IDD->VirtualAddress,ISH[i].VirtualAddress, ISH[i].PointerToRawData);//(IDD->VirtualAddress - ISH->VirtualAddress) + ISH->PointerToRawData;
IMAGE_IMPORT_DESCRIPTOR * IID = (IMAGE_IMPORT_DESCRIPTOR*)&Mapa[Offset];
while (IID->Name != NULL)
{
DWORD nameOffset = AltRVAToOffset(IID->Name, Mapa);//RVAToOffset(IID->Name, ISH[i].VirtualAddress, ISH[i].PointerToRawData);//(IID->Name - ISH->VirtualAddress) + ISH->PointerToRawData;
char *dllName = (char*)&Mapa[nameOffset];
SetConsoleTextAttribute(Consola, FOREGROUND_RED);
SetConsoleTextAttribute(Consola, 0x0F);
DWORD ThunkOffset = AltRVAToOffset(IID->OriginalFirstThunk,Mapa);//RVAToOffset(IID->OriginalFirstThunk,ISH[i].VirtualAddress, ISH[i].PointerToRawData);
IMAGE_THUNK_DATA * ITD = (IMAGE_THUNK_DATA*)&Mapa[ThunkOffset];
while (ITD->u1.AddressOfData != NULL)
{
DWORD dirNombreFuncion = AltRVAToOffset(ITD->u1.AddressOfData, Mapa);//RVAToOffset(ITD->u1.AddressOfData,ISH[i].VirtualAddress, ISH[i].PointerToRawData);
IMAGE_IMPORT_BY_NAME *IIBN = (IMAGE_IMPORT_BY_NAME*)&Mapa[dirNombreFuncion];
printf("Funcion: %s\n",IIBN
->Name
); ITD++;
}
IID++;
}
return 0;
}
DWORD AltRVAToOffset(DWORD RVA, void *Mapa)
{
BYTE *base = (BYTE *)Mapa;
IMAGE_DOS_HEADER *IDH = (IMAGE_DOS_HEADER *)base;
IMAGE_NT_HEADERS *INTH =
(IMAGE_NT_HEADERS *)(base + IDH->e_lfanew);
IMAGE_SECTION_HEADER *ISH =
IMAGE_FIRST_SECTION(INTH);
// Caso: RVA en headers
if (RVA < INTH->OptionalHeader.SizeOfHeaders)
return RVA;
for (WORD i = 0; i < INTH->FileHeader.NumberOfSections; i++)
{
DWORD va = ISH[i].VirtualAddress;
DWORD size = max(ISH[i].Misc.VirtualSize,
ISH[i].SizeOfRawData);
if (RVA >= va && RVA < va + size)
{
return (RVA - va) + ISH[i].PointerToRawData;
}
}
// No encontrado
return 0;
}
int RVAToOffset(int IDDVirtual, int ISHVirtual, int ISHRaw)
{
return ((IDDVirtual - ISHVirtual) + ISHRaw);
}
int MostrarSecciones(void * Mapa)
{
IMAGE_DOS_HEADER * IDH = (IMAGE_DOS_HEADER*)&Mapa[0];
IMAGE_NT_HEADERS * INTH = (IMAGE_NT_HEADERS*)&Mapa[IDH->e_lfanew];
IMAGE_SECTION_HEADER * ISH = IMAGE_FIRST_SECTION(INTH);
int i;
for (i = 0; i < INTH->FileHeader.NumberOfSections; i++)
{
SetConsoleTextAttribute(Consola, FOREGROUND_RED);
printf("Name: %.8s\n", ISH
[i
].
Name); SetConsoleTextAttribute(Consola, 0x0F);
printf("VirtualAddress: 0x%x\n", ISH
[i
].
VirtualAddress); printf("SizeOfRawData: 0x%x\n",ISH
[i
].
SizeOfRawData); printf("PointerToRawData: 0x%x\n",ISH
[i
].
PointerToRawData); }
return 0;
}