Guest User

PeBmLoader.cpp

a guest
Feb 11th, 2017
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.78 KB | None | 0 0
  1. #include "PeBmLoader.h"
  2.  
  3. #include <stdio.h>
  4. #include <cstring>
  5. #include <vector>
  6.  
  7. #include <allegro5/allegro.h>
  8. #include <allegro5/allegro_memfile.h>
  9.  
  10. #include "WindowsDef.h"
  11.  
  12.  
  13. template <typename PE_STRUCT>
  14. static void Get_Pe_Struct(PE_STRUCT *& pe_struct,FILE * file,DWORD address)
  15. {
  16. fseek(file,address,SEEK_SET);
  17. fread(pe_struct,sizeof(char),sizeof(PE_STRUCT),file);
  18.  
  19. }
  20.  
  21.  
  22. static void Get_Res_Section_Header(IMAGE_SECTION_HEADER *& section_header,
  23. int NumberOfSections,
  24. DWORD offset_pe_header,
  25. FILE * file)
  26.  
  27. {
  28.  
  29. for(int i = 0 ; i < NumberOfSections ; i++ )
  30. {
  31. DWORD offset = offset_pe_header +
  32. sizeof(IMAGE_NT_HEADERS) +
  33. (sizeof(IMAGE_SECTION_HEADER) * i ) ;
  34.  
  35. Get_Pe_Struct(section_header,file,offset);
  36.  
  37. if(strcmp((char*)(section_header->Name),".rsrc") == 0)
  38. return ;
  39.  
  40. }
  41. }
  42.  
  43.  
  44. bool PeBmLoader::Get_Bit_Map_Dat(BitMapDat *& bitmapdat,
  45. int id,
  46. int gfxfileindex,
  47. FILE *file)
  48. {
  49.  
  50. IMAGE_RESOURCE_DIRECTORY_ENTRY * ResourceEntry = new IMAGE_RESOURCE_DIRECTORY_ENTRY;
  51. IMAGE_RESOURCE_DIRECTORY * ResourceDirectory = new IMAGE_RESOURCE_DIRECTORY;
  52.  
  53. DWORD ResourceDirectoryAddress = this->gfxs[gfxfileindex].ResourceDirectoryAddress;
  54. DWORD SecAddress = this->gfxs[gfxfileindex].SecAddress;
  55. DWORD SecRVA = this->gfxs[gfxfileindex].SecRVA;
  56.  
  57. bool found = false;
  58.  
  59. Get_Pe_Struct(ResourceDirectory,file,ResourceDirectoryAddress);
  60.  
  61. for(int i = 0; !found && i < ResourceDirectory->NumberOfNamedEntries +
  62. ResourceDirectory->NumberOfIdEntries; i++)
  63. {
  64. DWORD DirEAddress = ResourceDirectoryAddress+
  65. sizeof(IMAGE_RESOURCE_DIRECTORY)+
  66. sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)*i;
  67.  
  68. Get_Pe_Struct(ResourceEntry,file,DirEAddress);
  69.  
  70. if(ResourceEntry->Id == 2 ) // 2 for bitmap resources "Bitmap"
  71.  
  72. {
  73.  
  74. //in the BITMAP RES
  75.  
  76. ResourceDirectoryAddress = ResourceEntry->OffsetToDirectory + SecAddress;
  77. Get_Pe_Struct(ResourceDirectory,file,ResourceDirectoryAddress);
  78.  
  79. for (int p = 0; !found &&p < ResourceDirectory->NumberOfNamedEntries +
  80. ResourceDirectory->NumberOfIdEntries; p++)
  81. {
  82. DirEAddress = ResourceDirectoryAddress+
  83. sizeof(IMAGE_RESOURCE_DIRECTORY) +
  84. sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)*p;
  85.  
  86. Get_Pe_Struct(ResourceEntry,file,DirEAddress);
  87.  
  88. if(ResourceEntry->Id == id )
  89.  
  90. {
  91.  
  92.  
  93. //in the required directory,looping till a dead end!
  94. found = true;
  95. while(ResourceEntry->DataIsDirectory)
  96. {
  97.  
  98. ResourceDirectoryAddress = ResourceEntry->OffsetToDirectory + SecAddress;
  99. Get_Pe_Struct(ResourceDirectory,file,ResourceDirectoryAddress);
  100.  
  101. DirEAddress = ResourceDirectoryAddress+sizeof(IMAGE_RESOURCE_DIRECTORY);
  102. Get_Pe_Struct(ResourceEntry,file,DirEAddress);
  103.  
  104. }
  105.  
  106. IMAGE_RESOURCE_DATA_ENTRY * data_entry = new IMAGE_RESOURCE_DATA_ENTRY;
  107. Get_Pe_Struct(data_entry,file,ResourceEntry->OffsetToData+SecAddress);
  108.  
  109. bitmapdat->entry_address = SecAddress + data_entry->OffsetToData - SecRVA;
  110. bitmapdat->dump_size = data_entry->Size;
  111. bitmapdat->total_size = bitmapdat->dump_size + sizeof(BITMAPFILEHEADER);
  112.  
  113. delete data_entry;
  114.  
  115. /*Bitmap file header loading */
  116.  
  117. bitmapdat->bitmap_file_header.bfType = 0x4D42; // BM signature
  118. bitmapdat->bitmap_file_header.bfSize = bitmapdat->total_size;
  119. bitmapdat->bitmap_file_header.bfReserved1 = 0x00;
  120. bitmapdat->bitmap_file_header.bfReserved2 = 0x00;
  121. bitmapdat->bitmap_file_header.bfOffBits = sizeof(BITMAPFILEHEADER)+
  122. sizeof(BITMAPINFOHEADER);
  123.  
  124.  
  125.  
  126. }
  127.  
  128.  
  129. }
  130.  
  131.  
  132. }
  133.  
  134.  
  135. }
  136.  
  137.  
  138. delete ResourceEntry;
  139. delete ResourceDirectory;
  140.  
  141. return found;
  142.  
  143.  
  144.  
  145. }
  146.  
  147. void PeBmLoader::Get_Bit_Map_File(char *& b_file,BitMapDat * bitmapdat,FILE *file)
  148. {
  149.  
  150. memset(b_file,0,bitmapdat->total_size);
  151. memcpy(b_file,&bitmapdat->bitmap_file_header,sizeof(BITMAPFILEHEADER));
  152.  
  153. fseek(file,bitmapdat->entry_address,SEEK_SET);
  154. fread(b_file+sizeof(BITMAPFILEHEADER),sizeof(char),bitmapdat->dump_size,file);
  155.  
  156. }
  157.  
  158.  
  159.  
  160.  
  161. ALLEGRO_BITMAP * PeBmLoader::Get_Bit_Map(int id,const char * dir)
  162. {
  163.  
  164. for(size_t i = 0 ; i < this->gfxs.size() ; i++)
  165. {
  166.  
  167. if(strstr(this->gfxs[i].dir,dir))
  168. return Get_Bit_Map(id,i);
  169.  
  170. }
  171.  
  172. return 0;
  173.  
  174. }
  175.  
  176. ALLEGRO_BITMAP * PeBmLoader::Get_Bit_Map(int id,int index)
  177. {
  178.  
  179. ALLEGRO_FILE * mapped_file;
  180. ALLEGRO_BITMAP * bitmap;
  181. BitMapDat * bitmapdat;
  182. char *b_file;
  183. const char *dir = this->gfxs[index].dir;
  184. FILE *file;
  185.  
  186.  
  187. file = fopen ( dir,"rb" );
  188. if (file==NULL)
  189. {
  190. //[Error to be handled]
  191. //Fail not found!
  192. //what else could it be when you fail to open a file in read only mode?!
  193.  
  194. return NULL;
  195. }
  196.  
  197. bitmapdat = new BitMapDat;
  198. bool entry_found = Get_Bit_Map_Dat(bitmapdat,id,index,file);
  199.  
  200. if(!entry_found)
  201. {
  202. //[Error to be handled]
  203. //Entry is not found!
  204. delete bitmapdat;
  205. return NULL;
  206. }
  207.  
  208. b_file = new char[bitmapdat->total_size];
  209. Get_Bit_Map_File(b_file,bitmapdat,file);
  210.  
  211. mapped_file = al_open_memfile((void*)b_file,bitmapdat->total_size,"r");
  212. bitmap = al_load_bitmap_f(mapped_file, ".bmp");
  213.  
  214.  
  215. al_fclose(mapped_file);
  216. fclose(file);
  217. delete [] b_file;
  218. delete bitmapdat;
  219.  
  220. return bitmap;
  221.  
  222.  
  223.  
  224. }
  225.  
  226. bool PeBmLoader::LoadGfxFile(const char* dir)
  227. {
  228.  
  229. FILE *file = fopen ( dir, "rb" );
  230. if (file==NULL)
  231. {
  232. //[Error to be handled]
  233. //Fail not found!
  234. //what else could it be when you fail to open a file in read only mode?!
  235.  
  236. return false;
  237. }
  238.  
  239.  
  240. IMAGE_DOS_HEADER * image_dos_header = new IMAGE_DOS_HEADER;
  241. IMAGE_NT_HEADERS * pe_header = new IMAGE_NT_HEADERS;
  242. IMAGE_SECTION_HEADER * section_header = new IMAGE_SECTION_HEADER;
  243. IMAGE_DATA_DIRECTORY * DataDirectory = new IMAGE_DATA_DIRECTORY ;
  244.  
  245. DWORD ResourceDirectoryRVA;
  246. DWORD SecAddress;
  247. DWORD SecRVA;
  248. DWORD ResourceDirectoryAddress;
  249.  
  250.  
  251. Get_Pe_Struct(image_dos_header,file,0);
  252. Get_Pe_Struct(pe_header,file,image_dos_header->e_lfanew);
  253. Get_Res_Section_Header(section_header,pe_header->FileHeader.NumberOfSections,
  254. image_dos_header->e_lfanew,
  255. file);
  256.  
  257. *DataDirectory = pe_header->OptionalHeader.DataDirectory [2];
  258. ResourceDirectoryRVA = DataDirectory->VirtualAddress;
  259. SecAddress = section_header->PointerToRawData;
  260. SecRVA = section_header->VirtualAddress;
  261. ResourceDirectoryAddress = SecAddress + ResourceDirectoryRVA - SecRVA;
  262.  
  263. GfxFile gfxfile;
  264. gfxfile.dir = dir;
  265. gfxfile.ResourceDirectoryAddress = ResourceDirectoryAddress;
  266. gfxfile.SecAddress = SecAddress;
  267. gfxfile.SecRVA = SecRVA;
  268.  
  269. this->gfxs.push_back(gfxfile);
  270.  
  271. delete image_dos_header;
  272. delete pe_header;
  273. delete section_header;
  274. delete DataDirectory;
  275.  
  276. fclose(file);
  277.  
  278. return true;
  279.  
  280. }
Add Comment
Please, Sign In to add comment