Advertisement
alien_fx_fiend

PE-Parser Console-based Port in C *FINAL RELEASE*

Nov 19th, 2024
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.84 KB | Source Code | 0 0
  1. ==++ Here's the full code for (file 1/2) "source.cpp"::++==
  2. #include <Windows.h>
  3. #include <winternl.h>
  4. #include <cstdio>
  5. #include <strsafe.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "concol.h"
  9. #include <conio.h> // Include for _getch()
  10. #include "resource.h"  // Add this with your other includes
  11.  
  12. /**
  13. * Function to retrieve the PE file content.
  14. * \param lpFilePath : path of the PE file.
  15. * \return : address of the content in the explorer memory.
  16. */
  17. HANDLE GetFileContent(const char* lpFilePath)
  18. {
  19.    HANDLE hFile = CreateFileA(lpFilePath, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
  20.    if (hFile == INVALID_HANDLE_VALUE)
  21.    {
  22.        printf("[-] Error opening PE file!\n");
  23.        return nullptr;
  24.    }
  25.  
  26.    DWORD fileSize = GetFileSize(hFile, nullptr);
  27.    if (fileSize == INVALID_FILE_SIZE)
  28.    {
  29.        printf("[-] Error getting PE file size!\n");
  30.        CloseHandle(hFile);
  31.        return nullptr;
  32.    }
  33.  
  34.    // Allocate memory using HeapAlloc (preferred in Windows)
  35.    LPVOID lpFileContent = HeapAlloc(GetProcessHeap(), 0, fileSize);
  36.    if (lpFileContent == nullptr)
  37.    {
  38.        printf("[-] Error allocating memory for PE file content!\n");
  39.        CloseHandle(hFile);
  40.        return nullptr;
  41.    }
  42.  
  43.    DWORD dwBytesRead;
  44.    if (!ReadFile(hFile, lpFileContent, fileSize, &dwBytesRead, nullptr))
  45.    {
  46.        printf("[-] Error reading PE file content!\n");
  47.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  48.        CloseHandle(hFile);
  49.        return nullptr;
  50.    }
  51.  
  52.    CloseHandle(hFile);
  53.    return lpFileContent; // Return the allocated memory pointer
  54. }
  55.  
  56. /**
  57. * Function to identify the PE file characteristics.
  58. * \param dCharacteristics : characteristics in the file header section.
  59. * \return : the description of the PE file characteristics.
  60. */
  61. const char* GetImageCharacteristics(DWORD dCharacteristics)
  62. {
  63.    if (dCharacteristics & IMAGE_FILE_DLL)
  64.        return "(DLL)";
  65.  
  66.    if (dCharacteristics & IMAGE_FILE_SYSTEM)
  67.        return "(DRIVER)";
  68.  
  69.    if (dCharacteristics & IMAGE_FILE_EXECUTABLE_IMAGE)
  70.        return "(EXE)";
  71.  
  72.    return "(UNKNOWN)";
  73. }
  74.  
  75. /**
  76. * Function to identify the PE file subsystem.
  77. * \param Subsystem : subsystem in the optional header.
  78. * \return : the description of the PE file subsystem.
  79. */
  80. const char* GetSubsytem(WORD Subsystem)
  81. {
  82.    if (Subsystem == 1)
  83.        return "(NATIVE / DRIVER)";
  84.  
  85.    if (Subsystem == 2)
  86.        return "(GUI APP)";
  87.  
  88.    if (Subsystem == 3)
  89.        return "(CONSOLE APP)";
  90.  
  91.    return "(UNKNOWN)";
  92. }
  93.  
  94. /**
  95. * Function to identify the DataDirectory.
  96. * \param DirectoryNumber : index of the DataDirectory.
  97. * \return : the description of the DataDirectory.
  98. */
  99. const char* GetDataDirectoryName(int DirectoryNumber)
  100. {
  101.    switch (DirectoryNumber)
  102.    {
  103.    case 0:
  104.        return "Export Table";
  105.  
  106.    case 1:
  107.        return "Import Table";
  108.  
  109.    case 2:
  110.        return "Ressource Table";
  111.  
  112.    case 3:
  113.        return "Exception Entry";
  114.  
  115.    case 4:
  116.        return "Security Entry";
  117.  
  118.    case 5:
  119.        return "Relocation Table";
  120.  
  121.    case 6:
  122.        return "Debug Entry";
  123.  
  124.    case 7:
  125.        return "Copyright Entry";
  126.  
  127.    case 8:
  128.        return "Global PTR Entry";
  129.  
  130.    case 9:
  131.        return "TLS Entry";
  132.  
  133.    case 10:
  134.        return "Configuration Entry";
  135.  
  136.    case 11:
  137.        return "Bound Import Entry";
  138.  
  139.    case 12:
  140.        return "IAT";
  141.  
  142.    case 13:
  143.        return "Delay Import Descriptor";
  144.  
  145.    case 14:
  146.        return "COM Descriptor";
  147.  
  148.    default:
  149.        return nullptr;
  150.    }
  151. }
  152. /**
  153. * Retrieve and display the DataDirectory informations.
  154. * \param pImageDataDirectory : DataDirectory array of the optional header.
  155. */
  156. void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory)
  157. {
  158.    for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory)
  159.    {
  160.        if (pImageDataDirectory->VirtualAddress == 0)
  161.            continue;
  162.  
  163.        printf("\tDataDirectory (%s) VirtualAddress : 0x%X\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->VirtualAddress);
  164.        printf("\tDataDirectory (%s) Size : 0x%X\n\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->Size);
  165.    }
  166. }
  167.  
  168. /**
  169. * Retrieve and display the protection of the section.
  170. * \param dCharacteristics : characteristics of the section.
  171. * \return : the description of the protection.
  172. */
  173. const char* GetSectionProtection(DWORD dCharacteristics)
  174. {
  175.    char lpSectionProtection[1024] = {};
  176.    StringCchCatA(lpSectionProtection, 1024, "(");
  177.    bool bExecute = false, bRead = false;
  178.  
  179.    if (dCharacteristics & IMAGE_SCN_MEM_EXECUTE)
  180.    {
  181.        bExecute = true;
  182.        StringCchCatA(lpSectionProtection, 1024, "EXECUTE");
  183.    }
  184.  
  185.    if (dCharacteristics & IMAGE_SCN_MEM_READ)
  186.    {
  187.        bRead = true;
  188.        if (bExecute)
  189.            StringCchCatA(lpSectionProtection, 1024, " | ");
  190.        StringCchCatA(lpSectionProtection, 1024, "READ");
  191.    }
  192.  
  193.    if (dCharacteristics & IMAGE_SCN_MEM_WRITE)
  194.    {
  195.        if (bExecute || bRead)
  196.            StringCchCatA(lpSectionProtection, 1024, " | ");
  197.        StringCchCatA(lpSectionProtection, 1024, "WRITE");
  198.    }
  199.  
  200.    StringCchCatA(lpSectionProtection, 1024, ")");
  201.    return lpSectionProtection;
  202. }
  203.  
  204. /**
  205. * Function to retrieve sections from the PE file and get the section wich contains imports.
  206. * \param pImageSectionHeader : section header of the PE file.
  207. * \param NumberOfSections : number of section in the PE file.
  208. * \param dImportAddress : address of import found into DataDirectory 1.
  209. * \return : section which contains imports.
  210. */
  211. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader, int NumberOfSections, DWORD dImportAddress)
  212. {
  213.    PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
  214.  
  215.    printf("\n[+] PE IMAGE SECTIONS\n");
  216.  
  217.    for (int i = 0; i < NumberOfSections; ++i)
  218.    {
  219.        const auto pCurrentSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageSectionHeader + i * sizeof(IMAGE_SECTION_HEADER));
  220.        printf("\n\tSECTION : %s\n", (char*)pCurrentSectionHeader->Name);
  221.        printf("\t\tMisc (PhysicalAddress) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
  222.        printf("\t\tMisc (VirtualSize) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
  223.        printf("\t\tVirtualAddress : 0x%X\n", (uintptr_t)pCurrentSectionHeader->VirtualAddress);
  224.        printf("\t\tSizeOfRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
  225.        printf("\t\tPointerToRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->PointerToRawData);
  226.        printf("\t\tPointerToRelocations : 0x%X\n", (uintptr_t)pCurrentSectionHeader->PointerToRelocations);
  227.        printf("\t\tPointerToLinenumbers : 0x%X\n", (uintptr_t)pCurrentSectionHeader->PointerToLinenumbers);
  228.        printf("\t\tNumberOfRelocations : 0x%X\n", (uintptr_t)pCurrentSectionHeader->NumberOfRelocations);
  229.        printf("\t\tNumberOfLinenumbers : 0x%X\n", (uintptr_t)pCurrentSectionHeader->NumberOfLinenumbers);
  230.        printf("\t\tCharacteristics : 0x%X %s\n", (uintptr_t)pCurrentSectionHeader->Characteristics, GetSectionProtection(pCurrentSectionHeader->Characteristics));
  231.  
  232.        if (dImportAddress >= pCurrentSectionHeader->VirtualAddress && dImportAddress < pCurrentSectionHeader->VirtualAddress + pCurrentSectionHeader->Misc.VirtualSize)
  233.            pImageImportHeader = pCurrentSectionHeader;
  234.    }
  235.  
  236.    return pImageImportHeader;
  237. }
  238.  
  239. /**
  240. * Retrieve and display dll and functions imported (for x86 PE file).
  241. * \param pImageImportDescriptor : import descriptor of the PE file.
  242. * \param dRawOffset : address of raw data of the import section.
  243. * \param pImageImportSection : section wich contains imports.
  244. */
  245. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
  246. {
  247.    printf("\n[+] IMPORTED DLL\n");
  248.  
  249.    while (pImageImportDescriptor->Name != 0)
  250.    {
  251.        printf("\n\tDLL NAME : %s\n", (char*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  252.        printf("\tCharacteristics : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
  253.        printf("\tOriginalFirstThunk : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
  254.        printf("\tTimeDateStamp : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
  255.        printf("\tForwarderChain : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
  256.        printf("\tFirstThunk : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
  257.  
  258.        if (pImageImportDescriptor->OriginalFirstThunk == 0)
  259.            continue;
  260.  
  261.        auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA32)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  262.  
  263.        printf("\n\tImported Functions : \n\n");
  264.  
  265.        while (pOriginalFirstThrunk->u1.AddressOfData != 0)
  266.        {
  267.            if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG32)
  268.            {
  269.                ++pOriginalFirstThrunk;
  270.                continue;
  271.            }
  272.  
  273.            const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)pOriginalFirstThrunk->u1.AddressOfData;
  274.            if (pImageImportByName == nullptr)
  275.                continue;
  276.  
  277.            if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
  278.                printf("\t\t0x%X (Ordinal) : %s\n", (uintptr_t)pOriginalFirstThrunk->u1.AddressOfData, dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress));
  279.            else
  280.                printf("\t\t%s\n", dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress));
  281.  
  282.            ++pOriginalFirstThrunk;
  283.        }
  284.  
  285.        ++pImageImportDescriptor;
  286.    }
  287. }
  288.  
  289. /**
  290. * Retrieve and display dll and functions imported (for x64 PE file).
  291. * \param pImageImportDescriptor : import descriptor of the PE file.
  292. * \param dRawOffset : address of raw data of the import section.
  293. * \param pImageImportSection : section wich contains imports.
  294. */
  295. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
  296. {
  297.    printf("\n[+] IMPORTED DLL\n");
  298.  
  299.    while (pImageImportDescriptor->Name != 0)
  300.    {
  301.        printf("\n\tDLL NAME : %s\n", (char*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  302.        printf("\tCharacteristics : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
  303.        printf("\tOriginalFirstThunk : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
  304.        printf("\tTimeDateStamp : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
  305.        printf("\tForwarderChain : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
  306.        printf("\tFirstThunk : 0x%X\n", (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
  307.  
  308.        if (pImageImportDescriptor->OriginalFirstThunk == 0)
  309.            continue;
  310.  
  311.        auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA64)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  312.  
  313.        printf("\n\tImported Functions : \n\n");
  314.  
  315.        while (pOriginalFirstThrunk->u1.AddressOfData != 0)
  316.        {
  317.            if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG64)
  318.            {
  319.                ++pOriginalFirstThrunk;
  320.                continue;
  321.            }
  322.  
  323.            const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(dRawOffset + (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  324.            if (pImageImportByName == nullptr)
  325.                continue;
  326.  
  327.            if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
  328.                printf("\t\t0x%X (Ordinal) : %s\n", (uintptr_t)pOriginalFirstThrunk->u1.AddressOfData, (char*)pImageImportByName->Name);
  329.            else
  330.                printf("\t\t%s\n", (char*)pImageImportByName->Name);
  331.  
  332.            ++pOriginalFirstThrunk;
  333.        }
  334.  
  335.        ++pImageImportDescriptor;
  336.    }
  337. }
  338.  
  339. int main()
  340. {
  341.    // Get the handle to the console window
  342.    HWND consoleWindow = GetConsoleWindow();
  343.  
  344.    // Set the console window size 1200,659
  345.    SetWindowPos(consoleWindow, NULL, 0, 0, 800, 500, SWP_NOZORDER | SWP_NOMOVE);
  346.  
  347.    // Get the screen size
  348.    RECT screenRect;
  349.    GetWindowRect(GetDesktopWindow(), &screenRect);
  350.  
  351.    // Get the console window size
  352.    RECT consoleRect;
  353.    GetWindowRect(consoleWindow, &consoleRect);
  354.    int consoleWidth = consoleRect.right - consoleRect.left;
  355.    int consoleHeight = consoleRect.bottom - consoleRect.top;
  356.  
  357.    // Calculate the new console position
  358.    int xPos = (screenRect.right - consoleWidth) / 2;
  359.    int yPos = (screenRect.bottom - consoleHeight) / 2;
  360.  
  361.    // Set the console window position and size
  362.    SetWindowPos(consoleWindow, NULL, xPos, yPos, consoleWidth, consoleHeight, SWP_NOZORDER | SWP_NOSIZE);
  363.    /* End test injection */
  364.  
  365.    /* Start test BlockCaret */
  366.        // Get the handle to the console output
  367.    HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  368.  
  369.    // Get the current console cursor info
  370.    CONSOLE_CURSOR_INFO cursorInfo;
  371.    GetConsoleCursorInfo(hConsoleOutput, &cursorInfo);
  372.  
  373.    // Change the cursor size to maximum
  374.    cursorInfo.dwSize = 100;
  375.  
  376.    // Set the new console cursor info
  377.    SetConsoleCursorInfo(hConsoleOutput, &cursorInfo);
  378.    /* End test BlockCaret */
  379.  
  380.    /* Start test TitleBar ReCaptioning */
  381.        // Set the console window title
  382.    SetConsoleTitle(L"Chat Client CowSay Loop (Serialized)");
  383.    /* End test TitleBar ReCaptioning */
  384.  
  385.    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  386.    CONSOLE_FONT_INFOEX fontInfo = { sizeof(CONSOLE_FONT_INFOEX) };
  387.    GetCurrentConsoleFontEx(hConsole, FALSE, &fontInfo);
  388.    fontInfo.FontWeight = 1000; // 700 is the value for bold font weight
  389.    fontInfo.dwFontSize = { 10, 20 }; // set font size
  390.    wcscpy_s(fontInfo.FaceName, L"Source Code Pro Black"); // set font name
  391.  
  392.    SetCurrentConsoleFontEx(hConsole, FALSE, &fontInfo);
  393.    //This is one way to do it. Taken from stackoverflow.
  394.    system("color DB");
  395.  
  396.    char filePath[MAX_PATH];
  397.  
  398.    printf("Enter PE file path: ");
  399.    if (fgets(filePath, MAX_PATH, stdin) == NULL) {
  400.        printf("Error reading input\n");
  401.        printf("\nPress any key to exit...");
  402.        _getch();
  403.        return 1;
  404.    }
  405.  
  406.    // Remove newline if present
  407.    filePath[strcspn(filePath, "\n")] = 0;
  408.  
  409.    // Get PE file content
  410.    LPVOID lpFileContent = GetFileContent(filePath);
  411.    if (lpFileContent == nullptr)
  412.    {
  413.        printf("\nPress any key to exit...");
  414.        _getch();
  415.        return 1;
  416.    }
  417.  
  418.    // Get DOS header
  419.    const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
  420.    if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  421.    {
  422.        printf("[-] Invalid DOS signature!\n");
  423.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  424.        printf("\nPress any key to exit...");
  425.        _getch();
  426.        return 1;
  427.    }
  428.  
  429.    // Get NT headers
  430.    const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
  431.    if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE)
  432.    {
  433.        printf("[-] Invalid NT signature!\n");
  434.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  435.        printf("\nPress any key to exit...");
  436.        _getch();
  437.        return 1;
  438.    }
  439.  
  440.    // Display basic information
  441.    printf("[+] PE FILE INFORMATION\n");
  442.    printf("\tCharacteristics : 0x%X %s\n", pImageNtHeaders->FileHeader.Characteristics,
  443.        GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
  444.    printf("\tSubsystem : 0x%X %s\n", pImageNtHeaders->OptionalHeader.Subsystem,
  445.        GetSubsytem(pImageNtHeaders->OptionalHeader.Subsystem));
  446.  
  447.    // Get DataDirectory information
  448.    GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
  449.  
  450.    // Get section containing imports
  451.    const auto pImageSectionHeader = IMAGE_FIRST_SECTION(pImageNtHeaders);
  452.    const auto pImageImportSection = GetSections(pImageSectionHeader,
  453.        pImageNtHeaders->FileHeader.NumberOfSections,
  454.        pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
  455.  
  456.    if (pImageImportSection == nullptr)
  457.    {
  458.        printf("[-] No import section found!\n");
  459.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  460.        printf("\nPress any key to exit...");
  461.        _getch();
  462.        return 1;
  463.    }
  464.  
  465.    // Get imports
  466.    const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>((DWORD_PTR)lpFileContent +
  467.        (pImageImportSection->PointerToRawData + (pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress -
  468.            pImageImportSection->VirtualAddress)));
  469.  
  470.    // Check machine type and get imports accordingly
  471.    if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
  472.        GetImports32(pImageImportDescriptor, (DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
  473.    else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
  474.        GetImports64(pImageImportDescriptor, (DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
  475.  
  476.    // Cleanup
  477.    HeapFree(GetProcessHeap(), 0, lpFileContent);
  478.  
  479.    // Wait for user input before closing
  480.    printf("\nPress any key to exit...");
  481.    _getch();
  482.    return 0;
  483. }
  484.  
  485. ==++ Here's the full code for (file 2/2) "concol.h"::++==
  486. #pragma once
  487. //This is a header file taken from cplusplus.com
  488. //http://www.cplusplus.com/articles/Eyhv0pDG/
  489. //concol.h
  490. #ifndef _INC_EKU_IO_CONCOL
  491. #define _INC_EKU_IO_CONCOL
  492.  
  493. /*Header file to color text and background in windows console applications
  494. Global variables - textcol,backcol,deftextcol,defbackcol,colorprotect*/
  495.  
  496. #include<windows.h>
  497. #include<iosfwd>
  498.  
  499. namespace eku
  500. {
  501.  
  502. #ifndef CONCOL
  503. #define CONCOL
  504.     enum concol
  505.     {
  506.         black = 0,
  507.         dark_blue = 1,
  508.         dark_green = 2,
  509.         dark_aqua, dark_cyan = 3,
  510.         dark_red = 4,
  511.         dark_purple = 5, dark_pink = 5, dark_magenta = 5,
  512.         dark_yellow = 6,
  513.         dark_white = 7,
  514.         gray = 8,
  515.         blue = 9,
  516.         green = 10,
  517.         aqua = 11, cyan = 11,
  518.         red = 12,
  519.         purple = 13, pink = 13, magenta = 13,
  520.         yellow = 14,
  521.         white = 15
  522.     };
  523. #endif //CONCOL
  524.  
  525.     HANDLE std_con_out;
  526.     //Standard Output Handle
  527.     bool colorprotect = false;
  528.     //If colorprotect is true, background and text colors will never be the same
  529.     concol textcol, backcol, deftextcol, defbackcol;
  530.     /*textcol - current text color
  531.     backcol - current back color
  532.     deftextcol - original text color
  533.     defbackcol - original back color*/
  534.  
  535.     inline void update_colors()
  536.     {
  537.         CONSOLE_SCREEN_BUFFER_INFO csbi;
  538.         GetConsoleScreenBufferInfo(std_con_out, &csbi);
  539.         textcol = concol(csbi.wAttributes & 15);
  540.         backcol = concol((csbi.wAttributes & 0xf0) >> 4);
  541.     }
  542.  
  543.     inline void setcolor(concol textcolor, concol backcolor)
  544.     {
  545.         if (colorprotect && textcolor == backcolor)return;
  546.         textcol = textcolor; backcol = backcolor;
  547.         unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
  548.         SetConsoleTextAttribute(std_con_out, wAttributes);
  549.     }
  550.  
  551.     inline void settextcolor(concol textcolor)
  552.     {
  553.         if (colorprotect && textcolor == backcol)return;
  554.         textcol = textcolor;
  555.         unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
  556.         SetConsoleTextAttribute(std_con_out, wAttributes);
  557.     }
  558.  
  559.     inline void setbackcolor(concol backcolor)
  560.     {
  561.         if (colorprotect && textcol == backcolor)return;
  562.         backcol = backcolor;
  563.         unsigned short wAttributes = ((unsigned int)backcol << 4) | (unsigned int)textcol;
  564.         SetConsoleTextAttribute(std_con_out, wAttributes);
  565.     }
  566.  
  567.     inline void concolinit()
  568.     {
  569.         std_con_out = GetStdHandle(STD_OUTPUT_HANDLE);
  570.         update_colors();
  571.         deftextcol = textcol; defbackcol = backcol;
  572.     }
  573.  
  574.     template<class elem, class traits>
  575.     inline std::basic_ostream<elem, traits>& operator<<(std::basic_ostream<elem, traits>& os, concol col)
  576.     {
  577.         os.flush(); settextcolor(col); return os;
  578.     }
  579.  
  580.     template<class elem, class traits>
  581.     inline std::basic_istream<elem, traits>& operator>>(std::basic_istream<elem, traits>& is, concol col)
  582.     {
  583.         std::basic_ostream<elem, traits>* p = is.tie();
  584.         if (p != NULL)p->flush();
  585.         settextcolor(col);
  586.         return is;
  587.     }
  588.  
  589. }   //end of namespace eku
  590.  
  591. #endif  //_INC_EKU_IO_CONCOL
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement