Ladies_Man

#kacnep napcep

Jan 2nd, 2017
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <map>
  3. #include <vector>
  4. #include <stdint.h>
  5. #include <stdint-gcc.h>
  6.  
  7. using namespace std;
  8.  
  9. typedef uint32_t DWORD;
  10. typedef uint16_t WORD;
  11. typedef uint8_t BYTE;
  12.  
  13. typedef struct _IMAGE_DATA_DIRECTORY {
  14.     DWORD rva;
  15.     DWORD size;
  16. } IMAGE_DATA_DIRECTORY;
  17.  
  18. typedef struct _IMAGE_SECTION_HEADER {
  19.     BYTE    name[8];
  20.     union {
  21.         DWORD physicalAddress;
  22.         DWORD virtualSize;
  23.     } misc;
  24.     DWORD   virtualAddress;
  25.     DWORD   sizeOfRawData;
  26.     DWORD   pointerToRawData;
  27.     DWORD   pointerToRelocations;
  28.     DWORD   pointerToLinenumbers;
  29.     WORD    numberOfRelocations;
  30.     WORD    numberOfLinenumbers;
  31.     DWORD   characteristics;
  32. } IMAGE_SECTION_HEADER;
  33.  
  34. typedef struct _IMAGE_EXPORT_DIRECTORY {
  35.     DWORD   characteristics;
  36.     DWORD   timeDateStamp;
  37.     WORD    majorVersion;
  38.     WORD    minorVersion;
  39.     DWORD   name;
  40.     DWORD   base;
  41.     DWORD   numberOfFunctions;
  42.     DWORD   numberOfNames;
  43.     DWORD   addressOfFunctions;
  44.     DWORD   addressOfNames;
  45.     DWORD   addressOfNameOrdinals;
  46. } IMAGE_EXPORT_DIRECTORY;
  47.  
  48. #define IMAGE_DIRECTORY_ENTRY_EXPORT    0   // Export Directory
  49.  
  50. map<string, pair<int, DWORD>> addressByName;
  51.  
  52. unsigned int imageBase;
  53. unsigned int numberOfSections;
  54. unsigned int sectionAlignment = 0x50;
  55.  
  56. IMAGE_SECTION_HEADER *sections;
  57.  
  58. #define ALIGN_DOWN(x, align)  ( x & ~(align-1))
  59. #define ALIGN_UP(x, align)    ((x &  (align-1)) ? ALIGN_DOWN(x,align)+align : x)
  60.  
  61. int defSection(DWORD rva) {
  62.  
  63.     for (int i = 0; i < numberOfSections; ++i) {
  64.         DWORD start = sections[i].virtualAddress;
  65.         DWORD end = start + ALIGN_UP(sections[i].misc.virtualSize, sectionAlignment);
  66.  
  67.         if(rva >= start && rva < end)
  68.             return i;
  69.     }
  70.     return -1;
  71. }
  72.  
  73. DWORD rva2raw(DWORD rva)  {
  74.     //Image Base = app's entry point in virtual memory
  75.  
  76.     //VA = ImageBase + RVA;
  77.     //RAW = RVA - sectionRVA + rawSection;
  78.     // rawSection - смещение до секции от начала файла
  79.     // sectionRVA - RVA секции (это поле хранится внутри секции)
  80.  
  81.     //RVA >= sectionVitualAddress && RVA < ALIGN_UP(sectionVirtualSize, sectionAligment)
  82.     // sectionAligment - выравнивание для секции. Значение можно узнать в Optional-header.
  83.     // sectionVitualAddress - RVA секции - хранится непосредственно в секции
  84.     // ALIGN_UP() - функция, определяющая сколько занимает секция в памяти, учитывая выравнивание
  85.  
  86.     int indexSection = defSection(rva);
  87.     if(indexSection != -1)
  88.         return rva - sections[indexSection].virtualAddress + sections[indexSection].pointerToRawData;
  89.     else
  90.         return 0;
  91. }
  92.  
  93. IMAGE_SECTION_HEADER parseSection(FILE *f, int ptr) {
  94.  
  95.     IMAGE_SECTION_HEADER section;
  96.  
  97.     fseek(f, ptr, SEEK_SET);
  98.  
  99.     fread(&section.name,                   8, 1, f);
  100.     fread(&section.misc.virtualSize,       4, 1, f);
  101.     fread(&section.virtualAddress,         4, 1, f);
  102.     fread(&section.sizeOfRawData,          4, 1, f);
  103.     fread(&section.pointerToRawData,       4, 1, f);
  104.     fread(&section.pointerToRelocations,   4, 1, f);
  105.     fread(&section.pointerToLinenumbers,   4, 1, f);
  106.     fread(&section.numberOfRelocations,    2, 1, f);
  107.     fread(&section.numberOfLinenumbers,    2, 1, f);
  108.     fread(&section.characteristics,        4, 1, f);
  109.  
  110.     cout << section.name << "\t\t"
  111.         << hex << section.misc.virtualSize << "\t\t"
  112.         << hex << section.virtualAddress << "\t\t"
  113.         << hex << section.pointerToRawData << endl;
  114.  
  115.     return section;
  116. }
  117.  
  118. string getName(FILE *f, int ptr) {
  119.     BYTE tmp = 1;
  120.     string funcName = "";
  121.  
  122.     fseek(f, ptr, SEEK_SET);
  123.  
  124.     while (0 != tmp) {
  125.  
  126.         fread(&tmp, 1, 1, f);
  127.         funcName += tmp;
  128.     }
  129.  
  130.     return funcName.substr(0, funcName.length() - 1);//remove space
  131. }
  132.  
  133. void parseExportTable(FILE *f, int ptr) {
  134.     DWORD tmp = 0;
  135.     IMAGE_EXPORT_DIRECTORY exportDir;
  136.  
  137.     fseek(f, ptr, SEEK_SET);
  138.  
  139.     fread(&exportDir.characteristics,       4, 1, f);
  140.     fread(&exportDir.timeDateStamp,         4, 1, f);
  141.     fread(&exportDir.majorVersion,          2, 1, f);
  142.     fread(&exportDir.minorVersion,          2, 1, f);
  143.     fread(&exportDir.name,                  4, 1, f);
  144.     fread(&exportDir.base,                  4, 1, f);
  145.     fread(&exportDir.numberOfFunctions,     4, 1, f);
  146.     fread(&exportDir.numberOfNames,         4, 1, f);
  147.     fread(&exportDir.addressOfFunctions,    4, 1, f);
  148.     fread(&exportDir.addressOfNames,        4, 1, f);
  149.     fread(&exportDir.addressOfNameOrdinals, 4, 1, f);
  150.  
  151.     cout << "num of Names: #" << dec << exportDir.numberOfNames << endl;
  152.     cout << "num of Funcs: #" << dec << exportDir.numberOfFunctions << endl;
  153.  
  154.  
  155.     auto ptrToAddr = rva2raw(exportDir.addressOfFunctions);
  156.     auto ptrToNames = rva2raw(exportDir.addressOfNames);
  157.     auto ptrToOrdinals = rva2raw(exportDir.addressOfNameOrdinals);
  158.  
  159.     vector<string> names;
  160.     vector<int> ordinals;
  161.     vector<DWORD> addresses;
  162.  
  163.     for (int i = 0; i < exportDir.numberOfNames; i++) {
  164.  
  165.         fseek(f, ptrToNames, SEEK_SET);
  166.         fread(&tmp, 4, 1, f);
  167.         string name = getName(f, tmp);
  168.  
  169.         tmp = 0;
  170.         fseek(f, ptrToOrdinals, SEEK_SET);
  171.         fread(&tmp, 2, 1, f);
  172.         WORD ordinal = (WORD) tmp;
  173.  
  174.         names.push_back(name);
  175.         ordinals.push_back(ordinal);
  176.  
  177.         ptrToNames += 0x4;
  178.         ptrToOrdinals += 0x2;
  179.     }
  180.  
  181.  
  182.     for (int i = 0; i < exportDir.numberOfFunctions; i++) {
  183.  
  184.         fseek(f, ptrToAddr, SEEK_SET);
  185.         fread(&tmp, 4, 1, f);
  186.  
  187.         addresses.push_back(tmp);
  188.  
  189.         ptrToAddr += 0x4;
  190.     }
  191.  
  192.  
  193.  
  194.     for (int i = 0; i != exportDir.numberOfNames &&
  195.             i != exportDir.numberOfFunctions; i++)
  196.  
  197.         addressByName.insert(
  198.                 pair<string, pair<int, DWORD>>
  199.                         (names[i], pair<int, DWORD>(ordinals[i], addresses[i])));
  200.  
  201. }
  202.  
  203. void outputAllFunctions() {
  204.     cout << "Functions (ordinal / address / name):" << endl;
  205.     for (auto name : addressByName) {
  206.         cout << dec << name.second.first << "\t"
  207.             << hex << name.second.second << "\t"
  208.             << name.first << endl;
  209.     }
  210. }
  211.  
  212. void searchByName(string name) {
  213.     cout << endl << "Search address by name '" << name << "': ";
  214.  
  215.     if (addressByName.end() == addressByName.find(name))
  216.         cout << "no such function";
  217.     else
  218.         cout << addressByName.find(name)->second.second;
  219.  
  220.     cout << endl;
  221. }
  222.  
  223. bool parsePE(FILE *f) {
  224.     int ptr;
  225.  
  226.     if (f) {
  227.         if ('M' == fgetc(f) && 'Z' == fgetc(f)) {
  228.  
  229.             rewind(f);
  230.             unsigned int c = 1;
  231.             fseek(f, 0, SEEK_SET);
  232.             fread(&c, 2, 1, f);
  233.             cout << "e_magic:\t\t\t\t0x" << hex << c << endl;
  234.  
  235.             unsigned int e_lfnew = 1;
  236.             fseek(f, 0x3C, SEEK_SET);
  237.             fread(&e_lfnew, 4, 1, f);
  238.             cout << "e_lfnew:\t\t\t\t0x" << hex << e_lfnew << endl;
  239.  
  240.             unsigned int peHeader = 1;
  241.             fseek(f, e_lfnew, SEEK_SET);
  242.             fread(&peHeader, 4, 1, f);
  243.             cout << "peHeader:\t\t\t\t0x" << hex << peHeader << endl;
  244.  
  245.             fseek(f, e_lfnew + 0x30 + 4, SEEK_SET);
  246.             fread(&imageBase, 4, 1, f);
  247.             cout << "imageBase:\t\t\t\t0x" << hex << imageBase << endl;
  248.  
  249.             fseek(f, e_lfnew + 0x6, SEEK_SET);
  250.             fread(&numberOfSections, 2, 1, f);
  251.             cout << "numberOfSections:\t\t#" << dec << numberOfSections << endl;
  252.  
  253.             unsigned int numberOfRvaAndSizes = 1;
  254.             fseek(f, e_lfnew + 0x70 + 4, SEEK_SET);
  255.             fread(&numberOfRvaAndSizes, 4, 1, f);
  256.             cout << "numberOfRvaAndSizes:\t#" << dec << numberOfRvaAndSizes << endl;
  257.  
  258.  
  259.  
  260.             if (0 != numberOfRvaAndSizes) {
  261.  
  262.  
  263.                 IMAGE_DATA_DIRECTORY directories[numberOfRvaAndSizes];
  264.  
  265.                 ptr = e_lfnew + 0x70 + 0x8;
  266.                 for (int i = 0; i < numberOfRvaAndSizes; i++) {
  267.  
  268.                     fseek(f, ptr, SEEK_SET);
  269.                     fread(&directories[i].rva, 4, 1, f);
  270.                     fread(&directories[i].size, 4, 1, f);
  271.  
  272.                     ptr += 0x8;
  273.                 }
  274.  
  275.  
  276.                 sections = new IMAGE_SECTION_HEADER[numberOfSections];
  277.  
  278.                 cout << endl << "SECTIONS (name / size / rva / raw):" << endl;
  279.                 for (int i = 0; i < numberOfSections; i++) {
  280.  
  281.                     sections[i] = parseSection(f, ptr);
  282.                     ptr += sizeof(IMAGE_SECTION_HEADER); //0x28
  283.                 }
  284.  
  285.                 cout << endl <<"DATA_DIRECTORIES (size / rva -> raw):" << endl;
  286.                 for (int i = 0; i < numberOfRvaAndSizes; i++) {
  287.  
  288.                     DWORD resolvedRva = rva2raw(directories[i].rva);
  289.  
  290.                     cout << hex << directories[i].size << "\t\t"
  291.                         << hex << directories[i].rva << " -> "
  292.                         << hex << resolvedRva << endl;
  293.                 }
  294.  
  295.  
  296.  
  297.                 if (0 != directories[IMAGE_DIRECTORY_ENTRY_EXPORT].rva &&
  298.                     0 != directories[IMAGE_DIRECTORY_ENTRY_EXPORT].size) {
  299.  
  300.                     cout << endl << "EXPORT_TABLE (rva / raw):" << endl;
  301.  
  302.                     DWORD rva = directories[IMAGE_DIRECTORY_ENTRY_EXPORT].rva;
  303.                     DWORD raw = rva2raw(rva);
  304.  
  305.                     cout << hex << rva << "\t\t" << hex << raw << endl;
  306.  
  307.                     parseExportTable(f, raw);
  308.  
  309.                     return true;
  310.  
  311.                 } else {
  312.                     cout << "empty export table";
  313.                 }
  314.  
  315.             } else {
  316.                 cout << "data directories empty. file corrupted ?";
  317.             }
  318.  
  319.         } else {
  320.             cout << "file is not of PE-format";
  321.         }
  322.  
  323.         fclose(f);
  324.     } else {
  325.         cout << "no such file";
  326.     }
  327.  
  328.     return false;
  329. }
  330.  
  331. int main() {
  332.  
  333.     FILE *f = fopen(
  334.             "/home/anthony/Dropbox/Steam.dll",
  335.             //"/home/anthony/Рабочий стол/twain_32.dll",
  336.             "rb");
  337.  
  338.     cout << "Kacnep napcep" << endl;
  339.  
  340.     if (parsePE(f)) {
  341.  
  342.         outputAllFunctions();
  343.  
  344.         searchByName("SteamUnsubscribe");
  345.     }
  346.  
  347.     //getchar();
  348.     return 0;
  349. }
Advertisement
Add Comment
Please, Sign In to add comment