Author Topic: [C++] PEPrinter  (Read 2211 times)

0 Members and 1 Guest are viewing this topic.

Offline Zer0Flag

  • Serf
  • *
  • Posts: 20
  • Cookies: 5
    • View Profile
[C++] PEPrinter
« on: October 12, 2011, 07:16:19 am »
just another PEViewer: shows PEHeader , Imports , Exports , TLS

Code: [Select]
/* (C) Zer0Flag@drunken-nanomites.org */
#include <Windows.h>
#include <stdio.h>
DWORD dwCalculateTableOffset(int iTableEntryNr,PIMAGE_NT_HEADERS pINH,PIMAGE_DOS_HEADER pIDH,BYTE* pBuffer)
{
DWORD tableVA = pINH->OptionalHeader.DataDirectory[iTableEntryNr].VirtualAddress;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pBuffer + pIDH->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
for (WORD i = 0; i < pINH->FileHeader. NumberOfSections; i++)
{
  DWORD sectionVA = pSectionHeader->VirtualAddress;
  DWORD sectionSize = pSectionHeader->Misc. VirtualSize;
  if ((sectionVA <= tableVA) && (tableVA < (sectionVA+sectionSize)))
  {
   return (DWORD)(pBuffer + pSectionHeader->PointerToRawData + (tableVA-sectionVA));
   break;
  }
  pSectionHeader++;
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
//Init our console for printf
if(!AllocConsole()) return false;
freopen("CONOUT$", "wt", stdout);
SetConsoleTitle("PEView");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);

if(lpCmdLine == "" || strlen(lpCmdLine) < 1) return false;
BYTE* pFileBuffer;
HANDLE hFile = CreateFile(lpCmdLine,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
DWORD dwBytesRead;
if(hFile == INVALID_HANDLE_VALUE)
{
  return false;
}
int iFileSize = GetFileSize(hFile,0);
pFileBuffer = new BYTE[iFileSize];
if(iFileSize > 0 && !(ReadFile(hFile,pFileBuffer,iFileSize,&dwBytesRead,NULL)))
{
  delete [] pFileBuffer;
  return false;
}
PIMAGE_DOS_HEADER pIDH = 0;
PIMAGE_NT_HEADERS pINH = 0;
PIMAGE_SECTION_HEADER pISH = 0;
PIMAGE_EXPORT_DIRECTORY pIED = 0;
pIDH = (PIMAGE_DOS_HEADER)pFileBuffer;
if(pIDH->e_magic != IMAGE_DOS_SIGNATURE)
{
  delete [] pFileBuffer;
  return false;
}
pINH = (PIMAGE_NT_HEADERS)(pFileBuffer + pIDH->e_lfanew);
if(pINH->Signature != IMAGE_NT_SIGNATURE)
{
  delete [] pFileBuffer;
  return false;
}
//IMAGE_DOS_HEADER
printf("\r\nIMAGE_DOS_HEADER:\r\n\te_magic:\t\t\t0x%08X\r\n\te_cblp:\t\t\t\t0x%08X\r\n\te_cp:\t\t\t\t0x%08X\r\n\te_crlc:\t\t\t\t0x%08X\r\n\t",
  pIDH->e_magic,
  pIDH->e_cblp,
  pIDH->e_cp,
  pIDH->e_crlc);
printf("e_cparhdr:\t\t\t0x%08X\r\n\te_minalloc:\t\t\t0x%08X\r\n\te_maxalloc:\t\t\t0x%08X\r\n\te_ss:\t\t\t\t0x%08X\r\n\t",
  pIDH->e_cparhdr,
  pIDH->e_minalloc,
  pIDH->e_maxalloc,
  pIDH->e_ss);
printf("e_sp:\t\t\t\t0x%08X\r\n\te_csum:\t\t\t\t0x%08X\r\n\te_ip:\t\t\t\t0x%08X\r\n\te_cs:\t\t\t\t0x%08X\r\n\t",
  pIDH->e_sp,
  pIDH->e_csum,
  pIDH->e_ip,
  pIDH->e_cs);
printf("e_lfarlc:\t\t\t0x%08X\r\n\te_ovno:\t\t\t\t0x%08X\r\n\te_res:\t\t\t\t0x%08X\r\n\te_oemid:\t\t\t0x%08X\r\n\t",
  pIDH->e_lfarlc,
  pIDH->e_ovno,
  pIDH->e_res,
  pIDH->e_oemid);
printf("e_oeminfo:\t\t\t0x%08X\r\n\te_res2:\t\t\t\t0x%08X\r\n\te_lfanew:\t\t\t0x%08X\r\n",
  pIDH->e_oeminfo,
  pIDH->e_res2,
  pIDH->e_lfanew);

//IMAGE_FILE_HEADER
printf("\r\nIMAGE_FILE_HEADER:\r\n\tMachine:\t\t\t0x%08X\r\n\tNumberOfSections:\t\t0x%08X\r\n\tTimeDateStamp:\t\t\t0x%08X\r\n\tPointerToSymbolTable:\t\t0x%08X\r\n\t",
  pINH->FileHeader.Machine,
  pINH->FileHeader.NumberOfSections,
  pINH->FileHeader.TimeDateStamp,
  pINH->FileHeader.PointerToSymbolTable);
printf("NumberOfSymbols:\t\t0x%08X\r\n\tSizeOfOptionalHeader:\t\t0x%08X\r\n\tCharacteristics:\t\t0x%08X\r\n",
  pINH->FileHeader.NumberOfSymbols,
  pINH->FileHeader.SizeOfOptionalHeader,
  pINH->FileHeader.Characteristics);
//IMAGE_OPTIONAL_HEADER
printf("\r\nIMAGE_OPTIONAL_HEADER:\r\n\tMagic:\t\t\t\t0x%08X\r\n\tMajorLinkerVersion:\t\t0x%08X\r\n\tMinorLinkerVersion:\t\t0x%08X\r\n\tSizeOfCode:\t\t\t0x%08X\r\n\t",
  pINH->OptionalHeader.Magic,
  pINH->OptionalHeader.MajorLinkerVersion,
  pINH->OptionalHeader.MinorLinkerVersion,
  pINH->OptionalHeader.SizeOfCode);
printf("SizeOfInitializedData:\t\t0x%08X\r\n\tSizeOfUninitializedData:\t0x%08X\r\n\tAddressOfEntryPoint:\t\t0x%08X\r\n\tBaseOfCode:\t\t\t0x%08X\r\n\tBaseOfData:\t\t\t0x%08X\r\n",
  pINH->OptionalHeader.SizeOfInitializedData,
  pINH->OptionalHeader.SizeOfUninitializedData,
  pINH->OptionalHeader.AddressOfEntryPoint,
  pINH->OptionalHeader.BaseOfCode,
  pINH->OptionalHeader.BaseOfData);
printf("\tImageBase:\t\t\t0x%08X\r\n\tSectionAlignment:\t\t0x%08X\r\n\tFileAlignment:\t\t\t0x%08X\r\n\tMajorOperatingSystemVersion:\t0x%08X\r\n\t",
  pINH->OptionalHeader.ImageBase,
  pINH->OptionalHeader.SectionAlignment,
  pINH->OptionalHeader.FileAlignment,
  pINH->OptionalHeader.MajorOperatingSystemVersion);
printf("MinorOperatingSystemVersion:\t0x%08X\r\n\tMajorImageVersion:\t\t0x%08X\r\n\tMinorImageVersion:\t\t0x%08X\r\n\tMajorSubsystemVersion:\t\t0x%08X\r\n\tMinorSubsystemVersion:\t\t0x%08X\r\n",
  pINH->OptionalHeader.MinorOperatingSystemVersion,
  pINH->OptionalHeader.MajorImageVersion,
  pINH->OptionalHeader.MinorImageVersion,
  pINH->OptionalHeader.MajorSubsystemVersion,
  pINH->OptionalHeader.MinorSubsystemVersion);
printf("\tWin32VersionValue:\t\t0x%08X\r\n\tSizeOfImage:\t\t\t0x%08X\r\n\tSizeOfHeaders:\t\t\t0x%08X\r\n\tCheckSum:\t\t\t0x%08X\r\n\t",
  pINH->OptionalHeader.Win32VersionValue,
  pINH->OptionalHeader.SizeOfImage,
  pINH->OptionalHeader.SizeOfHeaders,
  pINH->OptionalHeader.CheckSum);
printf("Subsystem:\t\t\t0x%08X\r\n\tDllCharacteristics:\t\t0x%08X\r\n\tSizeOfStackReserve:\t\t0x%08X\r\n\tSizeOfStackCommit:\t\t0x%08X\r\n\t",
  pINH->OptionalHeader.Subsystem,
  pINH->OptionalHeader.DllCharacteristics,
  pINH->OptionalHeader.SizeOfStackReserve,
  pINH->OptionalHeader.SizeOfStackCommit);
printf("SizeOfHeapReserve:\t\t0x%08X\r\n\tSizeOfHeapCommit:\t\t0x%08X\r\n\tLoaderFlags:\t\t\t0x%08X\r\n\tNumberOfRvaAndSizes:\t\t0x%08X\r\n\t",
  pINH->OptionalHeader.SizeOfHeapReserve,
  pINH->OptionalHeader.SizeOfHeapCommit,
  pINH->OptionalHeader.LoaderFlags,
  pINH->OptionalHeader.NumberOfRvaAndSizes);
//IMAGE_DATA_DIRS
printf("\r\nIMAGE_DATA_DIRECTORY:\r\n");
for(int i = 0; i < pINH->OptionalHeader.NumberOfRvaAndSizes;i++)
{
  printf("\t Nr.%02d: VA: 0x%08X Size: 0x%08X\r\n",
   i,
   pINH->OptionalHeader.DataDirectory[i].VirtualAddress,
   pINH->OptionalHeader.DataDirectory[i].Size);
}
//IMAGE_SECTION_HEADER
printf("\r\nIMAGE_SECTION_HEADER:\r\n");
PIMAGE_SECTION_HEADER pSH = (PIMAGE_SECTION_HEADER)(pFileBuffer + pIDH->e_lfanew + sizeof(IMAGE_NT_HEADERS32));
for (int i = 0; i < pINH->FileHeader.NumberOfSections;i++)
{
  printf("\tName:\t\t\t%s\r\n\tVirtualSize:\t\t0x%08X\r\n\tVirtualAdress:\t\t0x%08X\r\n\tSizeOfRawData:\t\t0x%08X\r\n\tPointerToRawData:\t0x%08X\r\n\tCharacteristics:\t0x%08X\r\n",
   pSH->Name,
   pSH->Misc.VirtualSize,
   pSH->VirtualAddress,
   pSH->SizeOfRawData,
   pSH->PointerToRawData,
   pSH->Characteristics);
  pSH++;
}
DWORD dwVAOfImportSection = pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;     
DWORD dwImportSectionOffset = dwCalculateTableOffset(IMAGE_DIRECTORY_ENTRY_IMPORT,pINH,pIDH,pFileBuffer);
if(dwImportSectionOffset != 0)
{
  PIMAGE_IMPORT_DESCRIPTOR pImportHeader = (PIMAGE_IMPORT_DESCRIPTOR)dwImportSectionOffset;
  //IMAGE_IMPORTS_DESCRIPTORS
  printf("\r\nFILE_IMPORTS:\r\n");
  do
  {
   printf("\r\n\tName:\t\t\t%s\r\n\tCharacteristics:\t0x%08X\r\n\tFirstThunk(IAT):\t0x%08X\r\n\tOriginalFirstThunk(INT):0x%08X\r\n\tForwarderChain:\t\t0x%08X\r\n\tTimeDateStamp:\t\t0x%08X\r\n",
    (char*)((pImportHeader->Name)-dwVAOfImportSection) + dwImportSectionOffset,
    pImportHeader->Characteristics,
    pImportHeader->FirstThunk,
    pImportHeader->OriginalFirstThunk,
    pImportHeader->ForwarderChain,
    pImportHeader->TimeDateStamp);
   //DWORD rvaINT = pImportHeader->OriginalFirstThunk;
   DWORD rvaIAT = pImportHeader->FirstThunk;
   PIMAGE_THUNK_DATA32 pIAT = (PIMAGE_THUNK_DATA32)((rvaIAT - dwVAOfImportSection) + dwImportSectionOffset);
   if (pIAT->u1. Ordinal) //maybe no imports from dll
   {
    printf("\r\n\tIMPORTS:\r\n");
    do
    {
         if (IMAGE_SNAP_BY_ORDINAL32(pIAT->u1.Ordinal))
         {
          //by ordinal
          printf("\tOrdinal:\t\t\t0x%08X\r\n",
           IMAGE_ORDINAL32(pIAT->u1.Ordinal));
         } else {
          //by name
          PIMAGE_IMPORT_BY_NAME pImportName = (PIMAGE_IMPORT_BY_NAME)(((pIAT->u1.AddressOfData)- dwVAOfImportSection) + dwImportSectionOffset);
          printf("\t\tName:\t\t%s\r\n\t\tHint:\t\t0x%08X\r\n",
           pImportName->Name,
           pImportName->Hint);
         }
         pIAT++;
    } while (pIAT->u1. AddressOfData != 0);
   }
   pImportHeader++;
  } while (pImportHeader->Name);
}
DWORD exportTableVA = pINH->OptionalHeader. DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress;
DWORD exportTableOffset = dwCalculateTableOffset(IMAGE_DIRECTORY_ENTRY_EXPORT,pINH,pIDH,pFileBuffer);
if(exportTableOffset != 0)
{
  //IMAGE_EXPORT_DESCRIPTORS
  printf("\r\n\tFILE_EXPORTS:\r\n");
  PIMAGE_EXPORT_DIRECTORY pExportTable = (PIMAGE_EXPORT_DIRECTORY)(exportTableOffset);

  printf("\tName:\t\t\t%s\r\n\tBase:\t\t\t0x%08X\r\n\tNumberOfFunctions:\t0x%08X\r\n\tNumberOfNames:\t0x%08X\r\n\tAddressOfFunctions:\t\t0x%08X\r\n\tAddressOfNameOrdinals:\t0x%08X\r\n",
   (char *)((pExportTable->Name)-exportTableVA) + exportTableOffset,
   pExportTable->Base,
   pExportTable->NumberOfFunctions,
   pExportTable->NumberOfNames,
   pExportTable->AddressOfFunctions,
   pExportTable->AddressOfNameOrdinals);
  DWORD* addressOfFunctionsArray = (DWORD*)(((pExportTable->AddressOfFunctions)-exportTableVA) + exportTableOffset);
  DWORD* addressOfNamesArray = (DWORD*)(((pExportTable->AddressOfNames)-exportTableVA) + exportTableOffset);
  WORD* addressOfNameOrdinalsArray = (WORD*)(((pExportTable->AddressOfNameOrdinals)-exportTableVA) + exportTableOffset);
  for (DWORD i = 0; i < pExportTable->NumberOfNames; i++)
  {
   printf("\tName:\t\t\t%s\r\n\tOrdinal:\t\t\t0x%08X\r\n\tName Ordinal:\t0x%08X\r\n\tAdress(RVA):\t0x%08X\r\n",
    (char*)(((addressOfNamesArray[i])-exportTableVA) + exportTableOffset),
    (addressOfNameOrdinalsArray[i] + pExportTable->Base),
    addressOfNameOrdinalsArray[i],
    addressOfFunctionsArray[addressOfNameOrdinalsArray[i]]);
  }
}
DWORD TLSTableVA = pINH->OptionalHeader. DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]. VirtualAddress;
DWORD TLSTableOffset = dwCalculateTableOffset(IMAGE_DIRECTORY_ENTRY_TLS,pINH,pIDH,pFileBuffer);
if(TLSTableOffset != 0)
{
  //IMAGE_TLS_DIRECTORY
  printf("\r\nTLS-TABLE:\r\n");
  PIMAGE_TLS_DIRECTORY32 pTLS = (PIMAGE_TLS_DIRECTORY32)TLSTableOffset;
  printf("\tStartAddressOfRawData:t\t\t%s\r\n\tEndAddressOfRawData:\t0x%08X\r\n\tSizeOfZeroFill:\t0x%08X\r\n\tCharacteristics:\t0x%08X\r\n\tAddressOfIndex:\t0x%08X\r\n\tAddressOfCallBacks:\t0x%08X\r\n",
   pTLS->StartAddressOfRawData,
   pTLS->EndAddressOfRawData,
   pTLS->SizeOfZeroFill,
   pTLS->Characteristics,
   pTLS->AddressOfIndex,
   pTLS->AddressOfCallBacks);
}
delete [] pFileBuffer;
CloseHandle(hFile);
system("pause");
return 0;
}


~Zer0Flag
« Last Edit: October 13, 2011, 10:05:08 am by ande »

Offline xzid

  • Knight
  • **
  • Posts: 329
  • Cookies: 41
    • View Profile
Re: [C] PEPrinter
« Reply #1 on: October 13, 2011, 09:34:21 am »
Hmm cool, apparently using PE is significantly easier than using <elf.h> on linux. They give you a couple structs and macros, have fun loserz! Will be working with raw PE soon, some examples are always nice. +1

Btw this is C++, (new/delete, declaring variables in for()[C99], "false", etc..). Ran into about 8-9 errors when compiling, then was like WTF??!?... Oh C++.

Offline Zer0Flag

  • Serf
  • *
  • Posts: 20
  • Cookies: 5
    • View Profile
Re: [C++] PEPrinter
« Reply #2 on: October 13, 2011, 06:04:57 pm »
Yeah the support is fine under Windows for that :).

Ok sry. I´m used to code in VS ( C++ compiler but able to compile c too ) and sometimes mix up elements of both languages.