Browse Source

Removed PE-bliss, win32 binares so far remain without icon, had many issues with it:
-corrupted 32 binaries without reason
-does not support upx binaries
-forces dependency o libstdc++

Juan Linietsky 9 years ago
parent
commit
80e88c6a50
88 changed files with 2 additions and 18502 deletions
  1. 0 1
      drivers/register_driver_types.cpp
  2. 2 341
      platform/windows/export/export.cpp
  3. 0 33
      platform/windows/export/export.h
  4. 0 1
      tools/SCsub
  5. 0 84
      tools/pe_bliss/README
  6. 0 5
      tools/pe_bliss/SCsub
  7. 0 111
      tools/pe_bliss/entropy.cpp
  8. 0 51
      tools/pe_bliss/entropy.h
  9. 0 440
      tools/pe_bliss/file_version_info.cpp
  10. 0 199
      tools/pe_bliss/file_version_info.h
  11. 0 81
      tools/pe_bliss/message_table.cpp
  12. 0 56
      tools/pe_bliss/message_table.h
  13. 0 1680
      tools/pe_bliss/pe_base.cpp
  14. 0 544
      tools/pe_bliss/pe_base.h
  15. 0 39
      tools/pe_bliss/pe_bliss.h
  16. 0 118
      tools/pe_bliss/pe_bliss_godot.cpp
  17. 0 7
      tools/pe_bliss/pe_bliss_godot.h
  18. 0 36
      tools/pe_bliss/pe_bliss_resources.h
  19. 0 311
      tools/pe_bliss/pe_bound_import.cpp
  20. 0 108
      tools/pe_bliss/pe_bound_import.h
  21. 0 103
      tools/pe_bliss/pe_checksum.cpp
  22. 0 30
      tools/pe_bliss/pe_checksum.h
  23. 0 865
      tools/pe_bliss/pe_debug.cpp
  24. 0 324
      tools/pe_bliss/pe_debug.h
  25. 0 59
      tools/pe_bliss/pe_directory.cpp
  26. 0 50
      tools/pe_bliss/pe_directory.h
  27. 0 186
      tools/pe_bliss/pe_dotnet.cpp
  28. 0 97
      tools/pe_bliss/pe_dotnet.h
  29. 0 40
      tools/pe_bliss/pe_exception.cpp
  30. 0 130
      tools/pe_bliss/pe_exception.h
  31. 0 177
      tools/pe_bliss/pe_exception_directory.cpp
  32. 0 88
      tools/pe_bliss/pe_exception_directory.h
  33. 0 700
      tools/pe_bliss/pe_exports.cpp
  34. 0 184
      tools/pe_bliss/pe_exports.h
  35. 0 43
      tools/pe_bliss/pe_factory.cpp
  36. 0 39
      tools/pe_bliss/pe_factory.h
  37. 0 777
      tools/pe_bliss/pe_imports.cpp
  38. 0 208
      tools/pe_bliss/pe_imports.h
  39. 0 557
      tools/pe_bliss/pe_load_config.cpp
  40. 0 184
      tools/pe_bliss/pe_load_config.h
  41. 0 41
      tools/pe_bliss/pe_properties.cpp
  42. 0 236
      tools/pe_bliss/pe_properties.h
  43. 0 645
      tools/pe_bliss/pe_properties_generic.cpp
  44. 0 277
      tools/pe_bliss/pe_properties_generic.h
  45. 0 214
      tools/pe_bliss/pe_rebuilder.cpp
  46. 0 40
      tools/pe_bliss/pe_rebuilder.h
  47. 0 320
      tools/pe_bliss/pe_relocations.cpp
  48. 0 122
      tools/pe_bliss/pe_relocations.h
  49. 0 286
      tools/pe_bliss/pe_resource_manager.cpp
  50. 0 113
      tools/pe_bliss/pe_resource_manager.h
  51. 0 382
      tools/pe_bliss/pe_resource_viewer.cpp
  52. 0 153
      tools/pe_bliss/pe_resource_viewer.h
  53. 0 726
      tools/pe_bliss/pe_resources.cpp
  54. 0 245
      tools/pe_bliss/pe_resources.h
  55. 0 152
      tools/pe_bliss/pe_rich_data.cpp
  56. 0 58
      tools/pe_bliss/pe_rich_data.h
  57. 0 303
      tools/pe_bliss/pe_section.cpp
  58. 0 158
      tools/pe_bliss/pe_section.h
  59. 0 1028
      tools/pe_bliss/pe_structures.h
  60. 0 396
      tools/pe_bliss/pe_tls.cpp
  61. 0 122
      tools/pe_bliss/pe_tls.h
  62. 0 86
      tools/pe_bliss/resource_bitmap_reader.cpp
  63. 0 50
      tools/pe_bliss/resource_bitmap_reader.h
  64. 0 75
      tools/pe_bliss/resource_bitmap_writer.cpp
  65. 0 47
      tools/pe_bliss/resource_bitmap_writer.h
  66. 0 521
      tools/pe_bliss/resource_cursor_icon_reader.cpp
  67. 0 84
      tools/pe_bliss/resource_cursor_icon_reader.h
  68. 0 447
      tools/pe_bliss/resource_cursor_icon_writer.cpp
  69. 0 94
      tools/pe_bliss/resource_cursor_icon_writer.h
  70. 0 48
      tools/pe_bliss/resource_data_info.cpp
  71. 0 48
      tools/pe_bliss/resource_data_info.h
  72. 0 34
      tools/pe_bliss/resource_internal.h
  73. 0 131
      tools/pe_bliss/resource_message_list_reader.cpp
  74. 0 49
      tools/pe_bliss/resource_message_list_reader.h
  75. 0 109
      tools/pe_bliss/resource_string_table_reader.cpp
  76. 0 57
      tools/pe_bliss/resource_string_table_reader.h
  77. 0 311
      tools/pe_bliss/resource_version_info_reader.cpp
  78. 0 67
      tools/pe_bliss/resource_version_info_reader.h
  79. 0 283
      tools/pe_bliss/resource_version_info_writer.cpp
  80. 0 52
      tools/pe_bliss/resource_version_info_writer.h
  81. 0 45
      tools/pe_bliss/stdint_defs.h
  82. 0 85
      tools/pe_bliss/utils.cpp
  83. 0 105
      tools/pe_bliss/utils.h
  84. 0 184
      tools/pe_bliss/version_info_editor.cpp
  85. 0 79
      tools/pe_bliss/version_info_editor.h
  86. 0 38
      tools/pe_bliss/version_info_types.h
  87. 0 180
      tools/pe_bliss/version_info_viewer.cpp
  88. 0 89
      tools/pe_bliss/version_info_viewer.h

+ 0 - 1
drivers/register_driver_types.cpp

@@ -31,7 +31,6 @@
 #endif
 
 #ifdef TOOLS_ENABLED
-#include "pe_bliss/pe_bliss_godot.h"
 #include "platform/windows/export/export.h"
 #endif
 

+ 2 - 341
platform/windows/export/export.cpp

@@ -1,345 +1,6 @@
-/*************************************************************************/
-/*  export.cpp                                                           */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                    http://www.godotengine.org                         */
-/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
 #include "export.h"
 #include "platform/windows/logo.h"
-#include "os/os.h"
-#include "globals.h"
-#include "tools/editor/editor_node.h"
-#include "tools/pe_bliss/pe_bliss_godot.h"
-
-/**
-	@author Masoud BaniHashemian <[email protected]>
-*/
-
-
-void EditorExportPlatformWindows::store_16(DVector<uint8_t>& vector, uint16_t value) {
-	const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
-	int size = vector.size();
-	vector.resize( size + 2 );
-	DVector<uint8_t>::Write w = vector.write();
-	w[size]=bytes[0];
-	w[size+1]=bytes[1];
-}
-void EditorExportPlatformWindows::store_32(DVector<uint8_t>& vector, uint32_t value) {
-	const uint8_t* bytes = reinterpret_cast<const uint8_t*>(&value);
-	int size = vector.size();
-	vector.resize( size + 4 );
-	DVector<uint8_t>::Write w = vector.write();
-	w[size]=bytes[0];
-	w[size+1]=bytes[1];
-	w[size+2]=bytes[2];
-	w[size+3]=bytes[3];
-}
-
-bool EditorExportPlatformWindows::_set(const StringName& p_name, const Variant& p_value) {
-
-	String n = p_name;
-
-	if (n=="icon/icon_ico") {
-
-		icon_ico=p_value;
-	} else if (n=="icon/icon_png") {
-
-		icon_png=p_value;
-	} else if (n=="icon/icon_png16x16") {
-
-		icon16=p_value;
-	} else if (n=="icon/icon_png32x32") {
-
-		icon32=p_value;
-	} else if (n=="icon/icon_png48x48") {
-
-		icon48=p_value;
-	} else if (n=="icon/icon_png64x64") {
-
-		icon64=p_value;
-	} else if (n=="icon/icon_png128x128") {
-
-		icon128=p_value;
-	} else if (n=="icon/icon_png256x256") {
-
-		icon256=p_value;
-	} else if (n=="version_info/version_major") {
-
-		version_major=p_value;
-	} else if (n=="version_info/version_minor") {
-
-		version_minor=p_value;
-	} else if (n=="version_info/version_text") {
-
-		version_text=p_value;
-	} else if (n=="version_info/company_name") {
-
-		company_name=p_value;
-	} else if (n=="version_info/file_description") {
-
-		file_description=p_value;
-	} else if (n=="version_info/product_name") {
-
-		product_name=p_value;
-	} else if (n=="version_info/legal_copyright") {
-
-		legal_copyright=p_value;
-	} else if (n=="version_info/add_godot_version") {
-
-		set_godot_version=p_value;
-	} else
-		return false;
-
-	return true;
-
-}
-
-bool EditorExportPlatformWindows::_get(const StringName& p_name,Variant &r_ret) const {
-
-	String n = p_name;
-
-	if (n=="icon/icon_ico") {
-
-		r_ret=icon_ico;
-	} else if (n=="icon/icon_png") {
-
-		r_ret=icon_png;
-	} else if (n=="icon/icon_png16x16") {
-
-		r_ret=icon16;
-	} else if (n=="icon/icon_png32x32") {
-
-		r_ret=icon32;
-	} else if (n=="icon/icon_png48x48") {
-
-		r_ret=icon48;
-	} else if (n=="icon/icon_png64x64") {
-
-		r_ret=icon64;
-	} else if (n=="icon/icon_png128x128") {
-
-		r_ret=icon128;
-	} else if (n=="icon/icon_png256x256") {
-
-		r_ret=icon256;
-	} else if (n=="version_info/version_major") {
-
-		r_ret=version_major;
-	} else if (n=="version_info/version_minor") {
-
-		r_ret=version_minor;
-	} else if (n=="version_info/version_text") {
-
-		r_ret=version_text;
-	} else if (n=="version_info/company_name") {
-
-		r_ret=company_name;
-	} else if (n=="version_info/file_description") {
-
-		r_ret=file_description;
-	} else if (n=="version_info/product_name") {
-
-		r_ret=product_name;
-	} else if (n=="version_info/legal_copyright") {
-
-		r_ret=legal_copyright;
-	} else if (n=="version_info/add_godot_version") {
-
-		r_ret=set_godot_version;
-	} else
-		return false;
-
-	return true;
-
-}
-
-void EditorExportPlatformWindows::_get_property_list( List<PropertyInfo> *p_list) const {
-
-	p_list->push_back( PropertyInfo( Variant::STRING, "icon/icon_ico",PROPERTY_HINT_FILE,"ico") );
-	p_list->push_back( PropertyInfo( Variant::STRING, "icon/icon_png",PROPERTY_HINT_FILE,"png") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png16x16") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png32x32") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png48x48") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png64x64") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png128x128") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "icon/icon_png256x256") );
-	p_list->push_back( PropertyInfo( Variant::INT, "version_info/version_major", PROPERTY_HINT_RANGE,"0,65535,1"));
-	p_list->push_back( PropertyInfo( Variant::INT, "version_info/version_minor", PROPERTY_HINT_RANGE,"0,65535,0"));
-	p_list->push_back( PropertyInfo( Variant::STRING, "version_info/version_text") );
-	p_list->push_back( PropertyInfo( Variant::STRING, "version_info/company_name") );
-	p_list->push_back( PropertyInfo( Variant::STRING, "version_info/file_description") );
-	p_list->push_back( PropertyInfo( Variant::STRING, "version_info/product_name") );
-	p_list->push_back( PropertyInfo( Variant::STRING, "version_info/legal_copyright") );
-	p_list->push_back( PropertyInfo( Variant::BOOL, "version_info/add_godot_version") );
-	
-}
-
-Error EditorExportPlatformWindows::export_project(const String& p_path, bool p_debug, int p_flags) {
-
-	Error err = EditorExportPlatformPC::export_project(p_path, p_debug, p_flags);
-	if(err != OK)
-	{
-		return err;
-	}
-	EditorProgress ep("editexe","Edit EXE File",102);
-	ep.step("Create ico file..",0);
-	
-		DVector<uint8_t> icon_content;
-		if (this->icon_ico!="" && this->icon_ico.ends_with(".ico")) {
-			FileAccess *f = FileAccess::open(this->icon_ico,FileAccess::READ);
-			if (f) {
-				icon_content.resize(f->get_len());
-				DVector<uint8_t>::Write write = icon_content.write();
-				f->get_buffer(write.ptr(),icon_content.size());
-				f->close();
-				memdelete(f);
-			}
-		} else if (this->icon_png!="" && this->icon_png.ends_with(".png") && (icon16 || icon32 || icon48 || icon64 || icon128 || icon256)) {
-			#ifdef PNG_ENABLED
-			Vector<Image> pngs;
-			Image png;
-			Error err_png = png.load(this->icon_png);
-			if (err_png==OK && !png.empty()) {
-				if(icon256) {
-					Image icon_256(png);
-					if(!(png.get_height()==256 && png.get_width()==256)) icon_256.resize(256,256);
-					pngs.push_back(icon_256);
-				}
-				if(icon128) {
-					Image icon_128(png);
-					if(!(png.get_height()==128 && png.get_width()==128)) icon_128.resize(128,128);
-					pngs.push_back(icon_128);
-				}
-				if(icon64) {
-					Image icon_64(png);
-					if(!(png.get_height()==64 && png.get_width()==64)) icon_64.resize(64,64);
-					pngs.push_back(icon_64);
-				}
-				if(icon48) {
-					Image icon_48(png);
-					if(!(png.get_height()==48 && png.get_width()==48)) icon_48.resize(48,48);
-					pngs.push_back(icon_48);
-				}
-				if(icon32) {
-					Image icon_32(png);
-					if(!(png.get_height()==32 && png.get_width()==32)) icon_32.resize(32,32);
-					pngs.push_back(icon_32);
-				}
-				if(icon16) {
-					Image icon_16(png);
-					if(!(png.get_height()==16 && png.get_width()==16)) icon_16.resize(16,16);
-					pngs.push_back(icon_16);
-				}
-				// create icon according to https://www.daubnet.com/en/file-format-ico
-				store_16(icon_content,0); //Reserved
-				store_16(icon_content,1); //Type
-				store_16(icon_content,pngs.size()); //Count
-				int offset = 6+pngs.size()*16;
-				//List of bitmaps 
-				for(int i=0;i<pngs.size();i++) {
-					int w = pngs[i].get_width();
-					int h = pngs[i].get_height();
-					icon_content.push_back(w<256?w:0); //width
-					icon_content.push_back(h<256?h:0); //height
-					icon_content.push_back(0); //ColorCount = 0
-					icon_content.push_back(0); //Reserved
-					store_16(icon_content,1); //Planes
-					store_16(icon_content,32); //BitCount (bit per pixel)
-					int size = 40 + (w * h * 4) + (w * h / 8);
-					store_32(icon_content,size); //Size of (InfoHeader + ANDbitmap + XORbitmap) 
-					store_32(icon_content,offset); //FileOffset
-					offset += size;
-				}
-				//Write bmp files.
-				for(int i=0;i<pngs.size();i++) {
-					int w = pngs[i].get_width();
-					int h = pngs[i].get_height();
-					store_32(icon_content,40); //Size of InfoHeader structure = 40
-					store_32(icon_content,w); //Width
-					store_32(icon_content,h*2); //Height
-					store_16(icon_content,1); //Planes
-					store_16(icon_content,32); //BitCount
-					store_32(icon_content,0); //Compression
-					store_32(icon_content,w*h*4); //ImageSize = Size of Image in Bytes
-					store_32(icon_content,0); //unused = 0 
-					store_32(icon_content,0); //unused = 0 
-					store_32(icon_content,0); //unused = 0 
-					store_32(icon_content,0); //unused = 0 
-					//XORBitmap
-					for(int y=h-1;y>=0;y--) {
-						for(int x=0;x<w;x++) {
-							store_32(icon_content,pngs[i].get_pixel(x,y).to_32());
-						}
-					}
-					//ANDBitmap
-					for(int m=0;m<(w * h / 8);m+=4) store_32(icon_content,0x00000000); // Add empty ANDBitmap , TODO create full ANDBitmap Structure if need.
-				}
-			}
-			#endif
-		}
-	
-	ep.step("Add rsrc..",50);
-	
-		String basename = Globals::get_singleton()->get("application/name");
-		product_name=product_name.replace("$genname",basename);
-		String godot_version;
-		if(set_godot_version) godot_version = String( VERSION_MKSTRING );
-		String ret = pe_bliss_add_resrc(p_path.utf8(), version_major, version_minor,
-																						company_name, file_description, legal_copyright, version_text,
-																						product_name, godot_version, icon_content);
-		if (ret.empty()) {
-			return OK;
-		} else {
-			EditorNode::add_io_error(ret);
-			return ERR_FILE_CANT_WRITE;
-		}
-}
-
-EditorExportPlatformWindows::EditorExportPlatformWindows() {
-
-	icon16=true;
-	icon32=true;
-	icon48=true;
-	icon64=true;
-	icon128=true;
-	icon256=true;
-	product_name="$genname";
-	company_name="Godot Engine";
-	file_description="Created With Godot Engine";
-	version_text="1.0";
-	OS::Date date = OS::get_singleton()->get_date();
-	legal_copyright="Copyright (c) 2007-";
-	legal_copyright+=String::num(date.year);
-	legal_copyright+=" Juan Linietsky, Ariel Manzur";
-	version_major=1;
-	version_minor=0;
-	set_godot_version=true;
-}
-
-
+#include "tools/editor/editor_import_export.h"
 
 void register_windows_exporter() {
 
@@ -348,7 +9,7 @@ void register_windows_exporter() {
 	logo->create_from_image(img);
 
 	{
-		Ref<EditorExportPlatformWindows> exporter = Ref<EditorExportPlatformWindows>( memnew(EditorExportPlatformWindows) );
+		Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) );
 		exporter->set_binary_extension("exe");
 		exporter->set_release_binary32("windows_32_release.exe");
 		exporter->set_debug_binary32("windows_32_debug.exe");

+ 0 - 33
platform/windows/export/export.h

@@ -1,37 +1,4 @@
-#include "tools/editor/editor_import_export.h"
 
-class EditorExportPlatformWindows : public EditorExportPlatformPC {
-	OBJ_TYPE( EditorExportPlatformWindows,EditorExportPlatformPC );
-	
-private:
-	String icon_ico;
-	String icon_png;
-	bool icon16;
-	bool icon32;
-	bool icon48;
-	bool icon64;
-	bool icon128;
-	bool icon256;
-	String company_name;
-	String file_description;
-	String product_name;
-	String legal_copyright;
-	String version_text;
-	int version_major;
-	int version_minor;
-	bool set_godot_version;
-	void store_16(DVector<uint8_t>& vector, uint16_t value); ///< store 16 bits uint 
-	void store_32(DVector<uint8_t>& vector, uint32_t value); ///< store 32 bits uint 
-	
-protected:
-	bool _set(const StringName& p_name, const Variant& p_value);
-	bool _get(const StringName& p_name,Variant &r_ret) const;
-	void _get_property_list( List<PropertyInfo> *p_list) const;
-	
-public:
-	Error export_project(const String& p_path, bool p_debug,int p_flags=0);
-	EditorExportPlatformWindows();
-};
 
 void register_windows_exporter();
 

+ 0 - 1
tools/SCsub

@@ -11,7 +11,6 @@ if (env["tools"]!="no"):
 	SConscript('collada/SCsub');
 	SConscript('docdump/SCsub');
 	SConscript('freetype/SCsub');
-	SConscript('pe_bliss/SCsub');
 	SConscript('doc/SCsub')
 	SConscript('pck/SCsub')
 

+ 0 - 84
tools/pe_bliss/README

@@ -1,84 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-
-Открытая бесплатная библиотека для работы с PE-файлами PE Bliss.
-Бесплатна к использованию, модификации и распространению.
-Автор: DX
-(c) DX 2011-2012, kaimi.ru
-
-Совместимость: Windows, Linux
-
-Возможности:
-[+] Создание PE или PE+ файла с нуля
-[+] Чтение 32-разрядных и 64-разрядных PE-файлов (PE, PE+) и единообразная работа с ними
-[+] Пересборка 32-разрядных и 64-разрядных PE-файлов
-[+] Работа с директориями и заголовками
-[+] Конвертирование адресов
-[+] Чтение и редактирование секций PE-файла
-[+] Чтение и редактирование таблицы импортов
-[+] Чтение и редактирование таблицы экспортов
-[+] Чтение и редактирование таблиц релокаций
-[+] Чтение и редактирование ресурсов
-[+] Чтение и редактирование TLS
-[+] Чтение и редактирование конфигурации образа (image config)
-[+] Чтение базовой информации .NET
-[+] Чтение и редактирование информации о привязанном импорте
-[+] Чтение директории исключений (только PE+)
-[+] Чтение отладочной директории с расширенной информацией
-[+] Вычисление энтропии
-[+] Изменение файлового выравнивания
-[+] Изменение базового адреса загрузки
-[+] Работа с DOS Stub'ом и Rich overlay
-[+] Высокоуровневое чтение ресурсов: картинки, иконки, курсоры, информация о версии, строковые таблицы, таблицы сообщений
-[+] Высокоуровневое редактирование ресурсов: картинки, иконки, курсоры, информация о версии
-
-[English]
-Open a free library for working with PE-file PE Bliss.
-Free to use, modify, and distribute.
-Author: DX
-(c) DX 2011-2012, kaimi.ru
-Compatibility: Windows, Linux
-
-### Capabilities:
-[+] Creation of PE or PE + file from scratch
-[+] Reading the 32-bit and 64-bit PE-file (PE, PE +) and uniform working with them
-[+] Rebuild 32-bit and 64-bit PE-files
-[+] Working with the directors and titles
-[+] Converting addresses
-[+] Reading and editing sections of PE-file
-[+] Reading and editing the import table
-[+] Reading and editing tables exports
-[+] Reading and editing tables relocations
-[+] Reading and editing resources
-[+] Reading and editing TLS
-[+] Reading and editing the configuration of the image (image config)
-[+] Reading data base .NET
-[+] Reading and editing information about tethered import
-[+] Read the directory exceptions (only PE +)
-[+] Read debug directories with extended information
-[+] The calculation of entropy
-[+] Changing file alignment
-[+] Change the base load address
-[+] Support of DOS Stub'om and Rich overlay
-[+] High-level reading resources: images, icons, cursors, version information, string tables, message table
-[+] High-level editing resources: images, icons, cursors, version information

+ 0 - 5
tools/pe_bliss/SCsub

@@ -1,5 +0,0 @@
-Import('env')
-
-env.add_source_files(env.tool_sources,"*.cpp")
-
-Export('env')

+ 0 - 111
tools/pe_bliss/entropy.cpp

@@ -1,111 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <cmath>
-#include "entropy.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-//Calculates entropy for PE image section
-double entropy_calculator::calculate_entropy(const section& s)
-{
-	if(s.get_raw_data().empty()) //Don't count entropy for empty sections
-		throw pe_exception("Section is empty", pe_exception::section_is_empty);
-
-	return calculate_entropy(s.get_raw_data().data(), s.get_raw_data().length());
-}
-
-//Calculates entropy for istream (from current position of stream)
-double entropy_calculator::calculate_entropy(std::istream& file)
-{
-	uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
-	if(file.bad())
-		throw pe_exception("Stream is bad", pe_exception::stream_is_bad);
-
-	std::streamoff pos = file.tellg();
-
-	std::streamoff length = pe_utils::get_file_size(file);
-	length -= file.tellg();
-
-	if(!length) //Don't calculate entropy for empty buffers
-		throw pe_exception("Data length is zero", pe_exception::data_is_empty);
-
-	//Count bytes
-	for(std::streamoff i = 0; i != length; ++i)
-		++byte_count[static_cast<unsigned char>(file.get())];
-
-	file.seekg(pos);
-
-	return calculate_entropy(byte_count, length);
-}
-
-//Calculates entropy for data block
-double entropy_calculator::calculate_entropy(const char* data, size_t length)
-{
-	uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
-	if(!length) //Don't calculate entropy for empty buffers
-		throw pe_exception("Data length is zero", pe_exception::data_is_empty);
-
-	//Count bytes
-	for(size_t i = 0; i != length; ++i)
-		++byte_count[static_cast<unsigned char>(data[i])];
-
-	return calculate_entropy(byte_count, length);
-}
-
-//Calculates entropy for this PE file (only section data)
-double entropy_calculator::calculate_entropy(const pe_base& pe)
-{
-	uint32_t byte_count[256] = {0}; //Byte count for each of 255 bytes
-
-	size_t total_data_length = 0;
-
-	//Count bytes for each section
-	for(section_list::const_iterator it = pe.get_image_sections().begin(); it != pe.get_image_sections().end(); ++it)
-	{
-		const std::string& data = (*it).get_raw_data();
-		size_t length = data.length();
-		total_data_length += length;
-		for(size_t i = 0; i != length; ++i)
-			++byte_count[static_cast<unsigned char>(data[i])];
-	}
-
-	return calculate_entropy(byte_count, total_data_length);
-}
-
-//Calculates entropy from bytes count
-double entropy_calculator::calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length)
-{
-	double entropy = 0.; //Entropy result value
-	//Calculate entropy
-	for(uint32_t i = 0; i < 256; ++i)
-	{
-		double temp = static_cast<double>(byte_count[i]) / total_length;
-		if(temp > 0.)
-			entropy += std::abs(temp * (std::log(temp) * pe_utils::log_2));
-	}
-
-	return entropy;
-}
-}

+ 0 - 51
tools/pe_bliss/entropy.h

@@ -1,51 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-class entropy_calculator
-{
-public:
-	//Calculates entropy for PE image section
-	static double calculate_entropy(const section& s);
-
-	//Calculates entropy for istream (from current position of stream)
-	static double calculate_entropy(std::istream& file);
-
-	//Calculates entropy for data block
-	static double calculate_entropy(const char* data, size_t length);
-
-	//Calculates entropy for this PE file (only section data)
-	static double calculate_entropy(const pe_base& pe);
-
-private:
-	entropy_calculator();
-	entropy_calculator(const entropy_calculator&);
-	entropy_calculator& operator=(const entropy_calculator&);
-
-	//Calculates entropy from bytes count
-	static double calculate_entropy(const uint32_t byte_count[256], std::streamoff total_length);
-};
-}

+ 0 - 440
tools/pe_bliss/file_version_info.cpp

@@ -1,440 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "file_version_info.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Default constructor
-file_version_info::file_version_info()
-	:file_version_ms_(0), file_version_ls_(0),
-	product_version_ms_(0), product_version_ls_(0),
-	file_flags_(0),
-	file_os_(0),
-	file_type_(0), file_subtype_(0),
-	file_date_ms_(0), file_date_ls_(0)
-{}
-
-//Constructor from Windows fixed version info structure
-file_version_info::file_version_info(const vs_fixedfileinfo& info)
-	:file_version_ms_(info.dwFileVersionMS), file_version_ls_(info.dwFileVersionLS),
-	product_version_ms_(info.dwProductVersionMS), product_version_ls_(info.dwProductVersionLS),
-	file_flags_(info.dwFileFlags),
-	file_os_(info.dwFileOS),
-	file_type_(info.dwFileType), file_subtype_(info.dwFileSubtype),
-	file_date_ms_(info.dwFileDateMS), file_date_ls_(info.dwFileDateLS)
-{}
-
-//Returns true if file is debug-built
-bool file_version_info::is_debug() const
-{
-	return file_flags_ & vs_ff_debug ? true : false;
-}
-
-//Returns true if file is release-built
-bool file_version_info::is_prerelease() const
-{
-	return file_flags_ & vs_ff_prerelease ? true : false;
-}
-
-//Returns true if file is patched
-bool file_version_info::is_patched() const
-{
-	return file_flags_ & vs_ff_patched ? true : false;
-}
-
-//Returns true if private build
-bool file_version_info::is_private_build() const
-{
-	return file_flags_ & vs_ff_privatebuild ? true : false;
-}
-
-//Returns true if special build
-bool file_version_info::is_special_build() const
-{
-	return file_flags_ & vs_ff_specialbuild ? true : false;
-}
-
-//Returns true if info inferred
-bool file_version_info::is_info_inferred() const
-{
-	return file_flags_ & vs_ff_infoinferred ? true : false;
-}
-
-//Retuens file flags (raw DWORD)
-uint32_t file_version_info::get_file_flags() const
-{
-	return file_flags_;
-}
-
-//Returns file version most significant DWORD
-uint32_t file_version_info::get_file_version_ms() const
-{
-	return file_version_ms_;
-}
-
-//Returns file version least significant DWORD
-uint32_t file_version_info::get_file_version_ls() const
-{
-	return file_version_ls_;
-}
-
-//Returns product version most significant DWORD
-uint32_t file_version_info::get_product_version_ms() const
-{
-	return product_version_ms_;
-}
-
-//Returns product version least significant DWORD
-uint32_t file_version_info::get_product_version_ls() const
-{
-	return product_version_ls_;
-}
-
-//Returns file OS type (raw DWORD)
-uint32_t file_version_info::get_file_os_raw() const
-{
-	return file_os_;
-}
-
-//Returns file OS type
-file_version_info::file_os_type file_version_info::get_file_os() const
-{
-	//Determine file operation system type
-	switch(file_os_)
-	{
-	case vos_dos:
-		return file_os_dos;
-
-	case vos_os216:
-		return file_os_os216;
-
-	case vos_os232:
-		return file_os_os232;
-
-	case vos_nt:
-		return file_os_nt;
-
-	case vos_wince:
-		return file_os_wince;
-
-	case vos__windows16:
-		return file_os_win16;
-
-	case vos__pm16:
-		return file_os_pm16;
-
-	case vos__pm32:
-		return file_os_pm32;
-
-	case vos__windows32:
-		return file_os_win32;
-
-	case vos_dos_windows16:
-		return file_os_dos_win16;
-
-	case vos_dos_windows32:
-		return file_os_dos_win32;
-
-	case vos_os216_pm16:
-		return file_os_os216_pm16;
-
-	case vos_os232_pm32:
-		return file_os_os232_pm32;
-
-	case vos_nt_windows32:
-		return file_os_nt_win32;
-	}
-
-	return file_os_unknown;
-}
-
-//Returns file type (raw DWORD)
-uint32_t file_version_info::get_file_type_raw() const
-{
-	return file_type_;
-}
-
-//Returns file type
-file_version_info::file_type file_version_info::get_file_type() const
-{
-	//Determine file type
-	switch(file_type_)
-	{
-	case vft_app:
-		return file_type_application;
-
-	case vft_dll:
-		return file_type_dll;
-
-	case vft_drv:
-		return file_type_driver;
-
-	case vft_font:
-		return file_type_font;
-
-	case vft_vxd:
-		return file_type_vxd;
-
-	case vft_static_lib:
-		return file_type_static_lib;
-	}
-
-	return file_type_unknown;
-}
-
-//Returns file subtype (usually non-zero for drivers and fonts)
-uint32_t file_version_info::get_file_subtype() const
-{
-	return file_subtype_;
-}
-
-//Returns file date most significant DWORD
-uint32_t file_version_info::get_file_date_ms() const
-{
-	return file_date_ms_;
-}
-
-//Returns file date least significant DWORD
-uint32_t file_version_info::get_file_date_ls() const
-{
-	return file_date_ls_;
-}
-
-//Helper to set file flag
-void file_version_info::set_file_flag(uint32_t flag)
-{
-	file_flags_ |= flag;
-}
-
-//Helper to clear file flag
-void file_version_info::clear_file_flag(uint32_t flag)
-{
-	file_flags_ &= ~flag;
-}
-
-//Helper to set or clear file flag
-void file_version_info::set_file_flag(uint32_t flag, bool set_flag)
-{
-	set_flag ? set_file_flag(flag) : clear_file_flag(flag);
-}
-
-//Sets if file is debug-built
-void file_version_info::set_debug(bool debug)
-{
-	set_file_flag(vs_ff_debug, debug);
-}
-
-//Sets if file is prerelease
-void file_version_info::set_prerelease(bool prerelease)
-{
-	set_file_flag(vs_ff_prerelease, prerelease);
-}
-
-//Sets if file is patched
-void file_version_info::set_patched(bool patched)
-{
-	set_file_flag(vs_ff_patched, patched);
-}
-
-//Sets if private build
-void file_version_info::set_private_build(bool private_build)
-{
-	set_file_flag(vs_ff_privatebuild, private_build);
-}
-
-//Sets if special build
-void file_version_info::set_special_build(bool special_build)
-{
-	set_file_flag(vs_ff_specialbuild, special_build);
-}
-
-//Sets if info inferred
-void file_version_info::set_info_inferred(bool info_inferred)
-{
-	set_file_flag(vs_ff_infoinferred, info_inferred);
-}
-
-//Sets flags (raw DWORD)
-void file_version_info::set_file_flags(uint32_t file_flags)
-{
-	file_flags_ = file_flags;
-}
-
-//Sets file version most significant DWORD
-void file_version_info::set_file_version_ms(uint32_t file_version_ms)
-{
-	file_version_ms_ = file_version_ms;
-}
-
-//Sets file version least significant DWORD
-void file_version_info::set_file_version_ls(uint32_t file_version_ls)
-{
-	file_version_ls_ = file_version_ls;
-}
-
-//Sets product version most significant DWORD
-void file_version_info::set_product_version_ms(uint32_t product_version_ms)
-{
-	product_version_ms_ = product_version_ms;
-}
-
-//Sets product version least significant DWORD
-void file_version_info::set_product_version_ls(uint32_t product_version_ls)
-{
-	product_version_ls_ = product_version_ls;
-}
-
-//Sets file OS type (raw DWORD)
-void file_version_info::set_file_os_raw(uint32_t file_os)
-{
-	file_os_ = file_os;
-}
-
-//Sets file OS type
-void file_version_info::set_file_os(file_os_type file_os)
-{
-	//Determine file operation system type
-	switch(file_os)
-	{
-	case file_os_dos:
-		file_os_ = vos_dos;
-		return;
-
-	case file_os_os216:
-		file_os_ = vos_os216;
-		return;
-
-	case file_os_os232:
-		file_os_ = vos_os232;
-		return;
-
-	case file_os_nt:
-		file_os_ = vos_nt;
-		return;
-
-	case file_os_wince:
-		file_os_ = vos_wince;
-		return;
-
-	case file_os_win16:
-		file_os_ = vos__windows16;
-		return;
-		
-	case file_os_pm16:
-		file_os_ = vos__pm16;
-		return;
-
-	case file_os_pm32:
-		file_os_ = vos__pm32;
-		return;
-
-	case file_os_win32:
-		file_os_ = vos__windows32;
-		return;
-
-	case file_os_dos_win16:
-		file_os_ = vos_dos_windows16;
-		return;
-
-	case file_os_dos_win32:
-		file_os_ = vos_dos_windows32;
-		return;
-
-	case file_os_os216_pm16:
-		file_os_ = vos_os216_pm16;
-		return;
-
-	case file_os_os232_pm32:
-		file_os_ = vos_os232_pm32;
-		return;
-
-	case file_os_nt_win32:
-		file_os_ = vos_nt_windows32;
-		return;
-
-	default:
-		return;
-	}
-}
-
-//Sets file type (raw DWORD)
-void file_version_info::set_file_type_raw(uint32_t file_type)
-{
-	file_type_ = file_type;
-}
-
-//Sets file type
-void file_version_info::set_file_type(file_type file_type)
-{
-	//Determine file type
-	switch(file_type)
-	{
-	case file_type_application:
-		file_type_ = vft_app;
-		return;
-		
-	case file_type_dll:
-		file_type_ = vft_dll;
-		return;
-
-	case file_type_driver:
-		file_type_ = vft_drv;
-		return;
-
-	case file_type_font:
-		file_type_ = vft_font;
-		return;
-
-	case file_type_vxd:
-		file_type_ = vft_vxd;
-		return;
-
-	case file_type_static_lib:
-		file_type_ = vft_static_lib;
-		return;
-
-	default:
-		return;
-	}
-}
-
-//Sets file subtype (usually non-zero for drivers and fonts)
-void file_version_info::set_file_subtype(uint32_t file_subtype)
-{
-	file_subtype_ = file_subtype;
-}
-
-//Sets file date most significant DWORD
-void file_version_info::set_file_date_ms(uint32_t file_date_ms)
-{
-	file_date_ms_ = file_date_ms;
-}
-
-//Sets file date least significant DWORD
-void file_version_info::set_file_date_ls(uint32_t file_date_ls)
-{
-	file_date_ls_ = file_date_ls;
-}
-}

+ 0 - 199
tools/pe_bliss/file_version_info.h

@@ -1,199 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-//Structure representing fixed file version info
-class file_version_info
-{
-public:
-	//Enumeration of file operating system types
-	enum file_os_type
-	{
-		file_os_unknown,
-		file_os_dos,
-		file_os_os216,
-		file_os_os232,
-		file_os_nt,
-		file_os_wince,
-		file_os_win16,
-		file_os_pm16,
-		file_os_pm32,
-		file_os_win32,
-		file_os_dos_win16,
-		file_os_dos_win32,
-		file_os_os216_pm16,
-		file_os_os232_pm32,
-		file_os_nt_win32
-	};
-
-	//Enumeration of file types
-	enum file_type
-	{
-		file_type_unknown,
-		file_type_application,
-		file_type_dll,
-		file_type_driver,
-		file_type_font,
-		file_type_vxd,
-		file_type_static_lib
-	};
-
-public:
-	//Default constructor
-	file_version_info();
-	//Constructor from Windows fixed version info structure
-	explicit file_version_info(const pe_win::vs_fixedfileinfo& info);
-
-public: //Getters
-	//Returns true if file is debug-built
-	bool is_debug() const;
-	//Returns true if file is prerelease
-	bool is_prerelease() const;
-	//Returns true if file is patched
-	bool is_patched() const;
-	//Returns true if private build
-	bool is_private_build() const;
-	//Returns true if special build
-	bool is_special_build() const;
-	//Returns true if info inferred
-	bool is_info_inferred() const;
-	//Retuens file flags (raw DWORD)
-	uint32_t get_file_flags() const;
-
-	//Returns file version most significant DWORD
-	uint32_t get_file_version_ms() const;
-	//Returns file version least significant DWORD
-	uint32_t get_file_version_ls() const;
-	//Returns product version most significant DWORD
-	uint32_t get_product_version_ms() const;
-	//Returns product version least significant DWORD
-	uint32_t get_product_version_ls() const;
-
-	//Returns file OS type (raw DWORD)
-	uint32_t get_file_os_raw() const;
-	//Returns file OS type
-	file_os_type get_file_os() const;
-
-	//Returns file type (raw DWORD)
-	uint32_t get_file_type_raw() const;
-	//Returns file type
-	file_type get_file_type() const;
-
-	//Returns file subtype (usually non-zero for drivers and fonts)
-	uint32_t get_file_subtype() const;
-
-	//Returns file date most significant DWORD
-	uint32_t get_file_date_ms() const;
-	//Returns file date least significant DWORD
-	uint32_t get_file_date_ls() const;
-
-	//Returns file version string
-	template<typename T>
-	const std::basic_string<T> get_file_version_string() const
-	{
-		return get_version_string<T>(file_version_ms_, file_version_ls_);
-	}
-
-	//Returns product version string
-	template<typename T>
-	const std::basic_string<T> get_product_version_string() const
-	{
-		return get_version_string<T>(product_version_ms_, product_version_ls_);
-	}
-		
-public: //Setters
-	//Sets if file is debug-built
-	void set_debug(bool debug);
-	//Sets if file is prerelease
-	void set_prerelease(bool prerelease);
-	//Sets if file is patched
-	void set_patched(bool patched);
-	//Sets if private build
-	void set_private_build(bool private_build);
-	//Sets if special build
-	void set_special_build(bool special_build);
-	//Sets if info inferred
-	void set_info_inferred(bool info_inferred);
-	//Sets flags (raw DWORD)
-	void set_file_flags(uint32_t file_flags);
-
-	//Sets file version most significant DWORD
-	void set_file_version_ms(uint32_t file_version_ms);
-	//Sets file version least significant DWORD
-	void set_file_version_ls(uint32_t file_version_ls);
-	//Sets product version most significant DWORD
-	void set_product_version_ms(uint32_t product_version_ms);
-	//Sets product version least significant DWORD
-	void set_product_version_ls(uint32_t product_version_ls);
-
-	//Sets file OS type (raw DWORD)
-	void set_file_os_raw(uint32_t file_os);
-	//Sets file OS type
-	void set_file_os(file_os_type file_os);
-
-	//Sets file type (raw DWORD)
-	void set_file_type_raw(uint32_t file_type);
-	//Sets file type
-	void set_file_type(file_type file_type);
-
-	//Sets file subtype (usually non-zero for drivers and fonts)
-	void set_file_subtype(uint32_t file_subtype);
-
-	//Sets file date most significant DWORD
-	void set_file_date_ms(uint32_t file_date_ms);
-	//Sets file date least significant DWORD
-	void set_file_date_ls(uint32_t file_date_ls);
-
-private:
-	//Helper to convert version DWORDs to string
-	template<typename T>
-	static const std::basic_string<T> get_version_string(uint32_t ms, uint32_t ls)
-	{
-		std::basic_stringstream<T> ss;
-		ss << (ms >> 16) << static_cast<T>(L'.')
-			<< (ms & 0xFFFF) << static_cast<T>(L'.')
-			<< (ls >> 16) << static_cast<T>(L'.')
-			<< (ls & 0xFFFF);
-		return ss.str();
-	}
-
-	//Helper to set file flag
-	void set_file_flag(uint32_t flag);
-	//Helper to clear file flag
-	void clear_file_flag(uint32_t flag);
-	//Helper to set or clear file flag
-	void set_file_flag(uint32_t flag, bool set_flag);
-
-	uint32_t file_version_ms_, file_version_ls_,
-		product_version_ms_, product_version_ls_;
-	uint32_t file_flags_;
-	uint32_t file_os_;
-	uint32_t file_type_, file_subtype_;
-	uint32_t file_date_ms_, file_date_ls_;
-};
-}

+ 0 - 81
tools/pe_bliss/message_table.cpp

@@ -1,81 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "message_table.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-//Default constructor
-message_table_item::message_table_item()
-	:unicode_(false)
-{}
-
-//Constructor from ANSI string
-message_table_item::message_table_item(const std::string& str)
-	:unicode_(false), ansi_str_(str)
-{
-	pe_utils::strip_nullbytes(ansi_str_);
-}
-
-//Constructor from UNICODE string
-message_table_item::message_table_item(const std::wstring& str)
-	:unicode_(true), unicode_str_(str)
-{
-	pe_utils::strip_nullbytes(unicode_str_);
-}
-
-//Returns true if contained string is unicode
-bool message_table_item::is_unicode() const
-{
-	return unicode_;
-}
-
-//Returns ANSI string
-const std::string& message_table_item::get_ansi_string() const
-{
-	return ansi_str_;
-}
-
-//Returns UNICODE string
-const std::wstring& message_table_item::get_unicode_string() const
-{
-	return unicode_str_;
-}
-
-//Sets ANSI string (clears UNICODE one)
-void message_table_item::set_string(const std::string& str)
-{
-	ansi_str_ = str;
-	pe_utils::strip_nullbytes(ansi_str_);
-	unicode_str_.clear();
-	unicode_ = false;
-}
-
-//Sets UNICODE string (clears ANSI one)
-void message_table_item::set_string(const std::wstring& str)
-{
-	unicode_str_ = str;
-	pe_utils::strip_nullbytes(unicode_str_);
-	ansi_str_.clear();
-	unicode_ = true;
-}
-}

+ 0 - 56
tools/pe_bliss/message_table.h

@@ -1,56 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Structure representing message table string
-class message_table_item
-{
-public:
-	//Default constructor
-	message_table_item();
-	//Constructors from ANSI and UNICODE strings
-	explicit message_table_item(const std::string& str);
-	explicit message_table_item(const std::wstring& str);
-
-	//Returns true if string is UNICODE
-	bool is_unicode() const;
-	//Returns ANSI string
-	const std::string& get_ansi_string() const;
-	//Returns UNICODE string
-	const std::wstring& get_unicode_string() const;
-
-public:
-	//Sets ANSI or UNICODE string
-	void set_string(const std::string& str);
-	void set_string(const std::wstring& str);
-
-private:
-	bool unicode_;
-	std::string ansi_str_;
-	std::wstring unicode_str_;
-};
-}

+ 0 - 1680
tools/pe_bliss/pe_base.cpp

@@ -1,1680 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <algorithm>
-#include <cmath>
-#include <set>
-#include <string.h>
-#include "pe_exception.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor
-pe_base::pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data)
-{
-	props_ = props.duplicate().release();
-
-	//Save istream state
-	std::ios_base::iostate state = file.exceptions();
-	std::streamoff old_offset = file.tellg();
-
-	try
-	{
-		file.exceptions(std::ios::goodbit);
-		//Read DOS header, PE headers and section data
-		read_dos_header(file);
-		read_pe(file, read_debug_raw_data);
-	}
-	catch(const std::exception&)
-	{
-		//If something went wrong, restore istream state
-		file.seekg(old_offset);
-		file.exceptions(state);
-		file.clear();
-		//Rethrow
-		throw;
-	}
-
-	//Restore istream state
-	file.seekg(old_offset);
-	file.exceptions(state);
-	file.clear();
-}
-
-pe_base::pe_base(const pe_properties& props, uint32_t section_alignment, bool dll, uint16_t subsystem)
-{
-	props_ = props.duplicate().release();
-	props_->create_pe(section_alignment, subsystem);
-
-	has_overlay_ = false;
-	memset(&dos_header_, 0, sizeof(dos_header_));
-
-	dos_header_.e_magic = 0x5A4D; //"MZ"
-	//Magic numbers from MSVC++ build
-	dos_header_.e_maxalloc = 0xFFFF;
-	dos_header_.e_cblp = 0x90;
-	dos_header_.e_cp = 3;
-	dos_header_.e_cparhdr = 4;
-	dos_header_.e_sp = 0xB8;
-	dos_header_.e_lfarlc = 64;
-
-	set_characteristics(image_file_executable_image | image_file_relocs_stripped);
-
-	if(get_pe_type() == pe_type_32)
-		set_characteristics_flags(image_file_32bit_machine);
-
-	if(dll)
-		set_characteristics_flags(image_file_dll);
-
-	set_subsystem_version(5, 1); //WinXP
-	set_os_version(5, 1); //WinXP
-}
-
-pe_base::pe_base(const pe_base& pe)
-	:dos_header_(pe.dos_header_),
-	rich_overlay_(pe.rich_overlay_),
-	sections_(pe.sections_),
-	has_overlay_(pe.has_overlay_),
-	full_headers_data_(pe.full_headers_data_),
-	debug_data_(pe.debug_data_),
-	props_(0)
-{
-	props_ = pe.props_->duplicate().release();
-}
-
-pe_base& pe_base::operator=(const pe_base& pe)
-{
-	dos_header_ = pe.dos_header_;
-	rich_overlay_ = pe.rich_overlay_;
-	sections_ = pe.sections_;
-	has_overlay_ = pe.has_overlay_;
-	full_headers_data_ = pe.full_headers_data_;
-	debug_data_ = pe.debug_data_;
-	delete props_;
-	props_ = 0;
-	props_ = pe.props_->duplicate().release();
-
-	return *this;
-}
-
-pe_base::~pe_base()
-{
-	delete props_;
-}
-
-//Returns dos header
-const image_dos_header& pe_base::get_dos_header() const
-{
-	return dos_header_;
-}
-
-//Returns dos header
-image_dos_header& pe_base::get_dos_header()
-{
-	return dos_header_;
-}
-
-//Returns PE headers start position (e_lfanew)
-int32_t pe_base::get_pe_header_start() const
-{
-	return dos_header_.e_lfanew;
-}
-
-//Strips MSVC stub overlay
-void pe_base::strip_stub_overlay()
-{
-	rich_overlay_.clear();
-}
-
-//Fills MSVC stub overlay with character c
-void pe_base::fill_stub_overlay(char c)
-{
-	if(rich_overlay_.length())
-		rich_overlay_.assign(rich_overlay_.length(), c);
-}
-
-//Sets stub MSVS overlay
-void pe_base::set_stub_overlay(const std::string& data)
-{
-	rich_overlay_ = data;
-}
-
-//Returns stub overlay
-const std::string& pe_base::get_stub_overlay() const
-{
-	return rich_overlay_;
-}
-
-//Realigns all sections
-void pe_base::realign_all_sections()
-{
-	for(unsigned int i = 0; i < sections_.size(); i++)
-		realign_section(i);
-}
-
-//Returns number of sections from PE header
-uint16_t pe_base::get_number_of_sections() const
-{
-	return props_->get_number_of_sections();
-}
-
-//Updates number of sections in PE header
-uint16_t pe_base::update_number_of_sections()
-{
-	uint16_t new_number = static_cast<uint16_t>(sections_.size());
-	props_->set_number_of_sections(new_number);
-	return new_number;
-}
-
-//Returns section alignment
-uint32_t pe_base::get_section_alignment() const
-{
-	return props_->get_section_alignment();
-}
-
-//Returns image sections list
-section_list& pe_base::get_image_sections()
-{
-	return sections_;
-}
-
-//Returns image sections list
-const section_list& pe_base::get_image_sections() const
-{
-	return sections_;
-}
-
-//Realigns section by index
-void pe_base::realign_section(uint32_t index)
-{
-	//Check index
-	if(sections_.size() <= index)
-		throw pe_exception("Section not found", pe_exception::section_not_found);
-
-	//Get section iterator
-	section_list::iterator it = sections_.begin() + index;
-	section& s = *it;
-
-	//Calculate, how many null bytes we have in the end of raw section data
-	std::size_t strip = 0;
-	for(std::size_t i = (*it).get_raw_data().length(); i >= 1; --i)
-	{
-		if(s.get_raw_data()[i - 1] == 0)
-			strip++;
-		else
-			break;
-	}
-
-	if(it == sections_.end() - 1) //If we're realigning the last section
-	{
-		//We can strip ending null bytes
-		s.set_size_of_raw_data(static_cast<uint32_t>(s.get_raw_data().length() - strip));
-		s.get_raw_data().resize(s.get_raw_data().length() - strip, 0);
-	}
-	else
-	{
-		//Else just set size of raw data
-		uint32_t raw_size_aligned = s.get_aligned_raw_size(get_file_alignment());
-		s.set_size_of_raw_data(raw_size_aligned);
-		s.get_raw_data().resize(raw_size_aligned, 0);
-	}
-}
-
-//Returns file alignment
-uint32_t pe_base::get_file_alignment() const
-{
-	return props_->get_file_alignment();
-}
-
-//Sets file alignment
-void pe_base::set_file_alignment(uint32_t alignment)
-{
-	//Check alignment
-	if(alignment < minimum_file_alignment)
-		throw pe_exception("File alignment can't be less than 512", pe_exception::incorrect_file_alignment);
-
-	if(!pe_utils::is_power_of_2(alignment))
-		throw pe_exception("File alignment must be a power of 2", pe_exception::incorrect_file_alignment);
-
-	if(alignment > get_section_alignment())
-		throw pe_exception("File alignment must be <= section alignment", pe_exception::incorrect_file_alignment);
-
-	//Set file alignment without any additional checks
-	set_file_alignment_unchecked(alignment);
-}
-
-//Returns size of image
-uint32_t pe_base::get_size_of_image() const
-{
-	return props_->get_size_of_image();
-}
-
-//Returns image entry point
-uint32_t pe_base::get_ep() const
-{
-	return props_->get_ep();
-}
-
-//Sets image entry point (just a value of PE header)
-void pe_base::set_ep(uint32_t new_ep)
-{
-	props_->set_ep(new_ep);
-}
-
-//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-uint32_t pe_base::get_number_of_rvas_and_sizes() const
-{
-	return props_->get_number_of_rvas_and_sizes();
-}
-
-//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-void pe_base::set_number_of_rvas_and_sizes(uint32_t number)
-{
-	props_->set_number_of_rvas_and_sizes(number);
-}
-
-//Returns PE characteristics
-uint16_t pe_base::get_characteristics() const
-{
-	return props_->get_characteristics();
-}
-
-//Sets PE characteristics (a value inside header)
-void pe_base::set_characteristics(uint16_t ch)
-{
-	props_->set_characteristics(ch);
-}
-
-//Returns section from RVA
-section& pe_base::section_from_rva(uint32_t rva)
-{
-	//Search for section
-	for(section_list::iterator i = sections_.begin(); i != sections_.end(); ++i)
-	{
-		section& s = *i;
-		//Return section if found
-		if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
-			return s;
-	}
-
-	throw pe_exception("No section found by presented address", pe_exception::no_section_found);
-}
-
-//Returns section from RVA
-const section& pe_base::section_from_rva(uint32_t rva) const
-{
-	//Search for section
-	for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i)
-	{
-		const section& s = *i;
-		//Return section if found
-		if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
-			return s;
-	}
-
-	throw pe_exception("No section found by presented address", pe_exception::no_section_found);
-}
-
-//Returns section from directory ID
-section& pe_base::section_from_directory(uint32_t directory_id)
-{
-	return section_from_rva(get_directory_rva(directory_id));		
-}
-
-//Returns section from directory ID
-const section& pe_base::section_from_directory(uint32_t directory_id) const
-{
-	return section_from_rva(get_directory_rva(directory_id));	
-}
-
-//Sets section virtual size (actual for the last one of this PE or for unbound section)
-void pe_base::set_section_virtual_size(section& s, uint32_t vsize)
-{
-	//Check if we're changing virtual size of the last section
-	//Of course, we can change virtual size of section that's not bound to this PE file
-	if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1)
-		throw pe_exception("Can't change virtual size of any section, except last one", pe_exception::error_changing_section_virtual_size);
-
-	//If we're setting virtual size to zero
-	if(vsize == 0)
-	{
-		//Check if section is empty
-		if(s.empty())
-			throw pe_exception("Cannot set virtual size of empty section to zero", pe_exception::error_changing_section_virtual_size);
-
-		//Set virtual size equal to aligned size of raw data
-		s.set_virtual_size(s.get_size_of_raw_data());
-	}
-	else
-	{
-		s.set_virtual_size(vsize);
-	}
-
-	//Update image size if we're changing virtual size for the last section of this PE
-	if(!sections_.empty() || &s == &(*(sections_.end() - 1)))
-		update_image_size();
-}
-
-//Expands section raw or virtual size to hold data from specified RVA with specified size
-//Section must be free (not bound to any image)
-//or the last section of this image
-bool pe_base::expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand)
-{
-	//Check if we're changing the last section
-	//Of course, we can change the section that's not bound to this PE file
-	if(sections_.empty() || std::find_if(sections_.begin(), sections_.end() - 1, section_ptr_finder(s)) != sections_.end() - 1)
-		throw pe_exception("Can't expand any section, except last one", pe_exception::error_expanding_section);
-
-	//Check if we should expand our section
-	if(expand == expand_section_raw && section_data_length_from_rva(s, needed_rva, section_data_raw) < needed_size)
-	{
-		//Expand section raw data
-		s.get_raw_data().resize(needed_rva - s.get_virtual_address() + needed_size);
-		recalculate_section_sizes(s, false);
-		return true;
-	}
-	else if(expand == expand_section_virtual && section_data_length_from_rva(s, needed_rva, section_data_virtual) < needed_size)
-	{
-		//Expand section virtual data
-		set_section_virtual_size(s, needed_rva - s.get_virtual_address() + needed_size);
-		return true;
-	}
-	
-	return false;
-}
-
-//Updates image virtual size
-void pe_base::update_image_size()
-{
-	//Write virtual size of image to headers
-	if(!sections_.empty())
-		set_size_of_image(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()));
-	else
-		set_size_of_image(get_size_of_headers());
-}
-
-//Returns checksum of PE file from header
-uint32_t pe_base::get_checksum() const
-{
-	return props_->get_checksum();
-}
-
-//Sets checksum of PE file
-void pe_base::set_checksum(uint32_t checksum)
-{
-	props_->set_checksum(checksum);
-}
-
-//Returns timestamp of PE file from header
-uint32_t pe_base::get_time_date_stamp() const
-{
-	return props_->get_time_date_stamp();
-}
-
-//Sets timestamp of PE file
-void pe_base::set_time_date_stamp(uint32_t timestamp)
-{
-	props_->set_time_date_stamp(timestamp);
-}
-
-//Returns Machine field value of PE file from header
-uint16_t pe_base::get_machine() const
-{
-	return props_->get_machine();
-}
-
-//Sets Machine field value of PE file
-void pe_base::set_machine(uint16_t machine)
-{
-	props_->set_machine(machine);
-}
-
-//Prepares section before attaching it
-void pe_base::prepare_section(section& s)
-{
-	//Calculate its size of raw data
-	s.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(s.get_raw_data().length(), get_file_alignment())));
-
-	//Check section virtual and raw size
-	if(!s.get_size_of_raw_data() && !s.get_virtual_size())
-		throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes);
-
-	//If section virtual size is zero
-	if(!s.get_virtual_size())
-	{
-		s.set_virtual_size(s.get_size_of_raw_data());
-	}
-	else
-	{
-		//Else calculate its virtual size
-		s.set_virtual_size(
-			std::max<uint32_t>(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()),
-			pe_utils::align_up(s.get_virtual_size(), get_section_alignment())));
-	}
-}
-
-//Adds section to image
-section& pe_base::add_section(section s)
-{
-	if(sections_.size() >= maximum_number_of_sections)
-		throw pe_exception("Maximum number of sections has been reached", pe_exception::no_more_sections_can_be_added);
-
-	//Prepare section before adding it
-	prepare_section(s);
-
-	//Calculate section virtual address
-	if(!sections_.empty())
-	{
-		s.set_virtual_address(pe_utils::align_up(sections_.back().get_virtual_address() + sections_.back().get_aligned_virtual_size(get_section_alignment()), get_section_alignment()));
-
-		//We should align last section raw size, if it wasn't aligned
-		section& last = sections_.back();
-		last.set_size_of_raw_data(static_cast<uint32_t>(pe_utils::align_up(last.get_raw_data().length(), get_file_alignment())));
-	}
-	else
-	{
-		s.set_virtual_address(
-			s.get_virtual_address() == 0
-			? pe_utils::align_up(get_size_of_headers(), get_section_alignment())
-			: pe_utils::align_up(s.get_virtual_address(), get_section_alignment()));
-	}
-
-	//Add section to the end of section list
-	sections_.push_back(s);
-	//Set number of sections in PE header
-	set_number_of_sections(static_cast<uint16_t>(sections_.size()));
-	//Recalculate virtual size of image
-	set_size_of_image(get_size_of_image() + s.get_aligned_virtual_size(get_section_alignment()));
-	//Return last section
-	return sections_.back();
-}
-
-//Returns true if sectios "s" is already attached to this PE file
-bool pe_base::section_attached(const section& s) const
-{
-	return sections_.end() != std::find_if(sections_.begin(), sections_.end(), section_ptr_finder(s));
-}
-
-//Returns true if directory exists
-bool pe_base::directory_exists(uint32_t id) const
-{
-	return props_->directory_exists(id);
-}
-
-//Removes directory
-void pe_base::remove_directory(uint32_t id)
-{
-	props_->remove_directory(id);
-}
-
-//Returns directory RVA
-uint32_t pe_base::get_directory_rva(uint32_t id) const
-{
-	return props_->get_directory_rva(id);
-}
-
-//Returns directory size
-uint32_t pe_base::get_directory_size(uint32_t id) const
-{
-	return props_->get_directory_size(id);
-}
-
-//Sets directory RVA (just a value of PE header, no moving occurs)
-void pe_base::set_directory_rva(uint32_t id, uint32_t rva)
-{
-	return props_->set_directory_rva(id, rva);
-}
-
-//Sets directory size (just a value of PE header, no moving occurs)
-void pe_base::set_directory_size(uint32_t id, uint32_t size)
-{
-	return props_->set_directory_size(id, size);
-}
-
-//Strips only zero DATA_DIRECTORY entries to count = min_count
-//Returns resulting number of data directories
-//strip_iat_directory - if true, even not empty IAT directory will be stripped
-uint32_t pe_base::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
-{
-	return props_->strip_data_directories(min_count, strip_iat_directory);
-}
-
-//Returns true if image has import directory
-bool pe_base::has_imports() const
-{
-	return directory_exists(image_directory_entry_import);
-}
-
-//Returns true if image has export directory
-bool pe_base::has_exports() const
-{
-	return directory_exists(image_directory_entry_export);
-}
-
-//Returns true if image has resource directory
-bool pe_base::has_resources() const
-{
-	return directory_exists(image_directory_entry_resource);
-}
-
-//Returns true if image has security directory
-bool pe_base::has_security() const
-{
-	return directory_exists(image_directory_entry_security);
-}
-
-//Returns true if image has relocations
-bool pe_base::has_reloc() const
-{
-	return directory_exists(image_directory_entry_basereloc) && !(get_characteristics() & image_file_relocs_stripped);
-}
-
-//Returns true if image has TLS directory
-bool pe_base::has_tls() const
-{
-	return directory_exists(image_directory_entry_tls);
-}
-
-//Returns true if image has config directory
-bool pe_base::has_config() const
-{
-	return directory_exists(image_directory_entry_load_config);
-}
-
-//Returns true if image has bound import directory
-bool pe_base::has_bound_import() const
-{
-	return directory_exists(image_directory_entry_bound_import);
-}
-
-//Returns true if image has delay import directory
-bool pe_base::has_delay_import() const
-{
-	return directory_exists(image_directory_entry_delay_import);
-}
-
-//Returns true if image has COM directory
-bool pe_base::is_dotnet() const
-{
-	return directory_exists(image_directory_entry_com_descriptor);
-}
-
-//Returns true if image has exception directory
-bool pe_base::has_exception_directory() const
-{
-	return directory_exists(image_directory_entry_exception);
-}
-
-//Returns true if image has debug directory
-bool pe_base::has_debug() const
-{
-	return directory_exists(image_directory_entry_debug);
-}
-
-//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-char* pe_base::section_data_from_rva(section& s, uint32_t rva)
-{
-	//Check if RVA is inside section "s"
-	if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
-	{
-		if(s.get_raw_data().empty())
-			throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty);
-
-		return &s.get_raw_data()[rva - s.get_virtual_address()];
-	}
-
-	throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-const char* pe_base::section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype) const
-{
-	//Check if RVA is inside section "s"
-	if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
-		return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address();
-
-	throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
-uint32_t pe_base::section_data_length_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
-{
-	//if RVA is inside of headers and we're searching them too...
-	if(include_headers && rva < full_headers_data_.length())
-		return static_cast<unsigned long>(full_headers_data_.length());
-
-	const section& s = section_from_rva(rva);
-	return static_cast<unsigned long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()));
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32
-uint32_t pe_base::section_data_length_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
-{
-	return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32/PE64
-uint32_t pe_base::section_data_length_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
-{
-	return section_data_length_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
-uint32_t pe_base::section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype, bool include_headers) const
-{
-	//if RVAs are inside of headers and we're searching them too...
-	if(include_headers && rva < full_headers_data_.length() && rva_inside < full_headers_data_.length())
-		return static_cast<unsigned long>(full_headers_data_.length() - rva_inside);
-
-	const section& s = section_from_rva(rva);
-	if(rva_inside < s.get_virtual_address())
-		throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-
-	//Calculate remaining length of section data from "rva" address
-	long length = static_cast<long>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()))
-		+ s.get_virtual_address() - rva_inside;
-
-	if(length < 0)
-		return 0;
-
-	return static_cast<unsigned long>(length);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32
-uint32_t pe_base::section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype, bool include_headers) const
-{
-	return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32/PE64
-uint32_t pe_base::section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype, bool include_headers) const
-{
-	return section_data_length_from_rva(va_to_rva(va), va_to_rva(va_inside), datatype, include_headers);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
-uint32_t pe_base::section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype) const
-{
-	//Check rva_inside
-	if(rva_inside >= s.get_virtual_address() && rva_inside < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()))
-	{
-		//Calculate remaining length of section data from "rva" address
-		int32_t length = static_cast<int32_t>(datatype == section_data_raw ? s.get_raw_data().length() /* instead of SizeOfRawData */ : s.get_aligned_virtual_size(get_section_alignment()))
-			+ s.get_virtual_address() - rva_inside;
-
-		if(length < 0)
-			return 0;
-
-		return static_cast<uint32_t>(length);
-	}
-
-	throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 (checks bounds)
-uint32_t pe_base::section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype) const
-{
-	return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
-}
-
-//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32/PE64 (checks bounds)
-uint32_t pe_base::section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype) const
-{
-	return section_data_length_from_rva(s, va_to_rva(va_inside), datatype);
-}
-
-//Returns corresponding section data pointer from RVA inside section
-char* pe_base::section_data_from_rva(uint32_t rva, bool include_headers)
-{
-	//if RVA is inside of headers and we're searching them too...
-	if(include_headers && rva < full_headers_data_.length())
-		return &full_headers_data_[rva];
-
-	section& s = section_from_rva(rva);
-
-	if(s.get_raw_data().empty())
-		throw pe_exception("Section raw data is empty and cannot be changed", pe_exception::section_is_empty);
-
-	return &s.get_raw_data()[rva - s.get_virtual_address()];
-}
-
-//Returns corresponding section data pointer from RVA inside section
-const char* pe_base::section_data_from_rva(uint32_t rva, section_data_type datatype, bool include_headers) const
-{
-	//if RVA is inside of headers and we're searching them too...
-	if(include_headers && rva < full_headers_data_.length())
-		return &full_headers_data_[rva];
-
-	const section& s = section_from_rva(rva);
-	return (datatype == section_data_raw ? s.get_raw_data().data() : s.get_virtual_data(get_section_alignment()).c_str()) + rva - s.get_virtual_address();
-}
-
-//Reads DOS headers from istream
-void pe_base::read_dos_header(std::istream& file, image_dos_header& header)
-{
-	//Check istream flags
-	if(file.bad() || file.eof())
-		throw pe_exception("PE file stream is bad or closed.", pe_exception::bad_pe_file);
-
-	//Read DOS header and check istream
-	file.read(reinterpret_cast<char*>(&header), sizeof(image_dos_header));
-	if(file.bad() || file.eof())
-		throw pe_exception("Unable to read IMAGE_DOS_HEADER", pe_exception::bad_dos_header);
-
-	//Check DOS header magic
-	if(header.e_magic != 0x5a4d) //"MZ"
-		throw pe_exception("IMAGE_DOS_HEADER signature is incorrect", pe_exception::bad_dos_header);
-}
-
-//Reads DOS headers from istream
-void pe_base::read_dos_header(std::istream& file)
-{
-	read_dos_header(file, dos_header_);
-}
-
-//Reads PE image from istream
-void pe_base::read_pe(std::istream& file, bool read_debug_raw_data)
-{
-	//Get istream size
-	std::streamoff filesize = pe_utils::get_file_size(file);
-
-	//Check if PE header is DWORD-aligned
-	if((dos_header_.e_lfanew % sizeof(uint32_t)) != 0)
-		throw pe_exception("PE header is not DWORD-aligned", pe_exception::bad_dos_header);
-
-	//Seek to NT headers
-	file.seekg(dos_header_.e_lfanew);
-	if(file.bad() || file.fail())
-		throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found);
-
-	//Read NT headers
-	file.read(get_nt_headers_ptr(), get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries);
-	if(file.bad() || file.eof())
-		throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers);
-
-	//Check PE signature
-	if(get_pe_signature() != 0x4550) //"PE"
-		throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
-	//Check number of directories
-	if(get_number_of_rvas_and_sizes() > image_numberof_directory_entries)
-		set_number_of_rvas_and_sizes(image_numberof_directory_entries);
-
-	if(get_number_of_rvas_and_sizes() > 0)
-	{
-		//Read data directory headers, if any
-		file.read(get_nt_headers_ptr() + (get_sizeof_nt_header() - sizeof(image_data_directory) * image_numberof_directory_entries), sizeof(image_data_directory) * get_number_of_rvas_and_sizes());
-		if(file.bad() || file.eof())
-			throw pe_exception("Error reading DATA_DIRECTORY headers", pe_exception::error_reading_data_directories);
-	}
-
-	//Check section number
-	//Images with zero section number accepted
-	if(get_number_of_sections() > maximum_number_of_sections)
-		throw pe_exception("Incorrect number of sections", pe_exception::section_number_incorrect);
-
-	//Check PE magic
-	if(get_magic() != get_needed_magic())
-		throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
-	//Check section alignment
-	if(!pe_utils::is_power_of_2(get_section_alignment()))
-		throw pe_exception("Incorrect section alignment", pe_exception::incorrect_section_alignment);
-
-	//Check file alignment
-	if(!pe_utils::is_power_of_2(get_file_alignment()))
-		throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment);
-
-	if(get_file_alignment() != get_section_alignment() && (get_file_alignment() < minimum_file_alignment || get_file_alignment() > get_section_alignment()))
-		throw pe_exception("Incorrect file alignment", pe_exception::incorrect_file_alignment);
-
-	//Check size of image
-	if(pe_utils::align_up(get_size_of_image(), get_section_alignment()) == 0)
-		throw pe_exception("Incorrect size of image", pe_exception::incorrect_size_of_image);
-	
-	//Read rich data overlay / DOS stub (if any)
-	if(static_cast<uint32_t>(dos_header_.e_lfanew) > sizeof(image_dos_header))
-	{
-		rich_overlay_.resize(dos_header_.e_lfanew - sizeof(image_dos_header));
-		file.seekg(sizeof(image_dos_header));
-		file.read(&rich_overlay_[0], dos_header_.e_lfanew - sizeof(image_dos_header));
-		if(file.bad() || file.eof())
-			throw pe_exception("Error reading 'Rich' & 'DOS stub' overlay", pe_exception::error_reading_overlay);
-	}
-
-	//Calculate first section raw position
-	//Sum is safe here
-	uint32_t first_section = dos_header_.e_lfanew + get_size_of_optional_header() + sizeof(image_file_header) + sizeof(uint32_t) /* Signature */;
-
-	if(get_number_of_sections() > 0)
-	{
-		//Go to first section
-		file.seekg(first_section);
-		if(file.bad() || file.fail())
-			throw pe_exception("Cannot reach section headers", pe_exception::image_section_headers_not_found);
-	}
-
-	uint32_t last_raw_size = 0;
-
-	//Read all sections
-	for(int i = 0; i < get_number_of_sections(); i++)
-	{
-		section s;
-		//Read section header
-		file.read(reinterpret_cast<char*>(&s.get_raw_header()), sizeof(image_section_header));
-		if(file.bad() || file.eof())
-			throw pe_exception("Error reading section header", pe_exception::error_reading_section_header);
-
-		//Save next section header position
-		std::streamoff next_sect = file.tellg();
-
-		//Check section virtual and raw sizes
-		if(!s.get_size_of_raw_data() && !s.get_virtual_size())
-			throw pe_exception("Virtual and Physical sizes of section can't be 0 at the same time", pe_exception::zero_section_sizes);
-
-		//Check for adequate values of section fields
-		if(!pe_utils::is_sum_safe(s.get_virtual_address(), s.get_virtual_size()) || s.get_virtual_size() > pe_utils::two_gb
-			|| !pe_utils::is_sum_safe(s.get_pointer_to_raw_data(), s.get_size_of_raw_data()) || s.get_size_of_raw_data() > pe_utils::two_gb)
-			throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
-		if(s.get_size_of_raw_data() != 0)
-		{
-			//If section has raw data
-
-			//If section raw data size is greater than virtual, fix it
-			last_raw_size = s.get_size_of_raw_data();
-			if(pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()) > pe_utils::align_up(s.get_virtual_size(), get_section_alignment()))
-				s.set_size_of_raw_data(s.get_virtual_size());
-
-			//Check virtual and raw section sizes and addresses
-			if(s.get_virtual_address() + pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment())
-				||
-				pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()) + s.get_size_of_raw_data() > static_cast<uint32_t>(filesize))
-				throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
-			//Seek to section raw data
-			file.seekg(pe_utils::align_down(s.get_pointer_to_raw_data(), get_file_alignment()));
-			if(file.bad() || file.fail())
-				throw pe_exception("Cannot reach section data", pe_exception::image_section_data_not_found);
-
-			//Read section raw data
-			s.get_raw_data().resize(s.get_size_of_raw_data());
-			file.read(&s.get_raw_data()[0], s.get_size_of_raw_data());
-			if(file.bad() || file.fail())
-				throw pe_exception("Error reading section data", pe_exception::image_section_data_not_found);
-		}
-
-		//Check virtual address and size of section
-		if(s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) > pe_utils::align_up(get_size_of_image(), get_section_alignment()))
-			throw pe_exception("Incorrect section address or size", pe_exception::section_incorrect_addr_or_size);
-
-		//Save section
-		sections_.push_back(s);
-
-		//Seek to the next section header
-		file.seekg(next_sect);
-	}
-
-	//Check size of headers: SizeOfHeaders can't be larger than first section VA
-	if(!sections_.empty() && get_size_of_headers() > sections_.front().get_virtual_address())
-		throw pe_exception("Incorrect size of headers", pe_exception::incorrect_size_of_headers);
-
-	//If image has more than two sections
-	if(sections_.size() >= 2)
-	{
-		//Check sections virtual sizes
-		for(section_list::const_iterator i = sections_.begin() + 1; i != sections_.end(); ++i)
-		{
-			if((*i).get_virtual_address() != (*(i - 1)).get_virtual_address() + (*(i - 1)).get_aligned_virtual_size(get_section_alignment()))
-				throw pe_exception("Section table is incorrect", pe_exception::image_section_table_incorrect);
-		}
-	}
-
-	//Check if image has overlay in the end of file
-	has_overlay_ = !sections_.empty() && filesize > static_cast<std::streamoff>(sections_.back().get_pointer_to_raw_data() + last_raw_size);
-
-	{
-		//Additionally, read data from the beginning of istream to size of headers
-		file.seekg(0);
-		uint32_t size_of_headers = std::min<uint32_t>(get_size_of_headers(), static_cast<uint32_t>(filesize));
-
-		if(!sections_.empty())
-		{
-			for(section_list::const_iterator i = sections_.begin(); i != sections_.end(); ++i)
-			{
-				if(!(*i).empty())
-				{
-					size_of_headers = std::min<uint32_t>(get_size_of_headers(), (*i).get_pointer_to_raw_data());
-					break;
-				}
-			}
-		}
-
-		full_headers_data_.resize(size_of_headers);
-		file.read(&full_headers_data_[0], size_of_headers);
-		if(file.bad() || file.eof())
-			throw pe_exception("Error reading file", pe_exception::error_reading_file);
-	}
-
-	//Moreover, if there's debug directory, read its raw data for some debug info types
-	while(read_debug_raw_data && has_debug())
-	{
-		try
-		{
-			//Check the length in bytes of the section containing debug directory
-			if(section_data_length_from_rva(get_directory_rva(image_directory_entry_debug), get_directory_rva(image_directory_entry_debug), section_data_virtual, true) < sizeof(image_debug_directory))
-				break;
-
-			unsigned long current_pos = get_directory_rva(image_directory_entry_debug);
-
-			//First IMAGE_DEBUG_DIRECTORY table
-			image_debug_directory directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-
-			//Iterate over all IMAGE_DEBUG_DIRECTORY directories
-			while(directory.PointerToRawData
-				&& current_pos < get_directory_rva(image_directory_entry_debug) + get_directory_size(image_directory_entry_debug))
-			{
-				//If we have something to read
-				if((directory.Type == image_debug_type_codeview
-					|| directory.Type == image_debug_type_misc
-					|| directory.Type == image_debug_type_coff)
-					&& directory.SizeOfData)
-				{
-					std::string data;
-					data.resize(directory.SizeOfData);
-					file.seekg(directory.PointerToRawData);
-					file.read(&data[0], directory.SizeOfData);
-					if(file.bad() || file.eof())
-						throw pe_exception("Error reading file", pe_exception::error_reading_file);
-
-					debug_data_.insert(std::make_pair(directory.PointerToRawData, data));
-				}
-
-				//Go to next debug entry
-				current_pos += sizeof(image_debug_directory);
-				directory = section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-			}
-
-			break;
-		}
-		catch(const pe_exception&)
-		{
-			//Don't throw any exception here, if debug info is corrupted or incorrect
-			break;
-		}
-		catch(const std::bad_alloc&)
-		{
-			//Don't throw any exception here, if debug info is corrupted or incorrect
-			break;
-		}
-	}
-}
-
-//Returns PE type of this image
-pe_type pe_base::get_pe_type() const
-{
-	return props_->get_pe_type();
-}
-
-//Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks)
-pe_type pe_base::get_pe_type(std::istream& file)
-{
-	//Save state of the istream
-	std::ios_base::iostate state = file.exceptions();
-	std::streamoff old_offset = file.tellg();
-	image_nt_headers32 nt_headers;
-	image_dos_header header;
-
-	try
-	{
-		//Read dos header
-		file.exceptions(std::ios::goodbit);
-		read_dos_header(file, header);
-
-		//Seek to the NT headers start
-		file.seekg(header.e_lfanew);
-		if(file.bad() || file.fail())
-			throw pe_exception("Cannot reach IMAGE_NT_HEADERS", pe_exception::image_nt_headers_not_found);
-
-		//Read NT headers (we're using 32-bit version, because there's no significant differencies between 32 and 64 bit version structures)
-		file.read(reinterpret_cast<char*>(&nt_headers), sizeof(image_nt_headers32) - sizeof(image_data_directory) * image_numberof_directory_entries);
-		if(file.bad() || file.eof())
-			throw pe_exception("Error reading IMAGE_NT_HEADERS", pe_exception::error_reading_image_nt_headers);
-
-		//Check NT headers signature
-		if(nt_headers.Signature != 0x4550) //"PE"
-			throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-
-		//Check NT headers magic
-		if(nt_headers.OptionalHeader.Magic != image_nt_optional_hdr32_magic && nt_headers.OptionalHeader.Magic != image_nt_optional_hdr64_magic)
-			throw pe_exception("Incorrect PE signature", pe_exception::pe_signature_incorrect);
-	}
-	catch(const std::exception&)
-	{
-		//If something went wrong, restore istream state
-		file.exceptions(state);
-		file.seekg(old_offset);
-		file.clear();
-		//Retrhow exception
-		throw;
-	}
-
-	//Restore stream state
-	file.exceptions(state);
-	file.seekg(old_offset);
-	file.clear();
-
-	//Determine PE type and return it
-	return nt_headers.OptionalHeader.Magic == image_nt_optional_hdr64_magic ? pe_type_64 : pe_type_32;
-}
-
-//Returns true if image has overlay data at the end of file
-bool pe_base::has_overlay() const
-{
-	return has_overlay_;
-}
-
-//Clears PE characteristics flag
-void pe_base::clear_characteristics_flags(uint16_t flags)
-{
-	set_characteristics(get_characteristics() & ~flags);
-}
-
-//Sets PE characteristics flag
-void pe_base::set_characteristics_flags(uint16_t flags)
-{
-	set_characteristics(get_characteristics() | flags);
-}
-
-//Returns true if PE characteristics flag set
-bool pe_base::check_characteristics_flag(uint16_t flag) const
-{
-	return (get_characteristics() & flag) ? true : false;
-}
-
-//Returns subsystem value
-uint16_t pe_base::get_subsystem() const
-{
-	return props_->get_subsystem();
-}
-
-//Sets subsystem value
-void pe_base::set_subsystem(uint16_t subsystem)
-{
-	props_->set_subsystem(subsystem);
-}
-
-//Returns true if image has console subsystem
-bool pe_base::is_console() const
-{
-	return get_subsystem() == image_subsystem_windows_cui;
-}
-
-//Returns true if image has Windows GUI subsystem
-bool pe_base::is_gui() const
-{
-	return get_subsystem() == image_subsystem_windows_gui;
-}
-
-//Sets required operation system version
-void pe_base::set_os_version(uint16_t major, uint16_t minor)
-{
-	props_->set_os_version(major, minor);
-}
-
-//Returns required operation system version (minor word)
-uint16_t pe_base::get_minor_os_version() const
-{
-	return props_->get_minor_os_version();
-}
-
-//Returns required operation system version (major word)
-uint16_t pe_base::get_major_os_version() const
-{
-	return props_->get_major_os_version();
-}
-
-//Sets required subsystem version
-void pe_base::set_subsystem_version(uint16_t major, uint16_t minor)
-{
-	props_->set_subsystem_version(major, minor);
-}
-
-//Returns required subsystem version (minor word)
-uint16_t pe_base::get_minor_subsystem_version() const
-{
-	return props_->get_minor_subsystem_version();
-}
-
-//Returns required subsystem version (major word)
-uint16_t pe_base::get_major_subsystem_version() const
-{
-	return props_->get_major_subsystem_version();
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds)
-char* pe_base::section_data_from_va(section& s, uint32_t va) //Always returns raw data
-{
-	return section_data_from_rva(s, va_to_rva(va));
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32 (checks bounds)
-const char* pe_base::section_data_from_va(const section& s, uint32_t va, section_data_type datatype) const
-{
-	return section_data_from_rva(s, va_to_rva(va), datatype);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32
-char* pe_base::section_data_from_va(uint32_t va, bool include_headers) //Always returns raw data
-{
-	return section_data_from_rva(va_to_rva(va), include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32
-const char* pe_base::section_data_from_va(uint32_t va, section_data_type datatype, bool include_headers) const
-{
-	return section_data_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds)
-char* pe_base::section_data_from_va(section& s, uint64_t va)  //Always returns raw data
-{
-	return section_data_from_rva(s, va_to_rva(va));
-}
-
-//Returns corresponding section data pointer from VA inside section "s" for PE32/PE64 (checks bounds)
-const char* pe_base::section_data_from_va(const section& s, uint64_t va, section_data_type datatype) const
-{
-	return section_data_from_rva(s, va_to_rva(va), datatype);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32/PE64
-char* pe_base::section_data_from_va(uint64_t va, bool include_headers)  //Always returns raw data
-{
-	return section_data_from_rva(va_to_rva(va), include_headers);
-}
-
-//Returns corresponding section data pointer from VA inside section for PE32/PE64
-const char* pe_base::section_data_from_va(uint64_t va, section_data_type datatype, bool include_headers) const
-{
-	return section_data_from_rva(va_to_rva(va), datatype, include_headers);
-}
-
-//Returns section from VA inside it for PE32
-section& pe_base::section_from_va(uint32_t va)
-{
-	return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from VA inside it for PE32/PE64
-section& pe_base::section_from_va(uint64_t va)
-{
-	return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from RVA inside it for PE32
-const section& pe_base::section_from_va(uint32_t va) const
-{
-	return section_from_rva(va_to_rva(va));
-}
-
-//Returns section from RVA inside it for PE32/PE64
-const section& pe_base::section_from_va(uint64_t va) const
-{
-	return section_from_rva(va_to_rva(va));
-}
-
-uint32_t pe_base::va_to_rva(uint32_t va, bool bound_check) const
-{
-	return props_->va_to_rva(va, bound_check);
-}
-
-uint32_t pe_base::va_to_rva(uint64_t va, bool bound_check) const
-{
-	return props_->va_to_rva(va, bound_check);
-}
-
-uint32_t pe_base::rva_to_va_32(uint32_t rva) const
-{
-	return props_->rva_to_va_32(rva);
-}
-
-uint64_t pe_base::rva_to_va_64(uint32_t rva) const
-{
-	return props_->rva_to_va_64(rva);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertion for PE32
-void pe_base::rva_to_va(uint32_t rva, uint32_t& va) const
-{
-	va = rva_to_va_32(rva);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64
-void pe_base::rva_to_va(uint32_t rva, uint64_t& va) const
-{
-	va = rva_to_va_64(rva);
-}
-
-//Returns section from file offset (4gb max)
-section& pe_base::section_from_file_offset(uint32_t offset)
-{
-	return *file_offset_to_section(offset);
-}
-
-//Returns section from file offset (4gb max)
-const section& pe_base::section_from_file_offset(uint32_t offset) const
-{
-	return *file_offset_to_section(offset);
-}
-
-//Returns section and offset (raw data only) from its start from RVA
-const std::pair<uint32_t, const section*> pe_base::section_and_offset_from_rva(uint32_t rva) const
-{
-	const section& s = section_from_rva(rva);
-	return std::make_pair(rva - s.get_virtual_address(), &s);
-}
-
-//Returns DLL Characteristics
-uint16_t pe_base::get_dll_characteristics() const
-{
-	return props_->get_dll_characteristics();
-}
-
-//Sets DLL Characteristics
-void pe_base::set_dll_characteristics(uint16_t characteristics)
-{
-	props_->set_dll_characteristics(characteristics);
-}
-
-//Returns size of headers
-uint32_t pe_base::get_size_of_headers() const
-{
-	return props_->get_size_of_headers();
-}
-
-//Returns size of optional header
-uint16_t pe_base::get_size_of_optional_header() const
-{
-	return props_->get_size_of_optional_header();
-}
-
-//Returns PE signature
-uint32_t pe_base::get_pe_signature() const
-{
-	return props_->get_pe_signature();
-}
-
-//Returns magic value
-uint32_t pe_base::get_magic() const
-{
-	return props_->get_magic();
-}
-
-//Returns image base for PE32
-void pe_base::get_image_base(uint32_t& base) const
-{
-	base = get_image_base_32();
-}
-
-//Returns image base for PE32 and PE64 respectively
-uint32_t pe_base::get_image_base_32() const
-{
-	return props_->get_image_base_32();
-}
-
-//Sets image base for PE32 and PE64 respectively
-uint64_t pe_base::get_image_base_64() const
-{
-	return props_->get_image_base_64();
-}
-
-//RVA to RAW file offset convertion (4gb max)
-uint32_t pe_base::rva_to_file_offset(uint32_t rva) const
-{
-	//Maybe, RVA is inside PE headers
-	if(rva < get_size_of_headers())
-		return rva;
-
-	const section& s = section_from_rva(rva);
-	return s.get_pointer_to_raw_data() + rva - s.get_virtual_address();
-}
-
-//RAW file offset to RVA convertion (4gb max)
-uint32_t pe_base::file_offset_to_rva(uint32_t offset) const
-{
-	//Maybe, offset is inside PE headers
-	if(offset < get_size_of_headers())
-		return offset;
-
-	const section_list::const_iterator it = file_offset_to_section(offset);
-	return offset - (*it).get_pointer_to_raw_data() + (*it).get_virtual_address();
-}
-
-//RAW file offset to section convertion helper (4gb max)
-section_list::const_iterator pe_base::file_offset_to_section(uint32_t offset) const
-{
-	section_list::const_iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset));
-	if(it == sections_.end())
-		throw pe_exception("No section found by presented file offset", pe_exception::no_section_found);
-
-	return it;
-}
-
-//RAW file offset to section convertion helper (4gb max)
-section_list::iterator pe_base::file_offset_to_section(uint32_t offset)
-{
-	section_list::iterator it = std::find_if(sections_.begin(), sections_.end(), section_by_raw_offset(offset));
-	if(it == sections_.end())
-		throw pe_exception("No section found by presented file offset", pe_exception::no_section_found);
-	
-	return it;
-}
-
-//RVA from section raw data offset
-uint32_t pe_base::rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start)
-{
-	return s.get_virtual_address() + raw_offset_from_section_start;
-}
-
-//Returns image base for PE32/PE64
-void pe_base::get_image_base(uint64_t& base) const
-{
-	base = get_image_base_64();
-}
-
-//Sets new image base
-void pe_base::set_image_base(uint32_t base)
-{
-	props_->set_image_base(base);
-}
-
-void pe_base::set_image_base_64(uint64_t base)
-{
-	props_->set_image_base_64(base);
-}
-
-//Sets heap size commit for PE32 and PE64 respectively
-void pe_base::set_heap_size_commit(uint32_t size)
-{
-	props_->set_heap_size_commit(size);
-}
-
-void pe_base::set_heap_size_commit(uint64_t size)
-{
-	props_->set_heap_size_commit(size);
-}
-
-//Sets heap size reserve for PE32 and PE64 respectively
-void pe_base::set_heap_size_reserve(uint32_t size)
-{
-	props_->set_heap_size_reserve(size);
-}
-
-void pe_base::set_heap_size_reserve(uint64_t size)
-{
-	props_->set_heap_size_reserve(size);
-}
-
-//Sets stack size commit for PE32 and PE64 respectively
-void pe_base::set_stack_size_commit(uint32_t size)
-{
-	props_->set_stack_size_commit(size);
-}
-
-void pe_base::set_stack_size_commit(uint64_t size)
-{
-	props_->set_stack_size_commit(size);
-}
-
-//Sets stack size reserve for PE32 and PE64 respectively
-void pe_base::set_stack_size_reserve(uint32_t size)
-{
-	props_->set_stack_size_reserve(size);
-}
-
-void pe_base::set_stack_size_reserve(uint64_t size)
-{
-	props_->set_stack_size_reserve(size);
-}
-
-//Returns heap size commit for PE32 and PE64 respectively
-uint32_t pe_base::get_heap_size_commit_32() const
-{
-	return props_->get_heap_size_commit_32();
-}
-
-uint64_t pe_base::get_heap_size_commit_64() const
-{
-	return props_->get_heap_size_commit_64();
-}
-
-//Returns heap size reserve for PE32 and PE64 respectively
-uint32_t pe_base::get_heap_size_reserve_32() const
-{
-	return props_->get_heap_size_reserve_32();
-}
-
-uint64_t pe_base::get_heap_size_reserve_64() const
-{
-	return props_->get_heap_size_reserve_64();
-}
-
-//Returns stack size commit for PE32 and PE64 respectively
-uint32_t pe_base::get_stack_size_commit_32() const
-{
-	return props_->get_stack_size_commit_32();
-}
-
-uint64_t pe_base::get_stack_size_commit_64() const
-{
-	return props_->get_stack_size_commit_64();
-}
-
-//Returns stack size reserve for PE32 and PE64 respectively
-uint32_t pe_base::get_stack_size_reserve_32() const
-{
-	return props_->get_stack_size_reserve_32();
-}
-
-uint64_t pe_base::get_stack_size_reserve_64() const
-{
-	return props_->get_stack_size_reserve_64();
-}
-
-//Returns heap size commit for PE32
-void pe_base::get_heap_size_commit(uint32_t& size) const
-{
-	size = get_heap_size_commit_32();
-}
-
-//Returns heap size commit for PE32/PE64
-void pe_base::get_heap_size_commit(uint64_t& size) const
-{
-	size = get_heap_size_commit_64();
-}
-
-//Returns heap size reserve for PE32
-void pe_base::get_heap_size_reserve(uint32_t& size) const
-{
-	size = get_heap_size_reserve_32();
-}
-
-//Returns heap size reserve for PE32/PE64
-void pe_base::get_heap_size_reserve(uint64_t& size) const
-{
-	size = get_heap_size_reserve_64();
-}
-
-//Returns stack size commit for PE32
-void pe_base::get_stack_size_commit(uint32_t& size) const
-{
-	size = get_stack_size_commit_32();
-}
-
-//Returns stack size commit for PE32/PE64
-void pe_base::get_stack_size_commit(uint64_t& size) const
-{
-	size = get_stack_size_commit_64();
-}
-
-//Returns stack size reserve for PE32
-void pe_base::get_stack_size_reserve(uint32_t& size) const
-{
-	size = get_stack_size_reserve_32();
-}
-
-//Returns stack size reserve for PE32/PE64
-void pe_base::get_stack_size_reserve(uint64_t& size) const
-{
-	size = get_stack_size_reserve_64();
-}
-
-//Realigns file (changes file alignment)
-void pe_base::realign_file(uint32_t new_file_alignment)
-{
-	//Checks alignment for correctness
-	set_file_alignment(new_file_alignment);
-	realign_all_sections();
-}
-
-//Helper function to recalculate RAW and virtual section sizes and strip it, if necessary
-void pe_base::recalculate_section_sizes(section& s, bool auto_strip)
-{
-	prepare_section(s); //Recalculate section raw addresses
-
-	//Strip RAW size of section, if it is the last one
-	//For all others it must be file-aligned and calculated by prepare_section() call
-	if(auto_strip && !(sections_.empty() || &s == &*(sections_.end() - 1)))
-	{
-		//Strip ending raw data nullbytes to optimize size
-		std::string& raw_data = s.get_raw_data();
-		if(!raw_data.empty())
-		{
-			std::string::size_type i = raw_data.length();
-			for(; i != 1; --i)
-			{
-				if(raw_data[i - 1] != 0)
-					break;
-			}
-			
-			raw_data.resize(i);
-		}
-
-		s.set_size_of_raw_data(static_cast<uint32_t>(raw_data.length()));
-	}
-
-	//Can occur only for last section
-	if(pe_utils::align_up(s.get_virtual_size(), get_section_alignment()) < pe_utils::align_up(s.get_size_of_raw_data(), get_file_alignment()))
-		set_section_virtual_size(s, pe_utils::align_up(s.get_size_of_raw_data(), get_section_alignment())); //Recalculate section virtual size
-}
-
-//Returns data from the beginning of image
-//Size = SizeOfHeaders
-const std::string& pe_base::get_full_headers_data() const
-{
-	return full_headers_data_;
-}
-
-const pe_base::debug_data_list& pe_base::get_raw_debug_data_list() const
-{
-	return debug_data_;
-}
-
-//Sets number of sections
-void pe_base::set_number_of_sections(uint16_t number)
-{
-	props_->set_number_of_sections(number);
-}
-
-//Sets size of image
-void pe_base::set_size_of_image(uint32_t size)
-{
-	props_->set_size_of_image(size);
-}
-
-//Sets size of headers
-void pe_base::set_size_of_headers(uint32_t size)
-{
-	props_->set_size_of_headers(size);
-}
-
-//Sets size of optional headers
-void pe_base::set_size_of_optional_header(uint16_t size)
-{
-	props_->set_size_of_optional_header(size);
-}
-
-//Returns nt headers data pointer
-char* pe_base::get_nt_headers_ptr()
-{
-	return props_->get_nt_headers_ptr();
-}
-
-//Returns nt headers data pointer
-const char* pe_base::get_nt_headers_ptr() const
-{
-	return props_->get_nt_headers_ptr();
-}
-
-//Returns sizeof() nt headers
-uint32_t pe_base::get_sizeof_nt_header() const
-{
-	return props_->get_sizeof_nt_header();
-}
-
-//Returns sizeof() optional headers
-uint32_t pe_base::get_sizeof_opt_headers() const
-{
-	return props_->get_sizeof_opt_headers();
-}
-
-//Sets file alignment (no checks)
-void pe_base::set_file_alignment_unchecked(uint32_t alignment)
-{
-	props_->set_file_alignment_unchecked(alignment);
-}
-
-//Sets base of code
-void pe_base::set_base_of_code(uint32_t base)
-{
-	props_->set_base_of_code(base);
-}
-
-//Returns base of code
-uint32_t pe_base::get_base_of_code() const
-{
-	return props_->get_base_of_code();
-}
-
-//Returns needed magic of image
-uint32_t pe_base::get_needed_magic() const
-{
-	return props_->get_needed_magic();
-}
-}

+ 0 - 544
tools/pe_bliss/pe_base.h

@@ -1,544 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include <istream>
-#include <ostream>
-#include <map>
-#include "pe_exception.h"
-#include "pe_structures.h"
-#include "utils.h"
-#include "pe_section.h"
-#include "pe_properties.h"
-
-//Please don't remove this information from header
-//PEBliss 1.0.0
-//(c) DX 2011 - 2012, http://kaimi.ru
-//Free to use for commertial and non-commertial purposes, modification and distribution
-
-// == more important ==
-//TODO: compact import rebuilder
-//TODO: remove sections in the middle
-//== less important ==
-//TODO: relocations that take more than one element (seems to be not possible in Windows PE, but anyway)
-//TODO: delay import directory
-//TODO: write message tables
-//TODO: write string tables
-//TODO: read security information
-//TODO: read full .NET information
-
-namespace pe_bliss
-{
-//Portable executable class
-class pe_base
-{
-public: //CONSTRUCTORS
-	//Constructor from stream
-	pe_base(std::istream& file, const pe_properties& props, bool read_debug_raw_data = true);
-
-	//Constructor of empty PE-file
-	explicit pe_base(const pe_properties& props, uint32_t section_alignment = 0x1000, bool dll = false, uint16_t subsystem = pe_win::image_subsystem_windows_gui);
-
-	pe_base(const pe_base& pe);
-	pe_base& operator=(const pe_base& pe);
-
-public:
-	~pe_base();
-
-public: //STUB
-	//Strips stub MSVS overlay, if any
-	void strip_stub_overlay();
-	//Fills stub MSVS overlay with specified byte
-	void fill_stub_overlay(char c);
-	//Sets stub MSVS overlay
-	void set_stub_overlay(const std::string& data);
-	//Returns stub overlay contents
-	const std::string& get_stub_overlay() const;
-
-
-public: //DIRECTORIES
-	//Returns true if directory exists
-	bool directory_exists(uint32_t id) const;
-	//Removes directory
-	void remove_directory(uint32_t id);
-
-	//Returns directory RVA
-	uint32_t get_directory_rva(uint32_t id) const;
-	//Returns directory size
-	uint32_t get_directory_size(uint32_t id) const;
-
-	//Sets directory RVA (just a value of PE header, no moving occurs)
-	void set_directory_rva(uint32_t id, uint32_t rva);
-	//Sets directory size (just a value of PE header, no moving occurs)
-	void set_directory_size(uint32_t id, uint32_t size);
-
-	//Strips only zero DATA_DIRECTORY entries to count = min_count
-	//Returns resulting number of data directories
-	//strip_iat_directory - if true, even not empty IAT directory will be stripped
-	uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
-
-	//Returns true if image has import directory
-	bool has_imports() const;
-	//Returns true if image has export directory
-	bool has_exports() const;
-	//Returns true if image has resource directory
-	bool has_resources() const;
-	//Returns true if image has security directory
-	bool has_security() const;
-	//Returns true if image has relocations
-	bool has_reloc() const;
-	//Returns true if image has TLS directory
-	bool has_tls() const;
-	//Returns true if image has config directory
-	bool has_config() const;
-	//Returns true if image has bound import directory
-	bool has_bound_import() const;
-	//Returns true if image has delay import directory
-	bool has_delay_import() const;
-	//Returns true if image has COM directory
-	bool is_dotnet() const;
-	//Returns true if image has exception directory
-	bool has_exception_directory() const;
-	//Returns true if image has debug directory
-	bool has_debug() const;
-
-	//Returns subsystem value
-	uint16_t get_subsystem() const;
-	//Sets subsystem value
-	void set_subsystem(uint16_t subsystem);
-	//Returns true if image has console subsystem
-	bool is_console() const;
-	//Returns true if image has Windows GUI subsystem
-	bool is_gui() const;
-
-	//Sets required operation system version
-	void set_os_version(uint16_t major, uint16_t minor);
-	//Returns required operation system version (minor word)
-	uint16_t get_minor_os_version() const;
-	//Returns required operation system version (major word)
-	uint16_t get_major_os_version() const;
-
-	//Sets required subsystem version
-	void set_subsystem_version(uint16_t major, uint16_t minor);
-	//Returns required subsystem version (minor word)
-	uint16_t get_minor_subsystem_version() const;
-	//Returns required subsystem version (major word)
-	uint16_t get_major_subsystem_version() const;
-
-public: //PE HEADER
-	//Returns DOS header
-	const pe_win::image_dos_header& get_dos_header() const;
-	pe_win::image_dos_header& get_dos_header();
-
-	//Returns PE header start (e_lfanew)
-	int32_t get_pe_header_start() const;
-
-	//Returns file alignment
-	uint32_t get_file_alignment() const;
-	//Sets file alignment, checking the correctness of its value
-	void set_file_alignment(uint32_t alignment);
-
-	//Returns size of image
-	uint32_t get_size_of_image() const;
-
-	//Returns image entry point
-	uint32_t get_ep() const;
-	//Sets image entry point (just a value of PE header)
-	void set_ep(uint32_t new_ep);
-
-	//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-	uint32_t get_number_of_rvas_and_sizes() const;
-	//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-	void set_number_of_rvas_and_sizes(uint32_t number);
-
-	//Returns PE characteristics
-	uint16_t get_characteristics() const;
-	//Sets PE characteristics (a value inside header)
-	void set_characteristics(uint16_t ch);
-	//Clears PE characteristics flag
-	void clear_characteristics_flags(uint16_t flags);
-	//Sets PE characteristics flag
-	void set_characteristics_flags(uint16_t flags);
-	//Returns true if PE characteristics flag set
-	bool check_characteristics_flag(uint16_t flag) const;
-	
-	//Returns DLL Characteristics
-	uint16_t get_dll_characteristics() const;
-	//Sets DLL Characteristics
-	void set_dll_characteristics(uint16_t characteristics);
-
-	//Returns size of headers
-	uint32_t get_size_of_headers() const;
-	//Returns size of optional header
-	uint16_t get_size_of_optional_header() const;
-
-	//Returns PE signature
-	uint32_t get_pe_signature() const;
-
-	//Returns magic value
-	uint32_t get_magic() const;
-
-	//Returns image base for PE32 and PE64 respectively
-	uint32_t get_image_base_32() const;
-	void get_image_base(uint32_t& base) const;
-	//Sets image base for PE32 and PE64 respectively
-	uint64_t get_image_base_64() const;
-	void get_image_base(uint64_t& base) const;
-
-	//Sets new image base
-	void set_image_base(uint32_t base);
-	void set_image_base_64(uint64_t base);
-
-	//Sets heap size commit for PE32 and PE64 respectively
-	void set_heap_size_commit(uint32_t size);
-	void set_heap_size_commit(uint64_t size);
-	//Sets heap size reserve for PE32 and PE64 respectively
-	void set_heap_size_reserve(uint32_t size);
-	void set_heap_size_reserve(uint64_t size);
-	//Sets stack size commit for PE32 and PE64 respectively
-	void set_stack_size_commit(uint32_t size);
-	void set_stack_size_commit(uint64_t size);
-	//Sets stack size reserve for PE32 and PE64 respectively
-	void set_stack_size_reserve(uint32_t size);
-	void set_stack_size_reserve(uint64_t size);
-
-	//Returns heap size commit for PE32 and PE64 respectively
-	uint32_t get_heap_size_commit_32() const;
-	void get_heap_size_commit(uint32_t& size) const;
-	uint64_t get_heap_size_commit_64() const;
-	void get_heap_size_commit(uint64_t& size) const;
-	//Returns heap size reserve for PE32 and PE64 respectively
-	uint32_t get_heap_size_reserve_32() const;
-	void get_heap_size_reserve(uint32_t& size) const;
-	uint64_t get_heap_size_reserve_64() const;
-	void get_heap_size_reserve(uint64_t& size) const;
-	//Returns stack size commit for PE32 and PE64 respectively
-	uint32_t get_stack_size_commit_32() const;
-	void get_stack_size_commit(uint32_t& size) const;
-	uint64_t get_stack_size_commit_64() const;
-	void get_stack_size_commit(uint64_t& size) const;
-	//Returns stack size reserve for PE32 and PE64 respectively
-	uint32_t get_stack_size_reserve_32() const;
-	void get_stack_size_reserve(uint32_t& size) const;
-	uint64_t get_stack_size_reserve_64() const;
-	void get_stack_size_reserve(uint64_t& size) const;
-
-	//Updates virtual size of image corresponding to section virtual sizes
-	void update_image_size();
-
-	//Returns checksum of PE file from header
-	uint32_t get_checksum() const;
-	//Sets checksum of PE file
-	void set_checksum(uint32_t checksum);
-	
-	//Returns timestamp of PE file from header
-	uint32_t get_time_date_stamp() const;
-	//Sets timestamp of PE file
-	void set_time_date_stamp(uint32_t timestamp);
-	
-	//Returns Machine field value of PE file from header
-	uint16_t get_machine() const;
-	//Sets Machine field value of PE file
-	void set_machine(uint16_t machine);
-
-	//Returns data from the beginning of image
-	//Size = SizeOfHeaders
-	const std::string& get_full_headers_data() const;
-	
-	typedef std::multimap<uint32_t, std::string> debug_data_list;
-	//Returns raw list of debug data
-	const debug_data_list& get_raw_debug_data_list() const;
-	
-	//Reads and checks DOS header
-	static void read_dos_header(std::istream& file, pe_win::image_dos_header& header);
-	
-	//Returns sizeof() nt headers
-	uint32_t get_sizeof_nt_header() const;
-	//Returns sizeof() optional headers
-	uint32_t get_sizeof_opt_headers() const;
-	//Returns raw nt headers data pointer
-	const char* get_nt_headers_ptr() const;
-	
-	//Sets size of headers (to NT headers)
-	void set_size_of_headers(uint32_t size);
-	//Sets size of optional headers (to NT headers)
-	void set_size_of_optional_header(uint16_t size);
-	
-	//Sets base of code
-	void set_base_of_code(uint32_t base);
-	//Returns base of code
-	uint32_t get_base_of_code() const;
-
-public: //ADDRESS CONVERTIONS
-	//Virtual Address (VA) to Relative Virtual Address (RVA) convertions
-	//for PE32 and PE64 respectively
-	//bound_check checks integer overflow
-	uint32_t va_to_rva(uint32_t va, bool bound_check = true) const;
-	uint32_t va_to_rva(uint64_t va, bool bound_check = true) const;
-
-	//Relative Virtual Address (RVA) to Virtual Address (VA) convertions
-	//for PE32 and PE64 respectively
-	uint32_t rva_to_va_32(uint32_t rva) const;
-	void rva_to_va(uint32_t rva, uint32_t& va) const;
-	uint64_t rva_to_va_64(uint32_t rva) const;
-	void rva_to_va(uint32_t rva, uint64_t& va) const;
-
-	//RVA to RAW file offset convertion (4gb max)
-	uint32_t rva_to_file_offset(uint32_t rva) const;
-	//RAW file offset to RVA convertion (4gb max)
-	uint32_t file_offset_to_rva(uint32_t offset) const;
-
-	//RVA from section raw data offset
-	static uint32_t rva_from_section_offset(const section& s, uint32_t raw_offset_from_section_start);
-
-public: //IMAGE SECTIONS
-	//Returns number of sections from PE header
-	uint16_t get_number_of_sections() const;
-
-	//Updates number of sections in PE header
-	uint16_t update_number_of_sections();
-
-	//Returns section alignment
-	uint32_t get_section_alignment() const;
-
-	//Returns section list
-	section_list& get_image_sections();
-	const section_list& get_image_sections() const;
-
-	//Realigns all sections, if you made any changes to sections or alignments
-	void realign_all_sections();
-	//Resligns section with specified index
-	void realign_section(uint32_t index);
-
-	//Returns section from RVA inside it
-	section& section_from_rva(uint32_t rva);
-	const section& section_from_rva(uint32_t rva) const;
-	//Returns section from directory ID
-	section& section_from_directory(uint32_t directory_id);
-	const section& section_from_directory(uint32_t directory_id) const;
-	//Returns section from VA inside it for PE32 and PE64 respectively
-	section& section_from_va(uint32_t va);
-	const section& section_from_va(uint32_t va) const;
-	section& section_from_va(uint64_t va);
-	const section& section_from_va(uint64_t va) const;
-	//Returns section from file offset (4gb max)
-	section& section_from_file_offset(uint32_t offset);
-	const section& section_from_file_offset(uint32_t offset) const;
-
-	//Returns section TOTAL RAW/VIRTUAL data length from RVA inside section
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	uint32_t section_data_length_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	//Returns section TOTAL RAW/VIRTUAL data length from VA inside section for PE32 and PE64 respectively
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	uint32_t section_data_length_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	uint32_t section_data_length_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
-	//Returns section remaining RAW/VIRTUAL data length from RVA to the end of section "s" (checks bounds)
-	uint32_t section_data_length_from_rva(const section& s, uint32_t rva_inside, section_data_type datatype = section_data_raw) const;
-	//Returns section remaining RAW/VIRTUAL data length from VA to the end of section "s" for PE32 and PE64 respectively (checks bounds)
-	uint32_t section_data_length_from_va(const section& s, uint64_t va_inside, section_data_type datatype = section_data_raw) const;
-	uint32_t section_data_length_from_va(const section& s, uint32_t va_inside, section_data_type datatype = section_data_raw) const;
-
-	//Returns section remaining RAW/VIRTUAL data length from RVA "rva_inside" to the end of section containing RVA "rva"
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	uint32_t section_data_length_from_rva(uint32_t rva, uint32_t rva_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	//Returns section remaining RAW/VIRTUAL data length from VA "va_inside" to the end of section containing VA "va" for PE32 and PE64 respectively
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	uint32_t section_data_length_from_va(uint32_t va, uint32_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	uint32_t section_data_length_from_va(uint64_t va, uint64_t va_inside, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	//Returns corresponding section data pointer from RVA inside section
-	char* section_data_from_rva(uint32_t rva, bool include_headers = false);
-	const char* section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	//Returns corresponding section data pointer from VA inside section for PE32 and PE64 respectively
-	char* section_data_from_va(uint32_t va, bool include_headers = false);
-	const char* section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-	char* section_data_from_va(uint64_t va, bool include_headers = false);
-	const char* section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const;
-
-	//Returns corresponding section data pointer from RVA inside section "s" (checks bounds)
-	char* section_data_from_rva(section& s, uint32_t rva);
-	const char* section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const;
-	//Returns corresponding section data pointer from VA inside section "s" for PE32 and PE64 respectively (checks bounds)
-	char* section_data_from_va(section& s, uint32_t va); //Always returns raw data
-	const char* section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const;
-	char* section_data_from_va(section& s, uint64_t va); //Always returns raw data
-	const char* section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const;
-
-	//Returns corresponding section data pointer from RVA inside section "s" (checks bounds, checks sizes, the most safe function)
-	template<typename T>
-	T section_data_from_rva(const section& s, uint32_t rva, section_data_type datatype = section_data_raw) const
-	{
-		if(rva >= s.get_virtual_address() && rva < s.get_virtual_address() + s.get_aligned_virtual_size(get_section_alignment()) && pe_utils::is_sum_safe(rva, sizeof(T)))
-		{
-			const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment());
-			//Don't check for underflow here, comparsion is unsigned
-			if(data.size() < rva - s.get_virtual_address() + sizeof(T))
-				throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists);
-
-			return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address());
-		}
-
-		throw pe_exception("RVA not found inside section", pe_exception::rva_not_exists);
-	}
-
-	//Returns corresponding section data pointer from RVA inside section (checks rva, checks sizes, the most safe function)
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	template<typename T>
-	T section_data_from_rva(uint32_t rva, section_data_type datatype = section_data_raw, bool include_headers = false) const
-	{
-		//if RVA is inside of headers and we're searching them too...
-		if(include_headers && pe_utils::is_sum_safe(rva, sizeof(T)) && (rva + sizeof(T) < full_headers_data_.length()))
-			return *reinterpret_cast<const T*>(&full_headers_data_[rva]);
-
-		const section& s = section_from_rva(rva);
-		const std::string& data = datatype == section_data_raw ? s.get_raw_data() : s.get_virtual_data(get_section_alignment());
-		//Don't check for underflow here, comparsion is unsigned
-		if(data.size() < rva - s.get_virtual_address() + sizeof(T))
-			throw pe_exception("RVA and requested data size does not exist inside section", pe_exception::rva_not_exists);
-
-		return *reinterpret_cast<const T*>(data.data() + rva - s.get_virtual_address());
-	}
-
-	//Returns corresponding section data pointer from VA inside section "s" (checks bounds, checks sizes, the most safe function)
-	template<typename T>
-	T section_data_from_va(const section& s, uint32_t va, section_data_type datatype = section_data_raw) const
-	{
-		return section_data_from_rva<T>(s, va_to_rva(va), datatype);
-	}
-
-	template<typename T>
-	T section_data_from_va(const section& s, uint64_t va, section_data_type datatype = section_data_raw) const
-	{
-		return section_data_from_rva<T>(s, va_to_rva(va), datatype);
-	}
-
-	//Returns corresponding section data pointer from VA inside section (checks rva, checks sizes, the most safe function)
-	//If include_headers = true, data from the beginning of PE file to SizeOfHeaders will be searched, too
-	template<typename T>
-	T section_data_from_va(uint32_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const
-	{
-		return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers);
-	}
-
-	template<typename T>
-	T section_data_from_va(uint64_t va, section_data_type datatype = section_data_raw, bool include_headers = false) const
-	{
-		return section_data_from_rva<T>(va_to_rva(va), datatype, include_headers);
-	}
-
-	//Returns section and offset (raw data only) from its start from RVA
-	const std::pair<uint32_t, const section*> section_and_offset_from_rva(uint32_t rva) const;
-
-	//Sets virtual size of section "s"
-	//Section must be free (not bound to any image)
-	//or the last section of this image
-	//Function calls update_image_size automatically in second case
-	void set_section_virtual_size(section& s, uint32_t vsize);
-
-	//Represents section expand type for expand_section function
-	enum section_expand_type
-	{
-		expand_section_raw, //Section raw data size will be expanded
-		expand_section_virtual //Section virtual data size will be expanded
-	};
-
-	//Expands section raw or virtual size to hold data from specified RVA with specified size
-	//Section must be free (not bound to any image)
-	//or the last section of this image
-	//Returns true if section was expanded
-	bool expand_section(section& s, uint32_t needed_rva, uint32_t needed_size, section_expand_type expand);
-
-	//Adds section to image
-	//Returns last section
-	section& add_section(section s);
-	//Prepares section to later add it to image (checks and recalculates virtual and raw section size)
-	//Section must be prepared by this function before calling add_section
-	void prepare_section(section& s);
-
-	//Returns true if sectios "s" is already attached to this PE file
-	bool section_attached(const section& s) const;
-
-
-public: //IMAGE
-	//Returns PE type (PE or PE+) from pe_type enumeration (minimal correctness checks)
-	static pe_type get_pe_type(std::istream& file);
-	//Returns PE type of this image
-	pe_type get_pe_type() const;
-
-	//Returns true if image has overlay data at the end of file
-	bool has_overlay() const;
-
-	//Realigns file (changes file alignment)
-	void realign_file(uint32_t new_file_alignment);
-	
-	//Helper function to recalculate RAW and virtual section sizes and strip it, if necessary
-	//auto_strip = strip section, if necessary
-	void recalculate_section_sizes(section& s, bool auto_strip);
-
-	// ========== END OF PUBLIC MEMBERS AND STRUCTURES ========== //
-private:
-	//Image DOS header
-	pe_win::image_dos_header dos_header_;
-	//Rich (stub) overlay data (for MSVS)
-	std::string rich_overlay_;
-	//List of image sections
-	section_list sections_;
-	//True if image has overlay
-	bool has_overlay_;
-	//Raw SizeOfHeaders-sized data from the beginning of image
-	std::string full_headers_data_;
-	//Raw debug data for all directories
-	//PointerToRawData; Data
-	debug_data_list debug_data_;
-	//PE or PE+ related properties
-	pe_properties* props_;
-
-	//Reads and checks DOS header
-	void read_dos_header(std::istream& file);
-
-	//Reads and checks PE headers and section headers, data
-	void read_pe(std::istream& file, bool read_debug_raw_data);
-
-	//Sets number of sections
-	void set_number_of_sections(uint16_t number);
-	//Sets size of image
-	void set_size_of_image(uint32_t size);
-	//Sets file alignment (no checks)
-	void set_file_alignment_unchecked(uint32_t alignment);
-	//Returns needed magic of image
-	uint32_t get_needed_magic() const;
-	//Returns nt headers data pointer
-	char* get_nt_headers_ptr();
-
-private:
-	static const uint16_t maximum_number_of_sections = 0x60;
-	static const uint32_t minimum_file_alignment = 512;
-
-private:
-	//RAW file offset to section convertion helpers (4gb max)
-	section_list::const_iterator file_offset_to_section(uint32_t offset) const;
-	section_list::iterator file_offset_to_section(uint32_t offset);
-};
-}

+ 0 - 39
tools/pe_bliss/pe_bliss.h

@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "pe_base.h"
-#include "pe_rebuilder.h"
-#include "pe_factory.h"
-#include "pe_bound_import.h"
-#include "pe_debug.h"
-#include "pe_dotnet.h"
-#include "pe_exception_directory.h"
-#include "pe_exports.h"
-#include "pe_imports.h"
-#include "pe_load_config.h"
-#include "pe_relocations.h"
-#include "pe_resources.h"
-#include "pe_rich_data.h"
-#include "pe_tls.h"
-#include "pe_properties_generic.h"
-#include "pe_checksum.h"
-#include "entropy.h"

+ 0 - 118
tools/pe_bliss/pe_bliss_godot.cpp

@@ -1,118 +0,0 @@
-#include "pe_bliss/pe_bliss.h"
-#include "pe_bliss/pe_bliss_resources.h"
-#include "core/ustring.h"
-#include "core/dvector.h"
-#include "os/file_access.h"
-
-using namespace pe_bliss;
-
-String pe_bliss_add_resrc(const char* p_path, int version_major, int version_minor,
-												String& company_name, String& file_description,
-												String& legal_copyright, String& version_text, 
-												String& product_name, String& godot_version,
-												DVector<uint8_t>& icon_content) {
-	try
-	{
-		pe_base image(pe_factory::create_pe(p_path));
-		
-		const section_list& pe_sections = image.get_image_sections();
-		uint32_t end_of_pe = 0;
-		FileAccess *dst;
-		DVector<uint8_t> overlay_data;
-		if(image.has_overlay())
-		{
-			end_of_pe = pe_sections.back().get_pointer_to_raw_data() + pe_sections.back().get_size_of_raw_data();
-			dst=FileAccess::open(p_path,FileAccess::READ);
-			if (dst) {
-				overlay_data.resize(dst->get_len()-end_of_pe);
-				dst->seek(end_of_pe);
-				DVector<uint8_t>::Write overlay_data_write = overlay_data.write();
-				dst->get_buffer(overlay_data_write.ptr(),overlay_data.size());
-				dst->close();
-				memdelete(dst);
-			}
-		}
-		resource_directory root;
-		if(image.has_resources())
-		{
-			root = resource_directory(get_resources(image));
-		}
-		pe_resource_manager res(root);
-		if(image.has_resources())
-		{
-			if(icon_content.size()) {
-				if(res.resource_exists(pe_resource_viewer::resource_icon))
-				{
-					res.remove_resource_type(pe_resource_viewer::resource_icon);
-				}
-				if(res.resource_exists(pe_resource_viewer::resource_icon_group))
-				{
-					res.remove_resource_type(pe_resource_viewer::resource_icon_group);
-				}
-			}
-			if(res.resource_exists(pe_resource_viewer::resource_version))
-			{
-				res.remove_resource_type(pe_resource_viewer::resource_version);
-			}
-		}
-		file_version_info file_info;
-		file_info.set_file_os(file_version_info::file_os_nt_win32);
-		file_info.set_file_type(file_version_info::file_type_application);
-		unsigned int ver = version_major << 16;
-		ver = ver + version_minor;
-		file_info.set_file_version_ms(ver);
-		file_info.set_file_version_ls(0x00000000);
-		file_info.set_product_version_ms(ver);
-		file_info.set_product_version_ls(0x00000000);
-		lang_string_values_map strings;
-		translation_values_map translations;
-		version_info_editor version(strings, translations);
-		version.add_translation(version_info_editor::default_language_translation);
-		version.set_company_name(company_name.c_str());
-		version.set_file_description(file_description.c_str());
-		if (!product_name.empty()) {
-			version.set_internal_name((product_name+String(".exe")).c_str());
-			version.set_original_filename((product_name+String(".exe")).c_str());
-			version.set_product_name(product_name.c_str());
-		}
-		version.set_legal_copyright(legal_copyright.c_str());
-		version.set_product_version(version_text.c_str());
-		if(!godot_version.empty()) version.set_property(L"Godot Engine Version", godot_version.c_str() );
-		resource_version_info_writer(res).set_version_info(file_info, strings, translations, 1033, 1200);
-		if(icon_content.size()) {
-			std::string icon;
-			icon.resize(icon_content.size());
-			for(int i=0; i<icon_content.size(); i++)
-			{
-				icon[i] = icon_content[i];
-			}
-			resource_cursor_icon_writer(res).add_icon(icon, L"MAIN_ICON", 1033);
-		}
-		if(image.has_resources())
-		{
-			rebuild_resources(image, root, image.section_from_directory(pe_win::image_directory_entry_resource));
-		} else {
-			section new_resources;
-			new_resources.get_raw_data().resize(1);
-			new_resources.set_name(".rsrc");
-			new_resources.readable(true);
-			section& attached_section = image.add_section(new_resources);
-			rebuild_resources(image, root, attached_section);
-		}
-		rebuild_pe(image, p_path);
-		if(image.has_overlay() && end_of_pe) {
-			dst=FileAccess::open(p_path,FileAccess::READ_WRITE);
-			if (dst) {
-				dst->seek_end();
-				DVector<uint8_t>::Read overlay_data_read = overlay_data.read();
-				dst->store_buffer(overlay_data_read.ptr(),overlay_data.size());
-				dst->close();
-				memdelete(dst);
-			}
-		}
-		return String();
-	} catch(const pe_exception& e) {
-		String ret("Error In Add rsrc Section : ");
-		return ret + String(e.what());
-	}
-}

+ 0 - 7
tools/pe_bliss/pe_bliss_godot.h

@@ -1,7 +0,0 @@
-
-
-String pe_bliss_add_resrc(const char* p_path, int version_major, int version_minor,
-												String& company_name, String& file_description,
-												String& legal_copyright, String& version_text, 
-												String& product_name, String& godot_version,
-												DVector<uint8_t>& icon_content);

+ 0 - 36
tools/pe_bliss/pe_bliss_resources.h

@@ -1,36 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "file_version_info.h"
-#include "message_table.h"
-#include "pe_resource_manager.h"
-#include "pe_resource_viewer.h"
-#include "version_info_editor.h"
-#include "version_info_viewer.h"
-#include "resource_bitmap_reader.h"
-#include "resource_bitmap_writer.h"
-#include "resource_cursor_icon_reader.h"
-#include "resource_cursor_icon_writer.h"
-#include "resource_version_info_reader.h"
-#include "resource_version_info_writer.h"
-#include "resource_string_table_reader.h"
-#include "resource_message_list_reader.h"

+ 0 - 311
tools/pe_bliss/pe_bound_import.cpp

@@ -1,311 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_bound_import.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//BOUND IMPORT
-//Default constructor
-bound_import_ref::bound_import_ref()
-	:timestamp_(0)
-{}
-
-//Constructor from data
-bound_import_ref::bound_import_ref(const std::string& module_name, uint32_t timestamp)
-	:module_name_(module_name), timestamp_(timestamp)
-{}
-
-//Returns imported module name
-const std::string& bound_import_ref::get_module_name() const
-{
-	return module_name_;
-}
-
-//Returns bound import date and time stamp
-uint32_t bound_import_ref::get_timestamp() const
-{
-	return timestamp_;
-}
-
-//Sets module name
-void bound_import_ref::set_module_name(const std::string& module_name)
-{
-	module_name_ = module_name;
-}
-
-//Sets timestamp
-void bound_import_ref::set_timestamp(uint32_t timestamp)
-{
-	timestamp_ = timestamp;
-}
-
-//Default constructor
-bound_import::bound_import()
-	:timestamp_(0)
-{}
-
-//Constructor from data
-bound_import::bound_import(const std::string& module_name, uint32_t timestamp)
-	:module_name_(module_name), timestamp_(timestamp)
-{}
-
-//Returns imported module name
-const std::string& bound_import::get_module_name() const
-{
-	return module_name_;
-}
-
-//Returns bound import date and time stamp
-uint32_t bound_import::get_timestamp() const
-{
-	return timestamp_;
-}
-
-//Returns bound references cound
-size_t bound_import::get_module_ref_count() const
-{
-	return refs_.size();
-}
-
-//Returns module references
-const bound_import::ref_list& bound_import::get_module_ref_list() const
-{
-	return refs_;
-}
-
-//Adds module reference
-void bound_import::add_module_ref(const bound_import_ref& ref)
-{
-	refs_.push_back(ref);
-}
-
-//Clears module references list
-void bound_import::clear_module_refs()
-{
-	refs_.clear();
-}
-
-//Returns module references
-bound_import::ref_list& bound_import::get_module_ref_list()
-{
-	return refs_;
-}
-
-//Sets module name
-void bound_import::set_module_name(const std::string& module_name)
-{
-	module_name_ = module_name;
-}
-
-//Sets timestamp
-void bound_import::set_timestamp(uint32_t timestamp)
-{
-	timestamp_ = timestamp;
-}
-
-const bound_import_module_list get_bound_import_module_list(const pe_base& pe)
-{
-	//Returned bound import modules list
-	bound_import_module_list ret;
-
-	//If image has no bound imports
-	if(!pe.has_bound_import())
-		return ret;
-
-	uint32_t bound_import_data_len =
-		pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true);
-
-	if(bound_import_data_len < pe.get_directory_size(image_directory_entry_bound_import))
-		throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-	
-	const char* bound_import_data = pe.section_data_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true);
-
-	//Check read in "read_pe" function raw bound import data size
-	if(bound_import_data_len < sizeof(image_bound_import_descriptor))
-		throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-	//current bound_import_data_ in-string position
-	unsigned long current_pos = 0;
-	//first bound import descriptor
-	//so, we're working with raw data here, no section helpers available
-	const image_bound_import_descriptor* descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]);
-
-	//Enumerate until zero
-	while(descriptor->OffsetModuleName)
-	{
-		//Check module name offset
-		if(descriptor->OffsetModuleName >= bound_import_data_len)
-			throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-		//Check module name for null-termination
-		if(!pe_utils::is_null_terminated(&bound_import_data[descriptor->OffsetModuleName], bound_import_data_len - descriptor->OffsetModuleName))
-			throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-		//Create bound import descriptor structure
-		bound_import elem(&bound_import_data[descriptor->OffsetModuleName], descriptor->TimeDateStamp);
-
-		//Check DWORDs
-		if(descriptor->NumberOfModuleForwarderRefs >= pe_utils::max_dword / sizeof(image_bound_forwarder_ref)
-			|| !pe_utils::is_sum_safe(current_pos, 2 /* this descriptor and the next one */ * sizeof(image_bound_import_descriptor) + descriptor->NumberOfModuleForwarderRefs * sizeof(image_bound_forwarder_ref)))
-			throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-		//Move after current descriptor
-		current_pos += sizeof(image_bound_import_descriptor);
-
-		//Enumerate referenced bound import descriptors
-		for(unsigned long i = 0; i != descriptor->NumberOfModuleForwarderRefs; ++i)
-		{
-			//They're just after parent descriptor
-			//Check size of structure
-			if(current_pos + sizeof(image_bound_forwarder_ref) > bound_import_data_len)
-				throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-			//Get IMAGE_BOUND_FORWARDER_REF pointer
-			const image_bound_forwarder_ref* ref_descriptor = reinterpret_cast<const image_bound_forwarder_ref*>(&bound_import_data[current_pos]);
-
-			//Check referenced module name
-			if(ref_descriptor->OffsetModuleName >= bound_import_data_len)
-				throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-			//And its null-termination
-			if(!pe_utils::is_null_terminated(&bound_import_data[ref_descriptor->OffsetModuleName], bound_import_data_len - ref_descriptor->OffsetModuleName))
-				throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-			//Add referenced module to current bound import structure
-			elem.add_module_ref(bound_import_ref(&bound_import_data[ref_descriptor->OffsetModuleName], ref_descriptor->TimeDateStamp));
-
-			//Move after referenced bound import descriptor
-			current_pos += sizeof(image_bound_forwarder_ref);
-		}
-
-		//Check structure size
-		if(current_pos + sizeof(image_bound_import_descriptor) > bound_import_data_len)
-			throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-
-		//Move to next bound import descriptor
-		descriptor = reinterpret_cast<const image_bound_import_descriptor*>(&bound_import_data[current_pos]);
-
-		//Save created descriptor structure and references
-		ret.push_back(elem);
-	}
-
-	//Return result
-	return ret;
-}
-
-//imports - bound imported modules list
-//imports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from imports_section raw data start
-//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
-//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
-const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	//Check that exports_section is attached to this PE image
-	if(!pe.section_attached(imports_section))
-		throw pe_exception("Bound import section must be attached to PE file", pe_exception::section_is_not_attached);
-
-	uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-	uint32_t needed_size = sizeof(image_bound_import_descriptor) /* Ending null descriptor */;
-	uint32_t needed_size_for_strings = 0;
-
-	//Calculate needed size for bound import data
-	for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
-	{
-		const bound_import& import = *it;
-		needed_size += sizeof(image_bound_import_descriptor);
-		needed_size_for_strings += static_cast<uint32_t>((*it).get_module_name().length()) + 1 /* nullbyte */;
-
-		const bound_import::ref_list& refs = import.get_module_ref_list();
-		for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
-		{
-			needed_size_for_strings += static_cast<uint32_t>((*ref_it).get_module_name().length()) + 1 /* nullbyte */;
-			needed_size += sizeof(image_bound_forwarder_ref);
-		}
-	}
-	
-	needed_size += needed_size_for_strings;
-	
-	//Check if imports_section is last one. If it's not, check if there's enough place for bound import data
-	if(&imports_section != &*(pe.get_image_sections().end() - 1) && 
-		(imports_section.empty() || pe_utils::align_up(imports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
-		throw pe_exception("Insufficient space for bound import directory", pe_exception::insufficient_space);
-
-	std::string& raw_data = imports_section.get_raw_data();
-
-	//This will be done only if imports_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + directory_pos)
-		raw_data.resize(needed_size + directory_pos); //Expand section raw data
-	
-	uint32_t current_pos_for_structures = directory_pos;
-	uint32_t current_pos_for_strings = current_pos_for_structures + needed_size - needed_size_for_strings;
-
-	for(bound_import_module_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
-	{
-		const bound_import& import = *it;
-		image_bound_import_descriptor descriptor;
-		descriptor.NumberOfModuleForwarderRefs = static_cast<uint16_t>(import.get_module_ref_list().size());
-		descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
-		descriptor.TimeDateStamp = import.get_timestamp();
-
-		memcpy(&raw_data[current_pos_for_structures], &descriptor, sizeof(descriptor));
-		current_pos_for_structures += sizeof(descriptor);
-		
-		size_t length = import.get_module_name().length() + 1 /* nullbyte */;
-		memcpy(&raw_data[current_pos_for_strings], import.get_module_name().c_str(), length);
-		current_pos_for_strings += static_cast<uint32_t>(length);
-
-		const bound_import::ref_list& refs = import.get_module_ref_list();
-		for(bound_import::ref_list::const_iterator ref_it = refs.begin(); ref_it != refs.end(); ++ref_it)
-		{
-			const bound_import_ref& ref = *ref_it;
-			image_bound_forwarder_ref ref_descriptor = {0};
-			ref_descriptor.OffsetModuleName = static_cast<uint16_t>(current_pos_for_strings - directory_pos);
-			ref_descriptor.TimeDateStamp = ref.get_timestamp();
-
-			memcpy(&raw_data[current_pos_for_structures], &ref_descriptor, sizeof(ref_descriptor));
-			current_pos_for_structures += sizeof(ref_descriptor);
-
-			length = ref.get_module_name().length() + 1 /* nullbyte */;
-			memcpy(&raw_data[current_pos_for_strings], ref.get_module_name().c_str(), length);
-			current_pos_for_strings += static_cast<uint32_t>(length);
-		}
-	}
-
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(imports_section, auto_strip_last_section);
-	
-	image_directory ret(pe.rva_from_section_offset(imports_section, directory_pos), needed_size);
-
-	//If auto-rewrite of PE headers is required
-	if(save_to_pe_header)
-	{
-		pe.set_directory_rva(image_directory_entry_bound_import, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_bound_import, ret.get_size());
-	}
-
-	return ret;
-}
-}

+ 0 - 108
tools/pe_bliss/pe_bound_import.h

@@ -1,108 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing bound import reference
-class bound_import_ref
-{
-public:
-	//Default constructor
-	bound_import_ref();
-	//Constructor from data
-	bound_import_ref(const std::string& module_name, uint32_t timestamp);
-
-	//Returns imported module name
-	const std::string& get_module_name() const;
-	//Returns bound import date and time stamp
-	uint32_t get_timestamp() const;
-
-public: //Setters
-	//Sets module name
-	void set_module_name(const std::string& module_name);
-	//Sets timestamp
-	void set_timestamp(uint32_t timestamp);
-
-private:
-	std::string module_name_; //Imported module name
-	uint32_t timestamp_; //Bound import timestamp
-};
-
-//Class representing image bound import information
-class bound_import
-{
-public:
-	typedef std::vector<bound_import_ref> ref_list;
-
-public:
-	//Default constructor
-	bound_import();
-	//Constructor from data
-	bound_import(const std::string& module_name, uint32_t timestamp);
-
-	//Returns imported module name
-	const std::string& get_module_name() const;
-	//Returns bound import date and time stamp
-	uint32_t get_timestamp() const;
-
-	//Returns bound references cound
-	size_t get_module_ref_count() const;
-	//Returns module references
-	const ref_list& get_module_ref_list() const;
-
-public: //Setters
-	//Sets module name
-	void set_module_name(const std::string& module_name);
-	//Sets timestamp
-	void set_timestamp(uint32_t timestamp);
-
-	//Adds module reference
-	void add_module_ref(const bound_import_ref& ref);
-	//Clears module references list
-	void clear_module_refs();
-	//Returns module references
-	ref_list& get_module_ref_list();
-
-private:
-	std::string module_name_; //Imported module name
-	uint32_t timestamp_; //Bound import timestamp
-	ref_list refs_; //Module references list
-};
-
-typedef std::vector<bound_import> bound_import_module_list;
-
-//Returns bound import information
-const bound_import_module_list get_bound_import_module_list(const pe_base& pe);//Export directory rebuilder
-
-//imports - bound imported modules list
-//imports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from imports_section raw data start
-//save_to_pe_headers - if true, new bound import directory information will be saved to PE image headers
-//auto_strip_last_section - if true and bound imports are placed in the last section, it will be automatically stripped
-const image_directory rebuild_bound_imports(pe_base& pe, const bound_import_module_list& imports, section& imports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}

+ 0 - 103
tools/pe_bliss/pe_checksum.cpp

@@ -1,103 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_checksum.h"
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Calculate checksum of image
-uint32_t calculate_checksum(std::istream& file)
-{
-	//Save istream state
-	std::ios_base::iostate state = file.exceptions();
-	std::streamoff old_offset = file.tellg();
-
-	//Checksum value
-	unsigned long long checksum = 0;
-
-	try
-	{
-		image_dos_header header;
-
-		file.exceptions(std::ios::goodbit);
-
-		//Read DOS header
-		pe_base::read_dos_header(file, header);
-
-		//Calculate PE checksum
-		file.seekg(0);
-		unsigned long long top = 0xFFFFFFFF;
-		top++;
-
-		//"CheckSum" field position in optional PE headers - it's always 64 for PE and PE+
-		static const unsigned long checksum_pos_in_optional_headers = 64;
-		//Calculate real PE headers "CheckSum" field position
-		//Sum is safe here
-		unsigned long pe_checksum_pos = header.e_lfanew + sizeof(image_file_header) + sizeof(uint32_t) + checksum_pos_in_optional_headers;
-
-		//Calculate checksum for each byte of file
-		std::streamoff filesize = pe_utils::get_file_size(file);
-		for(long long i = 0; i < filesize; i += 4)
-		{
-			unsigned long dw = 0;
-
-			//Read DWORD from file
-			file.read(reinterpret_cast<char*>(&dw), sizeof(unsigned long));
-			//Skip "CheckSum" DWORD
-			if(i == pe_checksum_pos)
-				continue;
-
-			//Calculate checksum
-			checksum = (checksum & 0xffffffff) + dw + (checksum >> 32);
-			if(checksum > top)
-				checksum = (checksum & 0xffffffff) + (checksum >> 32);
-		}
-
-		//Finish checksum
-		checksum = (checksum & 0xffff) + (checksum >> 16);
-		checksum = (checksum) + (checksum >> 16);
-		checksum = checksum & 0xffff;
-
-		checksum += static_cast<unsigned long>(filesize);
-	}
-	catch(const std::exception&)
-	{
-		//If something went wrong, restore istream state
-		file.exceptions(state);
-		file.seekg(old_offset);
-		file.clear();
-		//Rethrow
-		throw;
-	}
-
-	//Restore istream state
-	file.exceptions(state);
-	file.seekg(old_offset);
-	file.clear();
-
-	//Return checksum
-	return static_cast<uint32_t>(checksum);	
-}
-}

+ 0 - 30
tools/pe_bliss/pe_checksum.h

@@ -1,30 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Calculate checksum of image (performs no checks on PE structures)
-uint32_t calculate_checksum(std::istream& file);
-}

+ 0 - 865
tools/pe_bliss/pe_debug.cpp

@@ -1,865 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_debug.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-//DEBUG
-//Default constructor
-debug_info::debug_info()
-	:characteristics_(0),
-	time_stamp_(0),
-	major_version_(0), minor_version_(0),
-	type_(0),
-	size_of_data_(0),
-	address_of_raw_data_(0),
-	pointer_to_raw_data_(0),
-	advanced_info_type_(advanced_info_none)
-{}
-
-//Constructor from data
-debug_info::debug_info(const image_debug_directory& debug)
-	:characteristics_(debug.Characteristics),
-	time_stamp_(debug.TimeDateStamp),
-	major_version_(debug.MajorVersion), minor_version_(debug.MinorVersion),
-	type_(debug.Type),
-	size_of_data_(debug.SizeOfData),
-	address_of_raw_data_(debug.AddressOfRawData),
-	pointer_to_raw_data_(debug.PointerToRawData),
-	advanced_info_type_(advanced_info_none)
-{}
-
-//Returns debug characteristics
-uint32_t debug_info::get_characteristics() const
-{
-	return characteristics_;
-}
-
-//Returns debug datetimestamp
-uint32_t debug_info::get_time_stamp() const
-{
-	return time_stamp_;
-}
-
-//Returns major version
-uint32_t debug_info::get_major_version() const
-{
-	return major_version_;
-}
-
-//Returns minor version
-uint32_t debug_info::get_minor_version() const
-{
-	return minor_version_;
-}
-
-//Returns type of debug info (unchecked)
-uint32_t debug_info::get_type_raw() const
-{
-	return type_;
-}
-
-//Returns type of debug info from debug_info_type enumeration
-debug_info::debug_info_type debug_info::get_type() const
-{
-	//Determine debug type
-	switch(type_)
-	{
-	case image_debug_type_coff:
-		return debug_type_coff;
-
-	case image_debug_type_codeview:
-		return debug_type_codeview;
-
-	case image_debug_type_fpo:
-		return debug_type_fpo;
-
-	case image_debug_type_misc:
-		return debug_type_misc;
-
-	case image_debug_type_exception:
-		return debug_type_exception;
-
-	case image_debug_type_fixup:
-		return debug_type_fixup;
-
-	case image_debug_type_omap_to_src:
-		return debug_type_omap_to_src;
-
-	case image_debug_type_omap_from_src:
-		return debug_type_omap_from_src;
-
-	case image_debug_type_borland:
-		return debug_type_borland;
-
-	case image_debug_type_clsid:
-		return debug_type_clsid;
-
-	case image_debug_type_reserved10:
-		return debug_type_reserved10;
-	}
-
-	return debug_type_unknown;
-}
-
-//Returns size of debug data (internal, .pdb or other file doesn't count)
-uint32_t debug_info::get_size_of_data() const
-{
-	return size_of_data_;
-}
-
-//Returns RVA of debug info when mapped to memory or zero, if info is not mapped
-uint32_t debug_info::get_rva_of_raw_data() const
-{
-	return address_of_raw_data_;
-}
-
-//Returns raw file pointer to raw data
-uint32_t debug_info::get_pointer_to_raw_data() const
-{
-	return pointer_to_raw_data_;
-}
-
-//Copy constructor
-debug_info::debug_info(const debug_info& info)
-	:characteristics_(info.characteristics_),
-	time_stamp_(info.time_stamp_),
-	major_version_(info.major_version_), minor_version_(info.minor_version_),
-	type_(info.type_),
-	size_of_data_(info.size_of_data_),
-	address_of_raw_data_(info.address_of_raw_data_),
-	pointer_to_raw_data_(info.pointer_to_raw_data_),
-	advanced_info_type_(info.advanced_info_type_)
-{
-	copy_advanced_info(info);
-}
-
-//Copy assignment operator
-debug_info& debug_info::operator=(const debug_info& info)
-{
-	copy_advanced_info(info);
-
-	characteristics_ = info.characteristics_;
-	time_stamp_ = info.time_stamp_;
-	major_version_ = info.major_version_;
-	minor_version_ = info.minor_version_;
-	type_ = info.type_;
-	size_of_data_ = info.size_of_data_;
-	address_of_raw_data_ = info.address_of_raw_data_;
-	pointer_to_raw_data_ = info.pointer_to_raw_data_;
-	advanced_info_type_ = info.advanced_info_type_;
-
-	return *this;
-}
-
-//Default constructor
-debug_info::advanced_info::advanced_info()
-	:adv_pdb_7_0_info(0) //Zero pointer to advanced data
-{}
-
-//Returns true if advanced debug info is present
-bool debug_info::advanced_info::is_present() const
-{
-	return adv_pdb_7_0_info != 0;
-}
-
-//Helper for advanced debug information copying
-void debug_info::copy_advanced_info(const debug_info& info)
-{
-	free_present_advanced_info();
-
-	switch(info.advanced_info_type_)
-	{
-	case advanced_info_pdb_7_0:
-		advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(*info.advanced_debug_info_.adv_pdb_7_0_info);
-		break;
-	case advanced_info_pdb_2_0:
-		advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(*info.advanced_debug_info_.adv_pdb_2_0_info);
-		break;
-	case advanced_info_misc:
-		advanced_debug_info_.adv_misc_info = new misc_debug_info(*info.advanced_debug_info_.adv_misc_info);
-		break;
-	case advanced_info_coff:
-		advanced_debug_info_.adv_coff_info = new coff_debug_info(*info.advanced_debug_info_.adv_coff_info);
-		break;
-	default:
-		break;
-	}
-
-	advanced_info_type_ = info.advanced_info_type_;
-}
-
-//Helper for clearing any present advanced debug information
-void debug_info::free_present_advanced_info()
-{
-	switch(advanced_info_type_)
-	{
-	case advanced_info_pdb_7_0:
-		delete advanced_debug_info_.adv_pdb_7_0_info;
-		break;
-	case advanced_info_pdb_2_0:
-		delete advanced_debug_info_.adv_pdb_2_0_info;
-		break;
-	case advanced_info_misc:
-		delete advanced_debug_info_.adv_misc_info;
-		break;
-	case advanced_info_coff:
-		delete advanced_debug_info_.adv_coff_info;
-		break;
-	default:
-		break;
-	}
-
-	advanced_debug_info_.adv_pdb_7_0_info = 0;
-	advanced_info_type_ = advanced_info_none;
-}
-
-//Destructor
-debug_info::~debug_info()
-{
-	free_present_advanced_info();
-}
-
-//Sets advanced debug information
-void debug_info::set_advanced_debug_info(const pdb_7_0_info& info)
-{
-	free_present_advanced_info();
-	advanced_debug_info_.adv_pdb_7_0_info = new pdb_7_0_info(info);
-	advanced_info_type_ = advanced_info_pdb_7_0;
-}
-
-void debug_info::set_advanced_debug_info(const pdb_2_0_info& info)
-{
-	free_present_advanced_info();
-	advanced_debug_info_.adv_pdb_2_0_info = new pdb_2_0_info(info);
-	advanced_info_type_ = advanced_info_pdb_2_0;
-}
-
-void debug_info::set_advanced_debug_info(const misc_debug_info& info)
-{
-	free_present_advanced_info();
-	advanced_debug_info_.adv_misc_info = new misc_debug_info(info);
-	advanced_info_type_ = advanced_info_misc;
-}
-
-void debug_info::set_advanced_debug_info(const coff_debug_info& info)
-{
-	free_present_advanced_info();
-	advanced_debug_info_.adv_coff_info = new coff_debug_info(info);
-	advanced_info_type_ = advanced_info_coff;
-}
-
-//Returns advanced debug information type
-debug_info::advanced_info_type debug_info::get_advanced_info_type() const
-{
-	return advanced_info_type_;
-}
-
-//Returns advanced debug information or throws an exception,
-//if requested information type is not contained by structure
-template<>
-const pdb_7_0_info debug_info::get_advanced_debug_info<pdb_7_0_info>() const
-{
-	if(advanced_info_type_ != advanced_info_pdb_7_0)
-		throw pe_exception("Debug info structure does not contain PDB 7.0 data", pe_exception::advanced_debug_information_request_error);
-
-	return *advanced_debug_info_.adv_pdb_7_0_info;
-}
-
-template<>
-const pdb_2_0_info debug_info::get_advanced_debug_info<pdb_2_0_info>() const
-{
-	if(advanced_info_type_ != advanced_info_pdb_2_0)
-		throw pe_exception("Debug info structure does not contain PDB 2.0 data", pe_exception::advanced_debug_information_request_error);
-
-	return *advanced_debug_info_.adv_pdb_2_0_info;
-}
-
-template<>
-const misc_debug_info debug_info::get_advanced_debug_info<misc_debug_info>() const
-{
-	if(advanced_info_type_ != advanced_info_misc)
-		throw pe_exception("Debug info structure does not contain MISC data", pe_exception::advanced_debug_information_request_error);
-
-	return *advanced_debug_info_.adv_misc_info;
-}
-
-template<>
-const coff_debug_info debug_info::get_advanced_debug_info<coff_debug_info>() const
-{
-	if(advanced_info_type_ != advanced_info_coff)
-		throw pe_exception("Debug info structure does not contain COFF data", pe_exception::advanced_debug_information_request_error);
-
-	return *advanced_debug_info_.adv_coff_info;
-}
-
-//Sets advanced debug information type, if no advanced info structure available
-void debug_info::set_advanced_info_type(advanced_info_type type)
-{
-	free_present_advanced_info();
-	if(advanced_info_type_ >= advanced_info_codeview_4_0) //Don't set info type for those types, which have advanced info structures
-		advanced_info_type_ = type;
-}
-
-//Default constructor
-pdb_7_0_info::pdb_7_0_info()
-	:age_(0)
-{
-	memset(&guid_, 0, sizeof(guid_));
-}
-
-//Constructor from data
-pdb_7_0_info::pdb_7_0_info(const CV_INFO_PDB70* info)
-	:age_(info->Age), guid_(info->Signature),
-	pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination
-{}
-
-//Returns debug PDB 7.0 structure GUID
-const guid pdb_7_0_info::get_guid() const
-{
-	return guid_;
-}
-
-//Returns age of build
-uint32_t pdb_7_0_info::get_age() const
-{
-	return age_;
-}
-
-//Returns PDB file name / path
-const std::string& pdb_7_0_info::get_pdb_file_name() const
-{
-	return pdb_file_name_;
-}
-
-//Default constructor
-pdb_2_0_info::pdb_2_0_info()
-	:age_(0), signature_(0)
-{}
-
-//Constructor from data
-pdb_2_0_info::pdb_2_0_info(const CV_INFO_PDB20* info)
-	:age_(info->Age), signature_(info->Signature),
-	pdb_file_name_(reinterpret_cast<const char*>(info->PdbFileName)) //Must be checked before for null-termination
-{}
-
-//Returns debug PDB 2.0 structure signature
-uint32_t pdb_2_0_info::get_signature() const
-{
-	return signature_;
-}
-
-//Returns age of build
-uint32_t pdb_2_0_info::get_age() const
-{
-	return age_;
-}
-
-//Returns PDB file name / path
-const std::string& pdb_2_0_info::get_pdb_file_name() const
-{
-	return pdb_file_name_;
-}
-
-//Default constructor
-misc_debug_info::misc_debug_info()
-	:data_type_(0), unicode_(false)
-{}
-
-//Constructor from data
-misc_debug_info::misc_debug_info(const image_debug_misc* info)
-	:data_type_(info->DataType), unicode_(info->Unicode ? true : false)
-{
-	//IMAGE_DEBUG_MISC::Data must be checked before!
-	if(info->Unicode)
-	{
-#ifdef PE_BLISS_WINDOWS
-		debug_data_unicode_ = std::wstring(reinterpret_cast<const wchar_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2);
-#else
-		debug_data_unicode_ = pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(info->Data), (info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */) / 2));
-#endif
-		
-		pe_utils::strip_nullbytes(debug_data_unicode_); //Strip nullbytes in the end of string
-	}
-	else
-	{
-		debug_data_ansi_ = std::string(reinterpret_cast<const char*>(info->Data), info->Length - sizeof(image_debug_misc) + 1 /* BYTE[1] in the end of structure */);
-		pe_utils::strip_nullbytes(debug_data_ansi_); //Strip nullbytes in the end of string
-	}
-}
-
-//Returns debug data type
-uint32_t misc_debug_info::get_data_type() const
-{
-	return data_type_;
-}
-
-//Returns true if data type is exe name
-bool misc_debug_info::is_exe_name() const
-{
-	return data_type_ == image_debug_misc_exename;
-}
-
-//Returns true if debug data is UNICODE
-bool misc_debug_info::is_unicode() const
-{
-	return unicode_;
-}
-
-//Returns debug data (ANSI)
-const std::string& misc_debug_info::get_data_ansi() const
-{
-	return debug_data_ansi_;
-}
-
-//Returns debug data (UNICODE)
-const std::wstring& misc_debug_info::get_data_unicode() const
-{
-	return debug_data_unicode_;
-}
-
-//Default constructor
-coff_debug_info::coff_debug_info()
-	:number_of_symbols_(0),
-	lva_to_first_symbol_(0),
-	number_of_line_numbers_(0),
-	lva_to_first_line_number_(0),
-	rva_to_first_byte_of_code_(0),
-	rva_to_last_byte_of_code_(0),
-	rva_to_first_byte_of_data_(0),
-	rva_to_last_byte_of_data_(0)
-{}
-
-//Constructor from data
-coff_debug_info::coff_debug_info(const image_coff_symbols_header* info)
-	:number_of_symbols_(info->NumberOfSymbols),
-	lva_to_first_symbol_(info->LvaToFirstSymbol),
-	number_of_line_numbers_(info->NumberOfLinenumbers),
-	lva_to_first_line_number_(info->LvaToFirstLinenumber),
-	rva_to_first_byte_of_code_(info->RvaToFirstByteOfCode),
-	rva_to_last_byte_of_code_(info->RvaToLastByteOfCode),
-	rva_to_first_byte_of_data_(info->RvaToFirstByteOfData),
-	rva_to_last_byte_of_data_(info->RvaToLastByteOfData)
-{}
-
-//Returns number of symbols
-uint32_t coff_debug_info::get_number_of_symbols() const
-{
-	return number_of_symbols_;
-}
-
-//Returns virtual address of the first symbol
-uint32_t coff_debug_info::get_lva_to_first_symbol() const
-{
-	return lva_to_first_symbol_;
-}
-
-//Returns number of line-number entries
-uint32_t coff_debug_info::get_number_of_line_numbers() const
-{
-	return number_of_line_numbers_;
-}
-
-//Returns virtual address of the first line-number entry
-uint32_t coff_debug_info::get_lva_to_first_line_number() const
-{
-	return lva_to_first_line_number_;
-}
-
-//Returns relative virtual address of the first byte of code
-uint32_t coff_debug_info::get_rva_to_first_byte_of_code() const
-{
-	return rva_to_first_byte_of_code_;
-}
-
-//Returns relative virtual address of the last byte of code
-uint32_t coff_debug_info::get_rva_to_last_byte_of_code() const
-{
-	return rva_to_last_byte_of_code_;
-}
-
-//Returns relative virtual address of the first byte of data
-uint32_t coff_debug_info::get_rva_to_first_byte_of_data() const
-{
-	return rva_to_first_byte_of_data_;
-}
-
-//Returns relative virtual address of the last byte of data
-uint32_t coff_debug_info::get_rva_to_last_byte_of_data() const
-{
-	return rva_to_last_byte_of_data_;
-}
-
-//Returns COFF symbols list
-const coff_debug_info::coff_symbols_list& coff_debug_info::get_symbols() const
-{
-	return symbols_;
-}
-
-//Adds COFF symbol
-void coff_debug_info::add_symbol(const coff_symbol& sym)
-{
-	symbols_.push_back(sym);
-}
-
-//Default constructor
-coff_debug_info::coff_symbol::coff_symbol()
-	:storage_class_(0),
-	index_(0),
-	section_number_(0), rva_(0),
-	type_(0),
-	is_filename_(false)
-{}
-
-//Returns storage class
-uint32_t coff_debug_info::coff_symbol::get_storage_class() const
-{
-	return storage_class_;
-}
-
-//Returns symbol index
-uint32_t coff_debug_info::coff_symbol::get_index() const
-{
-	return index_;
-}
-
-//Returns section number
-uint32_t coff_debug_info::coff_symbol::get_section_number() const
-{
-	return section_number_;
-}
-
-//Returns RVA
-uint32_t coff_debug_info::coff_symbol::get_rva() const
-{
-	return rva_;
-}
-
-//Returns true if structure contains file name
-bool coff_debug_info::coff_symbol::is_file() const
-{
-	return is_filename_;
-}
-
-//Returns text data (symbol or file name)
-const std::string& coff_debug_info::coff_symbol::get_symbol() const
-{
-	return name_;
-}
-
-//Sets storage class
-void coff_debug_info::coff_symbol::set_storage_class(uint32_t storage_class)
-{
-	storage_class_ = storage_class;
-}
-
-//Sets symbol index
-void coff_debug_info::coff_symbol::set_index(uint32_t index)
-{
-	index_ = index;
-}
-
-//Sets section number
-void coff_debug_info::coff_symbol::set_section_number(uint32_t section_number)
-{
-	section_number_ = section_number;
-}
-
-//Sets RVA
-void coff_debug_info::coff_symbol::set_rva(uint32_t rva)
-{
-	rva_ = rva;
-}
-
-//Sets file name
-void coff_debug_info::coff_symbol::set_file_name(const std::string& file_name)
-{
-	name_ = file_name;
-	is_filename_ = true;
-}
-
-//Sets symbol name
-void coff_debug_info::coff_symbol::set_symbol_name(const std::string& symbol_name)
-{
-	name_ = symbol_name;
-	is_filename_ = false;
-}
-
-//Returns type
-uint16_t coff_debug_info::coff_symbol::get_type() const
-{
-	return type_;
-}
-
-//Sets type
-void coff_debug_info::coff_symbol::set_type(uint16_t type)
-{
-	type_ = type;
-}
-
-//Returns debug information list
-const debug_info_list get_debug_information(const pe_base& pe)
-{
-	debug_info_list ret;
-
-	//If there's no debug directory, return empty list
-	if(!pe.has_debug())
-		return ret;
-
-	//Check the length in bytes of the section containing debug directory
-	if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_rva(image_directory_entry_debug), section_data_virtual, true)
-		< sizeof(image_debug_directory))
-		throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-	unsigned long current_pos = pe.get_directory_rva(image_directory_entry_debug);
-
-	//First IMAGE_DEBUG_DIRECTORY table
-	image_debug_directory directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-
-	if(!pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_debug), pe.get_directory_size(image_directory_entry_debug)))
-		throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-	//Iterate over all IMAGE_DEBUG_DIRECTORY directories
-	while(directory.PointerToRawData
-		&& current_pos < pe.get_directory_rva(image_directory_entry_debug) + pe.get_directory_size(image_directory_entry_debug))
-	{
-		//Create debug information structure
-		debug_info info(directory);
-
-		//Find raw debug data
-		const pe_base::debug_data_list& debug_datas = pe.get_raw_debug_data_list();
-		pe_base::debug_data_list::const_iterator it = debug_datas.find(directory.PointerToRawData);
-		if(it != debug_datas.end()) //If it exists, we'll do some detailed debug info research
-		{
-			const std::string& debug_data = (*it).second;
-			switch(directory.Type)
-			{
-			case image_debug_type_coff:
-				{
-					//Check data length
-					if(debug_data.length() < sizeof(image_coff_symbols_header))
-						throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-					//Get coff header structure pointer
-					const image_coff_symbols_header* coff = reinterpret_cast<const image_coff_symbols_header*>(debug_data.data());
-
-					//Check possible overflows
-					if(coff->NumberOfSymbols >= pe_utils::max_dword / sizeof(image_symbol)
-						|| !pe_utils::is_sum_safe(coff->NumberOfSymbols * sizeof(image_symbol), coff->LvaToFirstSymbol))
-						throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-					//Check data length again
-					if(debug_data.length() < coff->NumberOfSymbols * sizeof(image_symbol) + coff->LvaToFirstSymbol)
-						throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-					//Create COFF debug info structure
-					coff_debug_info coff_info(coff);
-
-					//Enumerate debug symbols data
-					for(uint32_t i = 0; i < coff->NumberOfSymbols; ++i)
-					{
-						//Safe sum (checked above)
-						const image_symbol* sym = reinterpret_cast<const image_symbol*>(debug_data.data() + i * sizeof(image_symbol) + coff->LvaToFirstSymbol);
-
-						coff_debug_info::coff_symbol symbol;
-						symbol.set_index(i); //Save symbol index
-						symbol.set_storage_class(sym->StorageClass); //Save storage class
-						symbol.set_type(sym->Type); //Save storage class
-
-						//Check data length again
-						if(!pe_utils::is_sum_safe(i, sym->NumberOfAuxSymbols)
-							|| (i + sym->NumberOfAuxSymbols) > coff->NumberOfSymbols
-							|| debug_data.length() < (i + 1) * sizeof(image_symbol) + coff->LvaToFirstSymbol + sym->NumberOfAuxSymbols * sizeof(image_symbol))
-							throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-						//If symbol is filename
-						if(sym->StorageClass == image_sym_class_file)
-						{
-							//Save file name, it is situated just after this IMAGE_SYMBOL structure
-							std::string file_name(reinterpret_cast<const char*>(debug_data.data() + (i + 1) * sizeof(image_symbol)), sym->NumberOfAuxSymbols * sizeof(image_symbol));
-							pe_utils::strip_nullbytes(file_name);
-							symbol.set_file_name(file_name);
-
-							//Save symbol info
-							coff_info.add_symbol(symbol);
-
-							//Move to next symbol
-							i += sym->NumberOfAuxSymbols;
-							continue;
-						}
-
-						//Dump some other symbols
-						if(((sym->StorageClass == image_sym_class_static)
-							&& (sym->NumberOfAuxSymbols == 0)
-							&& (sym->SectionNumber == 1))
-							||
-							((sym->StorageClass == image_sym_class_external)
-							&& ISFCN(sym->Type)
-							&& (sym->SectionNumber > 0))
-							)
-						{
-							//Save RVA and section number
-							symbol.set_section_number(sym->SectionNumber);
-							symbol.set_rva(sym->Value);
-
-							//If symbol has short name
-							if(sym->N.Name.Short)
-							{
-								//Copy and save symbol name
-								char name_buff[9];
-								memcpy(name_buff, sym->N.ShortName, 8);
-								name_buff[8] = '\0';
-								symbol.set_symbol_name(name_buff);
-							}
-							else
-							{
-								//Symbol has long name
-
-								//Check possible overflows
-								if(!pe_utils::is_sum_safe(coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol), sym->N.Name.Long))
-									throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-								//Here we have an offset to the string table
-								uint32_t symbol_offset = coff->LvaToFirstSymbol + coff->NumberOfSymbols * sizeof(image_symbol) + sym->N.Name.Long;
-
-								//Check data length
-								if(debug_data.length() < symbol_offset)
-									throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-								//Check symbol name for null-termination
-								if(!pe_utils::is_null_terminated(debug_data.data() + symbol_offset, debug_data.length() - symbol_offset))
-									throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-								//Save symbol name
-								symbol.set_symbol_name(debug_data.data() + symbol_offset);
-							}
-
-							//Save symbol info
-							coff_info.add_symbol(symbol);
-
-							//Move to next symbol
-							i += sym->NumberOfAuxSymbols;
-							continue;
-						}
-					}
-
-					info.set_advanced_debug_info(coff_info);
-				}
-				break;
-
-			case image_debug_type_codeview:
-				{
-					//Check data length
-					if(debug_data.length() < sizeof(OMFSignature*))
-						throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-					//Get POMFSignature structure pointer from the very beginning of debug data
-					const OMFSignature* sig = reinterpret_cast<const OMFSignature*>(debug_data.data());
-					if(!memcmp(sig->Signature, "RSDS", 4))
-					{
-						//Signature is "RSDS" - PDB 7.0
-
-						//Check data length
-						if(debug_data.length() < sizeof(CV_INFO_PDB70))
-							throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-						const CV_INFO_PDB70* pdb_data = reinterpret_cast<const CV_INFO_PDB70*>(debug_data.data());
-
-						//Check PDB file name null-termination
-						if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB70) - 1 /* BYTE of filename in structure */)))
-							throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-						info.set_advanced_debug_info(pdb_7_0_info(pdb_data));
-					}
-					else if(!memcmp(sig->Signature, "NB10", 4))
-					{
-						//Signature is "NB10" - PDB 2.0
-
-						//Check data length
-						if(debug_data.length() < sizeof(CV_INFO_PDB20))
-							throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-						const CV_INFO_PDB20* pdb_data = reinterpret_cast<const CV_INFO_PDB20*>(debug_data.data());
-
-						//Check PDB file name null-termination
-						if(!pe_utils::is_null_terminated(pdb_data->PdbFileName, debug_data.length() - (sizeof(CV_INFO_PDB20) - 1 /* BYTE of filename in structure */)))
-							throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-						info.set_advanced_debug_info(pdb_2_0_info(pdb_data));
-					}
-					else if(!memcmp(sig->Signature, "NB09", 4))
-					{
-						//CodeView 4.0, no structures available
-						info.set_advanced_info_type(debug_info::advanced_info_codeview_4_0);
-					}
-					else if(!memcmp(sig->Signature, "NB11", 4))
-					{
-						//CodeView 5.0, no structures available
-						info.set_advanced_info_type(debug_info::advanced_info_codeview_5_0);
-					}
-					else if(!memcmp(sig->Signature, "NB05", 4))
-					{
-						//Other CodeView, no structures available
-						info.set_advanced_info_type(debug_info::advanced_info_codeview);
-					}
-				}
-
-				break;
-
-			case image_debug_type_misc:
-				{
-					//Check data length
-					if(debug_data.length() < sizeof(image_debug_misc))
-						throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-					//Get misc structure pointer
-					const image_debug_misc* misc_data = reinterpret_cast<const image_debug_misc*>(debug_data.data());
-
-					//Check misc data length
-					if(debug_data.length() < misc_data->Length /* Total length of record */)
-						throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-					//Save advanced information
-					info.set_advanced_debug_info(misc_debug_info(misc_data));
-				}
-				break;
-			}
-		}
-
-		//Save debug information structure
-		ret.push_back(info);
-
-		//Check possible overflow
-		if(!pe_utils::is_sum_safe(current_pos, sizeof(image_debug_directory)))
-			throw pe_exception("Incorrect debug directory", pe_exception::incorrect_debug_directory);
-
-		//Go to next debug entry
-		current_pos += sizeof(image_debug_directory);
-		directory = pe.section_data_from_rva<image_debug_directory>(current_pos, section_data_virtual, true);
-	}
-
-	return ret;
-}
-}

+ 0 - 324
tools/pe_bliss/pe_debug.h

@@ -1,324 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing advanced RSDS (PDB 7.0) information
-class pdb_7_0_info
-{
-public:
-	//Default constructor
-	pdb_7_0_info();
-	//Constructor from data
-	explicit pdb_7_0_info(const pe_win::CV_INFO_PDB70* info);
-
-	//Returns debug PDB 7.0 structure GUID
-	const pe_win::guid get_guid() const;
-	//Returns age of build
-	uint32_t get_age() const;
-	//Returns PDB file name / path
-	const std::string& get_pdb_file_name() const;
-
-private:
-	uint32_t age_;
-	pe_win::guid guid_;
-	std::string pdb_file_name_;
-};
-
-//Class representing advanced NB10 (PDB 2.0) information
-class pdb_2_0_info
-{
-public:
-	//Default constructor
-	pdb_2_0_info();
-	//Constructor from data
-	explicit pdb_2_0_info(const pe_win::CV_INFO_PDB20* info);
-
-	//Returns debug PDB 2.0 structure signature
-	uint32_t get_signature() const;
-	//Returns age of build
-	uint32_t get_age() const;
-	//Returns PDB file name / path
-	const std::string& get_pdb_file_name() const;
-
-private:
-	uint32_t age_;
-	uint32_t signature_;
-	std::string pdb_file_name_;
-};
-
-//Class representing advanced misc (IMAGE_DEBUG_TYPE_MISC) info
-class misc_debug_info
-{
-public:
-	//Default constructor
-	misc_debug_info();
-	//Constructor from data
-	explicit misc_debug_info(const pe_win::image_debug_misc* info);
-
-	//Returns debug data type
-	uint32_t get_data_type() const;
-	//Returns true if data type is exe name
-	bool is_exe_name() const;
-
-	//Returns true if debug data is UNICODE
-	bool is_unicode() const;
-	//Returns debug data (ANSI or UNICODE)
-	const std::string& get_data_ansi() const;
-	const std::wstring& get_data_unicode() const;
-
-private:
-	uint32_t data_type_;
-	bool unicode_;
-	std::string debug_data_ansi_;
-	std::wstring debug_data_unicode_;
-};
-
-//Class representing COFF (IMAGE_DEBUG_TYPE_COFF) debug info
-class coff_debug_info
-{
-public:
-	//Structure representing COFF symbol
-	struct coff_symbol
-	{
-	public:
-		//Default constructor
-		coff_symbol();
-
-		//Returns storage class
-		uint32_t get_storage_class() const;
-		//Returns symbol index
-		uint32_t get_index() const;
-		//Returns section number
-		uint32_t get_section_number() const;
-		//Returns RVA
-		uint32_t get_rva() const;
-		//Returns type
-		uint16_t get_type() const;
-
-		//Returns true if structure contains file name
-		bool is_file() const;
-		//Returns text data (symbol or file name)
-		const std::string& get_symbol() const;
-
-	public: //These functions do not change everything inside image, they are used by PE class
-		//Sets storage class
-		void set_storage_class(uint32_t storage_class);
-		//Sets symbol index
-		void set_index(uint32_t index);
-		//Sets section number
-		void set_section_number(uint32_t section_number);
-		//Sets RVA
-		void set_rva(uint32_t rva);
-		//Sets type
-		void set_type(uint16_t type);
-
-		//Sets file name
-		void set_file_name(const std::string& file_name);
-		//Sets symbol name
-		void set_symbol_name(const std::string& symbol_name);
-
-	private:
-		uint32_t storage_class_;
-		uint32_t index_;
-		uint32_t section_number_, rva_;
-		uint16_t type_;
-		bool is_filename_;
-		std::string name_;
-	};
-
-public:
-	typedef std::vector<coff_symbol> coff_symbols_list;
-
-public:
-	//Default constructor
-	coff_debug_info();
-	//Constructor from data
-	explicit coff_debug_info(const pe_win::image_coff_symbols_header* info);
-
-	//Returns number of symbols
-	uint32_t get_number_of_symbols() const;
-	//Returns virtual address of the first symbol
-	uint32_t get_lva_to_first_symbol() const;
-	//Returns number of line-number entries
-	uint32_t get_number_of_line_numbers() const;
-	//Returns virtual address of the first line-number entry
-	uint32_t get_lva_to_first_line_number() const;
-	//Returns relative virtual address of the first byte of code
-	uint32_t get_rva_to_first_byte_of_code() const;
-	//Returns relative virtual address of the last byte of code
-	uint32_t get_rva_to_last_byte_of_code() const;
-	//Returns relative virtual address of the first byte of data
-	uint32_t get_rva_to_first_byte_of_data() const;
-	//Returns relative virtual address of the last byte of data
-	uint32_t get_rva_to_last_byte_of_data() const;
-
-	//Returns COFF symbols list
-	const coff_symbols_list& get_symbols() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//Adds COFF symbol
-	void add_symbol(const coff_symbol& sym);
-
-private:
-	uint32_t number_of_symbols_;
-	uint32_t lva_to_first_symbol_;
-	uint32_t number_of_line_numbers_;
-	uint32_t lva_to_first_line_number_;
-	uint32_t rva_to_first_byte_of_code_;
-	uint32_t rva_to_last_byte_of_code_;
-	uint32_t rva_to_first_byte_of_data_;
-	uint32_t rva_to_last_byte_of_data_;
-
-private:
-	coff_symbols_list symbols_;
-};
-
-//Class representing debug information
-class debug_info
-{
-public:
-	//Enumeration of debug information types
-	enum debug_info_type
-	{
-		debug_type_unknown,
-		debug_type_coff,
-		debug_type_codeview,
-		debug_type_fpo,
-		debug_type_misc,
-		debug_type_exception,
-		debug_type_fixup,
-		debug_type_omap_to_src,
-		debug_type_omap_from_src,
-		debug_type_borland,
-		debug_type_reserved10,
-		debug_type_clsid
-	};
-
-public:
-	//Enumeration of advanced debug information types
-	enum advanced_info_type
-	{
-		advanced_info_none, //No advanced info
-		advanced_info_pdb_7_0, //PDB 7.0
-		advanced_info_pdb_2_0, //PDB 2.0
-		advanced_info_misc, //MISC debug info
-		advanced_info_coff, //COFF debug info
-		//No advanced info structures available for types below
-		advanced_info_codeview_4_0, //CodeView 4.0
-		advanced_info_codeview_5_0, //CodeView 5.0
-		advanced_info_codeview //CodeView
-	};
-
-public:
-	//Default constructor
-	debug_info();
-	//Constructor from data
-	explicit debug_info(const pe_win::image_debug_directory& debug);
-	//Copy constructor
-	debug_info(const debug_info& info);
-	//Copy assignment operator
-	debug_info& operator=(const debug_info& info);
-	//Destructor
-	~debug_info();
-
-	//Returns debug characteristics
-	uint32_t get_characteristics() const;
-	//Returns debug datetimestamp
-	uint32_t get_time_stamp() const;
-	//Returns major version
-	uint32_t get_major_version() const;
-	//Returns minor version
-	uint32_t get_minor_version() const;
-	//Returns type of debug info (unchecked)
-	uint32_t get_type_raw() const;
-	//Returns type of debug info from debug_info_type enumeration
-	debug_info_type get_type() const;
-	//Returns size of debug data (internal, .pdb or other file doesn't count)
-	uint32_t get_size_of_data() const;
-	//Returns RVA of debug info when mapped to memory or zero, if info is not mapped
-	uint32_t get_rva_of_raw_data() const;
-	//Returns raw file pointer to raw data
-	uint32_t get_pointer_to_raw_data() const;
-
-	//Returns advanced debug information type
-	advanced_info_type get_advanced_info_type() const;
-	//Returns advanced debug information or throws an exception,
-	//if requested information type is not contained by structure
-	template<typename AdvancedInfo>
-	const AdvancedInfo get_advanced_debug_info() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//Sets advanced debug information
-	void set_advanced_debug_info(const pdb_7_0_info& info);
-	void set_advanced_debug_info(const pdb_2_0_info& info);
-	void set_advanced_debug_info(const misc_debug_info& info);
-	void set_advanced_debug_info(const coff_debug_info& info);
-
-	//Sets advanced debug information type, if no advanced info structure available
-	void set_advanced_info_type(advanced_info_type type);
-
-private:
-	uint32_t characteristics_;
-	uint32_t time_stamp_;
-	uint32_t major_version_, minor_version_;
-	uint32_t type_;
-	uint32_t size_of_data_;
-	uint32_t address_of_raw_data_; //RVA when mapped or 0
-	uint32_t pointer_to_raw_data_; //RAW file offset
-
-	//Union containing advanced debug information pointer
-	union advanced_info
-	{
-	public:
-		//Default constructor
-		advanced_info();
-
-		//Returns true if advanced debug info is present
-		bool is_present() const;
-
-	public:
-		pdb_7_0_info* adv_pdb_7_0_info;
-		pdb_2_0_info* adv_pdb_2_0_info;
-		misc_debug_info* adv_misc_info;
-		coff_debug_info* adv_coff_info;
-	};
-
-	//Helper for advanced debug information copying
-	void copy_advanced_info(const debug_info& info);
-	//Helper for clearing any present advanced debug information
-	void free_present_advanced_info();
-
-	advanced_info advanced_debug_info_;
-	//Advanced information type
-	advanced_info_type advanced_info_type_;
-};
-
-typedef std::vector<debug_info> debug_info_list;
-
-//Returns debug information list
-const debug_info_list get_debug_information(const pe_base& pe);
-}

+ 0 - 59
tools/pe_bliss/pe_directory.cpp

@@ -1,59 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Default constructor
-image_directory::image_directory()
-	:rva_(0), size_(0)
-{}
-
-//Constructor from data
-image_directory::image_directory(uint32_t rva, uint32_t size)
-	:rva_(rva), size_(size)
-{}
-
-//Returns RVA
-uint32_t image_directory::get_rva() const
-{
-	return rva_;
-}
-
-//Returns size
-uint32_t image_directory::get_size() const
-{
-	return size_;
-}
-
-//Sets RVA
-void image_directory::set_rva(uint32_t rva)
-{
-	rva_ = rva;
-}
-
-//Sets size
-void image_directory::set_size(uint32_t size)
-{
-	size_ = size;
-}
-}

+ 0 - 50
tools/pe_bliss/pe_directory.h

@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-//Class representing image directory data
-class image_directory
-{
-public:
-	//Default constructor
-	image_directory();
-	//Constructor from data
-	image_directory(uint32_t rva, uint32_t size);
-
-	//Returns RVA
-	uint32_t get_rva() const;
-	//Returns size
-	uint32_t get_size() const;
-
-	//Sets RVA
-	void set_rva(uint32_t rva);
-	//Sets size
-	void set_size(uint32_t size);
-
-private:
-	uint32_t rva_;
-	uint32_t size_;
-};
-}

+ 0 - 186
tools/pe_bliss/pe_dotnet.cpp

@@ -1,186 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_dotnet.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//.NET
-basic_dotnet_info::basic_dotnet_info()
-{
-	memset(&header_, 0, sizeof(header_));
-}
-
-//Constructor from data
-basic_dotnet_info::basic_dotnet_info(const image_cor20_header& header)
-	:header_(header)
-{}
-
-//Returns major runtime version
-uint16_t basic_dotnet_info::get_major_runtime_version() const
-{
-	return header_.MajorRuntimeVersion;
-}
-
-//Returns minor runtime version
-uint16_t basic_dotnet_info::get_minor_runtime_version() const
-{
-	return header_.MinorRuntimeVersion;
-}
-
-//Returns RVA of metadata (symbol table and startup information)
-uint32_t basic_dotnet_info::get_rva_of_metadata() const
-{
-	return header_.MetaData.VirtualAddress;
-}
-
-//Returns size of metadata (symbol table and startup information)
-uint32_t basic_dotnet_info::get_size_of_metadata() const
-{
-	return header_.MetaData.Size;
-}
-
-//Returns flags
-uint32_t basic_dotnet_info::get_flags() const
-{
-	return header_.Flags;
-}
-
-//Returns true if entry point is native
-bool basic_dotnet_info::is_native_entry_point() const
-{
-	return (header_.Flags & comimage_flags_native_entrypoint) ? true : false;
-}
-
-//Returns true if 32 bit required
-bool basic_dotnet_info::is_32bit_required() const
-{
-	return (header_.Flags & comimage_flags_32bitrequired) ? true : false;
-}
-
-//Returns true if image is IL library
-bool basic_dotnet_info::is_il_library() const
-{
-	return (header_.Flags & comimage_flags_il_library) ? true : false;
-}
-
-//Returns true if image uses IL only
-bool basic_dotnet_info::is_il_only() const
-{
-	return (header_.Flags & comimage_flags_ilonly) ? true : false;
-}
-
-//Returns entry point RVA (if entry point is native)
-//Returns entry point managed token (if entry point is managed)
-uint32_t basic_dotnet_info::get_entry_point_rva_or_token() const
-{
-	return header_.EntryPointToken;
-}
-
-//Returns RVA of managed resources
-uint32_t basic_dotnet_info::get_rva_of_resources() const
-{
-	return header_.Resources.VirtualAddress;
-}
-
-//Returns size of managed resources
-uint32_t basic_dotnet_info::get_size_of_resources() const
-{
-	return header_.Resources.Size;
-}
-
-//Returns RVA of strong name signature
-uint32_t basic_dotnet_info::get_rva_of_strong_name_signature() const
-{
-	return header_.StrongNameSignature.VirtualAddress;
-}
-
-//Returns size of strong name signature
-uint32_t basic_dotnet_info::get_size_of_strong_name_signature() const
-{
-	return header_.StrongNameSignature.Size;
-}
-
-//Returns RVA of code manager table
-uint32_t basic_dotnet_info::get_rva_of_code_manager_table() const
-{
-	return header_.CodeManagerTable.VirtualAddress;
-}
-
-//Returns size of code manager table
-uint32_t basic_dotnet_info::get_size_of_code_manager_table() const
-{
-	return header_.CodeManagerTable.Size;
-}
-
-//Returns RVA of VTable fixups
-uint32_t basic_dotnet_info::get_rva_of_vtable_fixups() const
-{
-	return header_.VTableFixups.VirtualAddress;
-}
-
-//Returns size of VTable fixups
-uint32_t basic_dotnet_info::get_size_of_vtable_fixups() const
-{
-	return header_.VTableFixups.Size;
-}
-
-//Returns RVA of export address table jumps
-uint32_t basic_dotnet_info::get_rva_of_export_address_table_jumps() const
-{
-	return header_.ExportAddressTableJumps.VirtualAddress;
-}
-
-//Returns size of export address table jumps
-uint32_t basic_dotnet_info::get_size_of_export_address_table_jumps() const
-{
-	return header_.ExportAddressTableJumps.Size;
-}
-
-//Returns RVA of managed native header
-//(precompiled header info, usually set to zero, for internal use)
-uint32_t basic_dotnet_info::get_rva_of_managed_native_header() const
-{
-	return header_.ManagedNativeHeader.VirtualAddress;
-}
-
-//Returns size of managed native header
-//(precompiled header info, usually set to zero, for internal use)
-uint32_t basic_dotnet_info::get_size_of_managed_native_header() const
-{
-	return header_.ManagedNativeHeader.Size;
-}
-
-//Returns basic .NET information
-//If image is not native, throws an exception
-const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe)
-{
-	//If there's no debug directory, return empty list
-	if(!pe.is_dotnet())
-		throw pe_exception("Image does not have managed code", pe_exception::image_does_not_have_managed_code);
-
-	//Return basic .NET information
-	return basic_dotnet_info(pe.section_data_from_rva<image_cor20_header>(pe.get_directory_rva(image_directory_entry_com_descriptor), section_data_virtual, true));
-}
-}

+ 0 - 97
tools/pe_bliss/pe_dotnet.h

@@ -1,97 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing basic .NET header information
-class basic_dotnet_info
-{
-public:
-	//Default constructor
-	basic_dotnet_info();
-	//Constructor from data
-	explicit basic_dotnet_info(const pe_win::image_cor20_header& header);
-
-	//Returns major runtime version
-	uint16_t get_major_runtime_version() const;
-	//Returns minor runtime version
-	uint16_t get_minor_runtime_version() const;
-
-	//Returns RVA of metadata (symbol table and startup information)
-	uint32_t get_rva_of_metadata() const;
-	//Returns size of metadata (symbol table and startup information)
-	uint32_t get_size_of_metadata() const;
-
-	//Returns flags
-	uint32_t get_flags() const;
-
-	//Returns true if entry point is native
-	bool is_native_entry_point() const;
-	//Returns true if 32 bit required
-	bool is_32bit_required() const;
-	//Returns true if image is IL library
-	bool is_il_library() const;
-	//Returns true if image uses IL only
-	bool is_il_only() const;
-
-	//Returns entry point RVA (if entry point is native)
-	//Returns entry point managed token (if entry point is managed)
-	uint32_t get_entry_point_rva_or_token() const;
-
-	//Returns RVA of managed resources
-	uint32_t get_rva_of_resources() const;
-	//Returns size of managed resources
-	uint32_t get_size_of_resources() const;
-	//Returns RVA of strong name signature
-	uint32_t get_rva_of_strong_name_signature() const;
-	//Returns size of strong name signature
-	uint32_t get_size_of_strong_name_signature() const;
-	//Returns RVA of code manager table
-	uint32_t get_rva_of_code_manager_table() const;
-	//Returns size of code manager table
-	uint32_t get_size_of_code_manager_table() const;
-	//Returns RVA of VTable fixups
-	uint32_t get_rva_of_vtable_fixups() const;
-	//Returns size of VTable fixups
-	uint32_t get_size_of_vtable_fixups() const;
-	//Returns RVA of export address table jumps
-	uint32_t get_rva_of_export_address_table_jumps() const;
-	//Returns size of export address table jumps
-	uint32_t get_size_of_export_address_table_jumps() const;
-	//Returns RVA of managed native header
-	//(precompiled header info, usually set to zero, for internal use)
-	uint32_t get_rva_of_managed_native_header() const;
-	//Returns size of managed native header
-	//(precompiled header info, usually set to zero, for internal use)
-	uint32_t get_size_of_managed_native_header() const;
-
-private:
-	pe_win::image_cor20_header header_;
-};
-
-//Returns basic .NET information
-//If image is not native, throws an exception
-const basic_dotnet_info get_basic_dotnet_info(const pe_base& pe);
-}

+ 0 - 40
tools/pe_bliss/pe_exception.cpp

@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_exception.h"
-
-namespace pe_bliss
-{
-//PE exception class constructors
-pe_exception::pe_exception(const char* text, exception_id id)
-	:std::runtime_error(text), id_(id)
-{}
-
-pe_exception::pe_exception(const std::string& text, exception_id id)
-	:std::runtime_error(text), id_(id)
-{}
-
-//Returns exception ID
-pe_exception::exception_id pe_exception::get_id() const
-{
-	return id_;
-}
-}

+ 0 - 130
tools/pe_bliss/pe_exception.h

@@ -1,130 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <exception>
-#include <stdexcept>
-
-namespace pe_bliss
-{
-//PE exception class
-class pe_exception : public std::runtime_error
-{
-public:
-	//Exception IDs
-	enum exception_id
-	{
-		unknown_error,
-		bad_pe_file,
-		bad_dos_header,
-		image_nt_headers_not_found,
-		error_reading_image_nt_headers,
-		error_reading_data_directories,
-		error_reading_file,
-		pe_signature_incorrect,
-		incorrect_number_of_rva_and_sizes,
-		error_changing_section_virtual_size,
-		section_number_incorrect,
-		section_table_incorrect,
-		incorrect_section_alignment,
-		incorrect_file_alignment,
-		incorrect_size_of_image,
-		incorrect_size_of_headers,
-		image_section_headers_not_found,
-		zero_section_sizes,
-		section_incorrect_addr_or_size,
-		section_not_found,
-		image_section_data_not_found,
-		no_section_found,
-		image_section_table_incorrect,
-		directory_does_not_exist,
-		rva_not_exists,
-		error_reading_section_header,
-		error_reading_overlay,
-		incorrect_address_conversion,
-
-		incorrect_export_directory,
-		incorrect_import_directory,
-		incorrect_relocation_directory,
-		incorrect_tls_directory,
-		incorrect_config_directory,
-		incorrect_bound_import_directory,
-		incorrect_resource_directory,
-		incorrect_exception_directory,
-		incorrect_debug_directory,
-
-		resource_directory_entry_error,
-		resource_directory_entry_not_found,
-		resource_data_entry_not_found,
-		resource_incorrect_bitmap,
-		resource_incorrect_icon,
-		resource_incorrect_cursor,
-		resource_incorrect_string_table,
-		resource_string_not_found,
-		resource_incorrect_message_table,
-		resource_incorrect_version_info,
-
-		advanced_debug_information_request_error,
-		image_does_not_have_managed_code,
-
-		section_is_empty,
-		data_is_empty,
-		stream_is_bad,
-
-		section_is_not_attached,
-		insufficient_space,
-
-		cannot_rebase_relocations,
-
-		exports_list_is_empty,
-		duplicate_exported_function_ordinal,
-		duplicate_exported_function_name,
-
-		version_info_string_does_not_exist,
-
-		no_more_sections_can_be_added,
-
-		no_icon_group_found,
-		no_cursor_group_found,
-
-		encoding_convertion_error,
-
-		error_expanding_section,
-
-		cannot_rebuild_image
-	};
-
-public:
-	//Class constructors
-	explicit pe_exception(const char* text, exception_id id = unknown_error);
-	explicit pe_exception(const std::string& text, exception_id id = unknown_error);
-
-	//Returns exception ID from exception_id enumeration
-	exception_id get_id() const;
-
-	//Destructor
-	virtual ~pe_exception() throw()
-	{}
-
-private:
-	exception_id id_;
-};
-}

+ 0 - 177
tools/pe_bliss/pe_exception_directory.cpp

@@ -1,177 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_exception_directory.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//EXCEPTION DIRECTORY (exists on PE+ only)
-//Default constructor
-exception_entry::exception_entry()
-	:begin_address_(0), end_address_(0), unwind_info_address_(0),
-	unwind_info_version_(0),
-	flags_(0),
-	size_of_prolog_(0),
-	count_of_codes_(0),
-	frame_register_(0),
-	frame_offset_(0)
-{}
-
-//Constructor from data
-exception_entry::exception_entry(const image_runtime_function_entry& entry, const unwind_info& unwind_info)
-	:begin_address_(entry.BeginAddress), end_address_(entry.EndAddress), unwind_info_address_(entry.UnwindInfoAddress),
-	unwind_info_version_(unwind_info.Version),
-	flags_(unwind_info.Flags),
-	size_of_prolog_(unwind_info.SizeOfProlog),
-	count_of_codes_(unwind_info.CountOfCodes),
-	frame_register_(unwind_info.FrameRegister),
-	frame_offset_(unwind_info.FrameOffset)
-{}
-
-//Returns starting address of function, affected by exception unwinding
-uint32_t exception_entry::get_begin_address() const
-{
-	return begin_address_;
-}
-
-//Returns ending address of function, affected by exception unwinding
-uint32_t exception_entry::get_end_address() const
-{
-	return end_address_;
-}
-
-//Returns unwind info address
-uint32_t exception_entry::get_unwind_info_address() const
-{
-	return unwind_info_address_;
-}
-
-//Returns UNWIND_INFO structure version
-uint8_t exception_entry::get_unwind_info_version() const
-{
-	return unwind_info_version_;
-}
-
-//Returns unwind info flags
-uint8_t exception_entry::get_flags() const
-{
-	return flags_;
-}
-
-//The function has an exception handler that should be called
-//when looking for functions that need to examine exceptions
-bool exception_entry::has_exception_handler() const
-{
-	return (flags_ & unw_flag_ehandler) ? true : false;
-}
-
-//The function has a termination handler that should be called
-//when unwinding an exception
-bool exception_entry::has_termination_handler() const
-{
-	return (flags_ & unw_flag_uhandler) ? true : false;
-}
-
-//The unwind info structure is not the primary one for the procedure
-bool exception_entry::is_chaininfo() const
-{
-	return (flags_ & unw_flag_chaininfo) ? true : false;
-}
-
-//Returns size of function prolog
-uint8_t exception_entry::get_size_of_prolog() const
-{
-	return size_of_prolog_;
-}
-
-//Returns number of unwind slots
-uint8_t exception_entry::get_number_of_unwind_slots() const
-{
-	return count_of_codes_;
-}
-
-//If the function uses frame pointer
-bool exception_entry::uses_frame_pointer() const
-{
-	return frame_register_ != 0;
-}
-
-//Number of the nonvolatile register used as the frame pointer,
-//using the same encoding for the operation info field of UNWIND_CODE nodes
-uint8_t exception_entry::get_frame_pointer_register_number() const
-{
-	return frame_register_;
-}
-
-//The scaled offset from RSP that is applied to the FP reg when it is established.
-//The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240
-uint8_t exception_entry::get_scaled_rsp_offset() const
-{
-	return frame_offset_;
-}
-
-//Returns exception directory data (exists on PE+ only)
-//Unwind opcodes are not listed, because their format and list are subject to change
-const exception_entry_list get_exception_directory_data(const pe_base& pe)
-{
-	exception_entry_list ret;
-
-	//If image doesn't have exception directory, return empty list
-	if(!pe.has_exception_directory())
-		return ret;
-
-	//Check the length in bytes of the section containing exception directory
-	if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_exception), pe.get_directory_rva(image_directory_entry_exception), section_data_virtual, true)
-		< sizeof(image_runtime_function_entry))
-		throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
-	unsigned long current_pos = pe.get_directory_rva(image_directory_entry_exception);
-
-	//Check if structures are DWORD-aligned
-	if(current_pos % sizeof(uint32_t))
-		throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
-	//First IMAGE_RUNTIME_FUNCTION_ENTRY table
-	image_runtime_function_entry exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true);
-
-	//todo: virtual addresses BeginAddress and EndAddress are not checked to be inside image
-	while(exception_table.BeginAddress)
-	{
-		//Check addresses
-		if(exception_table.BeginAddress > exception_table.EndAddress)
-			throw pe_exception("Incorrect exception directory", pe_exception::incorrect_exception_directory);
-
-		//Get unwind information
-		unwind_info info = pe.section_data_from_rva<unwind_info>(exception_table.UnwindInfoAddress, section_data_virtual, true);
-
-		//Create exception entry and save it
-		ret.push_back(exception_entry(exception_table, info));
-
-		//Go to next exception entry
-		current_pos += sizeof(image_runtime_function_entry);
-		exception_table = pe.section_data_from_rva<image_runtime_function_entry>(current_pos, section_data_virtual, true);
-	}
-
-	return ret;
-}
-}

+ 0 - 88
tools/pe_bliss/pe_exception_directory.h

@@ -1,88 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing exception directory entry
-class exception_entry
-{
-public:
-	//Default constructor
-	exception_entry();
-	//Constructor from data
-	exception_entry(const pe_win::image_runtime_function_entry& entry, const pe_win::unwind_info& unwind_info);
-
-	//Returns starting address of function, affected by exception unwinding
-	uint32_t get_begin_address() const;
-	//Returns ending address of function, affected by exception unwinding
-	uint32_t get_end_address() const;
-	//Returns unwind info address
-	uint32_t get_unwind_info_address() const;
-
-	//Returns UNWIND_INFO structure version
-	uint8_t get_unwind_info_version() const;
-
-	//Returns unwind info flags
-	uint8_t get_flags() const;
-	//The function has an exception handler that should be called
-	//when looking for functions that need to examine exceptions
-	bool has_exception_handler() const;
-	//The function has a termination handler that should be called
-	//when unwinding an exception
-	bool has_termination_handler() const;
-	//The unwind info structure is not the primary one for the procedure
-	bool is_chaininfo() const;
-
-	//Returns size of function prolog
-	uint8_t get_size_of_prolog() const;
-
-	//Returns number of unwind slots
-	uint8_t get_number_of_unwind_slots() const;
-
-	//If the function uses frame pointer
-	bool uses_frame_pointer() const;
-	//Number of the nonvolatile register used as the frame pointer,
-	//using the same encoding for the operation info field of UNWIND_CODE nodes
-	uint8_t get_frame_pointer_register_number() const;
-	//The scaled offset from RSP that is applied to the FP reg when it is established.
-	//The actual FP reg is set to RSP + 16 * this number, allowing offsets from 0 to 240
-	uint8_t get_scaled_rsp_offset() const;
-
-private:
-	uint32_t begin_address_, end_address_, unwind_info_address_;
-	uint8_t unwind_info_version_;
-	uint8_t flags_;
-	uint8_t size_of_prolog_;
-	uint8_t count_of_codes_;
-	uint8_t frame_register_, frame_offset_;
-};
-
-typedef std::vector<exception_entry> exception_entry_list;
-
-//Returns exception directory data (exists on PE+ only)
-//Unwind opcodes are not listed, because their format and list are subject to change
-const exception_entry_list get_exception_directory_data(const pe_base& pe);
-}

+ 0 - 700
tools/pe_bliss/pe_exports.cpp

@@ -1,700 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <set>
-#include <algorithm>
-#include <string.h>
-#include "pe_exports.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//EXPORTS
-//Default constructor
-exported_function::exported_function()
-	:ordinal_(0), rva_(0), has_name_(false), name_ordinal_(0), forward_(false)
-{}
-
-//Returns ordinal of function (actually, ordinal = hint + ordinal base)
-uint16_t exported_function::get_ordinal() const
-{
-	return ordinal_;
-}
-
-//Returns RVA of function
-uint32_t exported_function::get_rva() const
-{
-	return rva_;
-}
-
-//Returns name of function
-const std::string& exported_function::get_name() const
-{
-	return name_;
-}
-
-//Returns true if function has name and name ordinal
-bool exported_function::has_name() const
-{
-	return has_name_;
-}
-
-//Returns name ordinal of function
-uint16_t exported_function::get_name_ordinal() const
-{
-	return name_ordinal_;
-}
-
-//Returns true if function is forwarded to other library
-bool exported_function::is_forwarded() const
-{
-	return forward_;
-}
-
-//Returns the name of forwarded function
-const std::string& exported_function::get_forwarded_name() const
-{
-	return forward_name_;
-}
-
-//Sets ordinal of function
-void exported_function::set_ordinal(uint16_t ordinal)
-{
-	ordinal_ = ordinal;
-}
-
-//Sets RVA of function
-void exported_function::set_rva(uint32_t rva)
-{
-	rva_ = rva;
-}
-
-//Sets name of function (or clears it, if empty name is passed)
-void exported_function::set_name(const std::string& name)
-{
-	name_ = name;
-	has_name_ = !name.empty();
-}
-
-//Sets name ordinal
-void exported_function::set_name_ordinal(uint16_t name_ordinal)
-{
-	name_ordinal_ = name_ordinal;
-}
-
-//Sets forwarded function name (or clears it, if empty name is passed)
-void exported_function::set_forwarded_name(const std::string& name)
-{
-	forward_name_ = name;
-	forward_ = !name.empty();
-}
-
-//Default constructor
-export_info::export_info()
-	:characteristics_(0),
-	timestamp_(0),
-	major_version_(0),
-	minor_version_(0),
-	ordinal_base_(0),
-	number_of_functions_(0),
-	number_of_names_(0),
-	address_of_functions_(0),
-	address_of_names_(0),
-	address_of_name_ordinals_(0)
-{}
-
-//Returns characteristics
-uint32_t export_info::get_characteristics() const
-{
-	return characteristics_;
-}
-
-//Returns timestamp
-uint32_t export_info::get_timestamp() const
-{
-	return timestamp_;
-}
-
-//Returns major version
-uint16_t export_info::get_major_version() const
-{
-	return major_version_;
-}
-
-//Returns minor version
-uint16_t export_info::get_minor_version() const
-{
-	return minor_version_;
-}
-
-//Returns DLL name
-const std::string& export_info::get_name() const
-{
-	return name_;
-}
-
-//Returns ordinal base
-uint32_t export_info::get_ordinal_base() const
-{
-	return ordinal_base_;
-}
-
-//Returns number of functions
-uint32_t export_info::get_number_of_functions() const
-{
-	return number_of_functions_;
-}
-
-//Returns number of function names
-uint32_t export_info::get_number_of_names() const
-{
-	return number_of_names_;
-}
-
-//Returns RVA of function address table
-uint32_t export_info::get_rva_of_functions() const
-{
-	return address_of_functions_;
-}
-
-//Returns RVA of function name address table
-uint32_t export_info::get_rva_of_names() const
-{
-	return address_of_names_;
-}
-
-//Returns RVA of name ordinals table
-uint32_t export_info::get_rva_of_name_ordinals() const
-{
-	return address_of_name_ordinals_;
-}
-
-//Sets characteristics
-void export_info::set_characteristics(uint32_t characteristics)
-{
-	characteristics_ = characteristics;
-}
-
-//Sets timestamp
-void export_info::set_timestamp(uint32_t timestamp)
-{
-	timestamp_ = timestamp;
-}
-
-//Sets major version
-void export_info::set_major_version(uint16_t major_version)
-{
-	major_version_ = major_version;
-}
-
-//Sets minor version
-void export_info::set_minor_version(uint16_t minor_version)
-{
-	minor_version_ = minor_version;
-}
-
-//Sets DLL name
-void export_info::set_name(const std::string& name)
-{
-	name_ = name;
-}
-
-//Sets ordinal base
-void export_info::set_ordinal_base(uint32_t ordinal_base)
-{
-	ordinal_base_ = ordinal_base;
-}
-
-//Sets number of functions
-void export_info::set_number_of_functions(uint32_t number_of_functions)
-{
-	number_of_functions_ = number_of_functions;
-}
-
-//Sets number of function names
-void export_info::set_number_of_names(uint32_t number_of_names)
-{
-	number_of_names_ = number_of_names;
-}
-
-//Sets RVA of function address table
-void export_info::set_rva_of_functions(uint32_t rva_of_functions)
-{
-	address_of_functions_ = rva_of_functions;
-}
-
-//Sets RVA of function name address table
-void export_info::set_rva_of_names(uint32_t rva_of_names)
-{
-	address_of_names_ = rva_of_names;
-}
-
-//Sets RVA of name ordinals table
-void export_info::set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals)
-{
-	address_of_name_ordinals_ = rva_of_name_ordinals;
-}
-
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info);
-
-//Returns array of exported functions
-const exported_functions_list get_exported_functions(const pe_base& pe)
-{
-	return get_exported_functions(pe, 0);
-}
-
-//Returns array of exported functions and information about export
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info)
-{
-	return get_exported_functions(pe, &info);
-}
-
-//Helper: sorts exported function list by ordinals
-struct ordinal_sorter
-{
-public:
-		bool operator()(const exported_function& func1, const exported_function& func2) const;
-};
-
-//Returns array of exported functions and information about export (if info != 0)
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info* info)
-{
-	//Returned exported functions info array
-	std::vector<exported_function> ret;
-
-	if(pe.has_exports())
-	{
-		//Check the length in bytes of the section containing export directory
-		if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_export),
-			pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true)
-			< sizeof(image_export_directory))
-			throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-		image_export_directory exports = pe.section_data_from_rva<image_export_directory>(pe.get_directory_rva(image_directory_entry_export), section_data_virtual, true);
-
-		unsigned long max_name_length;
-
-		if(info)
-		{
-			//Save some export info data
-			info->set_characteristics(exports.Characteristics);
-			info->set_major_version(exports.MajorVersion);
-			info->set_minor_version(exports.MinorVersion);
-
-			//Get byte count that we have for dll name
-			if((max_name_length = pe.section_data_length_from_rva(exports.Name, exports.Name, section_data_virtual, true)) < 2)
-				throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-			//Get dll name pointer
-			const char* dll_name = pe.section_data_from_rva(exports.Name, section_data_virtual, true);
-
-			//Check for null-termination
-			if(!pe_utils::is_null_terminated(dll_name, max_name_length))
-				throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-			//Save the rest of export information data
-			info->set_name(dll_name);
-			info->set_number_of_functions(exports.NumberOfFunctions);
-			info->set_number_of_names(exports.NumberOfNames);
-			info->set_ordinal_base(exports.Base);
-			info->set_rva_of_functions(exports.AddressOfFunctions);
-			info->set_rva_of_names(exports.AddressOfNames);
-			info->set_rva_of_name_ordinals(exports.AddressOfNameOrdinals);
-			info->set_timestamp(exports.TimeDateStamp);
-		}
-
-		if(!exports.NumberOfFunctions)
-			return ret;
-
-		//Check IMAGE_EXPORT_DIRECTORY fields
-		if(exports.NumberOfNames > exports.NumberOfFunctions)
-			throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-		//Check some export directory fields
-		if((!exports.AddressOfNameOrdinals && exports.AddressOfNames) ||
-			(exports.AddressOfNameOrdinals && !exports.AddressOfNames) ||
-			!exports.AddressOfFunctions
-			|| exports.NumberOfFunctions >= pe_utils::max_dword / sizeof(uint32_t)
-			|| exports.NumberOfNames > pe_utils::max_dword / sizeof(uint32_t)
-			|| !pe_utils::is_sum_safe(exports.AddressOfFunctions, exports.NumberOfFunctions * sizeof(uint32_t))
-			|| !pe_utils::is_sum_safe(exports.AddressOfNames, exports.NumberOfNames * sizeof(uint32_t))
-			|| !pe_utils::is_sum_safe(exports.AddressOfNameOrdinals, exports.NumberOfFunctions * sizeof(uint32_t))
-			|| !pe_utils::is_sum_safe(pe.get_directory_rva(image_directory_entry_export), pe.get_directory_size(image_directory_entry_export)))
-			throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-		//Check if it is enough bytes to hold AddressOfFunctions table
-		if(pe.section_data_length_from_rva(exports.AddressOfFunctions, exports.AddressOfFunctions, section_data_virtual, true)
-			< exports.NumberOfFunctions * sizeof(uint32_t))
-			throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-		if(exports.AddressOfNames)
-		{
-			//Check if it is enough bytes to hold name and ordinal tables
-			if(pe.section_data_length_from_rva(exports.AddressOfNameOrdinals, exports.AddressOfNameOrdinals, section_data_virtual, true)
-				< exports.NumberOfNames * sizeof(uint16_t))
-				throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-			if(pe.section_data_length_from_rva(exports.AddressOfNames, exports.AddressOfNames, section_data_virtual, true)
-				< exports.NumberOfNames * sizeof(uint32_t))
-				throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-		}
-		
-		for(uint32_t ordinal = 0; ordinal < exports.NumberOfFunctions; ordinal++)
-		{
-			//Get function address
-			//Sum and multiplication are safe (checked above)
-			uint32_t rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfFunctions + ordinal * sizeof(uint32_t), section_data_virtual, true);
-
-			//If we have a skip
-			if(!rva)
-				continue;
-
-			exported_function func;
-			func.set_rva(rva);
-
-			if(!pe_utils::is_sum_safe(exports.Base, ordinal) || exports.Base + ordinal > pe_utils::max_word)
-				throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-			func.set_ordinal(static_cast<uint16_t>(ordinal + exports.Base));
-
-			//Scan for function name ordinal
-			for(uint32_t i = 0; i < exports.NumberOfNames; i++)
-			{
-				uint16_t ordinal2 = pe.section_data_from_rva<uint16_t>(exports.AddressOfNameOrdinals + i * sizeof(uint16_t), section_data_virtual, true);
-
-				//If function has name (and name ordinal)
-				if(ordinal == ordinal2)
-				{
-					//Get function name
-					//Sum and multiplication are safe (checked above)
-					uint32_t function_name_rva = pe.section_data_from_rva<uint32_t>(exports.AddressOfNames + i * sizeof(uint32_t), section_data_virtual, true);
-
-					//Get byte count that we have for function name
-					if((max_name_length = pe.section_data_length_from_rva(function_name_rva, function_name_rva, section_data_virtual, true)) < 2)
-						throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-					//Get function name pointer
-					const char* func_name = pe.section_data_from_rva(function_name_rva, section_data_virtual, true);
-
-					//Check for null-termination
-					if(!pe_utils::is_null_terminated(func_name, max_name_length))
-						throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-					//Save function info
-					func.set_name(func_name);
-					func.set_name_ordinal(ordinal2);
-
-					//If the function is just a redirect, save its name
-					if(rva >= pe.get_directory_rva(image_directory_entry_export) + sizeof(image_directory_entry_export) &&
-						rva < pe.get_directory_rva(image_directory_entry_export) + pe.get_directory_size(image_directory_entry_export))
-					{
-						if((max_name_length = pe.section_data_length_from_rva(rva, rva, section_data_virtual, true)) < 2)
-							throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-						//Get forwarded function name pointer
-						const char* forwarded_func_name = pe.section_data_from_rva(rva, section_data_virtual, true);
-
-						//Check for null-termination
-						if(!pe_utils::is_null_terminated(forwarded_func_name, max_name_length))
-							throw pe_exception("Incorrect export directory", pe_exception::incorrect_export_directory);
-
-						//Set the name of forwarded function
-						func.set_forwarded_name(forwarded_func_name);
-					}
-
-					break;
-				}
-			}
-
-			//Add function info to output array
-			ret.push_back(func);
-		}
-	}
-
-	return ret;
-}
-
-//Helper export functions
-//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions>
-const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports)
-{
-	if(exports.empty())
-		return std::make_pair(0, 0);
-
-	uint16_t max_ordinal = 0; //Maximum ordinal number
-	uint16_t ordinal_base = pe_utils::max_word; //Minimum ordinal value
-	for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
-	{
-		const exported_function& func = (*it);
-
-		//Calculate maximum and minimum ordinal numbers
-		max_ordinal = std::max<uint16_t>(max_ordinal, func.get_ordinal());
-		ordinal_base = std::min<uint16_t>(ordinal_base, func.get_ordinal());
-	}
-
-	return std::make_pair(ordinal_base, max_ordinal);
-}
-
-//Checks if exported function name already exists
-bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports)
-{
-	for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
-	{
-		if((*it).has_name() && (*it).get_name() == function_name)
-			return true;
-	}
-
-	return false;
-}
-
-//Checks if exported function name already exists
-bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports)
-{
-	for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
-	{
-		if((*it).get_ordinal() == ordinal)
-			return true;
-	}
-
-	return false;
-}
-
-//Helper: sorts exported function list by ordinals
-bool ordinal_sorter::operator()(const exported_function& func1, const exported_function& func2) const
-{
-	return func1.get_ordinal() < func2.get_ordinal();
-}
-
-//Export directory rebuilder
-//info - export information
-//exported_functions_list - list of exported functions
-//exports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from exports_section raw data start
-//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
-//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
-//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
-//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
-//Returns new export directory information
-//exported_functions_list is copied intentionally to be sorted by ordinal values later
-//Name ordinals in exported function don't matter, they will be recalculated
-const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	//Check that exports_section is attached to this PE image
-	if(!pe.section_attached(exports_section))
-		throw pe_exception("Exports section must be attached to PE file", pe_exception::section_is_not_attached);
-
-	//Needed space for strings
-	uint32_t needed_size_for_strings = static_cast<uint32_t>(info.get_name().length() + 1);
-	uint32_t number_of_names = 0; //Number of named functions
-	uint32_t max_ordinal = 0; //Maximum ordinal number
-	uint32_t ordinal_base = static_cast<uint32_t>(-1); //Minimum ordinal value
-	
-	if(exports.empty())
-		ordinal_base = info.get_ordinal_base();
-
-	uint32_t needed_size_for_function_names = 0; //Needed space for function name strings
-	uint32_t needed_size_for_function_forwards = 0; //Needed space for function forwards names
-	
-	//List all exported functions
-	//Calculate needed size for function list
-	{
-		//Also check that there're no duplicate names and ordinals
-		std::set<std::string> used_function_names;
-		std::set<uint16_t> used_function_ordinals;
-
-		for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
-		{
-			const exported_function& func = (*it);
-			//Calculate maximum and minimum ordinal numbers
-			max_ordinal = std::max<uint32_t>(max_ordinal, func.get_ordinal());
-			ordinal_base = std::min<uint32_t>(ordinal_base, func.get_ordinal());
-
-			//Check if ordinal is unique
-			if(!used_function_ordinals.insert(func.get_ordinal()).second)
-				throw pe_exception("Duplicate exported function ordinal", pe_exception::duplicate_exported_function_ordinal);
-			
-			if(func.has_name())
-			{
-				//If function is named
-				++number_of_names;
-				needed_size_for_function_names += static_cast<uint32_t>(func.get_name().length() + 1);
-				
-				//Check if it's name and name ordinal are unique
-				if(!used_function_names.insert(func.get_name()).second)
-					throw pe_exception("Duplicate exported function name", pe_exception::duplicate_exported_function_name);
-			}
-
-			//If function is forwarded to another DLL
-			if(func.is_forwarded())
-				needed_size_for_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
-		}
-	}
-	
-	//Sort functions by ordinal value
-	std::sort(exports.begin(), exports.end(), ordinal_sorter());
-
-	//Calculate needed space for different things...
-	needed_size_for_strings += needed_size_for_function_names;
-	needed_size_for_strings += needed_size_for_function_forwards;
-	uint32_t needed_size_for_function_name_ordinals = number_of_names * sizeof(uint16_t);
-	uint32_t needed_size_for_function_name_rvas = number_of_names * sizeof(uint32_t);
-	uint32_t needed_size_for_function_addresses = (max_ordinal - ordinal_base + 1) * sizeof(uint32_t);
-	
-	//Export directory header will be placed first
-	uint32_t directory_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-
-	uint32_t needed_size = sizeof(image_export_directory); //Calculate needed size for export tables and strings
-	//sizeof(IMAGE_EXPORT_DIRECTORY) = export directory header
-
-	//Total needed space...
-	needed_size += needed_size_for_function_name_ordinals; //For list of names ordinals
-	needed_size += needed_size_for_function_addresses; //For function RVAs
-	needed_size += needed_size_for_strings; //For all strings
-	needed_size += needed_size_for_function_name_rvas; //For function name strings RVAs
-
-	//Check if exports_section is last one. If it's not, check if there's enough place for exports data
-	if(&exports_section != &*(pe.get_image_sections().end() - 1) && 
-		(exports_section.empty() || pe_utils::align_up(exports_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + directory_pos))
-		throw pe_exception("Insufficient space for export directory", pe_exception::insufficient_space);
-
-	std::string& raw_data = exports_section.get_raw_data();
-
-	//This will be done only if exports_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + directory_pos)
-		raw_data.resize(needed_size + directory_pos); //Expand section raw data
-
-	//Library name will be placed after it
-	uint32_t current_pos_of_function_names = static_cast<uint32_t>(info.get_name().length() + 1 + directory_pos + sizeof(image_export_directory));
-	//Next - function names
-	uint32_t current_pos_of_function_name_ordinals = current_pos_of_function_names + needed_size_for_function_names;
-	//Next - function name ordinals
-	uint32_t current_pos_of_function_forwards = current_pos_of_function_name_ordinals + needed_size_for_function_name_ordinals;
-	//Finally - function addresses
-	uint32_t current_pos_of_function_addresses = current_pos_of_function_forwards + needed_size_for_function_forwards;
-	//Next - function names RVAs
-	uint32_t current_pos_of_function_names_rvas = current_pos_of_function_addresses + needed_size_for_function_addresses;
-
-	{
-		//Create export directory and fill it
-		image_export_directory dir = {0};
-		dir.Characteristics = info.get_characteristics();
-		dir.MajorVersion = info.get_major_version();
-		dir.MinorVersion = info.get_minor_version();
-		dir.TimeDateStamp = info.get_timestamp();
-		dir.NumberOfFunctions = max_ordinal - ordinal_base + 1;
-		dir.NumberOfNames = number_of_names;
-		dir.Base = ordinal_base;
-		dir.AddressOfFunctions = pe.rva_from_section_offset(exports_section, current_pos_of_function_addresses);
-		dir.AddressOfNameOrdinals = pe.rva_from_section_offset(exports_section, current_pos_of_function_name_ordinals);
-		dir.AddressOfNames = pe.rva_from_section_offset(exports_section, current_pos_of_function_names_rvas);
-		dir.Name = pe.rva_from_section_offset(exports_section, directory_pos + sizeof(image_export_directory));
-
-		//Save it
-		memcpy(&raw_data[directory_pos], &dir, sizeof(dir));
-	}
-
-	//Sve library name
-	memcpy(&raw_data[directory_pos + sizeof(image_export_directory)], info.get_name().c_str(), info.get_name().length() + 1);
-
-	//A map to sort function names alphabetically
-	typedef std::map<std::string, uint16_t> funclist; //function name; function name ordinal
-	funclist funcs;
-
-	uint32_t last_ordinal = ordinal_base;
-	//Enumerate all exported functions
-	for(exported_functions_list::const_iterator it = exports.begin(); it != exports.end(); ++it)
-	{
-		const exported_function& func = (*it);
-
-		//If we're skipping some ordinals...
-		if(func.get_ordinal() > last_ordinal)
-		{
-			//Fill this function RVAs data with zeros
-			uint32_t len = sizeof(uint32_t) * (func.get_ordinal() - last_ordinal - 1);
-			if(len)
-			{
-				memset(&raw_data[current_pos_of_function_addresses], 0, len);
-				current_pos_of_function_addresses += len;
-			}
-			
-			//Save last encountered ordinal
-			last_ordinal = func.get_ordinal();
-		}
-		
-		//If function is named, save its name ordinal and name in sorted alphabetically order
-		if(func.has_name())
-			funcs.insert(std::make_pair(func.get_name(), static_cast<uint16_t>(func.get_ordinal() - ordinal_base))); //Calculate name ordinal
-
-		//If function is forwarded to another DLL
-		if(func.is_forwarded())
-		{
-			//Write its forwarded name and its RVA
-			uint32_t function_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_forwards);
-			memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva));
-			current_pos_of_function_addresses += sizeof(function_rva);
-
-			memcpy(&raw_data[current_pos_of_function_forwards], func.get_forwarded_name().c_str(), func.get_forwarded_name().length() + 1);
-			current_pos_of_function_forwards += static_cast<uint32_t>(func.get_forwarded_name().length() + 1);
-		}
-		else
-		{
-			//Write actual function RVA
-			uint32_t function_rva = func.get_rva();
-			memcpy(&raw_data[current_pos_of_function_addresses], &function_rva, sizeof(function_rva));
-			current_pos_of_function_addresses += sizeof(function_rva);
-		}
-	}
-	
-	//Enumerate sorted function names
-	for(funclist::const_iterator it = funcs.begin(); it != funcs.end(); ++it)
-	{
-		//Save function name RVA
-		uint32_t function_name_rva = pe.rva_from_section_offset(exports_section, current_pos_of_function_names);
-		memcpy(&raw_data[current_pos_of_function_names_rvas], &function_name_rva, sizeof(function_name_rva));
-		current_pos_of_function_names_rvas += sizeof(function_name_rva);
-
-		//Save function name
-		memcpy(&raw_data[current_pos_of_function_names], (*it).first.c_str(), (*it).first.length() + 1);
-		current_pos_of_function_names += static_cast<uint32_t>((*it).first.length() + 1);
-
-		//Save function name ordinal
-		uint16_t name_ordinal = (*it).second;
-		memcpy(&raw_data[current_pos_of_function_name_ordinals], &name_ordinal, sizeof(name_ordinal));
-		current_pos_of_function_name_ordinals += sizeof(name_ordinal);
-	}
-	
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(exports_section, auto_strip_last_section);
-	
-	image_directory ret(pe.rva_from_section_offset(exports_section, directory_pos), needed_size);
-
-	//If auto-rewrite of PE headers is required
-	if(save_to_pe_header)
-	{
-		pe.set_directory_rva(image_directory_entry_export, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_export, ret.get_size());
-	}
-
-	return ret;
-}
-}

+ 0 - 184
tools/pe_bliss/pe_exports.h

@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing exported function
-class exported_function
-{
-public:
-	//Default constructor
-	exported_function();
-
-	//Returns ordinal of function (actually, ordinal = hint + ordinal base)
-	uint16_t get_ordinal() const;
-
-	//Returns RVA of function
-	uint32_t get_rva() const;
-
-	//Returns true if function has name and name ordinal
-	bool has_name() const;
-	//Returns name of function
-	const std::string& get_name() const;
-	//Returns name ordinal of function
-	uint16_t get_name_ordinal() const;
-
-	//Returns true if function is forwarded to other library
-	bool is_forwarded() const;
-	//Returns the name of forwarded function
-	const std::string& get_forwarded_name() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild export directory
-
-	//Sets ordinal of function
-	void set_ordinal(uint16_t ordinal);
-
-	//Sets RVA of function
-	void set_rva(uint32_t rva);
-
-	//Sets name of function (or clears it, if empty name is passed)
-	void set_name(const std::string& name);
-	//Sets name ordinal
-	void set_name_ordinal(uint16_t name_ordinal);
-
-	//Sets forwarded function name (or clears it, if empty name is passed)
-	void set_forwarded_name(const std::string& name);
-
-private:
-	uint16_t ordinal_; //Function ordinal
-	uint32_t rva_; //Function RVA
-	std::string name_; //Function name
-	bool has_name_; //true == function has name
-	uint16_t name_ordinal_; //Function name ordinal
-	bool forward_; //true == function is forwarded
-	std::string forward_name_; //Name of forwarded function
-};
-
-//Class representing export information
-class export_info
-{
-public:
-	//Default constructor
-	export_info();
-
-	//Returns characteristics
-	uint32_t get_characteristics() const;
-	//Returns timestamp
-	uint32_t get_timestamp() const;
-	//Returns major version
-	uint16_t get_major_version() const;
-	//Returns minor version
-	uint16_t get_minor_version() const;
-	//Returns DLL name
-	const std::string& get_name() const;
-	//Returns ordinal base
-	uint32_t get_ordinal_base() const;
-	//Returns number of functions
-	uint32_t get_number_of_functions() const;
-	//Returns number of function names
-	uint32_t get_number_of_names() const;
-	//Returns RVA of function address table
-	uint32_t get_rva_of_functions() const;
-	//Returns RVA of function name address table
-	uint32_t get_rva_of_names() const;
-	//Returns RVA of name ordinals table
-	uint32_t get_rva_of_name_ordinals() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild export directory using rebuild_exports
-
-	//Sets characteristics
-	void set_characteristics(uint32_t characteristics);
-	//Sets timestamp
-	void set_timestamp(uint32_t timestamp);
-	//Sets major version
-	void set_major_version(uint16_t major_version);
-	//Sets minor version
-	void set_minor_version(uint16_t minor_version);
-	//Sets DLL name
-	void set_name(const std::string& name);
-	//Sets ordinal base
-	void set_ordinal_base(uint32_t ordinal_base);
-	//Sets number of functions
-	void set_number_of_functions(uint32_t number_of_functions);
-	//Sets number of function names
-	void set_number_of_names(uint32_t number_of_names);
-	//Sets RVA of function address table
-	void set_rva_of_functions(uint32_t rva_of_functions);
-	//Sets RVA of function name address table
-	void set_rva_of_names(uint32_t rva_of_names);
-	//Sets RVA of name ordinals table
-	void set_rva_of_name_ordinals(uint32_t rva_of_name_ordinals);
-
-private:
-	uint32_t characteristics_;
-	uint32_t timestamp_;
-	uint16_t major_version_;
-	uint16_t minor_version_;
-	std::string name_;
-	uint32_t ordinal_base_;
-	uint32_t number_of_functions_;
-	uint32_t number_of_names_;
-	uint32_t address_of_functions_;
-	uint32_t address_of_names_;
-	uint32_t address_of_name_ordinals_;
-};
-
-//Exported functions list typedef
-typedef std::vector<exported_function> exported_functions_list;
-
-//Returns array of exported functions
-const exported_functions_list get_exported_functions(const pe_base& pe);
-//Returns array of exported functions and information about export
-const exported_functions_list get_exported_functions(const pe_base& pe, export_info& info);
-	
-//Helper export functions
-//Returns pair: <ordinal base for supplied functions; maximum ordinal value for supplied functions>
-const std::pair<uint16_t, uint16_t> get_export_ordinal_limits(const exported_functions_list& exports);
-
-//Checks if exported function name already exists
-bool exported_name_exists(const std::string& function_name, const exported_functions_list& exports);
-
-//Checks if exported function ordinal already exists
-bool exported_ordinal_exists(uint16_t ordinal, const exported_functions_list& exports);
-
-//Export directory rebuilder
-//info - export information
-//exported_functions_list - list of exported functions
-//exports_section - section where export directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from exports_section raw data start
-//save_to_pe_headers - if true, new export directory information will be saved to PE image headers
-//auto_strip_last_section - if true and exports are placed in the last section, it will be automatically stripped
-//number_of_functions and number_of_names parameters don't matter in "info" when rebuilding, they're calculated independently
-//characteristics, major_version, minor_version, timestamp and name are the only used members of "info" structure
-//Returns new export directory information
-//exported_functions_list is copied intentionally to be sorted by ordinal values later
-//Name ordinals in exported function don't matter, they will be recalculated
-const image_directory rebuild_exports(pe_base& pe, const export_info& info, exported_functions_list exports, section& exports_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}

+ 0 - 43
tools/pe_bliss/pe_factory.cpp

@@ -1,43 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_factory.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-pe_base pe_factory::create_pe(std::istream& file, bool read_debug_raw_data)
-{
-	return pe_base::get_pe_type(file) == pe_type_32
-		? pe_base(file, pe_properties_32(), read_debug_raw_data)
-		: pe_base(file, pe_properties_64(), read_debug_raw_data);
-}
-
-pe_base pe_factory::create_pe(const char* file_path, bool read_debug_raw_data)
-{
-	std::ifstream pe_file(file_path, std::ios::in | std::ios::binary);
-	if(!pe_file)
-	{
-		throw pe_exception("Error in open file.", pe_exception::stream_is_bad);
-	}
-	return pe_factory::create_pe(pe_file,read_debug_raw_data);
-}
-}

+ 0 - 39
tools/pe_bliss/pe_factory.h

@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include <istream>
-#include <fstream>
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-class pe_factory
-{
-public:
-	//Creates pe_base class instance from PE or PE+ istream
-	//If read_bound_import_raw_data, raw bound import data will be read (used to get bound import info)
-	//If read_debug_raw_data, raw debug data will be read (used to get image debug info)
-	static pe_base create_pe(std::istream& file, bool read_debug_raw_data = true);
-	static pe_base create_pe(const char* file_path, bool read_debug_raw_data = true);
-};
-}

+ 0 - 777
tools/pe_bliss/pe_imports.cpp

@@ -1,777 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_imports.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//IMPORTS
-//Default constructor
-//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
-//to new value after import rebuilding
-//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
-//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
-//to be able to modify IAT thunks
-import_rebuilder_settings::import_rebuilder_settings(bool set_to_pe_headers, bool auto_zero_directory_entry_iat)
-	:offset_from_section_start_(0),
-	build_original_iat_(true),
-	save_iat_and_original_iat_rvas_(true),
-	fill_missing_original_iats_(false),
-	set_to_pe_headers_(set_to_pe_headers),
-	zero_directory_entry_iat_(auto_zero_directory_entry_iat),
-	rewrite_iat_and_original_iat_contents_(false),
-	auto_strip_last_section_(true)
-{}
-
-//Returns offset from section start where import directory data will be placed
-uint32_t import_rebuilder_settings::get_offset_from_section_start() const
-{
-	return offset_from_section_start_;
-}
-
-//Returns true if Original import address table (IAT) will be rebuilt
-bool import_rebuilder_settings::build_original_iat() const
-{
-	return build_original_iat_;
-}
-
-//Returns true if Original import address and import address tables will not be rebuilt,
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-bool import_rebuilder_settings::save_iat_and_original_iat_rvas() const
-{
-	return save_iat_and_original_iat_rvas_;
-}
-
-//Returns true if Original import address and import address tables contents will be rewritten
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-//and save_iat_and_original_iat_rvas is true
-bool import_rebuilder_settings::rewrite_iat_and_original_iat_contents() const
-{
-	return rewrite_iat_and_original_iat_contents_;
-}
-
-//Returns true if original missing IATs will be rebuilt
-//(only if IATs are saved)
-bool import_rebuilder_settings::fill_missing_original_iats() const
-{
-	return fill_missing_original_iats_;
-}
-
-//Returns true if PE headers should be updated automatically after rebuilding of imports
-bool import_rebuilder_settings::auto_set_to_pe_headers() const
-{
-	return set_to_pe_headers_;
-}
-
-//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-bool import_rebuilder_settings::zero_directory_entry_iat() const
-{
-	return zero_directory_entry_iat_;	
-}
-
-//Returns true if the last section should be stripped automatically, if imports are inside it
-bool import_rebuilder_settings::auto_strip_last_section_enabled() const
-{
-	return auto_strip_last_section_;
-}
-
-//Sets offset from section start where import directory data will be placed
-void import_rebuilder_settings::set_offset_from_section_start(uint32_t offset)
-{
-	offset_from_section_start_ = offset;
-}
-
-//Sets if Original import address table (IAT) will be rebuilt
-void import_rebuilder_settings::build_original_iat(bool enable)
-{
-	build_original_iat_ = enable;
-}
-
-//Sets if Original import address and import address tables will not be rebuilt,
-//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-void import_rebuilder_settings::save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents)
-{
-	save_iat_and_original_iat_rvas_ = enable;
-	if(save_iat_and_original_iat_rvas_)
-		rewrite_iat_and_original_iat_contents_ = enable_rewrite_iat_and_original_iat_contents;
-	else
-		rewrite_iat_and_original_iat_contents_ = false;
-}
-
-//Sets if original missing IATs will be rebuilt
-//(only if IATs are saved)
-void import_rebuilder_settings::fill_missing_original_iats(bool enable)
-{
-	fill_missing_original_iats_ = enable;
-}
-
-//Sets if PE headers should be updated automatically after rebuilding of imports
-void import_rebuilder_settings::auto_set_to_pe_headers(bool enable)
-{
-	set_to_pe_headers_ = enable;
-}
-
-//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-void import_rebuilder_settings::zero_directory_entry_iat(bool enable)
-{
-	zero_directory_entry_iat_ = enable;
-}
-
-//Sets if the last section should be stripped automatically, if imports are inside it, default true
-void import_rebuilder_settings::enable_auto_strip_last_section(bool enable)
-{
-	auto_strip_last_section_ = enable;
-}
-
-//Default constructor
-imported_function::imported_function()
-	:hint_(0), ordinal_(0), iat_va_(0)
-{}
-
-//Returns name of function
-const std::string& imported_function::get_name() const
-{
-	return name_;
-}
-
-//Returns true if imported function has name (and hint)
-bool imported_function::has_name() const
-{
-	return !name_.empty();
-}
-
-//Returns hint
-uint16_t imported_function::get_hint() const
-{
-	return hint_;
-}
-
-//Returns ordinal of function
-uint16_t imported_function::get_ordinal() const
-{
-	return ordinal_;
-}
-
-//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
-uint64_t imported_function::get_iat_va() const
-{
-	return iat_va_;
-}
-
-//Sets name of function
-void imported_function::set_name(const std::string& name)
-{
-	name_ = name;
-}
-
-//Sets hint
-void imported_function::set_hint(uint16_t hint)
-{
-	hint_ = hint;
-}
-
-//Sets ordinal
-void imported_function::set_ordinal(uint16_t ordinal)
-{
-	ordinal_ = ordinal;
-}
-
-//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
-void imported_function::set_iat_va(uint64_t va)
-{
-	iat_va_ = va;
-}
-
-//Default constructor
-import_library::import_library()
-	:rva_to_iat_(0), rva_to_original_iat_(0), timestamp_(0)
-{}
-
-//Returns name of library
-const std::string& import_library::get_name() const
-{
-	return name_;
-}
-
-//Returns RVA to Import Address Table (IAT)
-uint32_t import_library::get_rva_to_iat() const
-{
-	return rva_to_iat_;
-}
-
-//Returns RVA to Original Import Address Table (Original IAT)
-uint32_t import_library::get_rva_to_original_iat() const
-{
-	return rva_to_original_iat_;
-}
-
-//Returns timestamp
-uint32_t import_library::get_timestamp() const
-{
-	return timestamp_;
-}
-
-//Sets name of library
-void import_library::set_name(const std::string& name)
-{
-	name_ = name;
-}
-
-//Sets RVA to Import Address Table (IAT)
-void import_library::set_rva_to_iat(uint32_t rva_to_iat)
-{
-	rva_to_iat_ = rva_to_iat;
-}
-
-//Sets RVA to Original Import Address Table (Original IAT)
-void import_library::set_rva_to_original_iat(uint32_t rva_to_original_iat)
-{
-	rva_to_original_iat_ = rva_to_original_iat;
-}
-
-//Sets timestamp
-void import_library::set_timestamp(uint32_t timestamp)
-{
-	timestamp_ = timestamp;
-}
-
-//Returns imported functions list
-const import_library::imported_list& import_library::get_imported_functions() const
-{
-	return imports_;
-}
-
-//Adds imported function
-void import_library::add_import(const imported_function& func)
-{
-	imports_.push_back(func);
-}
-
-//Clears imported functions list
-void import_library::clear_imports()
-{
-	imports_.clear();
-}
-
-const imported_functions_list get_imported_functions(const pe_base& pe)
-{
-	return (pe.get_pe_type() == pe_type_32 ?
-		get_imported_functions_base<pe_types_class_32>(pe)
-		: get_imported_functions_base<pe_types_class_64>(pe));
-}
-
-const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings)
-{
-	return (pe.get_pe_type() == pe_type_32 ?
-		rebuild_imports_base<pe_types_class_32>(pe, imports, import_section, import_settings)
-		: rebuild_imports_base<pe_types_class_64>(pe, imports, import_section, import_settings));
-}
-
-//Returns imported functions list with related libraries info
-template<typename PEClassType>
-const imported_functions_list get_imported_functions_base(const pe_base& pe)
-{
-	imported_functions_list ret;
-
-	//If image has no imports, return empty array
-	if(!pe.has_imports())
-		return ret;
-
-	unsigned long current_descriptor_pos = pe.get_directory_rva(image_directory_entry_import);
-	//Get first IMAGE_IMPORT_DESCRIPTOR
-	image_import_descriptor import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true);
-
-	//Iterate them until we reach zero-element
-	//We don't need to check correctness of this, because exception will be thrown
-	//inside of loop if we go outsize of section
-	while(import_descriptor.Name)
-	{
-		//Get imported library information
-		import_library lib;
-
-		unsigned long max_name_length;
-		//Get byte count that we have for library name
-		if((max_name_length = pe.section_data_length_from_rva(import_descriptor.Name, import_descriptor.Name, section_data_virtual, true)) < 2)
-			throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
-		//Get DLL name pointer
-		const char* dll_name = pe.section_data_from_rva(import_descriptor.Name, section_data_virtual, true);
-
-		//Check for null-termination
-		if(!pe_utils::is_null_terminated(dll_name, max_name_length))
-			throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
-		//Set library name
-		lib.set_name(dll_name);
-		//Set library timestamp
-		lib.set_timestamp(import_descriptor.TimeDateStamp);
-		//Set library RVA to IAT and original IAT
-		lib.set_rva_to_iat(import_descriptor.FirstThunk);
-		lib.set_rva_to_original_iat(import_descriptor.OriginalFirstThunk);
-
-		//Get RVA to IAT (it must be filled by loader when loading PE)
-		uint32_t current_thunk_rva = import_descriptor.FirstThunk;
-		typename PEClassType::BaseSize import_address_table = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true);
-
-		//Get RVA to original IAT (lookup table), which must handle imported functions names
-		//Some linkers leave this pointer zero-filled
-		//Such image is valid, but it is not possible to restore imported functions names
-		//afted image was loaded, because IAT becomes the only one table
-		//containing both function names and function RVAs after loading
-		uint32_t current_original_thunk_rva = import_descriptor.OriginalFirstThunk;
-		typename PEClassType::BaseSize import_lookup_table = current_original_thunk_rva == 0 ? import_address_table : pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true);
-		if(current_original_thunk_rva == 0)
-			current_original_thunk_rva = current_thunk_rva;
-
-		//List all imported functions for current DLL
-		if(import_lookup_table != 0 && import_address_table != 0)
-		{
-			while(true)
-			{
-				//Imported function description
-				imported_function func;
-
-				//Get VA from IAT
-				typename PEClassType::BaseSize address = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_thunk_rva, section_data_virtual, true);
-				//Move pointer
-				current_thunk_rva += sizeof(typename PEClassType::BaseSize);
-
-				//Jump to next DLL if we finished with this one
-				if(!address)
-					break;
-
-				func.set_iat_va(address);
-
-				//Get VA from original IAT
-				typename PEClassType::BaseSize lookup = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_original_thunk_rva, section_data_virtual, true);
-				//Move pointer
-				current_original_thunk_rva += sizeof(typename PEClassType::BaseSize);
-
-				//Check if function is imported by ordinal
-				if((lookup & PEClassType::ImportSnapFlag) != 0)
-				{
-					//Set function ordinal
-					func.set_ordinal(static_cast<uint16_t>(lookup & 0xffff));
-				}
-				else
-				{
-					//Get byte count that we have for function name
-					if(lookup > static_cast<uint32_t>(-1) - sizeof(uint16_t))
-						throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
-					//Get maximum available length of function name
-					if((max_name_length = pe.section_data_length_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true)) < 2)
-						throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
-					//Get imported function name
-					const char* func_name = pe.section_data_from_rva(static_cast<uint32_t>(lookup + sizeof(uint16_t)), section_data_virtual, true);
-
-					//Check for null-termination
-					if(!pe_utils::is_null_terminated(func_name, max_name_length))
-						throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
-					//HINT in import table is ORDINAL in export table
-					uint16_t hint = pe.section_data_from_rva<uint16_t>(static_cast<uint32_t>(lookup), section_data_virtual, true);
-
-					//Save hint and name
-					func.set_name(func_name);
-					func.set_hint(hint);
-				}
-
-				//Add function to list
-				lib.add_import(func);
-			}
-		}
-
-		//Check possible overflow
-		if(!pe_utils::is_sum_safe(current_descriptor_pos, sizeof(image_import_descriptor)))
-			throw pe_exception("Incorrect import directory", pe_exception::incorrect_import_directory);
-
-		//Go to next library
-		current_descriptor_pos += sizeof(image_import_descriptor);
-		import_descriptor = pe.section_data_from_rva<image_import_descriptor>(current_descriptor_pos, section_data_virtual, true);
-
-		//Save import information
-		ret.push_back(lib);
-	}
-
-	//Return resulting list
-	return ret;
-}
-
-
-//Simple import directory rebuilder
-//You can get all image imports with get_imported_functions() function
-//You can use returned value to, for example, add new imported library with some functions
-//to the end of list of imported libraries
-//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
-//Don't add new imported functions to existing imported library entries, because this can cause
-//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
-//The safest way is just adding import libraries with functions to the end of imported_functions_list array
-template<typename PEClassType>
-const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings)
-{
-	//Check that import_section is attached to this PE image
-	if(!pe.section_attached(import_section))
-		throw pe_exception("Import section must be attached to PE file", pe_exception::section_is_not_attached);
-
-	uint32_t needed_size = 0; //Calculate needed size for import structures and strings
-	uint32_t needed_size_for_strings = 0; //Calculate needed size for import strings (library and function names and hints)
-	uint32_t size_of_iat = 0; //Size of IAT structures
-
-	needed_size += static_cast<uint32_t>((1 /* ending null descriptor */ + imports.size()) * sizeof(image_import_descriptor));
-	
-	//Enumerate imported functions
-	for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
-	{
-		needed_size_for_strings += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */);
-
-		const import_library::imported_list& funcs = (*it).get_imported_functions();
-
-		//IMAGE_THUNK_DATA
-		size_of_iat += static_cast<uint32_t>(sizeof(typename PEClassType::BaseSize) * (1 /*ending null */ + funcs.size()));
-
-		//Enumerate all imported functions in library
-		for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f)
-		{
-			if((*f).has_name())
-				needed_size_for_strings += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */);
-		}
-	}
-
-	if(import_settings.build_original_iat() || import_settings.fill_missing_original_iats())
-		needed_size += size_of_iat * 2; //We'll have two similar-sized IATs if we're building original IAT
-	else
-		needed_size += size_of_iat;
-
-	needed_size += sizeof(typename PEClassType::BaseSize); //Maximum align for IAT and original IAT
-	
-	//Total needed size for import structures and strings
-	needed_size += needed_size_for_strings;
-
-	//Check if import_section is last one. If it's not, check if there's enough place for import data
-	if(&import_section != &*(pe.get_image_sections().end() - 1) && 
-		(import_section.empty() || pe_utils::align_up(import_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + import_settings.get_offset_from_section_start()))
-		throw pe_exception("Insufficient space for import directory", pe_exception::insufficient_space);
-
-	std::string& raw_data = import_section.get_raw_data();
-
-	//This will be done only if image_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + import_settings.get_offset_from_section_start())
-		raw_data.resize(needed_size + import_settings.get_offset_from_section_start()); //Expand section raw data
-	
-	uint32_t current_string_pointer = import_settings.get_offset_from_section_start();/* we will paste structures after strings */
-	
-	//Position for IAT
-	uint32_t current_pos_for_iat = pe_utils::align_up(static_cast<uint32_t>(needed_size_for_strings + import_settings.get_offset_from_section_start() + (1 + imports.size()) * sizeof(image_import_descriptor)), sizeof(typename PEClassType::BaseSize));
-	//Position for original IAT
-	uint32_t current_pos_for_original_iat = current_pos_for_iat + size_of_iat;
-	//Position for import descriptors
-	uint32_t current_pos_for_descriptors = needed_size_for_strings + import_settings.get_offset_from_section_start();
-
-	//Build imports
-	for(imported_functions_list::const_iterator it = imports.begin(); it != imports.end(); ++it)
-	{
-		//Create import descriptor
-		image_import_descriptor descr;
-		memset(&descr, 0, sizeof(descr));
-		descr.TimeDateStamp = (*it).get_timestamp(); //Restore timestamp
-		descr.Name = pe.rva_from_section_offset(import_section, current_string_pointer); //Library name RVA
-
-		//If we should save IAT for current import descriptor
-		bool save_iats_for_this_descriptor = import_settings.save_iat_and_original_iat_rvas() && (*it).get_rva_to_iat() != 0;
-		//If we should write original IAT
-		bool write_original_iat = (!save_iats_for_this_descriptor && import_settings.build_original_iat()) || import_settings.fill_missing_original_iats();
-
-		//If we should rewrite saved original IAT for current import descriptor (without changing its position)
-		bool rewrite_saved_original_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && import_settings.build_original_iat();
-		//If we should rewrite saved IAT for current import descriptor (without changing its position)
-		bool rewrite_saved_iat = save_iats_for_this_descriptor && import_settings.rewrite_iat_and_original_iat_contents() && (*it).get_rva_to_iat() != 0;
-
-		//Helper values if we're rewriting existing IAT or orig.IAT
-		uint32_t original_first_thunk = 0;
-		uint32_t first_thunk = 0;
-
-		if(save_iats_for_this_descriptor)
-		{
-			//If there's no original IAT and we're asked to rebuild missing original IATs
-			if(!(*it).get_rva_to_original_iat() && import_settings.fill_missing_original_iats())
-				descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0;
-			else
-				descr.OriginalFirstThunk = import_settings.build_original_iat() ? (*it).get_rva_to_original_iat() : 0;
-			
-			descr.FirstThunk = (*it).get_rva_to_iat();
-
-			original_first_thunk = descr.OriginalFirstThunk;
-			first_thunk = descr.FirstThunk;
-
-			if(rewrite_saved_original_iat)
-			{
-				if((*it).get_rva_to_original_iat())
-					write_original_iat = true;
-				else
-					rewrite_saved_original_iat = false;
-			}
-
-			if(rewrite_saved_iat)
-				save_iats_for_this_descriptor = false;
-		}
-		else
-		{
-			//We are creating new IAT and original IAT (if needed)
-			descr.OriginalFirstThunk = import_settings.build_original_iat() ? pe.rva_from_section_offset(import_section, current_pos_for_original_iat) : 0;
-			descr.FirstThunk = pe.rva_from_section_offset(import_section, current_pos_for_iat);
-		}
-		
-		//Save import descriptor
-		memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr));
-		current_pos_for_descriptors += sizeof(descr);
-
-		//Save library name
-		memcpy(&raw_data[current_string_pointer], (*it).get_name().c_str(), (*it).get_name().length() + 1 /* nullbyte */);
-		current_string_pointer += static_cast<uint32_t>((*it).get_name().length() + 1 /* nullbyte */);
-		
-		//List all imported functions
-		const import_library::imported_list& funcs = (*it).get_imported_functions();
-		for(import_library::imported_list::const_iterator f = funcs.begin(); f != funcs.end(); ++f)
-		{
-			if((*f).has_name()) //If function is imported by name
-			{
-				//Get RVA of IMAGE_IMPORT_BY_NAME
-				typename PEClassType::BaseSize rva_of_named_import = pe.rva_from_section_offset(import_section, current_string_pointer);
-
-				if(!save_iats_for_this_descriptor)
-				{
-					if(write_original_iat)
-					{
-						//We're creating original IATs - so we can write to IAT saved VA (because IMAGE_IMPORT_BY_NAME will be read
-						//by PE loader from original IAT)
-						typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va());
-
-						if(rewrite_saved_iat)
-						{
-							if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value))
-								throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
-							memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value));
-
-							first_thunk += sizeof(iat_value);
-						}
-						else
-						{
-							memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value));
-							current_pos_for_iat += sizeof(rva_of_named_import);
-						}
-					}
-					else
-					{
-						//Else - write to IAT RVA of IMAGE_IMPORT_BY_NAME
-						if(rewrite_saved_iat)
-						{
-							if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import))
-								throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
-							memcpy(pe.section_data_from_rva(first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import));
-
-							first_thunk += sizeof(rva_of_named_import);
-						}
-						else
-						{
-							memcpy(&raw_data[current_pos_for_iat], &rva_of_named_import, sizeof(rva_of_named_import));
-							current_pos_for_iat += sizeof(rva_of_named_import);
-						}
-					}
-				}
-
-				if(write_original_iat)
-				{
-					if(rewrite_saved_original_iat)
-					{
-						if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(rva_of_named_import))
-							throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
-						memcpy(pe.section_data_from_rva(original_first_thunk, true), &rva_of_named_import, sizeof(rva_of_named_import));
-
-						original_first_thunk += sizeof(rva_of_named_import);
-					}
-					else
-					{
-						//We're creating original IATs
-						memcpy(&raw_data[current_pos_for_original_iat], &rva_of_named_import, sizeof(rva_of_named_import));
-						current_pos_for_original_iat += sizeof(rva_of_named_import);
-					}
-				}
-
-				//Write IMAGE_IMPORT_BY_NAME (WORD hint + string function name)
-				uint16_t hint = (*f).get_hint();
-				memcpy(&raw_data[current_string_pointer], &hint, sizeof(hint));
-				memcpy(&raw_data[current_string_pointer + sizeof(uint16_t)], (*f).get_name().c_str(), (*f).get_name().length() + 1 /* nullbyte */);
-				current_string_pointer += static_cast<uint32_t>((*f).get_name().length() + 1 /* nullbyte */ + sizeof(uint16_t) /* hint */);
-			}
-			else //Function is imported by ordinal
-			{
-				uint16_t ordinal = (*f).get_ordinal();
-				typename PEClassType::BaseSize thunk_value = ordinal;
-				thunk_value |= PEClassType::ImportSnapFlag; //Imported by ordinal
-
-				if(!save_iats_for_this_descriptor)
-				{
-					if(write_original_iat)
-					{
-						//We're creating original IATs - so we can wtire to IAT saved VA (because ordinal will be read
-						//by PE loader from original IAT)
-						typename PEClassType::BaseSize iat_value = static_cast<typename PEClassType::BaseSize>((*f).get_iat_va());
-						if(rewrite_saved_iat)
-						{
-							if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(iat_value))
-								throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
-							memcpy(pe.section_data_from_rva(first_thunk, true), &iat_value, sizeof(iat_value));
-
-							first_thunk += sizeof(iat_value);
-						}
-						else
-						{
-							memcpy(&raw_data[current_pos_for_iat], &iat_value, sizeof(iat_value));
-							current_pos_for_iat += sizeof(thunk_value);
-						}
-					}
-					else
-					{
-						//Else - write ordinal to IAT
-						if(rewrite_saved_iat)
-						{
-							if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value))
-								throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
-							memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value));
-
-							first_thunk += sizeof(thunk_value);
-						}
-						else
-						{
-							memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value));
-						}
-					}
-				}
-
-				//We're writing ordinal to original IAT slot
-				if(write_original_iat)
-				{
-					if(rewrite_saved_original_iat)
-					{
-						if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value))
-							throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
-						memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value));
-
-						original_first_thunk += sizeof(thunk_value);
-					}
-					else
-					{
-						memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value));
-						current_pos_for_original_iat += sizeof(thunk_value);
-					}
-				}
-			}
-		}
-
-		if(!save_iats_for_this_descriptor)
-		{
-			//Ending null thunks
-			typename PEClassType::BaseSize thunk_value = 0;
-
-			if(rewrite_saved_iat)
-			{
-				if(pe.section_data_length_from_rva(first_thunk, first_thunk, section_data_raw, true) <= sizeof(thunk_value))
-					throw pe_exception("Insufficient space inside initial IAT", pe_exception::insufficient_space);
-
-				memcpy(pe.section_data_from_rva(first_thunk, true), &thunk_value, sizeof(thunk_value));
-
-				first_thunk += sizeof(thunk_value);
-			}
-			else
-			{
-				memcpy(&raw_data[current_pos_for_iat], &thunk_value, sizeof(thunk_value));
-				current_pos_for_iat += sizeof(thunk_value);
-			}
-		}
-
-		if(write_original_iat)
-		{
-			//Ending null thunks
-			typename PEClassType::BaseSize thunk_value = 0;
-
-			if(rewrite_saved_original_iat)
-			{
-				if(pe.section_data_length_from_rva(original_first_thunk, original_first_thunk, section_data_raw, true) <= sizeof(thunk_value))
-					throw pe_exception("Insufficient space inside initial original IAT", pe_exception::insufficient_space);
-
-				memcpy(pe.section_data_from_rva(original_first_thunk, true), &thunk_value, sizeof(thunk_value));
-
-				original_first_thunk += sizeof(thunk_value);
-			}
-			else
-			{
-				memcpy(&raw_data[current_pos_for_original_iat], &thunk_value, sizeof(thunk_value));
-				current_pos_for_original_iat += sizeof(thunk_value);
-			}
-		}
-	}
-
-	{
-		//Null ending descriptor
-		image_import_descriptor descr;
-		memset(&descr, 0, sizeof(descr));
-		memcpy(&raw_data[current_pos_for_descriptors], &descr, sizeof(descr));
-	}
-
-	//Strip data a little, if we saved some place
-	//We're allocating more space than needed, if present original IAT and IAT are saved
-	raw_data.resize(current_pos_for_original_iat);
-
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(import_section, import_settings.auto_strip_last_section_enabled());
-
-	//Return information about rebuilt import directory
-	image_directory ret(pe.rva_from_section_offset(import_section, import_settings.get_offset_from_section_start() + needed_size_for_strings), needed_size - needed_size_for_strings);
-
-	//If auto-rewrite of PE headers is required
-	if(import_settings.auto_set_to_pe_headers())
-	{
-		pe.set_directory_rva(image_directory_entry_import, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_import, ret.get_size());
-
-		//If we are requested to zero IMAGE_DIRECTORY_ENTRY_IAT also
-		if(import_settings.zero_directory_entry_iat())
-		{
-			pe.set_directory_rva(image_directory_entry_iat, 0);
-			pe.set_directory_size(image_directory_entry_iat, 0);
-		}
-	}
-
-	return ret;
-}
-}

+ 0 - 208
tools/pe_bliss/pe_imports.h

@@ -1,208 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include "pe_structures.h"
-#include "pe_directory.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Class representing imported function
-class imported_function
-{
-public:
-	//Default constructor
-	imported_function();
-
-	//Returns true if imported function has name (and hint)
-	bool has_name() const;
-	//Returns name of function
-	const std::string& get_name() const;
-	//Returns hint
-	uint16_t get_hint() const;
-	//Returns ordinal of function
-	uint16_t get_ordinal() const;
-
-	//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
-	uint64_t get_iat_va() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
-	//You also can use them to rebuild image imports
-	//Sets name of function
-	void set_name(const std::string& name);
-	//Sets hint
-	void set_hint(uint16_t hint);
-	//Sets ordinal
-	void set_ordinal(uint16_t ordinal);
-
-	//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
-	void set_iat_va(uint64_t rva);
-
-private:
-	std::string name_; //Function name
-	uint16_t hint_; //Hint
-	uint16_t ordinal_; //Ordinal
-	uint64_t iat_va_;
-};
-
-//Class representing imported library information
-class import_library
-{
-public:
-	typedef std::vector<imported_function> imported_list;
-
-public:
-	//Default constructor
-	import_library();
-
-	//Returns name of library
-	const std::string& get_name() const;
-	//Returns RVA to Import Address Table (IAT)
-	uint32_t get_rva_to_iat() const;
-	//Returns RVA to Original Import Address Table (Original IAT)
-	uint32_t get_rva_to_original_iat() const;
-	//Returns timestamp
-	uint32_t get_timestamp() const;
-
-	//Returns imported functions list
-	const imported_list& get_imported_functions() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
-	//You also can use them to rebuild image imports
-	//Sets name of library
-	void set_name(const std::string& name);
-	//Sets RVA to Import Address Table (IAT)
-	void set_rva_to_iat(uint32_t rva_to_iat);
-	//Sets RVA to Original Import Address Table (Original IAT)
-	void set_rva_to_original_iat(uint32_t rva_to_original_iat);
-	//Sets timestamp
-	void set_timestamp(uint32_t timestamp);
-
-	//Adds imported function
-	void add_import(const imported_function& func);
-	//Clears imported functions list
-	void clear_imports();
-
-private:
-	std::string name_; //Library name
-	uint32_t rva_to_iat_; //RVA to IAT
-	uint32_t rva_to_original_iat_; //RVA to original IAT
-	uint32_t timestamp_; //DLL TimeStamp
-
-	imported_list imports_;
-};
-
-//Simple import directory rebuilder
-//Class representing import rebuilder advanced settings
-class import_rebuilder_settings
-{
-public:
-	//Default constructor
-	//Default constructor
-	//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
-	//to new value after import rebuilding
-	//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
-	//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
-	//to be able to modify IAT thunks
-	explicit import_rebuilder_settings(bool set_to_pe_headers = true, bool auto_zero_directory_entry_iat = false);
-
-	//Returns offset from section start where import directory data will be placed
-	uint32_t get_offset_from_section_start() const;
-	//Returns true if Original import address table (IAT) will be rebuilt
-	bool build_original_iat() const;
-
-	//Returns true if Original import address and import address tables will not be rebuilt,
-	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-	bool save_iat_and_original_iat_rvas() const;
-	//Returns true if Original import address and import address tables contents will be rewritten
-	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-	//and save_iat_and_original_iat_rvas is true
-	bool rewrite_iat_and_original_iat_contents() const;
-
-	//Returns true if original missing IATs will be rebuilt
-	//(only if IATs are saved)
-	bool fill_missing_original_iats() const;
-	//Returns true if PE headers should be updated automatically after rebuilding of imports
-	bool auto_set_to_pe_headers() const;
-	//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-	bool zero_directory_entry_iat() const;
-
-	//Returns true if the last section should be stripped automatically, if imports are inside it
-	bool auto_strip_last_section_enabled() const;
-
-public: //Setters
-	//Sets offset from section start where import directory data will be placed
-	void set_offset_from_section_start(uint32_t offset);
-	//Sets if Original import address table (IAT) will be rebuilt
-	void build_original_iat(bool enable);
-	//Sets if Original import address and import address tables will not be rebuilt,
-	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-	//enable_rewrite_iat_and_original_iat_contents sets if Original import address and import address tables contents will be rewritten
-	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
-	//and save_iat_and_original_iat_rvas is true
-	void save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents = false);
-	//Sets if original missing IATs will be rebuilt
-	//(only if IATs are saved)
-	void fill_missing_original_iats(bool enable);
-	//Sets if PE headers should be updated automatically after rebuilding of imports
-	void auto_set_to_pe_headers(bool enable);
-	//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
-	void zero_directory_entry_iat(bool enable);
-
-	//Sets if the last section should be stripped automatically, if imports are inside it, default true
-	void enable_auto_strip_last_section(bool enable);
-
-private:
-	uint32_t offset_from_section_start_;
-	bool build_original_iat_;
-	bool save_iat_and_original_iat_rvas_;
-	bool fill_missing_original_iats_;
-	bool set_to_pe_headers_;
-	bool zero_directory_entry_iat_;
-	bool rewrite_iat_and_original_iat_contents_;
-	bool auto_strip_last_section_;
-};
-
-typedef std::vector<import_library> imported_functions_list;
-
-
-//Returns imported functions list with related libraries info
-const imported_functions_list get_imported_functions(const pe_base& pe);
-
-template<typename PEClassType>
-const imported_functions_list get_imported_functions_base(const pe_base& pe);
-
-
-//You can get all image imports with get_imported_functions() function
-//You can use returned value to, for example, add new imported library with some functions
-//to the end of list of imported libraries
-//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
-//Don't add new imported functions to existing imported library entries, because this can cause
-//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
-//The safest way is just adding import libraries with functions to the end of imported_functions_list array
-const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
-
-template<typename PEClassType>
-const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
-}

+ 0 - 557
tools/pe_bliss/pe_load_config.cpp

@@ -1,557 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "pe_load_config.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//IMAGE CONFIG
-//Default constructor
-image_config_info::image_config_info()
-	:time_stamp_(0),
-	major_version_(0), minor_version_(0),
-	global_flags_clear_(0), global_flags_set_(0),
-	critical_section_default_timeout_(0),
-	decommit_free_block_threshold_(0), decommit_total_free_threshold_(0),
-	lock_prefix_table_va_(0),
-	max_allocation_size_(0),
-	virtual_memory_threshold_(0),
-	process_affinity_mask_(0),
-	process_heap_flags_(0),
-	service_pack_version_(0),
-	edit_list_va_(0),
-	security_cookie_va_(0),
-	se_handler_table_va_(0),
-	se_handler_count_(0)
-{}
-
-//Constructors from PE structures
-template<typename ConfigStructure>
-image_config_info::image_config_info(const ConfigStructure& info)
-	:time_stamp_(info.TimeDateStamp),
-	major_version_(info.MajorVersion), minor_version_(info.MinorVersion),
-	global_flags_clear_(info.GlobalFlagsClear), global_flags_set_(info.GlobalFlagsSet),
-	critical_section_default_timeout_(info.CriticalSectionDefaultTimeout),
-	decommit_free_block_threshold_(info.DeCommitFreeBlockThreshold), decommit_total_free_threshold_(info.DeCommitTotalFreeThreshold),
-	lock_prefix_table_va_(info.LockPrefixTable),
-	max_allocation_size_(info.MaximumAllocationSize),
-	virtual_memory_threshold_(info.VirtualMemoryThreshold),
-	process_affinity_mask_(info.ProcessAffinityMask),
-	process_heap_flags_(info.ProcessHeapFlags),
-	service_pack_version_(info.CSDVersion),
-	edit_list_va_(info.EditList),
-	security_cookie_va_(info.SecurityCookie),
-	se_handler_table_va_(info.SEHandlerTable),
-	se_handler_count_(info.SEHandlerCount)
-{}
-
-//Instantiate template constructor with needed structures
-template image_config_info::image_config_info(const image_load_config_directory32& info);
-template image_config_info::image_config_info(const image_load_config_directory64& info);
-
-//Returns the date and time stamp value
-uint32_t image_config_info::get_time_stamp() const
-{
-	return time_stamp_;
-}
-
-//Returns major version number
-uint16_t image_config_info::get_major_version() const
-{
-	return major_version_;
-}
-
-//Returns minor version number
-uint16_t image_config_info::get_minor_version() const
-{
-	return minor_version_;
-}
-
-//Returns clear global flags
-uint32_t image_config_info::get_global_flags_clear() const
-{
-	return global_flags_clear_;
-}
-
-//Returns set global flags
-uint32_t image_config_info::get_global_flags_set() const
-{
-	return global_flags_set_;
-}
-
-//Returns critical section default timeout
-uint32_t image_config_info::get_critical_section_default_timeout() const
-{
-	return critical_section_default_timeout_;
-}
-
-//Get the size of the minimum block that
-//must be freed before it is freed (de-committed), in bytes
-uint64_t image_config_info::get_decommit_free_block_threshold() const
-{
-	return decommit_free_block_threshold_;
-}
-
-//Returns the size of the minimum total memory
-//that must be freed in the process heap before it is freed (de-committed), in bytes
-uint64_t image_config_info::get_decommit_total_free_threshold() const
-{
-	return decommit_total_free_threshold_;
-}
-
-//Returns VA of a list of addresses where the LOCK prefix is used
-uint64_t image_config_info::get_lock_prefix_table_va() const
-{
-	return lock_prefix_table_va_;
-}
-
-//Returns the maximum allocation size, in bytes
-uint64_t image_config_info::get_max_allocation_size() const
-{
-	return max_allocation_size_;
-}
-
-//Returns the maximum block size that can be allocated from heap segments, in bytes
-uint64_t image_config_info::get_virtual_memory_threshold() const
-{
-	return virtual_memory_threshold_;
-}
-
-//Returns process affinity mask
-uint64_t image_config_info::get_process_affinity_mask() const
-{
-	return process_affinity_mask_;
-}
-
-//Returns process heap flags
-uint32_t image_config_info::get_process_heap_flags() const
-{
-	return process_heap_flags_;
-}
-
-//Returns service pack version (CSDVersion)
-uint16_t image_config_info::get_service_pack_version() const
-{
-	return service_pack_version_;
-}
-
-//Returns VA of edit list (reserved by system)
-uint64_t image_config_info::get_edit_list_va() const
-{
-	return edit_list_va_;
-}
-
-//Returns a pointer to a cookie that is used by Visual C++ or GS implementation
-uint64_t image_config_info::get_security_cookie_va() const
-{
-	return security_cookie_va_;
-}
-
-//Returns VA of the sorted table of RVAs of each valid, unique handler in the image
-uint64_t image_config_info::get_se_handler_table_va() const
-{
-	return se_handler_table_va_;
-}
-
-//Returns the count of unique handlers in the table
-uint64_t image_config_info::get_se_handler_count() const
-{
-	return se_handler_count_;
-}
-
-//Returns SE Handler RVA list
-const image_config_info::se_handler_list& image_config_info::get_se_handler_rvas() const
-{
-	return se_handlers_;
-}
-
-//Returns Lock Prefix RVA list
-const image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas() const
-{
-	return lock_prefixes_;
-}
-
-//Adds SE Handler RVA to list
-void image_config_info::add_se_handler_rva(uint32_t rva)
-{
-	se_handlers_.push_back(rva);
-}
-
-//Clears SE Handler list
-void image_config_info::clear_se_handler_list()
-{
-	se_handlers_.clear();
-}
-
-//Adds Lock Prefix RVA to list
-void image_config_info::add_lock_prefix_rva(uint32_t rva)
-{
-	lock_prefixes_.push_back(rva);
-}
-
-//Clears Lock Prefix list
-void image_config_info::clear_lock_prefix_list()
-{
-	lock_prefixes_.clear();
-}
-
-//Sets the date and time stamp value
-void image_config_info::set_time_stamp(uint32_t time_stamp)
-{
-	time_stamp_ = time_stamp;
-}
-
-//Sets major version number
-void image_config_info::set_major_version(uint16_t major_version)
-{
-	major_version_ = major_version;
-}
-
-//Sets minor version number
-void image_config_info::set_minor_version(uint16_t minor_version)
-{
-	minor_version_ = minor_version;
-}
-
-//Sets clear global flags
-void image_config_info::set_global_flags_clear(uint32_t global_flags_clear)
-{
-	global_flags_clear_ = global_flags_clear;
-}
-
-//Sets set global flags
-void image_config_info::set_global_flags_set(uint32_t global_flags_set)
-{
-	global_flags_set_ = global_flags_set;
-}
-
-//Sets critical section default timeout
-void image_config_info::set_critical_section_default_timeout(uint32_t critical_section_default_timeout)
-{
-	critical_section_default_timeout_ = critical_section_default_timeout;
-}
-
-//Sets the size of the minimum block that
-//must be freed before it is freed (de-committed), in bytes
-void image_config_info::set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold)
-{
-	decommit_free_block_threshold_ = decommit_free_block_threshold;
-}
-
-//Sets the size of the minimum total memory
-//that must be freed in the process heap before it is freed (de-committed), in bytes
-void image_config_info::set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold)
-{
-	decommit_total_free_threshold_ = decommit_total_free_threshold;
-}
-
-//Sets VA of a list of addresses where the LOCK prefix is used
-//If you rebuild this list, VA will be re-assigned automatically
-void image_config_info::set_lock_prefix_table_va(uint64_t lock_prefix_table_va)
-{
-	lock_prefix_table_va_ = lock_prefix_table_va;
-}
-
-//Sets the maximum allocation size, in bytes
-void image_config_info::set_max_allocation_size(uint64_t max_allocation_size)
-{
-	max_allocation_size_ = max_allocation_size;
-}
-
-//Sets the maximum block size that can be allocated from heap segments, in bytes
-void image_config_info::set_virtual_memory_threshold(uint64_t virtual_memory_threshold)
-{
-	virtual_memory_threshold_ = virtual_memory_threshold;
-}
-
-//Sets process affinity mask
-void image_config_info::set_process_affinity_mask(uint64_t process_affinity_mask)
-{
-	process_affinity_mask_ = process_affinity_mask;
-}
-
-//Sets process heap flags
-void image_config_info::set_process_heap_flags(uint32_t process_heap_flags)
-{
-	process_heap_flags_ = process_heap_flags;
-}
-
-//Sets service pack version (CSDVersion)
-void image_config_info::set_service_pack_version(uint16_t service_pack_version)
-{
-	service_pack_version_ = service_pack_version;
-}
-
-//Sets VA of edit list (reserved by system)
-void image_config_info::set_edit_list_va(uint64_t edit_list_va)
-{
-	edit_list_va_ = edit_list_va;
-}
-
-//Sets a pointer to a cookie that is used by Visual C++ or GS implementation
-void image_config_info::set_security_cookie_va(uint64_t security_cookie_va)
-{
-	security_cookie_va_ = security_cookie_va;
-}
-
-//Sets VA of the sorted table of RVAs of each valid, unique handler in the image
-//If you rebuild this list, VA will be re-assigned automatically
-void image_config_info::set_se_handler_table_va(uint64_t se_handler_table_va)
-{
-	se_handler_table_va_ = se_handler_table_va;
-}
-
-//Returns SE Handler RVA list
-image_config_info::se_handler_list& image_config_info::get_se_handler_rvas()
-{
-	return se_handlers_;
-}
-
-//Returns Lock Prefix RVA list
-image_config_info::lock_prefix_rva_list& image_config_info::get_lock_prefix_rvas()
-{
-	return lock_prefixes_;
-}
-
-//Returns image config info
-//If image does not have config info, throws an exception
-const image_config_info get_image_config(const pe_base& pe)
-{
-	return pe.get_pe_type() == pe_type_32
-		? get_image_config_base<pe_types_class_32>(pe)
-		: get_image_config_base<pe_types_class_64>(pe);
-}
-
-//Image config rebuilder
-const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	return pe.get_pe_type() == pe_type_32
-		? rebuild_image_config_base<pe_types_class_32>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section)
-		: rebuild_image_config_base<pe_types_class_64>(pe, info, image_config_section, offset_from_section_start, write_se_handlers, write_lock_prefixes, save_to_pe_header, auto_strip_last_section);
-}
-
-
-//Returns image config info
-//If image does not have config info, throws an exception
-template<typename PEClassType>
-const image_config_info get_image_config_base(const pe_base& pe)
-{
-	//Check if image has config directory
-	if(!pe.has_config())
-		throw pe_exception("Image does not have load config directory", pe_exception::directory_does_not_exist);
-
-	//Get load config structure
-	typename PEClassType::ConfigStruct config_info = pe.section_data_from_rva<typename PEClassType::ConfigStruct>(pe.get_directory_rva(image_directory_entry_load_config), section_data_virtual);
-
-	//Check size of config directory
-	if(config_info.Size != sizeof(config_info))
-		throw pe_exception("Incorrect (or old) load config directory", pe_exception::incorrect_config_directory);
-
-	//Fill return structure
-	image_config_info ret(config_info);
-
-	//Check possible overflow
-	if(config_info.SEHandlerCount >= pe_utils::max_dword / sizeof(uint32_t)
-		|| config_info.SEHandlerTable >= static_cast<typename PEClassType::BaseSize>(-1) - config_info.SEHandlerCount * sizeof(uint32_t))
-		throw pe_exception("Incorrect load config directory", pe_exception::incorrect_config_directory);
-
-	//Read sorted SE handler RVA list (if any)
-	for(typename PEClassType::BaseSize i = 0; i != config_info.SEHandlerCount; ++i)
-		ret.add_se_handler_rva(pe.section_data_from_va<uint32_t>(static_cast<typename PEClassType::BaseSize>(config_info.SEHandlerTable + i * sizeof(uint32_t))));
-
-	if(config_info.LockPrefixTable)
-	{
-		//Read Lock Prefix VA list (if any)
-		unsigned long current = 0;
-		while(true)
-		{
-			typename PEClassType::BaseSize lock_prefix_va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(config_info.LockPrefixTable + current * sizeof(typename PEClassType::BaseSize)));
-			if(!lock_prefix_va)
-				break;
-
-			ret.add_lock_prefix_rva(pe.va_to_rva(lock_prefix_va));
-
-			++current;
-		}
-	}
-
-	return ret;
-}
-
-//Image config directory rebuilder
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure
-//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure
-template<typename PEClassType>
-const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start, bool write_se_handlers, bool write_lock_prefixes, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	//Check that image_config_section is attached to this PE image
-	if(!pe.section_attached(image_config_section))
-		throw pe_exception("Image Config section must be attached to PE file", pe_exception::section_is_not_attached);
-	
-	uint32_t alignment = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize)) - offset_from_section_start;
-
-	uint32_t needed_size = sizeof(typename PEClassType::ConfigStruct); //Calculate needed size for Image Config table
-	
-	uint32_t image_config_data_pos = offset_from_section_start + alignment;
-
-	uint32_t current_pos_of_se_handlers = 0;
-	uint32_t current_pos_of_lock_prefixes = 0;
-	
-	if(write_se_handlers)
-	{
-		current_pos_of_se_handlers = needed_size + image_config_data_pos;
-		needed_size += static_cast<uint32_t>(info.get_se_handler_rvas().size()) * sizeof(uint32_t); //RVAs of SE Handlers
-	}
-	
-	if(write_lock_prefixes)
-	{
-		current_pos_of_lock_prefixes = needed_size + image_config_data_pos;
-		needed_size += static_cast<uint32_t>((info.get_lock_prefix_rvas().size() + 1) * sizeof(typename PEClassType::BaseSize)); //VAs of Lock Prefixes (and ending null element)
-	}
-
-	//Check if image_config_section is last one. If it's not, check if there's enough place for Image Config data
-	if(&image_config_section != &*(pe.get_image_sections().end() - 1) && 
-		(image_config_section.empty() || pe_utils::align_up(image_config_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + image_config_data_pos))
-		throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
-
-	std::string& raw_data = image_config_section.get_raw_data();
-
-	//This will be done only if image_config_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + image_config_data_pos)
-		raw_data.resize(needed_size + image_config_data_pos); //Expand section raw data
-
-	//Create and fill Image Config structure
-	typename PEClassType::ConfigStruct image_config_section_struct = {0};
-	image_config_section_struct.Size = sizeof(image_config_section_struct);
-	image_config_section_struct.TimeDateStamp = info.get_time_stamp();
-	image_config_section_struct.MajorVersion = info.get_major_version();
-	image_config_section_struct.MinorVersion = info.get_minor_version();
-	image_config_section_struct.GlobalFlagsClear = info.get_global_flags_clear();
-	image_config_section_struct.GlobalFlagsSet = info.get_global_flags_set();
-	image_config_section_struct.CriticalSectionDefaultTimeout = info.get_critical_section_default_timeout();
-	image_config_section_struct.DeCommitFreeBlockThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_free_block_threshold());
-	image_config_section_struct.DeCommitTotalFreeThreshold = static_cast<typename PEClassType::BaseSize>(info.get_decommit_total_free_threshold());
-	image_config_section_struct.MaximumAllocationSize = static_cast<typename PEClassType::BaseSize>(info.get_max_allocation_size());
-	image_config_section_struct.VirtualMemoryThreshold = static_cast<typename PEClassType::BaseSize>(info.get_virtual_memory_threshold());
-	image_config_section_struct.ProcessHeapFlags = info.get_process_heap_flags();
-	image_config_section_struct.ProcessAffinityMask = static_cast<typename PEClassType::BaseSize>(info.get_process_affinity_mask());
-	image_config_section_struct.CSDVersion = info.get_service_pack_version();
-	image_config_section_struct.EditList = static_cast<typename PEClassType::BaseSize>(info.get_edit_list_va());
-	image_config_section_struct.SecurityCookie = static_cast<typename PEClassType::BaseSize>(info.get_security_cookie_va());
-	image_config_section_struct.SEHandlerCount = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_rvas().size());
-	
-
-	if(write_se_handlers)
-	{
-		if(info.get_se_handler_rvas().empty())
-		{
-			write_se_handlers = false;
-			image_config_section_struct.SEHandlerTable = 0;
-		}
-		else
-		{
-			typename PEClassType::BaseSize va;
-			pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_se_handlers), va);
-			image_config_section_struct.SEHandlerTable = va;
-		}
-	}
-	else
-	{
-		image_config_section_struct.SEHandlerTable = static_cast<typename PEClassType::BaseSize>(info.get_se_handler_table_va());
-	}
-
-	if(write_lock_prefixes)
-	{
-		if(info.get_lock_prefix_rvas().empty())
-		{
-			write_lock_prefixes = false;
-			image_config_section_struct.LockPrefixTable = 0;
-		}
-		else
-		{
-			typename PEClassType::BaseSize va;
-			pe.rva_to_va(pe.rva_from_section_offset(image_config_section, current_pos_of_lock_prefixes), va);
-			image_config_section_struct.LockPrefixTable = va;
-		}
-	}
-	else
-	{
-		image_config_section_struct.LockPrefixTable = static_cast<typename PEClassType::BaseSize>(info.get_lock_prefix_table_va());
-	}
-
-	//Write image config section
-	memcpy(&raw_data[image_config_data_pos], &image_config_section_struct, sizeof(image_config_section_struct));
-
-	if(write_se_handlers)
-	{
-		//Sort SE Handlers list
-		image_config_info::se_handler_list sorted_list = info.get_se_handler_rvas();
-		std::sort(sorted_list.begin(), sorted_list.end());
-
-		//Write SE Handlers table
-		for(image_config_info::se_handler_list::const_iterator it = sorted_list.begin(); it != sorted_list.end(); ++it)
-		{
-			uint32_t se_handler_rva = *it;
-			memcpy(&raw_data[current_pos_of_se_handlers], &se_handler_rva, sizeof(se_handler_rva));
-			current_pos_of_se_handlers += sizeof(se_handler_rva);
-		}
-	}
-
-	if(write_lock_prefixes)
-	{
-		//Write Lock Prefixes VA list
-		for(image_config_info::lock_prefix_rva_list::const_iterator it = info.get_lock_prefix_rvas().begin(); it != info.get_lock_prefix_rvas().end(); ++it)
-		{
-			typename PEClassType::BaseSize lock_prefix_va;
-			pe.rva_to_va(*it, lock_prefix_va);
-			memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va));
-			current_pos_of_lock_prefixes += sizeof(lock_prefix_va);
-		}
-
-		{
-			//Ending null VA
-			typename PEClassType::BaseSize lock_prefix_va = 0;
-			memcpy(&raw_data[current_pos_of_lock_prefixes], &lock_prefix_va, sizeof(lock_prefix_va));
-		}
-	}
-
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(image_config_section, auto_strip_last_section);
-
-	image_directory ret(pe.rva_from_section_offset(image_config_section, image_config_data_pos), sizeof(typename PEClassType::ConfigStruct));
-
-	//If auto-rewrite of PE headers is required
-	if(save_to_pe_header)
-	{
-		pe.set_directory_rva(image_directory_entry_load_config, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_load_config, ret.get_size());
-	}
-
-	return ret;
-}
-
-}

+ 0 - 184
tools/pe_bliss/pe_load_config.h

@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing image configuration information
-class image_config_info
-{
-public:
-	typedef std::vector<uint32_t> se_handler_list;
-	typedef std::vector<uint32_t> lock_prefix_rva_list;
-
-public:
-	//Default constructor
-	image_config_info();
-	//Constructors from PE structures (no checks)
-	template<typename ConfigStructure>
-	explicit image_config_info(const ConfigStructure& info);
-
-	//Returns the date and time stamp value
-	uint32_t get_time_stamp() const;
-	//Returns major version number
-	uint16_t get_major_version() const;
-	//Returns minor version number
-	uint16_t get_minor_version() const;
-	//Returns clear global flags
-	uint32_t get_global_flags_clear() const;
-	//Returns set global flags
-	uint32_t get_global_flags_set() const;
-	//Returns critical section default timeout
-	uint32_t get_critical_section_default_timeout() const;
-	//Get the size of the minimum block that
-	//must be freed before it is freed (de-committed), in bytes
-	uint64_t get_decommit_free_block_threshold() const;
-	//Returns the size of the minimum total memory
-	//that must be freed in the process heap before it is freed (de-committed), in bytes
-	uint64_t get_decommit_total_free_threshold() const;
-	//Returns VA of a list of addresses where the LOCK prefix is used
-	uint64_t get_lock_prefix_table_va() const;
-	//Returns the maximum allocation size, in bytes
-	uint64_t get_max_allocation_size() const;
-	//Returns the maximum block size that can be allocated from heap segments, in bytes
-	uint64_t get_virtual_memory_threshold() const;
-	//Returns process affinity mask
-	uint64_t get_process_affinity_mask() const;
-	//Returns process heap flags
-	uint32_t get_process_heap_flags() const;
-	//Returns service pack version (CSDVersion)
-	uint16_t get_service_pack_version() const;
-	//Returns VA of edit list (reserved by system)
-	uint64_t get_edit_list_va() const;
-	//Returns a pointer to a cookie that is used by Visual C++ or GS implementation
-	uint64_t get_security_cookie_va() const;
-	//Returns VA of the sorted table of RVAs of each valid, unique handler in the image
-	uint64_t get_se_handler_table_va() const;
-	//Returns the count of unique handlers in the table
-	uint64_t get_se_handler_count() const;
-
-	//Returns SE Handler RVA list
-	const se_handler_list& get_se_handler_rvas() const;
-		
-	//Returns Lock Prefix RVA list
-	const lock_prefix_rva_list& get_lock_prefix_rvas() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//Also you can use these functions to rebuild image config directory
-
-	//Adds SE Handler RVA to list
-	void add_se_handler_rva(uint32_t rva);
-	//Clears SE Handler list
-	void clear_se_handler_list();
-		
-	//Adds Lock Prefix RVA to list
-	void add_lock_prefix_rva(uint32_t rva);
-	//Clears Lock Prefix list
-	void clear_lock_prefix_list();
-		
-	//Sets the date and time stamp value
-	void set_time_stamp(uint32_t time_stamp);
-	//Sets major version number
-	void set_major_version(uint16_t major_version);
-	//Sets minor version number
-	void set_minor_version(uint16_t minor_version);
-	//Sets clear global flags
-	void set_global_flags_clear(uint32_t global_flags_clear);
-	//Sets set global flags
-	void set_global_flags_set(uint32_t global_flags_set);
-	//Sets critical section default timeout
-	void set_critical_section_default_timeout(uint32_t critical_section_default_timeout);
-	//Sets the size of the minimum block that
-	//must be freed before it is freed (de-committed), in bytes
-	void set_decommit_free_block_threshold(uint64_t decommit_free_block_threshold);
-	//Sets the size of the minimum total memory
-	//that must be freed in the process heap before it is freed (de-committed), in bytes
-	void set_decommit_total_free_threshold(uint64_t decommit_total_free_threshold);
-	//Sets VA of a list of addresses where the LOCK prefix is used
-	//If you rebuild this list, VA will be re-assigned automatically
-	void set_lock_prefix_table_va(uint64_t lock_prefix_table_va);
-	//Sets the maximum allocation size, in bytes
-	void set_max_allocation_size(uint64_t max_allocation_size);
-	//Sets the maximum block size that can be allocated from heap segments, in bytes
-	void set_virtual_memory_threshold(uint64_t virtual_memory_threshold);
-	//Sets process affinity mask
-	void set_process_affinity_mask(uint64_t process_affinity_mask);
-	//Sets process heap flags
-	void set_process_heap_flags(uint32_t process_heap_flags);
-	//Sets service pack version (CSDVersion)
-	void set_service_pack_version(uint16_t service_pack_version);
-	//Sets VA of edit list (reserved by system)
-	void set_edit_list_va(uint64_t edit_list_va);
-	//Sets a pointer to a cookie that is used by Visual C++ or GS implementation
-	void set_security_cookie_va(uint64_t security_cookie_va);
-	//Sets VA of the sorted table of RVAs of each valid, unique handler in the image
-	//If you rebuild this list, VA will be re-assigned automatically
-	void set_se_handler_table_va(uint64_t se_handler_table_va);
-
-	//Returns SE Handler RVA list
-	se_handler_list& get_se_handler_rvas();
-
-	//Returns Lock Prefix RVA list
-	lock_prefix_rva_list& get_lock_prefix_rvas();
-
-private:
-	uint32_t time_stamp_;
-	uint16_t major_version_, minor_version_;
-	uint32_t global_flags_clear_, global_flags_set_;
-	uint32_t critical_section_default_timeout_;
-	uint64_t decommit_free_block_threshold_, decommit_total_free_threshold_;
-	uint64_t lock_prefix_table_va_;
-	uint64_t max_allocation_size_;
-	uint64_t virtual_memory_threshold_;
-	uint64_t process_affinity_mask_;
-	uint32_t process_heap_flags_;
-	uint16_t service_pack_version_;
-	uint64_t edit_list_va_;
-	uint64_t security_cookie_va_;
-	uint64_t se_handler_table_va_;
-	uint64_t se_handler_count_;
-
-	se_handler_list se_handlers_;
-	lock_prefix_rva_list lock_prefixes_;
-};
-
-//Returns image config info
-//If image does not have config info, throws an exception
-const image_config_info get_image_config(const pe_base& pe);
-
-template<typename PEClassType>
-const image_config_info get_image_config_base(const pe_base& pe);
-
-
-//Image config directory rebuilder
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//If write_se_handlers = true, SE Handlers list will be written just after image config directory structure
-//If write_lock_prefixes = true, Lock Prefixes address list will be written just after image config directory structure
-const image_directory rebuild_image_config(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-template<typename PEClassType>
-const image_directory rebuild_image_config_base(pe_base& pe, const image_config_info& info, section& image_config_section, uint32_t offset_from_section_start = 0, bool write_se_handlers = true, bool write_lock_prefixes = true, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}

+ 0 - 41
tools/pe_bliss/pe_properties.cpp

@@ -1,41 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_properties.h"
-
-namespace pe_bliss
-{
-//Destructor
-pe_properties::~pe_properties()
-{}
-
-//Clears PE characteristics flag
-void pe_properties::clear_characteristics_flags(uint16_t flags)
-{
-	set_characteristics(get_characteristics() & ~flags);
-}
-
-//Sets PE characteristics flag
-void pe_properties::set_characteristics_flags(uint16_t flags)
-{
-	set_characteristics(get_characteristics() | flags);
-}
-}

+ 0 - 236
tools/pe_bliss/pe_properties.h

@@ -1,236 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-class pe_properties
-{
-public: //Constructors
-	virtual std::auto_ptr<pe_properties> duplicate() const = 0;
-	
-	//Fills properly PE structures
-	virtual void create_pe(uint32_t section_alignment, uint16_t subsystem) = 0;
-
-public:
-	//Destructor
-	virtual ~pe_properties();
-
-
-public: //DIRECTORIES
-	//Returns true if directory exists
-	virtual bool directory_exists(uint32_t id) const = 0;
-
-	//Removes directory
-	virtual void remove_directory(uint32_t id) = 0;
-
-	//Returns directory RVA
-	virtual uint32_t get_directory_rva(uint32_t id) const = 0;
-	//Returns directory size
-	virtual uint32_t get_directory_size(uint32_t id) const = 0;
-
-	//Sets directory RVA (just a value of PE header, no moving occurs)
-	virtual void set_directory_rva(uint32_t id, uint32_t rva) = 0;
-	//Sets directory size (just a value of PE header, no moving occurs)
-	virtual void set_directory_size(uint32_t id, uint32_t size) = 0;
-	
-	//Strips only zero DATA_DIRECTORY entries to count = min_count
-	//Returns resulting number of data directories
-	//strip_iat_directory - if true, even not empty IAT directory will be stripped
-	virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true) = 0;
-
-
-public: //IMAGE
-	//Returns PE type of this image
-	virtual pe_type get_pe_type() const = 0;
-
-
-public: //PE HEADER
-	//Returns image base for PE32 and PE64 respectively
-	virtual uint32_t get_image_base_32() const = 0;
-	virtual uint64_t get_image_base_64() const = 0;
-
-	//Sets new image base for PE32
-	virtual void set_image_base(uint32_t base) = 0;
-	//Sets new image base for PE32/PE+
-	virtual void set_image_base_64(uint64_t base) = 0;
-
-	//Returns image entry point
-	virtual uint32_t get_ep() const = 0;
-	//Sets image entry point
-	virtual void set_ep(uint32_t new_ep) = 0;
-
-	//Returns file alignment
-	virtual uint32_t get_file_alignment() const = 0;
-	//Returns section alignment
-	virtual uint32_t get_section_alignment() const = 0;
-
-	//Sets heap size commit for PE32 and PE64 respectively
-	virtual void set_heap_size_commit(uint32_t size) = 0;
-	virtual void set_heap_size_commit(uint64_t size) = 0;
-	//Sets heap size reserve for PE32 and PE64 respectively
-	virtual void set_heap_size_reserve(uint32_t size) = 0;
-	virtual void set_heap_size_reserve(uint64_t size) = 0;
-	//Sets stack size commit for PE32 and PE64 respectively
-	virtual void set_stack_size_commit(uint32_t size) = 0;
-	virtual void set_stack_size_commit(uint64_t size) = 0;
-	//Sets stack size reserve for PE32 and PE64 respectively
-	virtual void set_stack_size_reserve(uint32_t size) = 0;
-	virtual void set_stack_size_reserve(uint64_t size) = 0;
-	
-	//Returns heap size commit for PE32 and PE64 respectively
-	virtual uint32_t get_heap_size_commit_32() const = 0;
-	virtual uint64_t get_heap_size_commit_64() const = 0;
-	//Returns heap size reserve for PE32 and PE64 respectively
-	virtual uint32_t get_heap_size_reserve_32() const = 0;
-	virtual uint64_t get_heap_size_reserve_64() const = 0;
-	//Returns stack size commit for PE32 and PE64 respectively
-	virtual uint32_t get_stack_size_commit_32() const = 0;
-	virtual uint64_t get_stack_size_commit_64() const = 0;
-	//Returns stack size reserve for PE32 and PE64 respectively
-	virtual uint32_t get_stack_size_reserve_32() const = 0;
-	virtual uint64_t get_stack_size_reserve_64() const = 0;
-
-	//Returns virtual size of image
-	virtual uint32_t get_size_of_image() const = 0;
-
-	//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-	virtual uint32_t get_number_of_rvas_and_sizes() const = 0;
-	//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-	virtual void set_number_of_rvas_and_sizes(uint32_t number) = 0;
-
-	//Returns PE characteristics
-	virtual uint16_t get_characteristics() const = 0;
-	//Sets PE characteristics
-	virtual void set_characteristics(uint16_t ch) = 0;
-	
-	//Clears PE characteristics flag
-	void clear_characteristics_flags(uint16_t flags);
-	//Sets PE characteristics flag
-	void set_characteristics_flags(uint16_t flags);
-
-	//Returns size of headers
-	virtual uint32_t get_size_of_headers() const = 0;
-
-	//Returns subsystem
-	virtual uint16_t get_subsystem() const = 0;
-
-	//Sets subsystem
-	virtual void set_subsystem(uint16_t subsystem) = 0;
-
-	//Returns size of optional header
-	virtual uint16_t get_size_of_optional_header() const = 0;
-
-	//Returns PE signature
-	virtual uint32_t get_pe_signature() const = 0;
-
-	//Returns PE magic value
-	virtual uint32_t get_magic() const = 0;
-
-	//Returns checksum of PE file from header
-	virtual uint32_t get_checksum() const = 0;
-	
-	//Sets checksum of PE file
-	virtual void set_checksum(uint32_t checksum) = 0;
-	
-	//Returns timestamp of PE file from header
-	virtual uint32_t get_time_date_stamp() const = 0;
-	
-	//Sets timestamp of PE file
-	virtual void set_time_date_stamp(uint32_t timestamp) = 0;
-	
-	//Returns Machine field value of PE file from header
-	virtual uint16_t get_machine() const = 0;
-
-	//Sets Machine field value of PE file
-	virtual void set_machine(uint16_t machine) = 0;
-
-	//Returns DLL Characteristics
-	virtual uint16_t get_dll_characteristics() const = 0;
-	
-	//Sets DLL Characteristics
-	virtual void set_dll_characteristics(uint16_t characteristics) = 0;
-	
-	//Sets required operation system version
-	virtual void set_os_version(uint16_t major, uint16_t minor) = 0;
-
-	//Returns required operation system version (minor word)
-	virtual uint16_t get_minor_os_version() const = 0;
-
-	//Returns required operation system version (major word)
-	virtual uint16_t get_major_os_version() const = 0;
-
-	//Sets required subsystem version
-	virtual void set_subsystem_version(uint16_t major, uint16_t minor) = 0;
-
-	//Returns required subsystem version (minor word)
-	virtual uint16_t get_minor_subsystem_version() const = 0;
-
-	//Returns required subsystem version (major word)
-	virtual uint16_t get_major_subsystem_version() const = 0;
-
-public: //ADDRESS CONVERTIONS
-	//Virtual Address (VA) to Relative Virtual Address (RVA) convertions
-	//for PE32 and PE64 respectively
-	//bound_check checks integer overflow
-	virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const = 0;
-	virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const = 0;
-	
-	//Relative Virtual Address (RVA) to Virtual Address (VA) convertions
-	//for PE32 and PE64 respectively
-	virtual uint32_t rva_to_va_32(uint32_t rva) const = 0;
-	virtual uint64_t rva_to_va_64(uint32_t rva) const = 0;
-
-
-public: //SECTIONS
-	//Returns number of sections
-	virtual uint16_t get_number_of_sections() const = 0;
-	
-public:
-	//Sets number of sections
-	virtual void set_number_of_sections(uint16_t number) = 0;
-	//Sets virtual size of image
-	virtual void set_size_of_image(uint32_t size) = 0;
-	//Sets size of headers
-	virtual void set_size_of_headers(uint32_t size) = 0;
-	//Sets size of optional headers
-	virtual void set_size_of_optional_header(uint16_t size) = 0;
-	//Returns nt headers data pointer
-	virtual char* get_nt_headers_ptr() = 0;
-	//Returns nt headers data pointer
-	virtual const char* get_nt_headers_ptr() const = 0;
-	//Returns size of NT header
-	virtual uint32_t get_sizeof_nt_header() const = 0;
-	//Returns size of optional headers
-	virtual uint32_t get_sizeof_opt_headers() const = 0;
-	//Sets file alignment (no checks)
-	virtual void set_file_alignment_unchecked(uint32_t alignment) = 0;
-	//Sets base of code
-	virtual void set_base_of_code(uint32_t base) = 0;
-	//Returns base of code
-	virtual uint32_t get_base_of_code() const = 0;
-	//Returns needed PE magic for PE or PE+ (from template parameters)
-	virtual uint32_t get_needed_magic() const = 0;
-};
-}

+ 0 - 645
tools/pe_bliss/pe_properties_generic.cpp

@@ -1,645 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_properties_generic.h"
-#include "pe_exception.h"
-#include "utils.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-	
-//Constructor
-template<typename PEClassType>
-std::auto_ptr<pe_properties> pe_properties_generic<PEClassType>::duplicate() const
-{
-	return std::auto_ptr<pe_properties>(new pe_properties_generic<PEClassType>(*this));
-}
-
-//Fills properly PE structures
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::create_pe(uint32_t section_alignment, uint16_t subsystem)
-{
-	memset(&nt_headers_, 0, sizeof(nt_headers_));
-	nt_headers_.Signature = 0x4550; //"PE"
-	nt_headers_.FileHeader.Machine = 0x14C; //i386
-	nt_headers_.FileHeader.SizeOfOptionalHeader = sizeof(nt_headers_.OptionalHeader);
-	nt_headers_.OptionalHeader.Magic = PEClassType::Id;
-	nt_headers_.OptionalHeader.ImageBase = 0x400000;
-	nt_headers_.OptionalHeader.SectionAlignment = section_alignment;
-	nt_headers_.OptionalHeader.FileAlignment = 0x200;
-	nt_headers_.OptionalHeader.SizeOfHeaders = 1024;
-	nt_headers_.OptionalHeader.Subsystem = subsystem;
-	nt_headers_.OptionalHeader.SizeOfHeapReserve = 0x100000;
-	nt_headers_.OptionalHeader.SizeOfHeapCommit = 0x1000;
-	nt_headers_.OptionalHeader.SizeOfStackReserve = 0x100000;
-	nt_headers_.OptionalHeader.SizeOfStackCommit = 0x1000;
-	nt_headers_.OptionalHeader.NumberOfRvaAndSizes = 0x10;
-}
-
-//Duplicate
-template<typename PEClassType>
-pe_properties_generic<PEClassType>::~pe_properties_generic()
-{}
-
-//Returns true if directory exists
-template<typename PEClassType>
-bool pe_properties_generic<PEClassType>::directory_exists(uint32_t id) const
-{
-	return (nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1) >= id &&
-		nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
-}
-
-//Removes directory
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::remove_directory(uint32_t id)
-{
-	if(directory_exists(id))
-	{
-		nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = 0;
-		nt_headers_.OptionalHeader.DataDirectory[id].Size = 0;
-
-		if(id == image_directory_entry_basereloc)
-		{
-			set_characteristics_flags(image_file_relocs_stripped);
-			set_dll_characteristics(get_dll_characteristics() & ~image_dllcharacteristics_dynamic_base);
-		}
-		else if(id == image_directory_entry_export)
-		{
-			clear_characteristics_flags(image_file_dll);
-		}
-	}
-}
-
-//Returns directory RVA
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_directory_rva(uint32_t id) const
-{
-	//Check if directory exists
-	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
-		throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
-	return nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress;
-}
-
-//Returns directory size
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_directory_rva(uint32_t id, uint32_t va)
-{
-	//Check if directory exists
-	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
-		throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
-	nt_headers_.OptionalHeader.DataDirectory[id].VirtualAddress = va;
-}
-
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_directory_size(uint32_t id, uint32_t size)
-{
-	//Check if directory exists
-	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
-		throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
-	nt_headers_.OptionalHeader.DataDirectory[id].Size = size;
-}
-
-//Returns directory size
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_directory_size(uint32_t id) const
-{
-	//Check if directory exists
-	if(nt_headers_.OptionalHeader.NumberOfRvaAndSizes <= id)
-		throw pe_exception("Specified directory does not exist", pe_exception::directory_does_not_exist);
-
-	return nt_headers_.OptionalHeader.DataDirectory[id].Size;
-}
-
-//Strips only zero DATA_DIRECTORY entries to count = min_count
-//Returns resulting number of data directories
-//strip_iat_directory - if true, even not empty IAT directory will be stripped
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::strip_data_directories(uint32_t min_count, bool strip_iat_directory)
-{
-	int i = nt_headers_.OptionalHeader.NumberOfRvaAndSizes - 1;
-
-	//Enumerate all data directories from the end
-	for(; i >= 0; i--)
-	{
-		//If directory exists, break
-		if(nt_headers_.OptionalHeader.DataDirectory[i].VirtualAddress && (static_cast<uint32_t>(i) != image_directory_entry_iat || !strip_iat_directory))
-			break;
-
-		if(i <= static_cast<int>(min_count) - 2)
-			break;
-	}
-
-	if(i == image_numberof_directory_entries - 1)
-		return image_numberof_directory_entries;
-
-	//Return new number of data directories
-	return nt_headers_.OptionalHeader.NumberOfRvaAndSizes = i + 1;
-}
-
-//Returns image base for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_image_base_32() const
-{
-	return static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Returns image base for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_image_base_64() const
-{
-	return static_cast<uint64_t>(nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Sets new image base
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_image_base(uint32_t base)
-{
-	nt_headers_.OptionalHeader.ImageBase = base;
-}
-
-//Sets new image base
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_image_base_64(uint64_t base)
-{
-	nt_headers_.OptionalHeader.ImageBase = static_cast<typename PEClassType::BaseSize>(base);
-}
-
-//Returns image entry point
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_ep() const
-{
-	return nt_headers_.OptionalHeader.AddressOfEntryPoint;
-}
-
-//Sets image entry point
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_ep(uint32_t new_ep)
-{
-	nt_headers_.OptionalHeader.AddressOfEntryPoint = new_ep;
-}
-
-//Returns file alignment
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_file_alignment() const
-{
-	return nt_headers_.OptionalHeader.FileAlignment;
-}
-
-//Returns section alignment
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_section_alignment() const
-{
-	return nt_headers_.OptionalHeader.SectionAlignment;
-}
-
-//Sets heap size commit for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_commit(uint32_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size commit for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_commit(uint64_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfHeapCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size reserve for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint32_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets heap size reserve for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_heap_size_reserve(uint64_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfHeapReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size commit for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_commit(uint32_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size commit for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_commit(uint64_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfStackCommit = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size reserve for PE32
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint32_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Sets stack size reserve for PE32/PE64
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_stack_size_reserve(uint64_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfStackReserve = static_cast<typename PEClassType::BaseSize>(size);
-}
-
-//Returns heap size commit for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_heap_size_commit_32() const
-{
-	return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit);
-}
-
-//Returns heap size commit for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_heap_size_commit_64() const
-{
-	return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapCommit);
-}
-
-//Returns heap size reserve for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_heap_size_reserve_32() const
-{
-	return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve);
-}
-
-//Returns heap size reserve for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_heap_size_reserve_64() const
-{
-	return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfHeapReserve);
-}
-
-//Returns stack size commit for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_stack_size_commit_32() const
-{
-	return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackCommit);
-}
-
-//Returns stack size commit for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_stack_size_commit_64() const
-{
-	return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackCommit);
-}
-
-//Returns stack size reserve for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_stack_size_reserve_32() const
-{
-	return static_cast<uint32_t>(nt_headers_.OptionalHeader.SizeOfStackReserve);
-}
-
-//Returns stack size reserve for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::get_stack_size_reserve_64() const
-{
-	return static_cast<uint64_t>(nt_headers_.OptionalHeader.SizeOfStackReserve);
-}
-
-//Returns virtual size of image
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_size_of_image() const
-{
-	return nt_headers_.OptionalHeader.SizeOfImage;
-}
-
-//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_number_of_rvas_and_sizes() const
-{
-	return nt_headers_.OptionalHeader.NumberOfRvaAndSizes;
-}
-
-//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_number_of_rvas_and_sizes(uint32_t number)
-{
-	nt_headers_.OptionalHeader.NumberOfRvaAndSizes = number;
-}
-
-//Returns PE characteristics
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_characteristics() const
-{
-	return nt_headers_.FileHeader.Characteristics;
-}
-
-//Returns checksum of PE file from header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_checksum() const
-{
-	return nt_headers_.OptionalHeader.CheckSum;
-}
-
-//Sets checksum of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_checksum(uint32_t checksum)
-{
-	nt_headers_.OptionalHeader.CheckSum = checksum;
-}
-
-//Returns DLL Characteristics
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_dll_characteristics() const
-{
-	return nt_headers_.OptionalHeader.DllCharacteristics;
-}
-
-//Returns timestamp of PE file from header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_time_date_stamp() const
-{
-	return nt_headers_.FileHeader.TimeDateStamp;
-}
-
-//Sets timestamp of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_time_date_stamp(uint32_t timestamp)
-{
-	nt_headers_.FileHeader.TimeDateStamp = timestamp;
-}
-
-//Sets DLL Characteristics
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_dll_characteristics(uint16_t characteristics)
-{
-	nt_headers_.OptionalHeader.DllCharacteristics = characteristics;
-}
-
-//Returns Machine field value of PE file from header
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_machine() const
-{
-	return nt_headers_.FileHeader.Machine;
-}
-
-//Sets Machine field value of PE file
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_machine(uint16_t machine)
-{
-	nt_headers_.FileHeader.Machine = machine;
-}
-
-//Sets PE characteristics
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_characteristics(uint16_t ch)
-{
-	nt_headers_.FileHeader.Characteristics = ch;
-}
-
-//Returns size of headers
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_size_of_headers() const
-{
-	return nt_headers_.OptionalHeader.SizeOfHeaders;
-}
-
-//Returns subsystem
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_subsystem() const
-{
-	return nt_headers_.OptionalHeader.Subsystem;
-}
-
-//Sets subsystem
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_subsystem(uint16_t subsystem)
-{
-	nt_headers_.OptionalHeader.Subsystem = subsystem;
-}
-
-//Returns size of optional header
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_size_of_optional_header() const
-{
-	return nt_headers_.FileHeader.SizeOfOptionalHeader;
-}
-
-//Returns PE signature
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_pe_signature() const
-{
-	return nt_headers_.Signature;
-}
-
-//Returns PE magic value
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_magic() const
-{
-	return nt_headers_.OptionalHeader.Magic;
-}
-
-//Sets required operation system version
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_os_version(uint16_t major, uint16_t minor)
-{
-	nt_headers_.OptionalHeader.MinorOperatingSystemVersion = minor;
-	nt_headers_.OptionalHeader.MajorOperatingSystemVersion = major;
-}
-
-//Returns required operation system version (minor word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_minor_os_version() const
-{
-	return nt_headers_.OptionalHeader.MinorOperatingSystemVersion;
-}
-
-//Returns required operation system version (major word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_major_os_version() const
-{
-	return nt_headers_.OptionalHeader.MajorOperatingSystemVersion;
-}
-
-//Sets required subsystem version
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_subsystem_version(uint16_t major, uint16_t minor)
-{
-	nt_headers_.OptionalHeader.MinorSubsystemVersion = minor;
-	nt_headers_.OptionalHeader.MajorSubsystemVersion = major;
-}
-
-//Returns required subsystem version (minor word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_minor_subsystem_version() const
-{
-	return nt_headers_.OptionalHeader.MinorSubsystemVersion;
-}
-
-//Returns required subsystem version (major word)
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_major_subsystem_version() const
-{
-	return nt_headers_.OptionalHeader.MajorSubsystemVersion;
-}
-
-//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint32_t va, bool bound_check) const
-{
-	if(bound_check && static_cast<uint64_t>(va) - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword)
-		throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
-	return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Virtual Address (VA) to Relative Virtual Address (RVA) convertions for PE32/PE64
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::va_to_rva(uint64_t va, bool bound_check) const
-{
-	if(bound_check && va - nt_headers_.OptionalHeader.ImageBase > pe_utils::max_dword)
-		throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
-	return static_cast<uint32_t>(va - nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::rva_to_va_32(uint32_t rva) const
-{
-	if(!pe_utils::is_sum_safe(rva, static_cast<uint32_t>(nt_headers_.OptionalHeader.ImageBase)))
-		throw pe_exception("Incorrect address conversion", pe_exception::incorrect_address_conversion);
-
-	return static_cast<uint32_t>(rva + nt_headers_.OptionalHeader.ImageBase);
-}
-
-//Relative Virtual Address (RVA) to Virtual Address (VA) convertions for PE32/PE64
-template<typename PEClassType>
-uint64_t pe_properties_generic<PEClassType>::rva_to_va_64(uint32_t rva) const
-{
-	return static_cast<uint64_t>(rva) + nt_headers_.OptionalHeader.ImageBase;
-}
-
-//Returns number of sections
-template<typename PEClassType>
-uint16_t pe_properties_generic<PEClassType>::get_number_of_sections() const
-{
-	return nt_headers_.FileHeader.NumberOfSections;
-}
-
-//Sets number of sections
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_number_of_sections(uint16_t number)
-{
-	nt_headers_.FileHeader.NumberOfSections = number;
-}
-
-//Sets virtual size of image
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_image(uint32_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfImage = size;
-}
-
-//Sets size of headers
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_headers(uint32_t size)
-{
-	nt_headers_.OptionalHeader.SizeOfHeaders = size;
-}
-
-//Sets size of optional headers
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_size_of_optional_header(uint16_t size)
-{
-	nt_headers_.FileHeader.SizeOfOptionalHeader = size;
-}
-
-//Returns nt headers data pointer
-template<typename PEClassType>
-char* pe_properties_generic<PEClassType>::get_nt_headers_ptr()
-{
-	return reinterpret_cast<char*>(&nt_headers_);
-}
-
-//Returns nt headers data pointer
-template<typename PEClassType>
-const char* pe_properties_generic<PEClassType>::get_nt_headers_ptr() const
-{
-	return reinterpret_cast<const char*>(&nt_headers_);
-}
-
-//Returns size of NT header
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_sizeof_nt_header() const
-{
-	return sizeof(typename PEClassType::NtHeaders);
-}
-
-//Returns size of optional headers
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_sizeof_opt_headers() const
-{
-	return sizeof(typename PEClassType::OptHeaders);
-}
-
-//Sets file alignment (no checks)
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_file_alignment_unchecked(uint32_t alignment) 
-{
-	nt_headers_.OptionalHeader.FileAlignment = alignment;
-}
-
-//Sets base of code
-template<typename PEClassType>
-void pe_properties_generic<PEClassType>::set_base_of_code(uint32_t base)
-{
-	nt_headers_.OptionalHeader.BaseOfCode = base;
-}
-
-//Returns base of code
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_base_of_code() const
-{
-	return nt_headers_.OptionalHeader.BaseOfCode;
-}
-
-//Returns needed PE magic for PE or PE+ (from template parameters)
-template<typename PEClassType>
-uint32_t pe_properties_generic<PEClassType>::get_needed_magic() const
-{
-	return PEClassType::Id;
-}
-
-//Returns PE type of this image
-template<typename PEClassType>
-pe_type pe_properties_generic<PEClassType>::get_pe_type() const
-{
-	return PEClassType::Id == image_nt_optional_hdr32_magic ? pe_type_32 : pe_type_64;
-}
-
-//Two used instantiations for PE32 (PE) and PE64 (PE+)
-template class pe_properties_generic<pe_types_class_32>;
-template class pe_properties_generic<pe_types_class_64>;
-}

+ 0 - 277
tools/pe_bliss/pe_properties_generic.h

@@ -1,277 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_properties.h"
-
-namespace pe_bliss
-{
-//Helper class to reduce code size and ease its editing
-template<
-	typename NtHeadersType,
-	typename OptHeadersType,
-	uint16_t IdVal,
-	typename BaseSizeType,
-	BaseSizeType ImportSnapFlagVal,
-	typename TLSStructType,
-	typename ConfigStructType>
-class pe_types
-{
-public:
-	typedef NtHeadersType NtHeaders; //NT HEADERS type
-	typedef OptHeadersType OptHeaders; //NT OPTIONAL HEADER type
-	typedef BaseSizeType BaseSize; //Base size of different values: DWORD or ULONGLONG
-	typedef TLSStructType TLSStruct; //TLS structure type
-	typedef ConfigStructType ConfigStruct; //Configuration structure type
-
-	static const uint16_t Id = IdVal; //Magic of PE or PE+
-	static const BaseSize ImportSnapFlag = ImportSnapFlagVal; //Import snap flag value
-};
-
-//Portable Executable derived class for PE and PE+
-//Describes PE/PE+ dependent things
-template<typename PEClassType>
-class pe_properties_generic : public pe_properties
-{
-public: //Constructor
-	virtual std::auto_ptr<pe_properties> duplicate() const;
-
-	//Fills properly PE structures
-	virtual void create_pe(uint32_t section_alignment, uint16_t subsystem);
-
-public:
-	//Destructor
-	virtual ~pe_properties_generic();
-
-
-public: //DIRECTORIES
-	//Returns true if directory exists
-	virtual bool directory_exists(uint32_t id) const;
-
-	//Removes directory
-	virtual void remove_directory(uint32_t id);
-
-	//Returns directory RVA
-	virtual uint32_t get_directory_rva(uint32_t id) const;
-	//Returns directory size
-	virtual uint32_t get_directory_size(uint32_t id) const;
-
-	//Sets directory RVA (just a value of PE header, no moving occurs)
-	virtual void set_directory_rva(uint32_t id, uint32_t rva);
-	//Sets directory size (just a value of PE header, no moving occurs)
-	virtual void set_directory_size(uint32_t id, uint32_t size);
-	
-	//Strips only zero DATA_DIRECTORY entries to count = min_count
-	//Returns resulting number of data directories
-	//strip_iat_directory - if true, even not empty IAT directory will be stripped
-	virtual uint32_t strip_data_directories(uint32_t min_count = 1, bool strip_iat_directory = true);
-
-
-public: //IMAGE
-	//Returns PE type of this image
-	virtual pe_type get_pe_type() const;
-
-
-public: //PE HEADER
-	//Returns image base for PE32 and PE64 respectively
-	virtual uint32_t get_image_base_32() const;
-	virtual uint64_t get_image_base_64() const;
-
-	//Sets new image base for PE32
-	virtual void set_image_base(uint32_t base);
-	//Sets new image base for PE32/PE+
-	virtual void set_image_base_64(uint64_t base);
-
-	//Returns image entry point
-	virtual uint32_t get_ep() const;
-	//Sets image entry point
-	virtual void set_ep(uint32_t new_ep);
-
-	//Returns file alignment
-	virtual uint32_t get_file_alignment() const;
-	//Returns section alignment
-	virtual uint32_t get_section_alignment() const;
-
-	//Sets heap size commit for PE32 and PE64 respectively
-	virtual void set_heap_size_commit(uint32_t size);
-	virtual void set_heap_size_commit(uint64_t size);
-	//Sets heap size reserve for PE32 and PE64 respectively
-	virtual void set_heap_size_reserve(uint32_t size);
-	virtual void set_heap_size_reserve(uint64_t size);
-	//Sets stack size commit for PE32 and PE64 respectively
-	virtual void set_stack_size_commit(uint32_t size);
-	virtual void set_stack_size_commit(uint64_t size);
-	//Sets stack size reserve for PE32 and PE64 respectively
-	virtual void set_stack_size_reserve(uint32_t size);
-	virtual void set_stack_size_reserve(uint64_t size);
-	
-	//Returns heap size commit for PE32 and PE64 respectively
-	virtual uint32_t get_heap_size_commit_32() const;
-	virtual uint64_t get_heap_size_commit_64() const;
-	//Returns heap size reserve for PE32 and PE64 respectively
-	virtual uint32_t get_heap_size_reserve_32() const;
-	virtual uint64_t get_heap_size_reserve_64() const;
-	//Returns stack size commit for PE32 and PE64 respectively
-	virtual uint32_t get_stack_size_commit_32() const;
-	virtual uint64_t get_stack_size_commit_64() const;
-	//Returns stack size reserve for PE32 and PE64 respectively
-	virtual uint32_t get_stack_size_reserve_32() const;
-	virtual uint64_t get_stack_size_reserve_64() const;
-
-	//Returns virtual size of image
-	virtual uint32_t get_size_of_image() const;
-
-	//Returns number of RVA and sizes (number of DATA_DIRECTORY entries)
-	virtual uint32_t get_number_of_rvas_and_sizes() const;
-	//Sets number of RVA and sizes (number of DATA_DIRECTORY entries)
-	virtual void set_number_of_rvas_and_sizes(uint32_t number);
-
-	//Returns PE characteristics
-	virtual uint16_t get_characteristics() const;
-	//Sets PE characteristics
-	virtual void set_characteristics(uint16_t ch);
-	
-	//Returns size of headers
-	virtual uint32_t get_size_of_headers() const;
-
-	//Returns subsystem
-	virtual uint16_t get_subsystem() const;
-
-	//Sets subsystem
-	virtual void set_subsystem(uint16_t subsystem);
-
-	//Returns size of optional header
-	virtual uint16_t get_size_of_optional_header() const;
-
-	//Returns PE signature
-	virtual uint32_t get_pe_signature() const;
-
-	//Returns PE magic value
-	virtual uint32_t get_magic() const;
-
-	//Returns checksum of PE file from header
-	virtual uint32_t get_checksum() const;
-	
-	//Sets checksum of PE file
-	virtual void set_checksum(uint32_t checksum);
-	
-	//Returns timestamp of PE file from header
-	virtual uint32_t get_time_date_stamp() const;
-	
-	//Sets timestamp of PE file
-	virtual void set_time_date_stamp(uint32_t timestamp);
-	
-	//Returns Machine field value of PE file from header
-	virtual uint16_t get_machine() const;
-
-	//Sets Machine field value of PE file
-	virtual void set_machine(uint16_t machine);
-
-	//Returns DLL Characteristics
-	virtual uint16_t get_dll_characteristics() const;
-	
-	//Sets DLL Characteristics
-	virtual void set_dll_characteristics(uint16_t characteristics);
-	
-	//Sets required operation system version
-	virtual void set_os_version(uint16_t major, uint16_t minor);
-
-	//Returns required operation system version (minor word)
-	virtual uint16_t get_minor_os_version() const;
-
-	//Returns required operation system version (major word)
-	virtual uint16_t get_major_os_version() const;
-
-	//Sets required subsystem version
-	virtual void set_subsystem_version(uint16_t major, uint16_t minor);
-
-	//Returns required subsystem version (minor word)
-	virtual uint16_t get_minor_subsystem_version() const;
-
-	//Returns required subsystem version (major word)
-	virtual uint16_t get_major_subsystem_version() const;
-
-public: //ADDRESS CONVERTIONS
-	//Virtual Address (VA) to Relative Virtual Address (RVA) convertions
-	//for PE32 and PE64 respectively
-	//bound_check checks integer overflow
-	virtual uint32_t va_to_rva(uint32_t va, bool bound_check = true) const;
-	virtual uint32_t va_to_rva(uint64_t va, bool bound_check = true) const;
-	
-	//Relative Virtual Address (RVA) to Virtual Address (VA) convertions
-	//for PE32 and PE64 respectively
-	virtual uint32_t rva_to_va_32(uint32_t rva) const;
-	virtual uint64_t rva_to_va_64(uint32_t rva) const;
-
-
-public: //SECTIONS
-	//Returns number of sections
-	virtual uint16_t get_number_of_sections() const;
-
-protected:
-	typename PEClassType::NtHeaders nt_headers_; //NT headers (PE32 or PE64)
-	
-public:
-	//Sets number of sections
-	virtual void set_number_of_sections(uint16_t number);
-	//Sets virtual size of image
-	virtual void set_size_of_image(uint32_t size);
-	//Sets size of headers
-	virtual void set_size_of_headers(uint32_t size);
-	//Sets size of optional headers
-	virtual void set_size_of_optional_header(uint16_t size);
-	//Returns nt headers data pointer
-	virtual char* get_nt_headers_ptr();
-	//Returns nt headers data pointer
-	virtual const char* get_nt_headers_ptr() const;
-	//Returns size of NT header
-	virtual uint32_t get_sizeof_nt_header() const;
-	//Returns size of optional headers
-	virtual uint32_t get_sizeof_opt_headers() const;
-	//Sets file alignment (no checks)
-	virtual void set_file_alignment_unchecked(uint32_t alignment);
-	//Sets base of code
-	virtual void set_base_of_code(uint32_t base);
-	//Returns base of code
-	virtual uint32_t get_base_of_code() const;
-	//Returns needed PE magic for PE or PE+ (from template parameters)
-	virtual uint32_t get_needed_magic() const;
-};
-
-//Two used typedefs for PE32 (PE) and PE64 (PE+)
-typedef pe_types<pe_win::image_nt_headers32,
-	pe_win::image_optional_header32,
-	pe_win::image_nt_optional_hdr32_magic,
-	uint32_t,
-	pe_win::image_ordinal_flag32,
-	pe_win::image_tls_directory32,
-	pe_win::image_load_config_directory32> pe_types_class_32;
-
-typedef pe_types<pe_win::image_nt_headers64,
-	pe_win::image_optional_header64,
-	pe_win::image_nt_optional_hdr64_magic,
-	uint64_t,
-	pe_win::image_ordinal_flag64,
-	pe_win::image_tls_directory64,
-	pe_win::image_load_config_directory64> pe_types_class_64;
-
-typedef pe_properties_generic<pe_types_class_32> pe_properties_32;
-typedef pe_properties_generic<pe_types_class_64> pe_properties_64;
-}

+ 0 - 214
tools/pe_bliss/pe_rebuilder.cpp

@@ -1,214 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_rebuilder.h"
-#include "pe_base.h"
-#include "pe_structures.h"
-#include "pe_exception.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Rebuilds PE image headers
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, image_dos_header& dos_header, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
-	dos_header = pe.get_dos_header();
-
-	if(strip_dos_header)
-	{
-		//Strip stub overlay
-		pe.strip_stub_overlay();
-		//BaseOfCode NT Headers field now overlaps
-		//e_lfanew field, so we're acrually setting
-		//e_lfanew with this call
-		pe.set_base_of_code(8 * sizeof(uint16_t));
-	}
-	else
-	{
-		//Set start of PE headers
-		dos_header.e_lfanew = sizeof(image_dos_header)
-			+ pe_utils::align_up(static_cast<uint32_t>(pe.get_stub_overlay().size()), sizeof(uint32_t));
-	}
-
-	section_list& sections = pe.get_image_sections();
-
-	//Calculate pointer to section data
-	size_t ptr_to_section_data = (strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header)) + pe.get_sizeof_nt_header()
-		+ pe_utils::align_up(pe.get_stub_overlay().size(), sizeof(uint32_t))
-		- sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())
-		+ sections.size() * sizeof(image_section_header);
-
-	if(save_bound_import && pe.has_bound_import())
-	{
-		//It will be aligned to DWORD, because we're aligning to DWORD everything above it
-		pe.set_directory_rva(image_directory_entry_bound_import, static_cast<uint32_t>(ptr_to_section_data));
-		ptr_to_section_data += pe.get_directory_size(image_directory_entry_bound_import);	
-	}
-	
-	ptr_to_section_data = pe_utils::align_up(ptr_to_section_data, pe.get_file_alignment());
-
-	//Set size of headers and size of optional header
-	if(change_size_of_headers)
-	{
-		if(!pe.get_image_sections().empty())
-		{
-			if(static_cast<uint32_t>(ptr_to_section_data) > (*sections.begin()).get_virtual_address())
-				throw pe_exception("Headers of PE file are too long. Try to strip STUB or don't build bound import", pe_exception::cannot_rebuild_image);
-		}
-
-		pe.set_size_of_headers(static_cast<uint32_t>(ptr_to_section_data));
-	}
-
-	//Set number of sections in PE header
-	pe.update_number_of_sections();
-
-	pe.update_image_size();
-
-	pe.set_size_of_optional_header(static_cast<uint16_t>(pe.get_sizeof_opt_headers()
-		- sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes())));
-
-	//Recalculate pointer to raw data according to section list
-	for(section_list::iterator it = sections.begin(); it != sections.end(); ++it)
-	{
-		//Save section headers PointerToRawData
-		(*it).set_pointer_to_raw_data(static_cast<uint32_t>(ptr_to_section_data));
-		ptr_to_section_data += (*it).get_aligned_raw_size(pe.get_file_alignment());
-	}
-}
-
-//Rebuild PE image and write it to "out" ostream
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
-	if(out.bad())
-		throw pe_exception("Stream is bad", pe_exception::stream_is_bad);
-
-	if(save_bound_import && pe.has_bound_import())
-	{
-		if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_bound_import), pe.get_directory_rva(image_directory_entry_bound_import), section_data_raw, true)
-			< pe.get_directory_size(image_directory_entry_bound_import))
-			throw pe_exception("Incorrect bound import directory", pe_exception::incorrect_bound_import_directory);
-	}
-
-	//Change ostream state
-	out.exceptions(std::ios::goodbit);
-	out.clear();
-	
-	uint32_t original_bound_import_rva = pe.has_bound_import() ? pe.get_directory_rva(image_directory_entry_bound_import) : 0;
-	if(original_bound_import_rva && original_bound_import_rva > pe.get_size_of_headers())
-	{
-		//No need to do anything with bound import directory
-		//if it is placed inside of any section, not headers
-		original_bound_import_rva = 0;
-		save_bound_import = false;
-	}
-
-	{
-		image_dos_header dos_header;
-
-		//Rebuild PE image headers
-		rebuild_pe(pe, dos_header, strip_dos_header, change_size_of_headers, save_bound_import);
-
-		//Write DOS header
-		out.write(reinterpret_cast<const char*>(&dos_header), strip_dos_header ? 8 * sizeof(uint16_t) : sizeof(image_dos_header));
-	}
-
-	//If we have stub overlay, write it too
-	{
-		const std::string& stub = pe.get_stub_overlay();
-		if(stub.size())
-		{
-			out.write(stub.data(), stub.size());
-			size_t aligned_size = pe_utils::align_up(stub.size(), sizeof(uint32_t));
-			//Align PE header, which is right after rich overlay
-			while(aligned_size > stub.size())
-			{
-				out.put('\0');
-				--aligned_size;
-			}
-		}
-	}
-	
-	//Write NT headers
-	out.write(static_cast<const pe_base&>(pe).get_nt_headers_ptr(), pe.get_sizeof_nt_header()
-		- sizeof(image_data_directory) * (image_numberof_directory_entries - pe.get_number_of_rvas_and_sizes()));
-
-	//Write section headers
-	const section_list& sections = pe.get_image_sections();
-	for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it)
-	{
-		if(it == sections.end() - 1) //If last section encountered
-		{
-			image_section_header header((*it).get_raw_header());
-			header.SizeOfRawData = static_cast<uint32_t>((*it).get_raw_data().length()); //Set non-aligned actual data length for it
-			out.write(reinterpret_cast<const char*>(&header), sizeof(image_section_header));
-		}
-		else
-		{
-			out.write(reinterpret_cast<const char*>(&(*it).get_raw_header()), sizeof(image_section_header));
-		}
-	}
-
-	//Write bound import data if requested
-	if(save_bound_import && pe.has_bound_import())
-	{
-		out.write(pe.section_data_from_rva(original_bound_import_rva, section_data_raw, true),
-			pe.get_directory_size(image_directory_entry_bound_import));
-	}
-
-	//Write section data finally
-	for(section_list::const_iterator it = sections.begin(); it != sections.end(); ++it)
-	{
-		const section& s = *it;
-
-		std::streamoff wpos = out.tellp();
-
-		//Fill unused overlay data between sections with null bytes
-		for(unsigned int i = 0; i < s.get_pointer_to_raw_data() - wpos; i++)
-			out.put(0);
-
-		//Write raw section data
-		out.write(s.get_raw_data().data(), s.get_raw_data().length());
-	}
-}
-
-//Rebuild PE image and write it to "out" file
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, const char* out, bool strip_dos_header, bool change_size_of_headers, bool save_bound_import)
-{
-	std::ofstream pe_file(out, std::ios::out | std::ios::binary | std::ios::trunc);
-	if(!pe_file)
-	{
-		throw pe_exception("Error in open file.", pe_exception::stream_is_bad);
-	}
-	rebuild_pe(pe, pe_file, strip_dos_header, change_size_of_headers, save_bound_import);
-}
-
-
-}

+ 0 - 40
tools/pe_bliss/pe_rebuilder.h

@@ -1,40 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <ostream>
-#include <fstream>
-
-namespace pe_bliss
-{
-class pe_base;
-//Rebuilds PE image, writes resulting image to ostream "out". If strip_dos_header == true, DOS header will be stripped a little
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, std::ostream& out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true);
-
-//Rebuild PE image and write it to "out" file
-//If strip_dos_header is true, DOS headers partially will be used for PE headers
-//If change_size_of_headers == true, SizeOfHeaders will be recalculated automatically
-//If save_bound_import == true, existing bound import directory will be saved correctly (because some compilers and bind.exe put it to PE headers)
-void rebuild_pe(pe_base& pe, const char* out, bool strip_dos_header = false, bool change_size_of_headers = true, bool save_bound_import = true);
-
-}

+ 0 - 320
tools/pe_bliss/pe_relocations.cpp

@@ -1,320 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_relocations.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//RELOCATIONS
-//Default constructor
-relocation_entry::relocation_entry()
-	:rva_(0), type_(0)
-{}
-
-//Constructor from relocation item (WORD)
-relocation_entry::relocation_entry(uint16_t relocation_value)
-	:rva_(relocation_value & ((1 << 12) - 1)), type_(relocation_value >> 12)
-{}
-
-//Constructor from relative rva and relocation type
-relocation_entry::relocation_entry(uint16_t rrva, uint16_t type)
-	:rva_(rrva), type_(type)
-{}
-
-//Returns RVA of relocation
-uint16_t relocation_entry::get_rva() const
-{
-	return rva_;
-}
-
-//Returns type of relocation
-uint16_t relocation_entry::get_type() const
-{
-	return type_;
-}
-
-//Sets RVA of relocation
-void relocation_entry::set_rva(uint16_t rva)
-{
-	rva_ = rva;
-}
-
-//Sets type of relocation
-void relocation_entry::set_type(uint16_t type)
-{
-	type_ = type;
-}
-
-//Returns relocation item (rrva + type)
-uint16_t relocation_entry::get_item() const
-{
-	return rva_ | (type_ << 12);
-}
-
-//Sets relocation item (rrva + type)
-void relocation_entry::set_item(uint16_t item)
-{
-	rva_ = item & ((1 << 12) - 1);
-	type_ = item >> 12;
-}
-
-//Returns relocation list
-const relocation_table::relocation_list& relocation_table::get_relocations() const
-{
-	return relocations_;
-}
-
-//Adds relocation to table
-void relocation_table::add_relocation(const relocation_entry& entry)
-{
-	relocations_.push_back(entry);
-}
-
-//Default constructor
-relocation_table::relocation_table()
-	:rva_(0)
-{}
-
-//Constructor from RVA of relocation table
-relocation_table::relocation_table(uint32_t rva)
-	:rva_(rva)
-{}
-
-//Returns RVA of block
-uint32_t relocation_table::get_rva() const
-{
-	return rva_;
-}
-
-//Sets RVA of block
-void relocation_table::set_rva(uint32_t rva)
-{
-	rva_ = rva;
-}
-
-//Returns changeable relocation list
-relocation_table::relocation_list& relocation_table::get_relocations()
-{
-	return relocations_;
-}
-
-//Get relocation list of pe file, supports one-word sized relocations only
-//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed
-const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries)
-{
-	relocation_table_list ret;
-
-	//If image does not have relocations
-	if(!pe.has_reloc())
-		return ret;
-
-	//Check the length in bytes of the section containing relocation directory
-	if(pe.section_data_length_from_rva(pe.get_directory_rva(image_directory_entry_basereloc),
-		pe.get_directory_rva(image_directory_entry_basereloc), section_data_virtual, true)
-		< sizeof(image_base_relocation))
-		throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
-	unsigned long current_pos = pe.get_directory_rva(image_directory_entry_basereloc);
-	//First IMAGE_BASE_RELOCATION table
-	image_base_relocation reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true);
-
-	if(reloc_table.SizeOfBlock % 2)
-		throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
-	unsigned long reloc_size = pe.get_directory_size(image_directory_entry_basereloc);
-	unsigned long read_size = 0;
-
-	//reloc_table.VirtualAddress is not checked (not so important)
-	while(reloc_table.SizeOfBlock && read_size < reloc_size)
-	{
-		//Create relocation table
-		relocation_table table;
-		//Save RVA
-		table.set_rva(reloc_table.VirtualAddress);
-
-		if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock))
-			throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
-		//List all relocations
-		for(unsigned long i = sizeof(image_base_relocation); i < reloc_table.SizeOfBlock; i += sizeof(uint16_t))
-		{
-			relocation_entry entry(pe.section_data_from_rva<uint16_t>(current_pos + i, section_data_virtual, true));
-			if(list_absolute_entries || entry.get_type() != image_rel_based_absolute)
-				table.add_relocation(entry);
-		}
-
-		//Save table
-		ret.push_back(table);
-		
-		//Go to next relocation block
-		if(!pe_utils::is_sum_safe(current_pos, reloc_table.SizeOfBlock))
-			throw pe_exception("Incorrect relocation directory", pe_exception::incorrect_relocation_directory);
-
-		current_pos += reloc_table.SizeOfBlock;
-		read_size += reloc_table.SizeOfBlock;
-		reloc_table = pe.section_data_from_rva<image_base_relocation>(current_pos, section_data_virtual, true);
-	}
-
-	return ret;
-}
-
-//Simple relocations rebuilder
-//To keep PE file working, don't remove any of existing relocations in
-//relocation_table_list returned by a call to get_relocations() function
-//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
-//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
-//If save_to_pe_header is true, PE header will be modified automatically
-const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	//Check that reloc_section is attached to this PE image
-	if(!pe.section_attached(reloc_section))
-		throw pe_exception("Relocations section must be attached to PE file", pe_exception::section_is_not_attached);
-	
-	uint32_t current_reloc_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-
-	uint32_t needed_size = current_reloc_data_pos - offset_from_section_start; //Calculate needed size for relocation tables
-	uint32_t size_delta = needed_size;
-
-	uint32_t start_reloc_pos = current_reloc_data_pos;
-
-	//Enumerate relocation tables
-	for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
-	{
-		needed_size += static_cast<uint32_t>((*it).get_relocations().size() * sizeof(uint16_t) /* relocations */ + sizeof(image_base_relocation) /* table header */);
-		//End of each table will be DWORD-aligned
-		if((start_reloc_pos + needed_size - size_delta) % sizeof(uint32_t))
-			needed_size += sizeof(uint16_t); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
-	}
-
-	//Check if reloc_section is last one. If it's not, check if there's enough place for relocations data
-	if(&reloc_section != &*(pe.get_image_sections().end() - 1) && 
-		(reloc_section.empty() || pe_utils::align_up(reloc_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + current_reloc_data_pos))
-		throw pe_exception("Insufficient space for relocations directory", pe_exception::insufficient_space);
-
-	std::string& raw_data = reloc_section.get_raw_data();
-
-	//This will be done only if reloc_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + current_reloc_data_pos)
-		raw_data.resize(needed_size + current_reloc_data_pos); //Expand section raw data
-
-	//Enumerate relocation tables
-	for(relocation_table_list::const_iterator it = relocs.begin(); it != relocs.end(); ++it)
-	{
-		//Create relocation table header
-		image_base_relocation reloc;
-		reloc.VirtualAddress = (*it).get_rva();
-		const relocation_table::relocation_list& reloc_list = (*it).get_relocations();
-		reloc.SizeOfBlock = static_cast<uint32_t>(sizeof(image_base_relocation) + sizeof(uint16_t) * reloc_list.size());
-		if((reloc_list.size() * sizeof(uint16_t)) % sizeof(uint32_t)) //If we must align end of relocation table
-			reloc.SizeOfBlock += sizeof(uint16_t);
-
-		memcpy(&raw_data[current_reloc_data_pos], &reloc, sizeof(reloc));
-		current_reloc_data_pos += sizeof(reloc);
-
-		//Enumerate relocations in table
-		for(relocation_table::relocation_list::const_iterator r = reloc_list.begin(); r != reloc_list.end(); ++r)
-		{
-			//Save relocations
-			uint16_t reloc_value = (*r).get_item();
-			memcpy(&raw_data[current_reloc_data_pos], &reloc_value, sizeof(reloc_value));
-			current_reloc_data_pos += sizeof(reloc_value);
-		}
-
-		if(current_reloc_data_pos % sizeof(uint32_t)) //If end of table is not DWORD-aligned
-		{
-			memset(&raw_data[current_reloc_data_pos], 0, sizeof(uint16_t)); //Align it with IMAGE_REL_BASED_ABSOLUTE relocation
-			current_reloc_data_pos += sizeof(uint16_t);
-		}
-	}
-
-	image_directory ret(pe.rva_from_section_offset(reloc_section, start_reloc_pos), needed_size - size_delta);
-	
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(reloc_section, auto_strip_last_section);
-
-	//If auto-rewrite of PE headers is required
-	if(save_to_pe_header)
-	{
-		pe.set_directory_rva(image_directory_entry_basereloc, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_basereloc, ret.get_size());
-
-		pe.clear_characteristics_flags(image_file_relocs_stripped);
-		pe.set_dll_characteristics(pe.get_dll_characteristics() | image_dllcharacteristics_dynamic_base);
-	}
-
-	return ret;
-}
-
-//Recalculates image base with the help of relocation tables
-void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base)
-{
-	pe.get_pe_type() == pe_type_32
-		? rebase_image_base<pe_types_class_32>(pe, tables, new_base)
-		: rebase_image_base<pe_types_class_64>(pe, tables, new_base);
-}
-
-//RELOCATIONS
-//Recalculates image base with the help of relocation tables
-//Recalculates VAs of DWORDS/QWORDS in image according to relocations
-//Notice: if you move some critical structures like TLS, image relocations will not fix new
-//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed.
-//It is recommended to rebase image in the very beginning and move all structures afterwards.
-template<typename PEClassType>
-void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base)
-{
-	//Get current image base value
-	typename PEClassType::BaseSize image_base;
-	pe.get_image_base(image_base);
-
-	//ImageBase difference
-	typename PEClassType::BaseSize base_rel = static_cast<typename PEClassType::BaseSize>(static_cast<int64_t>(new_base) - image_base);
-
-	//We need to fix addresses from relocation tables
-	//Enumerate relocation tables
-	for(relocation_table_list::const_iterator it = tables.begin(); it != tables.end(); ++it)
-	{
-		const relocation_table::relocation_list& relocs = (*it).get_relocations();
-
-		uint32_t base_rva = (*it).get_rva();
-
-		//Enumerate relocations
-		for(relocation_table::relocation_list::const_iterator rel = relocs.begin(); rel != relocs.end(); ++rel)
-		{
-			//Skip ABSOLUTE entries
-			if((*rel).get_type() == pe_win::image_rel_based_absolute)
-				continue;
-			
-			//Recalculate value by RVA and rewrite it
-			uint32_t current_rva = base_rva + (*rel).get_rva();
-			typename PEClassType::BaseSize value = pe.section_data_from_rva<typename PEClassType::BaseSize>(current_rva, section_data_raw, true);
-			value += base_rel;
-			memcpy(pe.section_data_from_rva(current_rva, true), &value, sizeof(value));
-		}
-	}
-
-	//Finally, save new image base
-	pe.set_image_base_64(new_base);
-}
-}

+ 0 - 122
tools/pe_bliss/pe_relocations.h

@@ -1,122 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing relocation entry
-//RVA of relocation is not actually RVA, but
-//(real RVA) - (RVA of table)
-class relocation_entry
-{
-public:
-	//Default constructor
-	relocation_entry();
-	//Constructor from relocation item (WORD)
-	explicit relocation_entry(uint16_t relocation_value);
-	//Constructor from relative rva and relocation type
-	relocation_entry(uint16_t rrva, uint16_t type);
-
-	//Returns RVA of relocation (actually, relative RVA from relocation table RVA)
-	uint16_t get_rva() const;
-	//Returns type of relocation
-	uint16_t get_type() const;
-
-	//Returns relocation item (rrva + type)
-	uint16_t get_item() const;
-
-public: //Setters do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild relocations using rebuild_relocations()
-
-	//Sets RVA of relocation (actually, relative RVA from relocation table RVA)
-	void set_rva(uint16_t rva);
-	//Sets type of relocation
-	void set_type(uint16_t type);
-		
-	//Sets relocation item (rrva + type)
-	void set_item(uint16_t item);
-
-private:
-	uint16_t rva_;
-	uint16_t type_;
-};
-
-//Class representing relocation table
-class relocation_table
-{
-public:
-	typedef std::vector<relocation_entry> relocation_list;
-
-public:
-	//Default constructor
-	relocation_table();
-	//Constructor from RVA of relocation table
-	explicit relocation_table(uint32_t rva);
-
-	//Returns relocation list
-	const relocation_list& get_relocations() const;
-	//Returns RVA of block
-	uint32_t get_rva() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild relocations using rebuild_relocations()
-
-	//Adds relocation to table
-	void add_relocation(const relocation_entry& entry);
-	//Returns changeable relocation list
-	relocation_list& get_relocations();
-	//Sets RVA of block
-	void set_rva(uint32_t rva);
-
-private:
-	uint32_t rva_;
-	relocation_list relocations_;
-};
-
-typedef std::vector<relocation_table> relocation_table_list;
-
-//Get relocation list of pe file, supports one-word sized relocations only
-//If list_absolute_entries = true, IMAGE_REL_BASED_ABSOLUTE will be listed
-const relocation_table_list get_relocations(const pe_base& pe, bool list_absolute_entries = false);
-
-//Simple relocations rebuilder
-//To keep PE file working, don't remove any of existing relocations in
-//relocation_table_list returned by a call to get_relocations() function
-//auto_strip_last_section - if true and relocations are placed in the last section, it will be automatically stripped
-//offset_from_section_start - offset from the beginning of reloc_section, where relocations data will be situated
-//If save_to_pe_header is true, PE header will be modified automatically
-const image_directory rebuild_relocations(pe_base& pe, const relocation_table_list& relocs, section& reloc_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-//Recalculates image base with the help of relocation tables
-//Recalculates VAs of DWORDS/QWORDS in image according to relocations
-//Notice: if you move some critical structures like TLS, image relocations will not fix new
-//positions of TLS VAs. Instead, some bytes that now doesn't belong to TLS will be fixed.
-//It is recommended to rebase image in the very beginning and move all structures afterwards.
-void rebase_image(pe_base& pe, const relocation_table_list& tables, uint64_t new_base);
-
-template<typename PEClassType>
-void rebase_image_base(pe_base& pe, const relocation_table_list& tables, uint64_t new_base);
-}

+ 0 - 286
tools/pe_bliss/pe_resource_manager.cpp

@@ -1,286 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include <sstream>
-#include <iomanip>
-#include <math.h>
-#include <string.h>
-#include "pe_resource_manager.h"
-#include "resource_internal.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor from root resource directory
-pe_resource_manager::pe_resource_manager(resource_directory& root_directory)
-	:pe_resource_viewer(root_directory), root_dir_edit_(root_directory)
-{}
-
-resource_directory& pe_resource_manager::get_root_directory()
-{
-	return root_dir_edit_;
-}
-
-//Removes all resources of given type or root name
-//If there's more than one directory entry of a given type, only the
-//first one will be deleted (that's an unusual situation)
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource_type(resource_type type)
-{
-	//Search for resource type
-	resource_directory::entry_list& entries = root_dir_edit_.get_entry_list();
-	resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type));
-	if(it != entries.end())
-	{
-		//Remove it, if found
-		entries.erase(it);
-		return true;
-	}
-
-	return false;
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name)
-{
-	//Search for resource type
-	resource_directory::entry_list& entries = root_dir_edit_.get_entry_list();
-	resource_directory::entry_list::iterator it = std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name));
-	if(it != entries.end())
-	{
-		//Remove it, if found
-		entries.erase(it);
-		return true;
-	}
-
-	return false;
-}
-
-//Helper to remove resource
-bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder)
-{
-	//Search for resource type
-	resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list();
-	resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder);
-	if(it_type != entries_type.end())
-	{
-		//Search for resource name/ID with "finder"
-		resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list();
-		resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder);
-		if(it_name != entries_name.end())
-		{
-			//Erase resource, if found
-			entries_name.erase(it_name);
-			if(entries_name.empty())
-				entries_type.erase(it_type);
-
-			return true;
-		}
-	}
-
-	return false;
-}
-
-//Removes all resource languages by resource type/root name and name
-//Deletes only one entry of given type and name
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name)
-{
-	return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name));
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name)
-{
-	return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name));
-}
-
-//Removes all resource languages by resource type/root name and ID
-//Deletes only one entry of given type and ID
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, uint32_t id)
-{
-	return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id));
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id)
-{
-	return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id));
-}
-
-//Helper to remove resource
-bool pe_resource_manager::remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language)
-{
-	//Search for resource type
-	resource_directory::entry_list& entries_type = root_dir_edit_.get_entry_list();
-	resource_directory::entry_list::iterator it_type = std::find_if(entries_type.begin(), entries_type.end(), root_finder);
-	if(it_type != entries_type.end())
-	{
-		//Search for resource name/ID with "finder"
-		resource_directory::entry_list& entries_name = (*it_type).get_resource_directory().get_entry_list();
-		resource_directory::entry_list::iterator it_name = std::find_if(entries_name.begin(), entries_name.end(), finder);
-		if(it_name != entries_name.end())
-		{
-			//Search for resource language
-			resource_directory::entry_list& entries_lang = (*it_name).get_resource_directory().get_entry_list();
-			resource_directory::entry_list::iterator it_lang = std::find_if(entries_lang.begin(), entries_lang.end(), resource_directory::id_entry_finder(language));
-			if(it_lang != entries_lang.end())
-			{
-				//Erase resource, if found
-				entries_lang.erase(it_lang);
-				if(entries_lang.empty())
-				{
-					entries_name.erase(it_name);
-					if(entries_name.empty())
-						entries_type.erase(it_type);
-				}
-
-				return true;
-			}
-		}
-	}
-
-	return false;
-}
-
-//Removes resource language by resource type/root name and name
-//Deletes only one entry of given type, name and language
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, const std::wstring& name, uint32_t language)
-{
-	return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(name), language);
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language)
-{
-	return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(name), language);
-}
-
-//Removes recource language by resource type/root name and ID
-//Deletes only one entry of given type, ID and language
-//Returns true if resource was deleted
-bool pe_resource_manager::remove_resource(resource_type type, uint32_t id, uint32_t language)
-{
-	return remove_resource(resource_directory::entry_finder(type), resource_directory::entry_finder(id), language);
-}
-
-bool pe_resource_manager::remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language)
-{
-	return remove_resource(resource_directory::entry_finder(root_name), resource_directory::entry_finder(id), language);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_type_entry;
-	new_type_entry.set_id(type);
-
-	add_resource(data, new_type_entry, resource_directory::entry_finder(type), new_entry, finder, language, codepage, timestamp);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_type_entry;
-	new_type_entry.set_name(root_name);
-	
-	add_resource(data, new_type_entry, resource_directory::entry_finder(root_name), new_entry, finder, language, codepage, timestamp);
-}
-
-//Helper to add/replace resource
-void pe_resource_manager::add_resource(const std::string& data, resource_directory_entry& new_root_entry, const resource_directory::entry_finder& root_finder, resource_directory_entry& new_entry, const resource_directory::entry_finder& finder, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	//Search for resource type
-	resource_directory::entry_list* entries = &root_dir_edit_.get_entry_list();
-	resource_directory::entry_list::iterator it = std::find_if(entries->begin(), entries->end(), root_finder);
-	if(it == entries->end())
-	{
-		//Add resource type directory, if it was not found
-		resource_directory dir;
-		dir.set_timestamp(timestamp);
-		new_root_entry.add_resource_directory(dir);
-		entries->push_back(new_root_entry);
-		it = entries->end() - 1;
-	}
-
-	//Search for resource name/ID directory with "finder"
-	entries = &(*it).get_resource_directory().get_entry_list();
-	it = std::find_if(entries->begin(), entries->end(), finder);
-	if(it == entries->end())
-	{
-		//Add resource name/ID directory, if it was not found
-		resource_directory dir;
-		dir.set_timestamp(timestamp);
-		new_entry.add_resource_directory(dir);
-		entries->push_back(new_entry);
-		it = entries->end() - 1;
-	}
-
-	//Search for data resource entry by language
-	entries = &(*it).get_resource_directory().get_entry_list();
-	it = std::find_if(entries->begin(), entries->end(), resource_directory::id_entry_finder(language));
-	if(it != entries->end())
-		entries->erase(it); //Erase it, if found
-
-	//Add new data entry
-	resource_directory_entry new_dir_data_entry;
-	resource_data_entry data_dir(data, codepage);
-	new_dir_data_entry.add_data_entry(data_dir);
-	new_dir_data_entry.set_id(language);
-	entries->push_back(new_dir_data_entry);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_entry;
-	new_entry.set_name(name);
-
-	add_resource(data, type, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_entry;
-	new_entry.set_name(name);
-
-	add_resource(data, root_name, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_entry;
-	new_entry.set_id(id);
-
-	add_resource(data, type, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-
-//Adds resource. If resource already exists, replaces it
-void pe_resource_manager::add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_entry;
-	new_entry.set_id(id);
-
-	add_resource(data, root_name, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-}

+ 0 - 113
tools/pe_bliss/pe_resource_manager.h

@@ -1,113 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <sstream>
-#include <string>
-#include <memory>
-#include "pe_base.h"
-#include "pe_structures.h"
-#include "pe_resources.h"
-#include "message_table.h"
-#include "file_version_info.h"
-#include "pe_resource_viewer.h"
-#include "resource_data_info.h"
-
-namespace pe_bliss
-{
-//Derived class to edit PE resources
-class pe_resource_manager : public pe_resource_viewer
-{
-public:
-	//Constructor from root resource directory
-	explicit pe_resource_manager(resource_directory& root_directory);
-	
-	resource_directory& get_root_directory();
-
-public: //Resource editing
-	//Removes all resources of given type or root name
-	//If there's more than one directory entry of a given type, only the
-	//first one will be deleted (that's an unusual situation)
-	//Returns true if resource was deleted
-	bool remove_resource_type(resource_type type);
-	bool remove_resource(const std::wstring& root_name);
-	
-	//Removes all resource languages by resource type/root name and name
-	//Deletes only one entry of given type and name
-	//Returns true if resource was deleted
-	bool remove_resource(resource_type type, const std::wstring& name);
-	bool remove_resource(const std::wstring& root_name, const std::wstring& name);
-	//Removes all resource languages by resource type/root name and ID
-	//Deletes only one entry of given type and ID
-	//Returns true if resource was deleted
-	bool remove_resource(resource_type type, uint32_t id);
-	bool remove_resource(const std::wstring& root_name, uint32_t id);
-
-	//Removes resource language by resource type/root name and name
-	//Deletes only one entry of given type, name and language
-	//Returns true if resource was deleted
-	bool remove_resource(resource_type type, const std::wstring& name, uint32_t language);
-	bool remove_resource(const std::wstring& root_name, const std::wstring& name, uint32_t language);
-	//Removes recource language by resource type/root name and ID
-	//Deletes only one entry of given type, ID and language
-	//Returns true if resource was deleted
-	bool remove_resource(resource_type type, uint32_t id, uint32_t language);
-	bool remove_resource(const std::wstring& root_name, uint32_t id, uint32_t language);
-	
-	//Adds resource. If resource already exists, replaces it
-	//timestamp will be used for directories that will be added
-	void add_resource(const std::string& data, resource_type type, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-	void add_resource(const std::string& data, const std::wstring& root_name, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-	//Adds resource. If resource already exists, replaces it
-	//timestamp will be used for directories that will be added
-	void add_resource(const std::string& data, resource_type type, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-	void add_resource(const std::string& data, const std::wstring& root_name, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-public:
-	//Helpers to add/replace resource
-	void add_resource(const std::string& data, resource_type type,
-		resource_directory_entry& new_entry,
-		const resource_directory::entry_finder& finder,
-		uint32_t language, uint32_t codepage, uint32_t timestamp);
-
-	void add_resource(const std::string& data, const std::wstring& root_name,
-		resource_directory_entry& new_entry,
-		const resource_directory::entry_finder& finder,
-		uint32_t language, uint32_t codepage, uint32_t timestamp);
-
-	void add_resource(const std::string& data, resource_directory_entry& new_root_entry,
-		const resource_directory::entry_finder& root_finder,
-		resource_directory_entry& new_entry,
-		const resource_directory::entry_finder& finder,
-		uint32_t language, uint32_t codepage, uint32_t timestamp);
-
-private:
-	//Root resource directory. We're not copying it, because it might be heavy
-	resource_directory& root_dir_edit_;
-
-	//Helper to remove resource
-	bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder);
-
-	//Helper to remove resource
-	bool remove_resource(const resource_directory::entry_finder& root_finder, const resource_directory::entry_finder& finder, uint32_t language);
-};
-}

+ 0 - 382
tools/pe_bliss/pe_resource_viewer.cpp

@@ -1,382 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include <cmath>
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Constructor from root resource_directory
-pe_resource_viewer::pe_resource_viewer(const resource_directory& root_directory)
-	:root_dir_(root_directory)
-{}
-
-const resource_directory& pe_resource_viewer::get_root_directory() const
-{
-	return root_dir_;
-}
-
-//Finder helpers
-bool pe_resource_viewer::has_name::operator()(const resource_directory_entry& entry) const
-{
-	return entry.is_named();
-}
-
-bool pe_resource_viewer::has_id::operator()(const resource_directory_entry& entry) const
-{
-	return !entry.is_named();
-}
-
-//Lists resource types existing in PE file (non-named only)
-const pe_resource_viewer::resource_type_list pe_resource_viewer::list_resource_types() const
-{
-	resource_type_list ret;
-
-	//Get root directory entries list
-	const resource_directory::entry_list& entries = root_dir_.get_entry_list();
-	for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
-	{
-		//List all non-named items
-		if(!(*it).is_named())
-			ret.push_back((*it).get_id());
-	}
-
-	return ret;
-}
-
-//Returns true if resource type exists
-bool pe_resource_viewer::resource_exists(resource_type type) const
-{
-	const resource_directory::entry_list& entries = root_dir_.get_entry_list();
-	return std::find_if(entries.begin(), entries.end(), resource_directory::id_entry_finder(type)) != entries.end();
-}
-
-//Returns true if resource name exists
-bool pe_resource_viewer::resource_exists(const std::wstring& root_name) const
-{
-	const resource_directory::entry_list& entries = root_dir_.get_entry_list();
-	return std::find_if(entries.begin(), entries.end(), resource_directory::name_entry_finder(root_name)) != entries.end();
-}
-
-//Helper function to get name list from entry list
-const pe_resource_viewer::resource_name_list pe_resource_viewer::get_name_list(const resource_directory::entry_list& entries)
-{
-	resource_name_list ret;
-
-	for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
-	{
-		//List all named items
-		if((*it).is_named())
-			ret.push_back((*it).get_name());
-	}
-
-	return ret;
-}
-
-//Helper function to get ID list from entry list
-const pe_resource_viewer::resource_id_list pe_resource_viewer::get_id_list(const resource_directory::entry_list& entries)
-{
-	resource_id_list ret;
-
-	for(resource_directory::entry_list::const_iterator it = entries.begin(); it != entries.end(); ++it)
-	{
-		//List all non-named items
-		if(!(*it).is_named())
-			ret.push_back((*it).get_id());
-	}
-
-	return ret;
-}
-
-//Lists resource names existing in PE file by resource type
-const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(resource_type type) const
-{
-	return get_name_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list());
-}
-
-//Lists resource names existing in PE file by resource name
-const pe_resource_viewer::resource_name_list pe_resource_viewer::list_resource_names(const std::wstring& root_name) const
-{
-	return get_name_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list());
-}
-
-//Lists resource IDs existing in PE file by resource type
-const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(resource_type type) const
-{
-	return get_id_list(root_dir_.entry_by_id(type).get_resource_directory().get_entry_list());
-}
-
-//Lists resource IDs existing in PE file by resource name
-const pe_resource_viewer::resource_id_list pe_resource_viewer::list_resource_ids(const std::wstring& root_name) const
-{
-	return get_id_list(root_dir_.entry_by_name(root_name).get_resource_directory().get_entry_list());
-}
-
-//Returns resource count by type
-unsigned long pe_resource_viewer::get_resource_count(resource_type type) const
-{
-	return static_cast<unsigned long>(
-		root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.get_entry_list()
-		.size());
-}
-
-//Returns resource count by name
-unsigned long pe_resource_viewer::get_resource_count(const std::wstring& root_name) const
-{
-	return static_cast<unsigned long>(
-		root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.get_entry_list()
-		.size());
-}
-
-//Returns language count of resource by resource type and name
-unsigned long pe_resource_viewer::get_language_count(resource_type type, const std::wstring& name) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource names
-unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, const std::wstring& name) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource type and ID
-unsigned long pe_resource_viewer::get_language_count(resource_type type, uint32_t id) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Returns language count of resource by resource name and ID
-unsigned long pe_resource_viewer::get_language_count(const std::wstring& root_name, uint32_t id) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return static_cast<unsigned long>(std::count_if(entries.begin(), entries.end(), has_id()));
-}
-
-//Lists resource languages by resource type and name
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, const std::wstring& name) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return get_id_list(entries);
-}
-
-//Lists resource languages by resource names
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, const std::wstring& name) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return get_id_list(entries);
-}
-
-//Lists resource languages by resource type and ID
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(resource_type type, uint32_t id) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return get_id_list(entries);
-}
-
-//Lists resource languages by resource name and ID
-const pe_resource_viewer::resource_language_list pe_resource_viewer::list_resource_languages(const std::wstring& root_name, uint32_t id) const
-{
-	const resource_directory::entry_list& entries =
-		root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	return get_id_list(entries);
-}
-
-//Returns raw resource data by type, name and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const
-{
-	return resource_data_info(root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.entry_by_id(language)
-		.get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, name and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const
-{
-	return resource_data_info(root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.entry_by_id(language)
-		.get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, ID and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const
-{
-	return resource_data_info(root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.entry_by_id(language)
-		.get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, ID and language
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const
-{
-	return resource_data_info(root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.entry_by_id(language)
-		.get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, name and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index) const
-{
-	const resource_directory::entry_list& entries = root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	if(entries.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
-	return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, name and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index) const
-{
-	const resource_directory::entry_list& entries = root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_name(name)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	if(entries.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
-	return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by type, ID and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index) const
-{
-	const resource_directory::entry_list& entries = root_dir_ //Type directory
-		.entry_by_id(type)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	if(entries.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
-	return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-
-//Returns raw resource data by root name, ID and index in language directory (instead of language)
-const resource_data_info pe_resource_viewer::get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index) const
-{
-	const resource_directory::entry_list& entries = root_dir_ //Type directory
-		.entry_by_name(root_name)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(id)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	if(entries.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
-	return resource_data_info(entries.at(index).get_data_entry()); //Data directory
-}
-}

+ 0 - 153
tools/pe_bliss/pe_resource_viewer.h

@@ -1,153 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <string>
-#include "pe_structures.h"
-#include "pe_resources.h"
-#include "message_table.h"
-#include "resource_data_info.h"
-
-namespace pe_bliss
-{
-	//PE resource manager allows to read resources from PE files
-class pe_resource_viewer
-{
-public:
-	//Resource type enumeration
-	enum resource_type
-	{
-		resource_cursor = 1,
-		resource_bitmap = 2,
-		resource_icon = 3,
-		resource_menu = 4,
-		resource_dialog = 5,
-		resource_string = 6,
-		resource_fontdir = 7,
-		resource_font = 8,
-		resource_accelerator = 9,
-		resource_rcdata = 10,
-		resource_message_table = 11,
-		resource_cursor_group = 12,
-		resource_icon_group = 14,
-		resource_version = 16,
-		resource_dlginclude = 17,
-		resource_plugplay = 19,
-		resource_vxd = 20,
-		resource_anicursor = 21,
-		resource_aniicon = 22,
-		resource_html = 23,
-		resource_manifest = 24
-	};
-
-public:
-	//Some useful typedefs
-	typedef std::vector<uint32_t> resource_type_list;
-	typedef std::vector<uint32_t> resource_id_list;
-	typedef std::vector<std::wstring> resource_name_list;
-	typedef std::vector<uint32_t> resource_language_list;
-	
-public:
-	//Constructor from root resource_directory from PE file
-	explicit pe_resource_viewer(const resource_directory& root_directory);
-
-	const resource_directory& get_root_directory() const;
-
-	//Lists resource types existing in PE file (non-named only)
-	const resource_type_list list_resource_types() const;
-	//Returns true if resource type exists
-	bool resource_exists(resource_type type) const;
-	//Returns true if resource name exists
-	bool resource_exists(const std::wstring& root_name) const;
-
-	//Lists resource names existing in PE file by resource type
-	const resource_name_list list_resource_names(resource_type type) const;
-	//Lists resource names existing in PE file by resource name
-	const resource_name_list list_resource_names(const std::wstring& root_name) const;
-	//Lists resource IDs existing in PE file by resource type
-	const resource_id_list list_resource_ids(resource_type type) const;
-	//Lists resource IDs existing in PE file by resource name
-	const resource_id_list list_resource_ids(const std::wstring& root_name) const;
-	//Returns resource count by type
-	unsigned long get_resource_count(resource_type type) const;
-	//Returns resource count by name
-	unsigned long get_resource_count(const std::wstring& root_name) const;
-
-	//Returns language count of resource by resource type and name
-	unsigned long get_language_count(resource_type type, const std::wstring& name) const;
-	//Returns language count of resource by resource names
-	unsigned long get_language_count(const std::wstring& root_name, const std::wstring& name) const;
-	//Returns language count of resource by resource type and ID
-	unsigned long get_language_count(resource_type type, uint32_t id) const;
-	//Returns language count of resource by resource name and ID
-	unsigned long get_language_count(const std::wstring& root_name, uint32_t id) const;
-	//Lists resource languages by resource type and name
-	const resource_language_list list_resource_languages(resource_type type, const std::wstring& name) const;
-	//Lists resource languages by resource names
-	const resource_language_list list_resource_languages(const std::wstring& root_name, const std::wstring& name) const;
-	//Lists resource languages by resource type and ID
-	const resource_language_list list_resource_languages(resource_type type, uint32_t id) const;
-	//Lists resource languages by resource name and ID
-	const resource_language_list list_resource_languages(const std::wstring& root_name, uint32_t id) const;
-
-	//Returns raw resource data by type, name and language
-	const resource_data_info get_resource_data_by_name(uint32_t language, resource_type type, const std::wstring& name) const;
-	//Returns raw resource data by root name, name and language
-	const resource_data_info get_resource_data_by_name(uint32_t language, const std::wstring& root_name, const std::wstring& name) const;
-	//Returns raw resource data by type, ID and language
-	const resource_data_info get_resource_data_by_id(uint32_t language, resource_type type, uint32_t id) const;
-	//Returns raw resource data by root name, ID and language
-	const resource_data_info get_resource_data_by_id(uint32_t language, const std::wstring& root_name, uint32_t id) const;
-	//Returns raw resource data by type, name and index in language directory (instead of language)
-	const resource_data_info get_resource_data_by_name(resource_type type, const std::wstring& name, uint32_t index = 0) const;
-	//Returns raw resource data by root name, name and index in language directory (instead of language)
-	const resource_data_info get_resource_data_by_name(const std::wstring& root_name, const std::wstring& name, uint32_t index = 0) const;
-	//Returns raw resource data by type, ID and index in language directory (instead of language)
-	const resource_data_info get_resource_data_by_id(resource_type type, uint32_t id, uint32_t index = 0) const;
-	//Returns raw resource data by root name, ID and index in language directory (instead of language)
-	const resource_data_info get_resource_data_by_id(const std::wstring& root_name, uint32_t id, uint32_t index = 0) const;
-
-protected:
-	//Root resource directory. We're not copying it, because it might be heavy
-	const resource_directory& root_dir_;
-
-	//Helper function to get ID list from entry list
-	static const resource_id_list get_id_list(const resource_directory::entry_list& entries);
-	//Helper function to get name list from entry list
-	static const resource_name_list get_name_list(const resource_directory::entry_list& entries);
-
-protected:
-	//Helper structure - finder of resource_directory_entry that is named
-	struct has_name
-	{
-	public:
-		bool operator()(const resource_directory_entry& entry) const;
-	};
-
-	//Helper structure - finder of resource_directory_entry that is not named (has id)
-	struct has_id
-	{
-	public:
-		bool operator()(const resource_directory_entry& entry) const;
-	};
-};
-}

+ 0 - 726
tools/pe_bliss/pe_resources.cpp

@@ -1,726 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "pe_resources.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//RESOURCES
-//Default constructor
-resource_data_entry::resource_data_entry()
-	:codepage_(0)
-{}
-
-//Constructor from data
-resource_data_entry::resource_data_entry(const std::string& data, uint32_t codepage)
-	:codepage_(codepage), data_(data)
-{}
-
-//Returns resource data codepage
-uint32_t resource_data_entry::get_codepage() const
-{
-	return codepage_;
-}
-
-//Returns resource data
-const std::string& resource_data_entry::get_data() const
-{
-	return data_;
-}
-
-//Sets resource data codepage
-void resource_data_entry::set_codepage(uint32_t codepage)
-{
-	codepage_ = codepage;
-}
-
-//Sets resource data
-void resource_data_entry::set_data(const std::string& data)
-{
-	data_ = data;
-}
-
-//Default constructor
-resource_directory_entry::includes::includes()
-	:data_(0)
-{}
-
-//Default constructor
-resource_directory_entry::resource_directory_entry()
-	:id_(0), includes_data_(false), named_(false)
-{}
-
-//Copy constructor
-resource_directory_entry::resource_directory_entry(const resource_directory_entry& other)
-	:id_(other.id_), name_(other.name_), includes_data_(other.includes_data_), named_(other.named_)
-{
-	//If union'ed pointer is not zero
-	if(other.ptr_.data_)
-	{
-		if(other.includes_data())
-			ptr_.data_ = new resource_data_entry(*other.ptr_.data_);
-		else
-			ptr_.dir_ = new resource_directory(*other.ptr_.dir_);
-	}
-}
-
-//Copy assignment operator
-resource_directory_entry& resource_directory_entry::operator=(const resource_directory_entry& other)
-{
-	release();
-
-	id_ = other.id_;
-	name_ = other.name_;
-	includes_data_ = other.includes_data_;
-	named_ = other.named_;
-
-	//If other union'ed pointer is not zero
-	if(other.ptr_.data_)
-	{
-		if(other.includes_data())
-			ptr_.data_ = new resource_data_entry(*other.ptr_.data_);
-		else
-			ptr_.dir_ = new resource_directory(*other.ptr_.dir_);
-	}
-
-	return *this;
-}
-
-//Destroys included data
-void resource_directory_entry::release()
-{
-	//If union'ed pointer is not zero
-	if(ptr_.data_)
-	{
-		if(includes_data())
-			delete ptr_.data_;
-		else
-			delete ptr_.dir_;
-
-		ptr_.data_ = 0;
-	}
-}
-
-//Destructor
-resource_directory_entry::~resource_directory_entry()
-{
-	release();
-}
-
-//Returns entry ID
-uint32_t resource_directory_entry::get_id() const
-{
-	return id_;
-}
-
-//Returns entry name
-const std::wstring& resource_directory_entry::get_name() const
-{
-	return name_;
-}
-
-//Returns true, if entry has name
-//Returns false, if entry has ID
-bool resource_directory_entry::is_named() const
-{
-	return named_;
-}
-
-//Returns true, if entry includes resource_data_entry
-//Returns false, if entry includes resource_directory
-bool resource_directory_entry::includes_data() const
-{
-	return includes_data_;
-}
-
-//Returns resource_directory if entry includes it, otherwise throws an exception
-const resource_directory& resource_directory_entry::get_resource_directory() const
-{
-	if(!ptr_.dir_ || includes_data_)
-		throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error);
-
-	return *ptr_.dir_;
-}
-
-//Returns resource_data_entry if entry includes it, otherwise throws an exception
-const resource_data_entry& resource_directory_entry::get_data_entry() const
-{
-	if(!ptr_.data_ || !includes_data_)
-		throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error);
-
-	return *ptr_.data_;
-}
-
-//Returns resource_directory if entry includes it, otherwise throws an exception
-resource_directory& resource_directory_entry::get_resource_directory()
-{
-	if(!ptr_.dir_ || includes_data_)
-		throw pe_exception("Resource directory entry does not contain resource directory", pe_exception::resource_directory_entry_error);
-
-	return *ptr_.dir_;
-}
-
-//Returns resource_data_entry if entry includes it, otherwise throws an exception
-resource_data_entry& resource_directory_entry::get_data_entry()
-{
-	if(!ptr_.data_ || !includes_data_)
-		throw pe_exception("Resource directory entry does not contain resource data entry", pe_exception::resource_directory_entry_error);
-
-	return *ptr_.data_;
-}
-
-//Sets entry name
-void resource_directory_entry::set_name(const std::wstring& name)
-{
-	name_ = name;
-	named_ = true;
-	id_ = 0;
-}
-
-//Sets entry ID
-void resource_directory_entry::set_id(uint32_t id)
-{
-	id_ = id;
-	named_ = false;
-	name_.clear();
-}
-
-//Adds resource_data_entry
-void resource_directory_entry::add_data_entry(const resource_data_entry& entry)
-{
-	release();
-	ptr_.data_ = new resource_data_entry(entry);
-	includes_data_ = true;
-}
-
-//Adds resource_directory
-void resource_directory_entry::add_resource_directory(const resource_directory& dir)
-{
-	release();
-	ptr_.dir_ = new resource_directory(dir);
-	includes_data_ = false;
-}
-
-//Default constructor
-resource_directory::resource_directory()
-	:characteristics_(0),
-	timestamp_(0),
-	major_version_(0), minor_version_(0),
-	number_of_named_entries_(0), number_of_id_entries_(0)
-{}
-
-//Constructor from data
-resource_directory::resource_directory(const image_resource_directory& dir)
-	:characteristics_(dir.Characteristics),
-	timestamp_(dir.TimeDateStamp),
-	major_version_(dir.MajorVersion), minor_version_(dir.MinorVersion),
-	number_of_named_entries_(0), number_of_id_entries_(0) //Set to zero here, calculate on add
-{}
-
-//Returns characteristics of directory
-uint32_t resource_directory::get_characteristics() const
-{
-	return characteristics_;
-}
-
-//Returns date and time stamp of directory
-uint32_t resource_directory::get_timestamp() const
-{
-	return timestamp_;
-}
-
-//Returns major version of directory
-uint16_t resource_directory::get_major_version() const
-{
-	return major_version_;
-}
-
-//Returns minor version of directory
-uint16_t resource_directory::get_minor_version() const
-{
-	return minor_version_;
-}
-
-//Returns number of named entries
-uint32_t resource_directory::get_number_of_named_entries() const
-{
-	return number_of_named_entries_;
-}
-
-//Returns number of ID entries
-uint32_t resource_directory::get_number_of_id_entries() const
-{
-	return number_of_id_entries_;
-}
-
-//Returns resource_directory_entry array
-const resource_directory::entry_list& resource_directory::get_entry_list() const
-{
-	return entries_;
-}
-
-//Returns resource_directory_entry array
-resource_directory::entry_list& resource_directory::get_entry_list()
-{
-	return entries_;
-}
-
-//Adds resource_directory_entry
-void resource_directory::add_resource_directory_entry(const resource_directory_entry& entry)
-{
-	entries_.push_back(entry);
-	if(entry.is_named())
-		++number_of_named_entries_;
-	else
-		++number_of_id_entries_;
-}
-
-//Clears resource_directory_entry array
-void resource_directory::clear_resource_directory_entry_list()
-{
-	entries_.clear();
-	number_of_named_entries_ = 0;
-	number_of_id_entries_ = 0;
-}
-
-//Sets characteristics of directory
-void resource_directory::set_characteristics(uint32_t characteristics)
-{
-	characteristics_ = characteristics;
-}
-
-//Sets date and time stamp of directory
-void resource_directory::set_timestamp(uint32_t timestamp)
-{
-	timestamp_ = timestamp;
-}
-
-//Sets number of named entries
-void resource_directory::set_number_of_named_entries(uint32_t number)
-{
-	number_of_named_entries_ = number;
-}
-
-//Sets number of ID entries
-void resource_directory::set_number_of_id_entries(uint32_t number)
-{
-	number_of_id_entries_ = number;
-}
-
-//Sets major version of directory
-void resource_directory::set_major_version(uint16_t major_version)
-{
-	major_version_ = major_version;
-}
-
-//Sets minor version of directory
-void resource_directory::get_minor_version(uint16_t minor_version)
-{
-	minor_version_ = minor_version;
-}
-
-//Processes resource directory
-const resource_directory process_resource_directory(const pe_base& pe, uint32_t res_rva, uint32_t offset_to_directory, std::set<uint32_t>& processed)
-{
-	resource_directory ret;
-	
-	//Check for resource loops
-	if(!processed.insert(offset_to_directory).second)
-		throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-	if(!pe_utils::is_sum_safe(res_rva, offset_to_directory))
-		throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-	//Get root IMAGE_RESOURCE_DIRECTORY
-	image_resource_directory directory = pe.section_data_from_rva<image_resource_directory>(res_rva + offset_to_directory, section_data_virtual, true);
-
-	ret = resource_directory(directory);
-
-	//Check DWORDs for possible overflows
-	if(!pe_utils::is_sum_safe(directory.NumberOfIdEntries, directory.NumberOfNamedEntries)
-		|| directory.NumberOfIdEntries + directory.NumberOfNamedEntries >= pe_utils::max_dword / sizeof(image_resource_directory_entry) + sizeof(image_resource_directory))
-		throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-	if(!pe_utils::is_sum_safe(offset_to_directory, sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry))
-		|| !pe_utils::is_sum_safe(res_rva, offset_to_directory + sizeof(image_resource_directory) + (directory.NumberOfIdEntries + directory.NumberOfNamedEntries) * sizeof(image_resource_directory_entry)))
-		throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-	for(unsigned long i = 0; i != static_cast<unsigned long>(directory.NumberOfIdEntries) + directory.NumberOfNamedEntries; ++i)
-	{
-		//Read directory entries one by one
-		image_resource_directory_entry dir_entry = pe.section_data_from_rva<image_resource_directory_entry>(
-			res_rva + sizeof(image_resource_directory) + i * sizeof(image_resource_directory_entry) + offset_to_directory, section_data_virtual, true);
-
-		//Create directory entry structure
-		resource_directory_entry entry;
-
-		//If directory is named
-		if(dir_entry.NameIsString)
-		{
-			if(!pe_utils::is_sum_safe(res_rva + sizeof(uint16_t) /* safe */, dir_entry.NameOffset))
-				throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-			//get directory name length
-			uint16_t directory_name_length = pe.section_data_from_rva<uint16_t>(res_rva + dir_entry.NameOffset, section_data_virtual, true);
-
-			//Check name length
-			if(pe.section_data_length_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)
-				< directory_name_length)
-				throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-#ifdef PE_BLISS_WINDOWS
-			//Set entry UNICODE name
-			entry.set_name(std::wstring(
-				reinterpret_cast<const wchar_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)),
-				directory_name_length));
-#else
-			//Set entry UNICODE name
-			entry.set_name(pe_utils::from_ucs2(u16string(
-				reinterpret_cast<const unicode16_t*>(pe.section_data_from_rva(res_rva + dir_entry.NameOffset + sizeof(uint16_t), section_data_virtual, true)),
-				directory_name_length)));
-#endif
-		}
-		else
-		{
-			//Else - set directory ID
-			entry.set_id(dir_entry.Id);
-		}
-
-		//If directory entry has another resource directory
-		if(dir_entry.DataIsDirectory)
-		{
-			entry.add_resource_directory(process_resource_directory(pe, res_rva, dir_entry.OffsetToDirectory, processed));
-		}
-		else
-		{
-			//If directory entry has data
-			image_resource_data_entry data_entry = pe.section_data_from_rva<image_resource_data_entry>(
-				res_rva + dir_entry.OffsetToData, section_data_virtual, true);
-
-			//Check byte count that stated by data entry
-			if(pe.section_data_length_from_rva(data_entry.OffsetToData, data_entry.OffsetToData, section_data_virtual, true) < data_entry.Size)
-				throw pe_exception("Incorrect resource directory", pe_exception::incorrect_resource_directory);
-
-			//Add data entry to directory entry
-			entry.add_data_entry(resource_data_entry(
-				std::string(pe.section_data_from_rva(data_entry.OffsetToData, section_data_virtual, true), data_entry.Size),
-				data_entry.CodePage));
-		}
-
-		//Save directory entry
-		ret.add_resource_directory_entry(entry);
-	}
-
-	//Return resource directory
-	return ret;
-}
-
-//Helper function to calculate needed space for resource data
-void calculate_resource_data_space(const resource_directory& root, uint32_t aligned_offset_from_section_start, uint32_t& needed_size_for_structures, uint32_t& needed_size_for_strings)
-{
-	needed_size_for_structures += sizeof(image_resource_directory);
-	for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
-	{
-		needed_size_for_structures += sizeof(image_resource_directory_entry);
-
-		if((*it).is_named())
-			needed_size_for_strings += static_cast<uint32_t>(((*it).get_name().length() + 1) * 2 /* unicode */ + sizeof(uint16_t) /* for string length */);
-
-		if(!(*it).includes_data())
-			calculate_resource_data_space((*it).get_resource_directory(), aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
-	}
-}
-
-//Helper function to calculate needed space for resource data
-void calculate_resource_data_space(const resource_directory& root, uint32_t needed_size_for_structures, uint32_t needed_size_for_strings, uint32_t& needed_size_for_data, uint32_t& current_data_pos)
-{
-	for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
-	{
-		if((*it).includes_data())
-		{
-			uint32_t data_size = static_cast<uint32_t>((*it).get_data_entry().get_data().length()
-				+ sizeof(image_resource_data_entry)
-				+ (pe_utils::align_up(current_data_pos, sizeof(uint32_t)) - current_data_pos) /* alignment */);
-			needed_size_for_data += data_size;
-			current_data_pos += data_size;
-		}
-		else
-		{
-			calculate_resource_data_space((*it).get_resource_directory(), needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
-		}
-	}
-}
-
-//Helper: sorts resource directory entries
-struct entry_sorter
-{
-public:
-	bool operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const;
-};
-
-//Helper function to rebuild resource directory
-void rebuild_resource_directory(pe_base& pe, section& resource_section, resource_directory& root, uint32_t& current_structures_pos, uint32_t& current_data_pos, uint32_t& current_strings_pos, uint32_t offset_from_section_start)
-{
-	//Create resource directory
-	image_resource_directory dir = {0};
-	dir.Characteristics = root.get_characteristics();
-	dir.MajorVersion = root.get_major_version();
-	dir.MinorVersion = root.get_minor_version();
-	dir.TimeDateStamp = root.get_timestamp();
-	
-	{
-		resource_directory::entry_list& entries = root.get_entry_list();
-		std::sort(entries.begin(), entries.end(), entry_sorter());
-	}
-
-	//Calculate number of named and ID entries
-	for(resource_directory::entry_list::const_iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
-	{
-		if((*it).is_named())
-			++dir.NumberOfNamedEntries;
-		else
-			++dir.NumberOfIdEntries;
-	}
-	
-	std::string& raw_data = resource_section.get_raw_data();
-
-	//Save resource directory
-	memcpy(&raw_data[current_structures_pos], &dir, sizeof(dir));
-	current_structures_pos += sizeof(dir);
-
-	uint32_t this_current_structures_pos = current_structures_pos;
-
-	current_structures_pos += sizeof(image_resource_directory_entry) * (dir.NumberOfNamedEntries + dir.NumberOfIdEntries);
-
-	//Create all resource directory entries
-	for(resource_directory::entry_list::iterator it = root.get_entry_list().begin(); it != root.get_entry_list().end(); ++it)
-	{
-		image_resource_directory_entry entry;
-		if((*it).is_named())
-		{
-			entry.Name = 0x80000000 | (current_strings_pos - offset_from_section_start);
-			uint16_t unicode_length = static_cast<uint16_t>((*it).get_name().length());
-			memcpy(&raw_data[current_strings_pos], &unicode_length, sizeof(unicode_length));
-			current_strings_pos += sizeof(unicode_length);
-
-#ifdef PE_BLISS_WINDOWS
-			memcpy(&raw_data[current_strings_pos], (*it).get_name().c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
-#else
-			{
-				u16string str(pe_utils::to_ucs2((*it).get_name()));
-				memcpy(&raw_data[current_strings_pos], str.c_str(), (*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
-			}
-#endif
-
-			current_strings_pos += static_cast<unsigned long>((*it).get_name().length() * sizeof(uint16_t) + sizeof(uint16_t) /* unicode */);
-		}
-		else
-		{
-			entry.Name = (*it).get_id();
-		}
-
-		if((*it).includes_data())
-		{
-			current_data_pos = pe_utils::align_up(current_data_pos, sizeof(uint32_t));
-			image_resource_data_entry data_entry = {0};
-			data_entry.CodePage = (*it).get_data_entry().get_codepage();
-			data_entry.Size = static_cast<uint32_t>((*it).get_data_entry().get_data().length());
-			data_entry.OffsetToData = pe.rva_from_section_offset(resource_section, current_data_pos + sizeof(data_entry));
-			
-			entry.OffsetToData = current_data_pos - offset_from_section_start;
-
-			memcpy(&raw_data[current_data_pos], &data_entry, sizeof(data_entry));
-			current_data_pos += sizeof(data_entry);
-			
-			memcpy(&raw_data[current_data_pos], (*it).get_data_entry().get_data().data(), data_entry.Size);
-			current_data_pos += data_entry.Size;
-
-			memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry));
-			this_current_structures_pos += sizeof(entry);
-		}
-		else
-		{
-			entry.OffsetToData = 0x80000000 | (current_structures_pos - offset_from_section_start);
-
-			memcpy(&raw_data[this_current_structures_pos], &entry, sizeof(entry));
-			this_current_structures_pos += sizeof(entry);
-
-			rebuild_resource_directory(pe, resource_section, (*it).get_resource_directory(), current_structures_pos, current_data_pos, current_strings_pos, offset_from_section_start);
-		}
-	}
-}
-
-//Helper function to rebuild resource directory
-bool entry_sorter::operator()(const resource_directory_entry& entry1, const resource_directory_entry& entry2) const
-{
-	if(entry1.is_named() && entry2.is_named())
-		return entry1.get_name() < entry2.get_name();
-	else if(!entry1.is_named() && !entry2.is_named())
-		return entry1.get_id() < entry2.get_id();
-	else
-		return entry1.is_named();
-}
-
-//Resources rebuilder
-//resource_directory - root resource directory
-//resources_section - section where resource directory will be placed (must be attached to PE image)
-//offset_from_section_start - offset from resources_section raw data start
-//resource_directory is non-constant, because it will be sorted
-//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
-//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
-//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
-const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	//Check that resources_section is attached to this PE image
-	if(!pe.section_attached(resources_section))
-		throw pe_exception("Resource section must be attached to PE file", pe_exception::section_is_not_attached);
-	
-	//Check resource directory correctness
-	if(info.get_entry_list().empty())
-		throw pe_exception("Empty resource directory", pe_exception::incorrect_resource_directory);
-	
-	uint32_t aligned_offset_from_section_start = pe_utils::align_up(offset_from_section_start, sizeof(uint32_t));
-	uint32_t needed_size_for_structures = aligned_offset_from_section_start - offset_from_section_start; //Calculate needed size for resource tables and data
-	uint32_t needed_size_for_strings = 0;
-	uint32_t needed_size_for_data = 0;
-
-	calculate_resource_data_space(info, aligned_offset_from_section_start, needed_size_for_structures, needed_size_for_strings);
-
-	{
-		uint32_t current_data_pos = aligned_offset_from_section_start + needed_size_for_structures + needed_size_for_strings;
-		calculate_resource_data_space(info, needed_size_for_structures, needed_size_for_strings, needed_size_for_data, current_data_pos);
-	}
-
-	uint32_t needed_size = needed_size_for_structures + needed_size_for_strings + needed_size_for_data;
-
-	//Check if resources_section is last one. If it's not, check if there's enough place for resource data
-	if(&resources_section != &*(pe.get_image_sections().end() - 1) && 
-		(resources_section.empty() || pe_utils::align_up(resources_section.get_size_of_raw_data(), pe.get_file_alignment())
-		< needed_size + aligned_offset_from_section_start))
-		throw pe_exception("Insufficient space for resource directory", pe_exception::insufficient_space);
-
-	std::string& raw_data = resources_section.get_raw_data();
-
-	//This will be done only if resources_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + aligned_offset_from_section_start)
-		raw_data.resize(needed_size + aligned_offset_from_section_start); //Expand section raw data
-
-	uint32_t current_structures_pos = aligned_offset_from_section_start;
-	uint32_t current_strings_pos = current_structures_pos + needed_size_for_structures;
-	uint32_t current_data_pos = current_strings_pos + needed_size_for_strings;
-	rebuild_resource_directory(pe, resources_section, info, current_structures_pos, current_data_pos, current_strings_pos, aligned_offset_from_section_start);
-	
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(resources_section, auto_strip_last_section);
-
-	image_directory ret(pe.rva_from_section_offset(resources_section, aligned_offset_from_section_start), needed_size);
-
-	//If auto-rewrite of PE headers is required
-	if(save_to_pe_header)
-	{
-		pe.set_directory_rva(image_directory_entry_resource, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_resource, ret.get_size());
-	}
-
-	return ret;
-}
-
-//Returns resources from PE file
-const resource_directory get_resources(const pe_base& pe)
-{
-	resource_directory ret;
-
-	if(!pe.has_resources())
-		return ret;
-
-	//Get resource directory RVA
-	uint32_t res_rva = pe.get_directory_rva(image_directory_entry_resource);
-	
-	//Store already processed directories to avoid resource loops
-	std::set<uint32_t> processed;
-	
-	//Process all directories (recursion)
-	ret = process_resource_directory(pe, res_rva, 0, processed);
-
-	return ret;
-}
-
-//Finds resource_directory_entry by ID
-resource_directory::id_entry_finder::id_entry_finder(uint32_t id)
-	:id_(id)
-{}
-
-bool resource_directory::id_entry_finder::operator()(const resource_directory_entry& entry) const
-{
-	return !entry.is_named() && entry.get_id() == id_;
-}
-
-//Finds resource_directory_entry by name
-resource_directory::name_entry_finder::name_entry_finder(const std::wstring& name)
-	:name_(name)
-{}
-
-bool resource_directory::name_entry_finder::operator()(const resource_directory_entry& entry) const
-{
-	return entry.is_named() && entry.get_name() == name_;
-}
-
-//Finds resource_directory_entry by name or ID (universal)
-resource_directory::entry_finder::entry_finder(const std::wstring& name)
-	:name_(name), named_(true)
-{}
-
-resource_directory::entry_finder::entry_finder(uint32_t id)
-	:id_(id), named_(false)
-{}
-
-bool resource_directory::entry_finder::operator()(const resource_directory_entry& entry) const
-{
-	if(named_)
-		return entry.is_named() && entry.get_name() == name_;
-	else
-		return !entry.is_named() && entry.get_id() == id_;
-}
-
-//Returns resource_directory_entry by ID. If not found - throws an exception
-const resource_directory_entry& resource_directory::entry_by_id(uint32_t id) const
-{
-	entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), id_entry_finder(id));
-	if(i == entries_.end())
-		throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found);
-
-	return *i;
-}
-
-//Returns resource_directory_entry by name. If not found - throws an exception
-const resource_directory_entry& resource_directory::entry_by_name(const std::wstring& name) const
-{
-	entry_list::const_iterator i = std::find_if(entries_.begin(), entries_.end(), name_entry_finder(name));
-	if(i == entries_.end())
-		throw pe_exception("Resource directory entry not found", pe_exception::resource_directory_entry_not_found);
-
-	return *i;
-}
-}

+ 0 - 245
tools/pe_bliss/pe_resources.h

@@ -1,245 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include <string>
-#include <set>
-#include "pe_structures.h"
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing resource data entry
-class resource_data_entry
-{
-public:
-	//Default constructor
-	resource_data_entry();
-	//Constructor from data
-	resource_data_entry(const std::string& data, uint32_t codepage);
-
-	//Returns resource data codepage
-	uint32_t get_codepage() const;
-	//Returns resource data
-	const std::string& get_data() const;
-		
-public: //These functions do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild resource directory
-		
-	//Sets resource data codepage
-	void set_codepage(uint32_t codepage);
-	//Sets resource data
-	void set_data(const std::string& data);
-
-private:
-	uint32_t codepage_; //Resource data codepage
-	std::string data_; //Resource data
-};
-
-//Forward declaration
-class resource_directory;
-
-//Class representing resource directory entry
-class resource_directory_entry
-{
-public:
-	//Default constructor
-	resource_directory_entry();
-	//Copy constructor
-	resource_directory_entry(const resource_directory_entry& other);
-	//Copy assignment operator
-	resource_directory_entry& operator=(const resource_directory_entry& other);
-
-	//Returns entry ID
-	uint32_t get_id() const;
-	//Returns entry name
-	const std::wstring& get_name() const;
-	//Returns true, if entry has name
-	//Returns false, if entry has ID
-	bool is_named() const;
-
-	//Returns true, if entry includes resource_data_entry
-	//Returns false, if entry includes resource_directory
-	bool includes_data() const;
-	//Returns resource_directory if entry includes it, otherwise throws an exception
-	const resource_directory& get_resource_directory() const;
-	//Returns resource_data_entry if entry includes it, otherwise throws an exception
-	const resource_data_entry& get_data_entry() const;
-
-	//Destructor
-	~resource_directory_entry();
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild resource directory
-
-	//Sets entry name
-	void set_name(const std::wstring& name);
-	//Sets entry ID
-	void set_id(uint32_t id);
-		
-	//Returns resource_directory if entry includes it, otherwise throws an exception
-	resource_directory& get_resource_directory();
-	//Returns resource_data_entry if entry includes it, otherwise throws an exception
-	resource_data_entry& get_data_entry();
-
-	//Adds resource_data_entry
-	void add_data_entry(const resource_data_entry& entry);
-	//Adds resource_directory
-	void add_resource_directory(const resource_directory& dir);
-
-private:
-	//Destroys included data
-	void release();
-
-private:
-	uint32_t id_;
-	std::wstring name_;
-
-	union includes
-	{
-		//Default constructor
-		includes();
-
-		//We use pointers, we're doing manual copying here
-		class resource_data_entry* data_;
-		class resource_directory* dir_; //We use pointer, because structs include each other
-	};
-
-	includes ptr_;
-
-	bool includes_data_, named_;
-};
-
-//Class representing resource directory
-class resource_directory
-{
-public:
-	typedef std::vector<resource_directory_entry> entry_list;
-
-public:
-	//Default constructor
-	resource_directory();
-	//Constructor from data
-	explicit resource_directory(const pe_win::image_resource_directory& dir);
-
-	//Returns characteristics of directory
-	uint32_t get_characteristics() const;
-	//Returns date and time stamp of directory
-	uint32_t get_timestamp() const;
-	//Returns number of named entries
-	uint32_t get_number_of_named_entries() const;
-	//Returns number of ID entries
-	uint32_t get_number_of_id_entries() const;
-	//Returns major version of directory
-	uint16_t get_major_version() const;
-	//Returns minor version of directory
-	uint16_t get_minor_version() const;
-	//Returns resource_directory_entry array
-	const entry_list& get_entry_list() const;
-	//Returns resource_directory_entry by ID. If not found - throws an exception
-	const resource_directory_entry& entry_by_id(uint32_t id) const;
-	//Returns resource_directory_entry by name. If not found - throws an exception
-	const resource_directory_entry& entry_by_name(const std::wstring& name) const;
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild resource directory
-
-	//Adds resource_directory_entry
-	void add_resource_directory_entry(const resource_directory_entry& entry);
-	//Clears resource_directory_entry array
-	void clear_resource_directory_entry_list();
-
-	//Sets characteristics of directory
-	void set_characteristics(uint32_t characteristics);
-	//Sets date and time stamp of directory
-	void set_timestamp(uint32_t timestamp);
-	//Sets number of named entries
-	void set_number_of_named_entries(uint32_t number);
-	//Sets number of ID entries
-	void set_number_of_id_entries(uint32_t number);
-	//Sets major version of directory
-	void set_major_version(uint16_t major_version);
-	//Sets minor version of directory
-	void get_minor_version(uint16_t minor_version);
-		
-	//Returns resource_directory_entry array
-	entry_list& get_entry_list();
-
-private:
-	uint32_t characteristics_;
-	uint32_t timestamp_;
-	uint16_t major_version_, minor_version_;
-	uint32_t number_of_named_entries_, number_of_id_entries_;
-	entry_list entries_;
-
-public: //Finder helpers
-	//Finds resource_directory_entry by ID
-	struct id_entry_finder
-	{
-	public:
-		explicit id_entry_finder(uint32_t id);
-		bool operator()(const resource_directory_entry& entry) const;
-
-	private:
-		uint32_t id_;
-	};
-
-	//Finds resource_directory_entry by name
-	struct name_entry_finder
-	{
-	public:
-		explicit name_entry_finder(const std::wstring& name);
-		bool operator()(const resource_directory_entry& entry) const;
-
-	private:
-		std::wstring name_;
-	};
-
-	//Finds resource_directory_entry by name or ID (universal)
-	struct entry_finder
-	{
-	public:
-		explicit entry_finder(const std::wstring& name);
-		explicit entry_finder(uint32_t id);
-		bool operator()(const resource_directory_entry& entry) const;
-
-	private:
-		std::wstring name_;
-		uint32_t id_;
-		bool named_;
-	};
-};
-
-//Returns resources (root resource_directory) from PE file
-const resource_directory get_resources(const pe_base& pe);
-
-//Resources rebuilder
-//resource_directory - root resource directory
-//resources_section - section where resource directory will be placed (must be attached to PE image)
-//resource_directory is non-constant, because it will be sorted
-//offset_from_section_start - offset from resources_section raw data start
-//save_to_pe_headers - if true, new resource directory information will be saved to PE image headers
-//auto_strip_last_section - if true and resources are placed in the last section, it will be automatically stripped
-//number_of_id_entries and number_of_named_entries for resource directories are recalculated and not used
-const image_directory rebuild_resources(pe_base& pe, resource_directory& info, section& resources_section, uint32_t offset_from_section_start = 0, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}

+ 0 - 152
tools/pe_bliss/pe_rich_data.cpp

@@ -1,152 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "pe_rich_data.h"
-
-namespace pe_bliss
-{
-//STUB OVERLAY
-//Default constructor
-rich_data::rich_data()
-	:number_(0), version_(0), times_(0)
-{}
-
-//Who knows, what these fields mean...
-uint32_t rich_data::get_number() const
-{
-	return number_;
-}
-
-uint32_t rich_data::get_version() const
-{
-	return version_;
-}
-
-uint32_t rich_data::get_times() const
-{
-	return times_;
-}
-
-void rich_data::set_number(uint32_t number)
-{
-	number_ = number;
-}
-
-void rich_data::set_version(uint32_t version)
-{
-	version_ = version;
-}
-
-void rich_data::set_times(uint32_t times)
-{
-	times_ = times;
-}
-
-//Returns MSVC rich data
-const rich_data_list get_rich_data(const pe_base& pe)
-{
-	//Returned value
-	rich_data_list ret;
-
-	const std::string& rich_overlay = pe.get_stub_overlay();
-
-	//If there's no rich overlay, return empty vector
-	if(rich_overlay.size() < sizeof(uint32_t))
-		return ret;
-
-	//True if rich data was found
-	bool found = false;
-
-	//Rich overlay ID ("Rich" word)
-	static const uint32_t rich_overlay_id = 0x68636952;
-
-	//Search for rich data overlay ID
-	const char* begin = &rich_overlay[0];
-	const char* end = begin + rich_overlay.length();
-	for(; begin != end; ++begin)
-	{
-		if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id)
-		{
-			found = true; //We've found it!
-			break;
-		}
-	}
-
-	//If we found it
-	if(found)
-	{
-		//Check remaining length
-		if(static_cast<size_t>(end - begin) < sizeof(uint32_t))
-			return ret;
-
-		//The XOR key is after "Rich" word, we should get it
-		uint32_t xorkey = *reinterpret_cast<const uint32_t*>(begin + sizeof(uint32_t));
-
-		//True if rich data was found
-		found = false;
-
-		//Second search for signature "DanS"
-		begin = &rich_overlay[0];
-		for(; begin != end; ++begin)
-		{
-			if((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) == 0x536e6144) //"DanS"
-			{
-				found = true;
-				break;
-			}
-		}
-
-		//If second signature is found
-		if(found)
-		{
-			begin += sizeof(uint32_t) * 3;
-			//List all rich data structures
-			while(begin < end)
-			{
-				begin += sizeof(uint32_t);
-				if(begin >= end)
-					break;
-
-				//Check for rich overlay data end ("Rich" word reached)
-				if(*reinterpret_cast<const uint32_t*>(begin) == rich_overlay_id)
-					break;
-
-				//Create rich_data structure
-				rich_data data;
-				data.set_number((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) >> 16);
-				data.set_version((*reinterpret_cast<const uint32_t*>(begin) ^ xorkey) & 0xFFFF);
-
-				begin += sizeof(uint32_t);
-				if(begin >= end)
-					break;
-
-				data.set_times(*reinterpret_cast<const uint32_t*>(begin) ^ xorkey);
-
-				//Save rich data structure
-				ret.push_back(data);
-			}
-		}
-	}
-
-	//Return rich data structures list
-	return ret;
-}
-}

+ 0 - 58
tools/pe_bliss/pe_rich_data.h

@@ -1,58 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <vector>
-#include "pe_structures.h"
-#include "pe_base.h"
-
-namespace pe_bliss
-{
-//Rich data overlay class of Microsoft Visual Studio
-class rich_data
-{
-public:
-	//Default constructor
-	rich_data();
-
-public: //Getters
-	//Who knows, what these fields mean...
-	uint32_t get_number() const;
-	uint32_t get_version() const;
-	uint32_t get_times() const;
-
-public: //Setters, used by PE library only
-	void set_number(uint32_t number);
-	void set_version(uint32_t version);
-	void set_times(uint32_t times);
-
-private:
-	uint32_t number_;
-	uint32_t version_;
-	uint32_t times_;
-};
-
-//Rich data list typedef
-typedef std::vector<rich_data> rich_data_list;
-
-//Returns a vector with rich data (stub overlay)
-const rich_data_list get_rich_data(const pe_base& pe);
-}

+ 0 - 303
tools/pe_bliss/pe_section.cpp

@@ -1,303 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "utils.h"
-#include "pe_section.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Section structure default constructor
-section::section()
-	:old_size_(static_cast<size_t>(-1))
-{
-	memset(&header_, 0, sizeof(image_section_header));
-}
-
-//Sets the name of section (8 characters maximum)
-void section::set_name(const std::string& name)
-{
-	memset(header_.Name, 0, sizeof(header_.Name));
-	memcpy(header_.Name, name.c_str(), std::min<size_t>(name.length(), sizeof(header_.Name)));
-}
-
-//Returns section name
-const std::string section::get_name() const
-{
-	char buf[9] = {0};
-	memcpy(buf, header_.Name, 8);
-	return std::string(buf);
-}
-
-//Set flag (attribute) of section
-section& section::set_flag(uint32_t flag, bool setflag)
-{
-	if(setflag)
-		header_.Characteristics |= flag;
-	else
-		header_.Characteristics &= ~flag;
-
-	return *this;
-}
-
-//Sets "readable" attribute of section
-section& section::readable(bool readable)
-{
-	return set_flag(image_scn_mem_read, readable);
-}
-
-//Sets "writeable" attribute of section
-section& section::writeable(bool writeable)
-{
-	return set_flag(image_scn_mem_write, writeable);
-}
-
-//Sets "executable" attribute of section
-section& section::executable(bool executable)
-{
-	return set_flag(image_scn_mem_execute, executable);
-}
-
-//Sets "shared" attribute of section
-section& section::shared(bool shared)
-{
-	return set_flag(image_scn_mem_shared, shared);
-}
-
-//Sets "discardable" attribute of section
-section& section::discardable(bool discardable)
-{
-	return set_flag(image_scn_mem_discardable, discardable);
-}
-
-//Returns true if section is readable
-bool section::readable() const
-{
-	return (header_.Characteristics & image_scn_mem_read) != 0;
-}
-
-//Returns true if section is writeable
-bool section::writeable() const
-{
-	return (header_.Characteristics & image_scn_mem_write) != 0;
-}
-
-//Returns true if section is executable
-bool section::executable() const
-{
-	return (header_.Characteristics & image_scn_mem_execute) != 0;
-}
-
-bool section::shared() const
-{
-	return (header_.Characteristics & image_scn_mem_shared) != 0;
-}
-
-bool section::discardable() const
-{
-	return (header_.Characteristics & image_scn_mem_discardable) != 0;
-}
-
-//Returns true if section has no RAW data
-bool section::empty() const
-{
-	if(old_size_ != static_cast<size_t>(-1)) //If virtual memory is mapped, check raw data length (old_size_)
-		return old_size_ == 0;
-	else
-		return raw_data_.empty();
-}
-
-//Returns raw section data from file image
-std::string& section::get_raw_data()
-{
-	unmap_virtual();
-	return raw_data_;
-}
-
-//Sets raw section data from file image
-void section::set_raw_data(const std::string& data)
-{
-	old_size_ = static_cast<size_t>(-1);
-	raw_data_ = data;
-}
-
-//Returns raw section data from file image
-const std::string& section::get_raw_data() const
-{
-	unmap_virtual();
-	return raw_data_;
-}
-
-//Returns mapped virtual section data
-const std::string& section::get_virtual_data(uint32_t section_alignment) const
-{
-	map_virtual(section_alignment);
-	return raw_data_;
-}
-
-//Returns mapped virtual section data
-std::string& section::get_virtual_data(uint32_t section_alignment)
-{
-	map_virtual(section_alignment);
-	return raw_data_;
-}
-
-//Maps virtual section data
-void section::map_virtual(uint32_t section_alignment) const
-{
-	uint32_t aligned_virtual_size = get_aligned_virtual_size(section_alignment);
-	if(old_size_ == static_cast<size_t>(-1) && aligned_virtual_size && aligned_virtual_size > raw_data_.length())
-	{
-		old_size_ = raw_data_.length();
-		raw_data_.resize(aligned_virtual_size, 0);
-	}
-}
-
-//Unmaps virtual section data
-void section::unmap_virtual() const
-{
-	if(old_size_ != static_cast<size_t>(-1))
-	{
-		raw_data_.resize(old_size_, 0);
-		old_size_ = static_cast<size_t>(-1);
-	}
-}
-
-//Returns section virtual size
-uint32_t section::get_virtual_size() const
-{
-	return header_.Misc.VirtualSize;
-}
-
-//Returns section virtual address
-uint32_t section::get_virtual_address() const
-{
-	return header_.VirtualAddress;
-}
-
-//Returns size of section raw data
-uint32_t section::get_size_of_raw_data() const
-{
-	return header_.SizeOfRawData;
-}
-
-//Returns pointer to raw section data in PE file
-uint32_t section::get_pointer_to_raw_data() const
-{
-	return header_.PointerToRawData;
-}
-
-//Returns section characteristics
-uint32_t section::get_characteristics() const
-{
-	return header_.Characteristics;
-}
-
-//Returns raw image section header
-const pe_win::image_section_header& section::get_raw_header() const
-{
-	return header_;
-}
-
-//Returns raw image section header
-pe_win::image_section_header& section::get_raw_header()
-{
-	return header_;
-}
-
-//Calculates aligned virtual section size
-uint32_t section::get_aligned_virtual_size(uint32_t section_alignment) const
-{
-	if(get_size_of_raw_data())
-	{
-		if(!get_virtual_size())
-		{
-			//If section virtual size is zero
-			//Set aligned virtual size of section as aligned raw size
-			return pe_utils::align_up(get_size_of_raw_data(), section_alignment);
-		}
-	}
-
-	return pe_utils::align_up(get_virtual_size(), section_alignment);
-}
-
-//Calculates aligned raw section size
-uint32_t section::get_aligned_raw_size(uint32_t file_alignment) const
-{
-	if(get_size_of_raw_data())
-		return pe_utils::align_up(get_size_of_raw_data(), file_alignment);
-	else
-		return 0;
-}
-
-//Sets size of raw section data
-void section::set_size_of_raw_data(uint32_t size_of_raw_data)
-{
-	header_.SizeOfRawData = size_of_raw_data;
-}
-
-//Sets pointer to section raw data
-void section::set_pointer_to_raw_data(uint32_t pointer_to_raw_data)
-{
-	header_.PointerToRawData = pointer_to_raw_data;
-}
-
-//Sets section characteristics
-void section::set_characteristics(uint32_t characteristics)
-{
-	header_.Characteristics = characteristics;
-}
-
-//Sets section virtual size
-void section::set_virtual_size(uint32_t virtual_size)
-{
-	header_.Misc.VirtualSize = virtual_size;
-}
-
-//Sets section virtual address
-void section::set_virtual_address(uint32_t virtual_address)
-{
-	header_.VirtualAddress = virtual_address;
-}
-
-//Section by file offset finder helper (4gb max)
-section_by_raw_offset::section_by_raw_offset(uint32_t offset)
-	:offset_(offset)
-{}
-
-bool section_by_raw_offset::operator()(const section& s) const
-{
-	return (s.get_pointer_to_raw_data() <= offset_)
-		&& (s.get_pointer_to_raw_data() + s.get_size_of_raw_data() > offset_);
-}
-
-section_ptr_finder::section_ptr_finder(const section& s)
-	:s_(s)
-{}
-
-bool section_ptr_finder::operator()(const section& s) const
-{
-	return &s == &s_;
-}
-}

+ 0 - 158
tools/pe_bliss/pe_section.h

@@ -1,158 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-//Enumeration of section data types, used in functions below
-enum section_data_type
-{
-	section_data_raw,
-	section_data_virtual
-};
-
-//Class representing image section
-class section
-{
-public:
-	//Default constructor
-	section();
-
-	//Sets the name of section (stripped to 8 characters)
-	void set_name(const std::string& name);
-
-	//Returns the name of section
-	const std::string get_name() const;
-
-	//Changes attributes of section
-	section& readable(bool readable);
-	section& writeable(bool writeable);
-	section& executable(bool executable);
-	section& shared(bool shared);
-	section& discardable(bool discardable);
-
-	//Returns attributes of section
-	bool readable() const;
-	bool writeable() const;
-	bool executable() const;
-	bool shared() const;
-	bool discardable() const;
-
-	//Returns true if section has no RAW data
-	bool empty() const;
-
-	//Returns raw section data from file image
-	std::string& get_raw_data();
-	//Returns raw section data from file image
-	const std::string& get_raw_data() const;
-	//Returns mapped virtual section data
-	const std::string& get_virtual_data(uint32_t section_alignment) const;
-	//Returns mapped virtual section data
-	std::string& get_virtual_data(uint32_t section_alignment);
-
-public: //Header getters
-	//Returns section virtual size
-	uint32_t get_virtual_size() const;
-	//Returns section virtual address (RVA)
-	uint32_t get_virtual_address() const;
-	//Returns size of section raw data
-	uint32_t get_size_of_raw_data() const;
-	//Returns pointer to raw section data in PE file
-	uint32_t get_pointer_to_raw_data() const;
-	//Returns section characteristics
-	uint32_t get_characteristics() const;
-
-	//Returns raw image section header
-	const pe_win::image_section_header& get_raw_header() const;
-
-public: //Aligned sizes calculation
-	//Calculates aligned virtual section size
-	uint32_t get_aligned_virtual_size(uint32_t section_alignment) const;
-	//Calculates aligned raw section size
-	uint32_t get_aligned_raw_size(uint32_t file_alignment) const;
-
-public: //Setters
-	//Sets size of raw section data
-	void set_size_of_raw_data(uint32_t size_of_raw_data);
-	//Sets pointer to section raw data
-	void set_pointer_to_raw_data(uint32_t pointer_to_raw_data);
-	//Sets section characteristics
-	void set_characteristics(uint32_t characteristics);
-	//Sets raw section data from file image
-	void set_raw_data(const std::string& data);
-
-public: //Setters, be careful
-	//Sets section virtual size (doesn't set internal aligned virtual size, changes only header value)
-	//Better use pe_base::set_section_virtual_size
-	void set_virtual_size(uint32_t virtual_size);
-	//Sets section virtual address
-	void set_virtual_address(uint32_t virtual_address);
-	//Returns raw image section header
-	pe_win::image_section_header& get_raw_header();
-
-private:
-	//Section header
-	pe_win::image_section_header header_;
-
-	//Maps virtual section data
-	void map_virtual(uint32_t section_alignment) const;
-
-	//Unmaps virtual section data
-	void unmap_virtual() const;
-
-	//Set flag (attribute) of section
-	section& set_flag(uint32_t flag, bool setflag);
-
-	//Old size of section (stored after mapping of virtual section memory)
-	mutable std::size_t old_size_;
-
-	//Section raw/virtual data
-	mutable std::string raw_data_;
-};
-
-//Section by file offset finder helper (4gb max)
-struct section_by_raw_offset
-{
-public:
-	explicit section_by_raw_offset(uint32_t offset);
-	bool operator()(const section& s) const;
-
-private:
-	uint32_t offset_;
-};
-
-//Helper: finder of section* in sections list
-struct section_ptr_finder
-{
-public:
-	explicit section_ptr_finder(const section& s);
-	bool operator()(const section& s) const;
-
-private:
-	const section& s_;
-};
-
-typedef std::vector<section> section_list;
-}

+ 0 - 1028
tools/pe_bliss/pe_structures.h

@@ -1,1028 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <sstream>
-#include "stdint_defs.h"
-#if defined(_MSC_VER) or defined(__MINGW32__)
-#define PE_BLISS_WINDOWS
-#endif
-
-namespace pe_bliss
-{
-//Enumeration of PE types
-enum pe_type
-{
-	pe_type_32,
-	pe_type_64
-};
-
-namespace pe_win
-{
-const uint32_t image_numberof_directory_entries = 16;
-const uint32_t image_nt_optional_hdr32_magic = 0x10b;
-const uint32_t image_nt_optional_hdr64_magic = 0x20b;
-const uint32_t image_resource_name_is_string = 0x80000000;
-const uint32_t image_resource_data_is_directory = 0x80000000;
-
-const uint32_t image_dllcharacteristics_dynamic_base = 0x0040;     // DLL can move.
-const uint32_t image_dllcharacteristics_force_integrity = 0x0080;     // Code Integrity Image
-const uint32_t image_dllcharacteristics_nx_compat = 0x0100;     // Image is NX compatible
-const uint32_t image_dllcharacteristics_no_isolation = 0x0200;     // Image understands isolation and doesn't want it
-const uint32_t image_dllcharacteristics_no_seh = 0x0400;     // Image does not use SEH.  No SE handler may reside in this image
-const uint32_t image_dllcharacteristics_no_bind = 0x0800;     // Do not bind this image.
-const uint32_t image_dllcharacteristics_wdm_driver = 0x2000;     // Driver uses WDM model
-const uint32_t image_dllcharacteristics_terminal_server_aware = 0x8000;
-
-const uint32_t image_sizeof_file_header = 20;
-
-const uint32_t image_file_relocs_stripped = 0x0001;  // Relocation info stripped from file.
-const uint32_t image_file_executable_image = 0x0002;  // File is executable  (i.e. no unresolved externel references).
-const uint32_t image_file_line_nums_stripped = 0x0004;  // Line nunbers stripped from file.
-const uint32_t image_file_local_syms_stripped = 0x0008;  // Local symbols stripped from file.
-const uint32_t image_file_aggresive_ws_trim = 0x0010;  // Agressively trim working set
-const uint32_t image_file_large_address_aware = 0x0020;  // App can handle >2gb addresses
-const uint32_t image_file_bytes_reversed_lo = 0x0080;  // Bytes of machine word are reversed.
-const uint32_t image_file_32bit_machine = 0x0100;  // 32 bit word machine.
-const uint32_t image_file_debug_stripped = 0x0200;  // Debugging info stripped from file in .DBG file
-const uint32_t image_file_removable_run_from_swap = 0x0400;  // If Image is on removable media, copy and run from the swap file.
-const uint32_t image_file_net_run_from_swap = 0x0800;  // If Image is on Net, copy and run from the swap file.
-const uint32_t image_file_system = 0x1000;  // System File.
-const uint32_t image_file_dll = 0x2000;  // File is a DLL.
-const uint32_t image_file_up_system_only = 0x4000;  // File should only be run on a UP machine
-const uint32_t image_file_bytes_reversed_hi = 0x8000;  // Bytes of machine word are reversed.
-
-const uint32_t image_scn_lnk_nreloc_ovfl = 0x01000000;  // Section contains extended relocations.
-const uint32_t image_scn_mem_discardable = 0x02000000;  // Section can be discarded.
-const uint32_t image_scn_mem_not_cached = 0x04000000;  // Section is not cachable.
-const uint32_t image_scn_mem_not_paged = 0x08000000;  // Section is not pageable.
-const uint32_t image_scn_mem_shared = 0x10000000;  // Section is shareable.
-const uint32_t image_scn_mem_execute = 0x20000000;  // Section is executable.
-const uint32_t image_scn_mem_read = 0x40000000;  // Section is readable.
-const uint32_t image_scn_mem_write = 0x80000000;  // Section is writeable.
-
-const uint32_t image_scn_cnt_code = 0x00000020;  // Section contains code.
-const uint32_t image_scn_cnt_initialized_data = 0x00000040;  // Section contains initialized data.
-const uint32_t image_scn_cnt_uninitialized_data = 0x00000080;  // Section contains uninitialized data.
-
-//Directory Entries
-const uint32_t image_directory_entry_export = 0;   // Export Directory
-const uint32_t image_directory_entry_import = 1;   // Import Directory
-const uint32_t image_directory_entry_resource = 2;   // Resource Directory
-const uint32_t image_directory_entry_exception = 3;   // Exception Directory
-const uint32_t image_directory_entry_security = 4;   // Security Directory
-const uint32_t image_directory_entry_basereloc = 5;   // Base Relocation Table
-const uint32_t image_directory_entry_debug = 6;   // Debug Directory
-const uint32_t image_directory_entry_architecture = 7;   // Architecture Specific Data
-const uint32_t image_directory_entry_globalptr = 8;   // RVA of GP
-const uint32_t image_directory_entry_tls = 9;   // TLS Directory
-const uint32_t image_directory_entry_load_config = 10;   // Load Configuration Directory
-const uint32_t image_directory_entry_bound_import = 11;   // Bound Import Directory in headers
-const uint32_t image_directory_entry_iat = 12;   // Import Address Table
-const uint32_t image_directory_entry_delay_import = 13;   // Delay Load Import Descriptors
-const uint32_t image_directory_entry_com_descriptor = 14;   // COM Runtime descriptor
-
-//Subsystem Values
-const uint32_t image_subsystem_unknown = 0;   // Unknown subsystem.
-const uint32_t image_subsystem_native = 1;   // Image doesn't require a subsystem.
-const uint32_t image_subsystem_windows_gui = 2;   // Image runs in the Windows GUI subsystem.
-const uint32_t image_subsystem_windows_cui = 3;   // Image runs in the Windows character subsystem.
-const uint32_t image_subsystem_os2_cui = 5;   // image runs in the OS/2 character subsystem.
-const uint32_t image_subsystem_posix_cui = 7;   // image runs in the Posix character subsystem.
-const uint32_t image_subsystem_native_windows = 8;   // image is a native Win9x driver.
-const uint32_t image_subsystem_windows_ce_gui = 9;   // Image runs in the Windows CE subsystem.
-const uint32_t image_subsystem_efi_application = 10;  //
-const uint32_t image_subsystem_efi_boot_service_driver = 11;   //
-const uint32_t image_subsystem_efi_runtime_driver = 12;  //
-const uint32_t image_subsystem_efi_rom = 13;
-const uint32_t image_subsystem_xbox = 14;
-const uint32_t image_subsystem_windows_boot_application = 16;
-
-//Imports
-const uint64_t image_ordinal_flag64 = 0x8000000000000000ull;
-const uint32_t image_ordinal_flag32 = 0x80000000;
-
-//Based relocation types
-const uint32_t image_rel_based_absolute = 0;
-const uint32_t image_rel_based_high =  1;
-const uint32_t image_rel_based_low = 2;
-const uint32_t image_rel_based_highlow = 3;
-const uint32_t image_rel_based_highadj = 4;
-const uint32_t image_rel_based_mips_jmpaddr = 5;
-const uint32_t image_rel_based_mips_jmpaddr16 = 9;
-const uint32_t image_rel_based_ia64_imm64 = 9;
-const uint32_t image_rel_based_dir64 = 10;
-
-//Exception directory
-//The function has an exception handler that should be called when looking for functions that need to examine exceptions
-const uint32_t unw_flag_ehandler = 0x01;
-//The function has a termination handler that should be called when unwinding an exception
-const uint32_t unw_flag_uhandler = 0x02;
-//This unwind info structure is not the primary one for the procedure.
-//Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry.
-//If this flag is set, then the UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER flags must be cleared.
-//Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info
-const uint32_t unw_flag_chaininfo = 0x04;
-
-//Debug
-const uint32_t image_debug_misc_exename = 1;
-const uint32_t image_debug_type_unknown = 0;
-const uint32_t image_debug_type_coff = 1;
-const uint32_t image_debug_type_codeview = 2;
-const uint32_t image_debug_type_fpo = 3;
-const uint32_t image_debug_type_misc = 4;
-const uint32_t image_debug_type_exception = 5;
-const uint32_t image_debug_type_fixup = 6;
-const uint32_t image_debug_type_omap_to_src = 7;
-const uint32_t image_debug_type_omap_from_src = 8;
-const uint32_t image_debug_type_borland = 9;
-const uint32_t image_debug_type_reserved10 = 10;
-const uint32_t image_debug_type_clsid = 11;
-
-
-//Storage classes
-const uint32_t image_sym_class_end_of_function = static_cast<uint8_t>(-1);
-const uint32_t image_sym_class_null = 0x0000;
-const uint32_t image_sym_class_automatic = 0x0001;
-const uint32_t image_sym_class_external = 0x0002;
-const uint32_t image_sym_class_static = 0x0003;
-const uint32_t image_sym_class_register = 0x0004;
-const uint32_t image_sym_class_external_def = 0x0005;
-const uint32_t image_sym_class_label = 0x0006;
-const uint32_t image_sym_class_undefined_label = 0x0007;
-const uint32_t image_sym_class_member_of_struct = 0x0008;
-const uint32_t image_sym_class_argument = 0x0009;
-const uint32_t image_sym_class_struct_tag = 0x000a;
-const uint32_t image_sym_class_member_of_union = 0x000b;
-const uint32_t image_sym_class_union_tag = 0x000c;
-const uint32_t image_sym_class_type_definition = 0x000d;
-const uint32_t image_sym_class_undefined_static = 0x000e;
-const uint32_t image_sym_class_enum_tag = 0x000f;
-const uint32_t image_sym_class_member_of_enum = 0x0010;
-const uint32_t image_sym_class_register_param = 0x0011;
-const uint32_t image_sym_class_bit_field = 0x0012;
-
-const uint32_t image_sym_class_far_external = 0x0044;
-
-const uint32_t image_sym_class_block = 0x0064;
-const uint32_t image_sym_class_function = 0x0065;
-const uint32_t image_sym_class_end_of_struct = 0x0066;
-const uint32_t image_sym_class_file = 0x0067;
-
-const uint32_t image_sym_class_section = 0x0068;
-const uint32_t image_sym_class_weak_external = 0x0069;
-
-const uint32_t image_sym_class_clr_token = 0x006b;
-
-//type packing constants
-const uint32_t n_btmask = 0x000f;
-const uint32_t n_tmask = 0x0030;
-const uint32_t n_tmask1 = 0x00c0;
-const uint32_t n_tmask2 = 0x00f0;
-const uint32_t n_btshft = 4;
-const uint32_t n_tshift = 2;
-
-//Type (derived) values.
-const uint32_t image_sym_dtype_null = 0;          // no derived type.
-const uint32_t image_sym_dtype_pointer = 1;       // pointer.
-const uint32_t image_sym_dtype_function = 2;      // function.
-const uint32_t image_sym_dtype_array = 3;         // array.
-
-// Is x a function?
-//TODO
-#ifndef ISFCN
-#define ISFCN(x) (((x) & n_tmask) == (image_sym_dtype_function << n_btshft))
-#endif
-
-//Version info
-const uint32_t vs_ffi_fileflagsmask = 0x0000003FL;
-
-const uint32_t vs_ffi_signature = 0xFEEF04BDL;
-const uint32_t vs_ffi_strucversion = 0x00010000L;
-
-/* ----- VS_VERSION.dwFileFlags ----- */
-const uint32_t vs_ff_debug = 0x00000001L;
-const uint32_t vs_ff_prerelease = 0x00000002L;
-const uint32_t vs_ff_patched = 0x00000004L;
-const uint32_t vs_ff_privatebuild = 0x00000008L;
-const uint32_t vs_ff_infoinferred = 0x00000010L;
-const uint32_t vs_ff_specialbuild = 0x00000020L;
-
-/* ----- VS_VERSION.dwFileOS ----- */
-const uint32_t vos_unknown = 0x00000000L;
-const uint32_t vos_dos = 0x00010000L;
-const uint32_t vos_os216 = 0x00020000L;
-const uint32_t vos_os232 = 0x00030000L;
-const uint32_t vos_nt = 0x00040000L;
-const uint32_t vos_wince = 0x00050000L;
-
-const uint32_t vos__base = 0x00000000L;
-const uint32_t vos__windows16 = 0x00000001L;
-const uint32_t vos__pm16 = 0x00000002L;
-const uint32_t vos__pm32 = 0x00000003L;
-const uint32_t vos__windows32 = 0x00000004L;
-
-const uint32_t vos_dos_windows16 = 0x00010001L;
-const uint32_t vos_dos_windows32 = 0x00010004L;
-const uint32_t vos_os216_pm16 = 0x00020002L;
-const uint32_t vos_os232_pm32 = 0x00030003L;
-const uint32_t vos_nt_windows32 = 0x00040004L;
-
-/* ----- VS_VERSION.dwFileType ----- */
-const uint32_t vft_unknown = 0x00000000L;
-const uint32_t vft_app = 0x00000001L;
-const uint32_t vft_dll = 0x00000002L;
-const uint32_t vft_drv = 0x00000003L;
-const uint32_t vft_font =  0x00000004L;
-const uint32_t vft_vxd = 0x00000005L;
-const uint32_t vft_static_lib = 0x00000007L;
-
-const uint32_t message_resource_unicode = 0x0001;
-
-#pragma pack(push, 1)
-
-//Windows GUID structure
-struct guid
-{
-	uint32_t Data1;
-	uint16_t Data2;
-	uint16_t Data3;
-	uint8_t Data4[8];
-};
-
-//DOS .EXE header
-struct image_dos_header
-{
-	uint16_t e_magic;                     // Magic number
-	uint16_t e_cblp;                      // Bytes on last page of file
-	uint16_t e_cp;                        // Pages in file
-	uint16_t e_crlc;                      // Relocations
-	uint16_t e_cparhdr;                   // Size of header in paragraphs
-	uint16_t e_minalloc;                  // Minimum extra paragraphs needed
-	uint16_t e_maxalloc;                  // Maximum extra paragraphs needed
-	uint16_t e_ss;                        // Initial (relative) SS value
-	uint16_t e_sp;                        // Initial SP value
-	uint16_t e_csum;                      // Checksum
-	uint16_t e_ip;                        // Initial IP value
-	uint16_t e_cs;                        // Initial (relative) CS value
-	uint16_t e_lfarlc;                    // File address of relocation table
-	uint16_t e_ovno;                      // Overlay number
-	uint16_t e_res[4];                    // Reserved words
-	uint16_t e_oemid;                     // OEM identifier (for e_oeminfo)
-	uint16_t e_oeminfo;                   // OEM information; e_oemid specific
-	uint16_t e_res2[10];                  // Reserved words
-	int32_t  e_lfanew;                    // File address of new exe header
-};
-
-//Directory format
-struct image_data_directory
-{
-	uint32_t VirtualAddress;
-	uint32_t Size;
-};
-
-//Optional header format
-struct image_optional_header32
-{
-	//Standard fields
-	uint16_t Magic;
-	uint8_t  MajorLinkerVersion;
-	uint8_t  MinorLinkerVersion;
-	uint32_t SizeOfCode;
-	uint32_t SizeOfInitializedData;
-	uint32_t SizeOfUninitializedData;
-	uint32_t AddressOfEntryPoint;
-	uint32_t BaseOfCode;
-	uint32_t BaseOfData;
-
-	//NT additional fields
-	uint32_t ImageBase;
-	uint32_t SectionAlignment;
-	uint32_t FileAlignment;
-	uint16_t MajorOperatingSystemVersion;
-	uint16_t MinorOperatingSystemVersion;
-	uint16_t MajorImageVersion;
-	uint16_t MinorImageVersion;
-	uint16_t MajorSubsystemVersion;
-	uint16_t MinorSubsystemVersion;
-	uint32_t Win32VersionValue;
-	uint32_t SizeOfImage;
-	uint32_t SizeOfHeaders;
-	uint32_t CheckSum;
-	uint16_t Subsystem;
-	uint16_t DllCharacteristics;
-	uint32_t SizeOfStackReserve;
-	uint32_t SizeOfStackCommit;
-	uint32_t SizeOfHeapReserve;
-	uint32_t SizeOfHeapCommit;
-	uint32_t LoaderFlags;
-	uint32_t NumberOfRvaAndSizes;
-	image_data_directory DataDirectory[image_numberof_directory_entries];
-};
-
-struct image_optional_header64
-{
-	uint16_t Magic;
-	uint8_t  MajorLinkerVersion;
-	uint8_t  MinorLinkerVersion;
-	uint32_t SizeOfCode;
-	uint32_t SizeOfInitializedData;
-	uint32_t SizeOfUninitializedData;
-	uint32_t AddressOfEntryPoint;
-	uint32_t BaseOfCode;
-	uint64_t ImageBase;
-	uint32_t SectionAlignment;
-	uint32_t FileAlignment;
-	uint16_t MajorOperatingSystemVersion;
-	uint16_t MinorOperatingSystemVersion;
-	uint16_t MajorImageVersion;
-	uint16_t MinorImageVersion;
-	uint16_t MajorSubsystemVersion;
-	uint16_t MinorSubsystemVersion;
-	uint32_t Win32VersionValue;
-	uint32_t SizeOfImage;
-	uint32_t SizeOfHeaders;
-	uint32_t CheckSum;
-	uint16_t Subsystem;
-	uint16_t DllCharacteristics;
-	uint64_t SizeOfStackReserve;
-	uint64_t SizeOfStackCommit;
-	uint64_t SizeOfHeapReserve;
-	uint64_t SizeOfHeapCommit;
-	uint32_t LoaderFlags;
-	uint32_t NumberOfRvaAndSizes;
-	image_data_directory DataDirectory[image_numberof_directory_entries];
-};
-
-struct image_file_header
-{
-	uint16_t Machine;
-	uint16_t NumberOfSections;
-	uint32_t TimeDateStamp;
-	uint32_t PointerToSymbolTable;
-	uint32_t NumberOfSymbols;
-	uint16_t SizeOfOptionalHeader;
-	uint16_t Characteristics;
-};
-
-struct image_nt_headers64
-{
-	uint32_t Signature;
-	image_file_header FileHeader;
-	image_optional_header64 OptionalHeader;
-};
-
-struct image_nt_headers32
-{
-	uint32_t Signature;
-	image_file_header FileHeader;
-	image_optional_header32 OptionalHeader;
-};
-
-//Section header format
-struct image_section_header
-{
-	uint8_t Name[8];
-	union
-	{
-		uint32_t PhysicalAddress;
-		uint32_t VirtualSize;
-	} Misc;
-
-	uint32_t VirtualAddress;
-	uint32_t SizeOfRawData;
-	uint32_t PointerToRawData;
-	uint32_t PointerToRelocations;
-	uint32_t PointerToLinenumbers;
-	uint16_t NumberOfRelocations;
-	uint16_t NumberOfLinenumbers;
-	uint32_t Characteristics;
-};
-
-
-/// RESOURCES ///
-struct image_resource_directory
-{
-	uint32_t Characteristics;
-	uint32_t TimeDateStamp;
-	uint16_t MajorVersion;
-	uint16_t MinorVersion;
-	uint16_t NumberOfNamedEntries;
-	uint16_t NumberOfIdEntries;
-	//  IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
-};
-
-struct vs_fixedfileinfo
-{
-	uint32_t dwSignature;            /* e.g. 0xfeef04bd */
-	uint32_t dwStrucVersion;         /* e.g. 0x00000042 = "0.42" */
-	uint32_t dwFileVersionMS;        /* e.g. 0x00030075 = "3.75" */
-	uint32_t dwFileVersionLS;        /* e.g. 0x00000031 = "0.31" */
-	uint32_t dwProductVersionMS;     /* e.g. 0x00030010 = "3.10" */
-	uint32_t dwProductVersionLS;     /* e.g. 0x00000031 = "0.31" */
-	uint32_t dwFileFlagsMask;        /* = 0x3F for version "0.42" */
-	uint32_t dwFileFlags;            /* e.g. VFF_DEBUG | VFF_PRERELEASE */
-	uint32_t dwFileOS;               /* e.g. VOS_DOS_WINDOWS16 */
-	uint32_t dwFileType;             /* e.g. VFT_DRIVER */
-	uint32_t dwFileSubtype;          /* e.g. VFT2_DRV_KEYBOARD */
-	uint32_t dwFileDateMS;           /* e.g. 0 */
-	uint32_t dwFileDateLS;           /* e.g. 0 */
-};
-
-struct bitmapinfoheader
-{
-	uint32_t biSize;
-	int32_t  biWidth;
-	int32_t  biHeight;
-	uint16_t biPlanes;
-	uint16_t biBitCount;
-	uint32_t biCompression;
-	uint32_t biSizeImage;
-	int32_t  biXPelsPerMeter;
-	int32_t  biYPelsPerMeter;
-	uint32_t biClrUsed;
-	uint32_t biClrImportant;
-};
-
-struct message_resource_entry
-{
-	uint16_t Length;
-	uint16_t Flags;
-	uint8_t  Text[1];
-};
-
-struct message_resource_block
-{
-	uint32_t LowId;
-	uint32_t HighId;
-	uint32_t OffsetToEntries;
-};
-
-struct message_resource_data
-{
-	uint32_t NumberOfBlocks;
-	message_resource_block Blocks[1];
-};
-
-struct image_resource_directory_entry
-{
-	union
-	{
-		struct
-		{
-			uint32_t NameOffset:31;
-			uint32_t NameIsString:1;
-		};
-		uint32_t Name;
-		uint16_t Id;
-	};
-
-	union
-	{
-		uint32_t OffsetToData;
-		struct
-		{
-			uint32_t OffsetToDirectory:31;
-			uint32_t DataIsDirectory:1;
-		};
-	};
-};
-
-struct image_resource_data_entry
-{
-	uint32_t OffsetToData;
-	uint32_t Size;
-	uint32_t CodePage;
-	uint32_t Reserved;
-};
-
-#pragma pack(push, 2)
-struct bitmapfileheader
-{
-	uint16_t bfType;
-	uint32_t bfSize;
-	uint16_t bfReserved1;
-	uint16_t bfReserved2;
-	uint32_t bfOffBits;
-};
-#pragma pack(pop)
-
-
-
-//Structure representing ICON file header
-struct ico_header
-{
-	uint16_t Reserved;
-	uint16_t Type; //1
-	uint16_t Count; //Count of icons included in icon group
-};
-
-//Structure that is stored in icon group directory in PE resources
-struct icon_group
-{
-	uint8_t Width;
-	uint8_t Height;
-	uint8_t ColorCount;
-	uint8_t Reserved;
-	uint16_t Planes;
-	uint16_t BitCount;
-	uint32_t SizeInBytes;
-	uint16_t Number; //Represents resource ID in PE icon list
-};
-
-//Structure representing ICON directory entry inside ICON file
-struct icondirentry
-{
-	uint8_t Width;
-	uint8_t Height;
-	uint8_t ColorCount;
-	uint8_t Reserved;
-	uint16_t Planes;
-	uint16_t BitCount;
-	uint32_t SizeInBytes;
-	uint32_t ImageOffset; //Offset from start of header to the image
-};
-
-//Structure representing CURSOR file header
-struct cursor_header
-{
-	uint16_t Reserved;
-	uint16_t Type; //2
-	uint16_t Count; //Count of cursors included in cursor group
-};
-
-struct cursor_group
-{
-	uint16_t Width;
-	uint16_t Height; //Divide by 2 to get the actual height.
-	uint16_t Planes;
-	uint16_t BitCount;
-	uint32_t SizeInBytes;
-	uint16_t Number; //Represents resource ID in PE icon list
-};
-
-//Structure representing CURSOR directory entry inside CURSOR file
-struct cursordirentry
-{
-	uint8_t Width; //Set to CURSOR_GROUP::Height/2.
-	uint8_t Height;
-	uint8_t ColorCount;
-	uint8_t Reserved;
-	uint16_t HotspotX;
-	uint16_t HotspotY;
-	uint32_t SizeInBytes;
-	uint32_t ImageOffset; //Offset from start of header to the image
-};
-
-//Structure representing BLOCK in version info resource
-struct version_info_block //(always aligned on 32-bit (DWORD) boundary)
-{
-	uint16_t Length; //Length of this block (doesn't include padding)
-	uint16_t ValueLength; //Value length (if any)
-	uint16_t Type; //Value type (0 = binary, 1 = text)
-	uint16_t Key[1]; //Value name (block key) (always NULL terminated)
-
-	//////////
-	//WORD padding1[]; //Padding, if any (ALIGNMENT)
-	//xxxxx Value[]; //Value data, if any (*ALIGNED*)
-	//WORD padding2[]; //Padding, if any (ALIGNMENT)
-	//xxxxx Child[]; //Child block(s), if any (*ALIGNED*)
-	//////////
-};
-
-
-/// IMPORTS ///
-#pragma pack(push, 8)
-struct image_thunk_data64
-{
-	union
-	{
-		uint64_t ForwarderString;  // PBYTE 
-		uint64_t Function;         // PDWORD
-		uint64_t Ordinal;
-		uint64_t AddressOfData;    // PIMAGE_IMPORT_BY_NAME
-	} u1;
-};
-#pragma pack(pop)
-
-struct image_thunk_data32
-{
-	union
-	{
-		uint32_t ForwarderString;      // PBYTE 
-		uint32_t Function;             // PDWORD
-		uint32_t Ordinal;
-		uint32_t AddressOfData;        // PIMAGE_IMPORT_BY_NAME
-	} u1;
-};
-
-struct image_import_descriptor
-{
-	union
-	{
-		uint32_t Characteristics;           // 0 for terminating null import descriptor
-		uint32_t OriginalFirstThunk;        // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
-	};
-
-	uint32_t TimeDateStamp;                 // 0 if not bound,
-											// -1 if bound, and real date\time stamp
-											//     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
-											// O.W. date/time stamp of DLL bound to (Old BIND)
-
-	uint32_t ForwarderChain;                // -1 if no forwarders
-	uint32_t Name;
-	uint32_t FirstThunk;                    // RVA to IAT (if bound this IAT has actual addresses)
-};
-
-
-/// TLS ///
-struct image_tls_directory64
-{
-	uint64_t StartAddressOfRawData;
-	uint64_t EndAddressOfRawData;
-	uint64_t AddressOfIndex;         // PDWORD
-	uint64_t AddressOfCallBacks;     // PIMAGE_TLS_CALLBACK *;
-	uint32_t SizeOfZeroFill;
-	uint32_t Characteristics;
-};
-
-struct image_tls_directory32
-{
-	uint32_t StartAddressOfRawData;
-	uint32_t EndAddressOfRawData;
-	uint32_t AddressOfIndex;             // PDWORD
-	uint32_t AddressOfCallBacks;         // PIMAGE_TLS_CALLBACK *
-	uint32_t SizeOfZeroFill;
-	uint32_t Characteristics;
-};
-
-
-/// Export Format ///
-struct image_export_directory
-{
-	uint32_t Characteristics;
-	uint32_t TimeDateStamp;
-	uint16_t MajorVersion;
-	uint16_t MinorVersion;
-	uint32_t Name;
-	uint32_t Base;
-	uint32_t NumberOfFunctions;
-	uint32_t NumberOfNames;
-	uint32_t AddressOfFunctions;     // RVA from base of image
-	uint32_t AddressOfNames;         // RVA from base of image
-	uint32_t AddressOfNameOrdinals;  // RVA from base of image
-};
-
-
-/// Based relocation format ///
-struct image_base_relocation
-{
-	uint32_t VirtualAddress;
-	uint32_t SizeOfBlock;
-	//  uint16_t TypeOffset[1];
-};
-
-
-/// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] ///
-struct image_bound_import_descriptor
-{
-	uint32_t TimeDateStamp;
-	uint16_t OffsetModuleName;
-	uint16_t NumberOfModuleForwarderRefs;
-	// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
-};
-
-struct image_bound_forwarder_ref
-{
-	uint32_t TimeDateStamp;
-	uint16_t OffsetModuleName;
-	uint16_t Reserved;
-};
-
-
-/// Exception directory ///
-struct image_runtime_function_entry
-{
-	uint32_t BeginAddress;
-	uint32_t EndAddress;
-	uint32_t UnwindInfoAddress;
-};
-
-enum unwind_op_codes
-{
-	uwop_push_nonvol = 0, /* info == register number */
-	uwop_alloc_large,     /* no info, alloc size in next 2 slots */
-	uwop_alloc_small,     /* info == size of allocation / 8 - 1 */
-	uwop_set_fpreg,       /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
-	uwop_save_nonvol,     /* info == register number, offset in next slot */
-	uwop_save_nonvol_far, /* info == register number, offset in next 2 slots */
-	uwop_save_xmm128,     /* info == XMM reg number, offset in next slot */
-	uwop_save_xmm128_far, /* info == XMM reg number, offset in next 2 slots */
-	uwop_push_machframe   /* info == 0: no error-code, 1: error-code */
-};
-
-union unwind_code
-{
-	struct s
-	{
-		uint8_t CodeOffset;
-		uint8_t UnwindOp : 4;
-		uint8_t OpInfo   : 4;
-	};
-
-	uint16_t FrameOffset;
-};
-
-struct unwind_info
-{
-	uint8_t Version       : 3;
-	uint8_t Flags         : 5;
-	uint8_t SizeOfProlog;
-	uint8_t CountOfCodes;
-	uint8_t FrameRegister : 4;
-	uint8_t FrameOffset   : 4;
-	unwind_code UnwindCode[1];
-	/*  unwind_code MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
-	*   union {
-	*       OPTIONAL ULONG ExceptionHandler;
-	*       OPTIONAL ULONG FunctionEntry;
-	*   };
-	*   OPTIONAL ULONG ExceptionData[]; */
-};
-
-
-
-/// Debug ///
-struct image_debug_misc
-{
-	uint32_t DataType;               // type of misc data, see defines
-	uint32_t Length;                 // total length of record, rounded to four
-	// byte multiple.
-	uint8_t  Unicode;                // TRUE if data is unicode string
-	uint8_t  Reserved[3];
-	uint8_t  Data[1];                // Actual data
-};
-
-struct image_coff_symbols_header
-{
-	uint32_t NumberOfSymbols;
-	uint32_t LvaToFirstSymbol;
-	uint32_t NumberOfLinenumbers;
-	uint32_t LvaToFirstLinenumber;
-	uint32_t RvaToFirstByteOfCode;
-	uint32_t RvaToLastByteOfCode;
-	uint32_t RvaToFirstByteOfData;
-	uint32_t RvaToLastByteOfData;
-};
-
-struct image_debug_directory
-{
-	uint32_t Characteristics;
-	uint32_t TimeDateStamp;
-	uint16_t MajorVersion;
-	uint16_t MinorVersion;
-	uint32_t Type;
-	uint32_t SizeOfData;
-	uint32_t AddressOfRawData;
-	uint32_t PointerToRawData;
-};
-
-
-#pragma pack(push, 2)
-struct image_symbol
-{
-	union
-	{
-		uint8_t ShortName[8];
-		struct
-		{
-			uint32_t Short;     // if 0, use LongName
-			uint32_t Long;      // offset into string table
-		} Name;
-		uint32_t LongName[2];    // PBYTE [2]
-	} N;
-	uint32_t Value;
-	int16_t  SectionNumber;
-	uint16_t Type;
-	uint8_t  StorageClass;
-	uint8_t  NumberOfAuxSymbols;
-};
-#pragma pack(pop)
-
-//CodeView Debug OMF signature. The signature at the end of the file is
-//a negative offset from the end of the file to another signature.  At
-//the negative offset (base address) is another signature whose filepos
-//field points to the first OMFDirHeader in a chain of directories.
-//The NB05 signature is used by the link utility to indicated a completely
-//unpacked file. The NB06 signature is used by ilink to indicate that the
-//executable has had CodeView information from an incremental link appended
-//to the executable. The NB08 signature is used by cvpack to indicate that
-//the CodeView Debug OMF has been packed. CodeView will only process
-//executables with the NB08 signature.
-struct OMFSignature
-{
-	char Signature[4];   // "NBxx"
-	uint32_t filepos;    // offset in file
-};
-
-struct CV_INFO_PDB20
-{
-	OMFSignature CvHeader;
-	uint32_t Signature;
-	uint32_t Age;
-	uint8_t PdbFileName[1];
-};
-
-struct CV_INFO_PDB70
-{
-	uint32_t CvSignature;
-	guid Signature;
-	uint32_t Age;
-	uint8_t PdbFileName[1];
-};
-
-//  directory information structure
-//  This structure contains the information describing the directory.
-//  It is pointed to by the signature at the base address or the directory
-//  link field of a preceeding directory.  The directory entries immediately
-//  follow this structure.
-struct OMFDirHeader
-{
-	uint16_t cbDirHeader;    // length of this structure
-	uint16_t cbDirEntry;     // number of bytes in each directory entry
-	uint32_t cDir;           // number of directorie entries
-	int32_t  lfoNextDir;     // offset from base of next directory
-	uint32_t flags;          // status flags
-};
-
-//  directory structure
-//  The data in this structure is used to reference the data for each
-//  subsection of the CodeView Debug OMF information.  Tables that are
-//  not associated with a specific module will have a module index of
-//  oxffff.  These tables are the global types table, the global symbol
-//  table, the global public table and the library table.
-struct OMFDirEntry
-{
-	uint16_t SubSection;     // subsection type (sst...)
-	uint16_t iMod;           // module index
-	int32_t  lfo;            // large file offset of subsection
-	uint32_t cb;             // number of bytes in subsection
-};
-
-
-/// CLR 2.0 header structure ///
-struct image_cor20_header
-{
-	//Header versioning
-	uint32_t cb;
-	uint16_t MajorRuntimeVersion;
-	uint16_t MinorRuntimeVersion;
-
-	// Symbol table and startup information
-	image_data_directory MetaData;
-	uint32_t Flags;
-
-	// If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
-	// If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint.
-	union
-	{
-		uint32_t EntryPointToken;
-		uint32_t EntryPointRVA;
-	};
-
-	// Binding information
-	image_data_directory Resources;
-	image_data_directory StrongNameSignature;
-
-	// Regular fixup and binding information
-	image_data_directory CodeManagerTable;
-	image_data_directory VTableFixups;
-	image_data_directory ExportAddressTableJumps;
-
-	// Precompiled image info (internal use only - set to zero)
-	image_data_directory ManagedNativeHeader;
-};
-
-enum replaces_cor_hdr_numeric_defines
-{
-	// COM+ Header entry point flags.
-	comimage_flags_ilonly               =0x00000001,
-	comimage_flags_32bitrequired        =0x00000002,
-	comimage_flags_il_library           =0x00000004,
-	comimage_flags_strongnamesigned     =0x00000008,
-	comimage_flags_native_entrypoint    =0x00000010,
-	comimage_flags_trackdebugdata       =0x00010000,
-
-	// Version flags for image.
-	cor_version_major_v2                =2,
-	cor_version_major                   =cor_version_major_v2,
-	cor_version_minor                   =0,
-	cor_deleted_name_length             =8,
-	cor_vtablegap_name_length           =8,
-
-	// Maximum size of a NativeType descriptor.
-	native_type_max_cb                  =1,
-	cor_ilmethod_sect_small_max_datasize=0xff,
-
-	// #defines for the MIH FLAGS
-	image_cor_mih_methodrva             =0x01,
-	image_cor_mih_ehrva                 =0x02,
-	image_cor_mih_basicblock            =0x08,
-
-	// V-table constants
-	cor_vtable_32bit                    =0x01,          // V-table slots are 32-bits in size.
-	cor_vtable_64bit                    =0x02,          // V-table slots are 64-bits in size.
-	cor_vtable_from_unmanaged           =0x04,          // If set, transition from unmanaged.
-	cor_vtable_from_unmanaged_retain_appdomain  =0x08,  // If set, transition from unmanaged with keeping the current appdomain.
-	cor_vtable_call_most_derived        =0x10,          // Call most derived method described by
-
-	// EATJ constants
-	image_cor_eatj_thunk_size           =32,            // Size of a jump thunk reserved range.
-
-	// Max name lengths
-	//@todo: Change to unlimited name lengths.
-	max_class_name                      =1024,
-	max_package_name                    =1024
-};
-
-/// Load Configuration Directory Entry ///
-struct image_load_config_directory32
-{
-	uint32_t Size;
-	uint32_t TimeDateStamp;
-	uint16_t MajorVersion;
-	uint16_t MinorVersion;
-	uint32_t GlobalFlagsClear;
-	uint32_t GlobalFlagsSet;
-	uint32_t CriticalSectionDefaultTimeout;
-	uint32_t DeCommitFreeBlockThreshold;
-	uint32_t DeCommitTotalFreeThreshold;
-	uint32_t LockPrefixTable;            // VA
-	uint32_t MaximumAllocationSize;
-	uint32_t VirtualMemoryThreshold;
-	uint32_t ProcessHeapFlags;
-	uint32_t ProcessAffinityMask;
-	uint16_t CSDVersion;
-	uint16_t Reserved1;
-	uint32_t EditList;                   // VA
-	uint32_t SecurityCookie;             // VA
-	uint32_t SEHandlerTable;             // VA
-	uint32_t SEHandlerCount;
-};
-
-struct image_load_config_directory64
-{
-	uint32_t Size;
-	uint32_t TimeDateStamp;
-	uint16_t MajorVersion;
-	uint16_t MinorVersion;
-	uint32_t GlobalFlagsClear;
-	uint32_t GlobalFlagsSet;
-	uint32_t CriticalSectionDefaultTimeout;
-	uint64_t DeCommitFreeBlockThreshold;
-	uint64_t DeCommitTotalFreeThreshold;
-	uint64_t LockPrefixTable;         // VA
-	uint64_t MaximumAllocationSize;
-	uint64_t VirtualMemoryThreshold;
-	uint64_t ProcessAffinityMask;
-	uint32_t ProcessHeapFlags;
-	uint16_t CSDVersion;
-	uint16_t Reserved1;
-	uint64_t EditList;                // VA
-	uint64_t SecurityCookie;          // VA
-	uint64_t SEHandlerTable;          // VA
-	uint64_t SEHandlerCount;
-};
-
-#pragma pack(pop)
-} //namespace pe_win
-
-#ifdef PE_BLISS_WINDOWS
-typedef wchar_t unicode16_t;
-typedef std::basic_string<unicode16_t> u16string;
-#else
-//Instead of wchar_t for windows
-typedef unsigned short unicode16_t;
-typedef std::basic_string<unicode16_t> u16string;
-#endif
-
-} //namespace pe_bliss

+ 0 - 396
tools/pe_bliss/pe_tls.cpp

@@ -1,396 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "pe_tls.h"
-#include "pe_properties_generic.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//TLS
-//Default constructor
-tls_info::tls_info()
-	:start_rva_(0), end_rva_(0), index_rva_(0), callbacks_rva_(0),
-	size_of_zero_fill_(0), characteristics_(0)
-{}
-
-//Returns start RVA of TLS raw data
-uint32_t tls_info::get_raw_data_start_rva() const
-{
-	return start_rva_;
-}
-
-//Returns end RVA of TLS raw data
-uint32_t tls_info::get_raw_data_end_rva() const
-{
-	return end_rva_;
-}
-
-//Returns TLS index RVA
-uint32_t tls_info::get_index_rva() const
-{
-	return index_rva_;
-}
-
-//Returns TLS callbacks RVA
-uint32_t tls_info::get_callbacks_rva() const
-{
-	return callbacks_rva_;
-}
-
-//Returns size of zero fill
-uint32_t tls_info::get_size_of_zero_fill() const
-{
-	return size_of_zero_fill_;
-}
-
-//Returns characteristics
-uint32_t tls_info::get_characteristics() const
-{
-	return characteristics_;
-}
-
-//Returns raw TLS data
-const std::string& tls_info::get_raw_data() const
-{
-	return raw_data_;
-}
-
-//Returns TLS callbacks addresses
-const tls_info::tls_callback_list& tls_info::get_tls_callbacks() const
-{
-	return callbacks_;
-}
-
-//Returns TLS callbacks addresses
-tls_info::tls_callback_list& tls_info::get_tls_callbacks()
-{
-	return callbacks_;
-}
-
-//Adds TLS callback
-void tls_info::add_tls_callback(uint32_t rva)
-{
-	callbacks_.push_back(rva);
-}
-
-//Clears TLS callbacks list
-void tls_info::clear_tls_callbacks()
-{
-	callbacks_.clear();
-}
-
-//Recalculates end address of raw TLS data
-void tls_info::recalc_raw_data_end_rva()
-{
-	end_rva_ = static_cast<uint32_t>(start_rva_ + raw_data_.length());
-}
-
-//Sets start RVA of TLS raw data
-void tls_info::set_raw_data_start_rva(uint32_t rva)
-{
-	start_rva_ = rva;
-}
-
-//Sets end RVA of TLS raw data
-void tls_info::set_raw_data_end_rva(uint32_t rva)
-{
-	end_rva_ = rva;
-}
-
-//Sets TLS index RVA
-void tls_info::set_index_rva(uint32_t rva)
-{
-	index_rva_ = rva;
-}
-
-//Sets TLS callbacks RVA
-void tls_info::set_callbacks_rva(uint32_t rva)
-{
-	callbacks_rva_ = rva;
-}
-
-//Sets size of zero fill
-void tls_info::set_size_of_zero_fill(uint32_t size)
-{
-	size_of_zero_fill_ = size;
-}
-
-//Sets characteristics
-void tls_info::set_characteristics(uint32_t characteristics)
-{
-	characteristics_ = characteristics;
-}
-
-//Sets raw TLS data
-void tls_info::set_raw_data(const std::string& data)
-{
-	raw_data_ = data;
-}
-
-//If image does not have TLS, throws an exception
-const tls_info get_tls_info(const pe_base& pe)
-{
-	return pe.get_pe_type() == pe_type_32
-		? get_tls_info_base<pe_types_class_32>(pe)
-		: get_tls_info_base<pe_types_class_64>(pe);
-}
-
-//TLS Rebuilder
-const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	return pe.get_pe_type() == pe_type_32
-		? rebuild_tls_base<pe_types_class_32>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section)
-		: rebuild_tls_base<pe_types_class_64>(pe, info, tls_section, offset_from_section_start, write_tls_callbacks, write_tls_data, expand, save_to_pe_header, auto_strip_last_section);
-}
-
-//Get TLS info
-//If image does not have TLS, throws an exception
-template<typename PEClassType>
-const tls_info get_tls_info_base(const pe_base& pe)
-{
-	tls_info ret;
-
-	//If there's no TLS directory, throw an exception
-	if(!pe.has_tls())
-		throw pe_exception("Image does not have TLS directory", pe_exception::directory_does_not_exist);
-
-	//Get TLS directory data
-	typename PEClassType::TLSStruct tls_directory_data = pe.section_data_from_rva<typename PEClassType::TLSStruct>(pe.get_directory_rva(image_directory_entry_tls), section_data_virtual, true);
-
-	//Check data addresses
-	if(tls_directory_data.EndAddressOfRawData == tls_directory_data.StartAddressOfRawData)
-	{
-		try
-		{
-			pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData));
-		}
-		catch(const pe_exception&)
-		{
-			//Fix addressess on incorrect conversion
-			tls_directory_data.EndAddressOfRawData = tls_directory_data.StartAddressOfRawData = 0;
-		}
-	}
-
-	if(tls_directory_data.StartAddressOfRawData &&
-		pe.section_data_length_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData),
-		static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true)
-		< (tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData))
-		throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory);
-
-	//Fill TLS info
-	//VAs are not checked
-	ret.set_raw_data_start_rva(tls_directory_data.StartAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData)) : 0);
-	ret.set_raw_data_end_rva(tls_directory_data.EndAddressOfRawData ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.EndAddressOfRawData)) : 0);
-	ret.set_index_rva(tls_directory_data.AddressOfIndex ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfIndex)) : 0);
-	ret.set_callbacks_rva(tls_directory_data.AddressOfCallBacks ? pe.va_to_rva(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks)) : 0);
-	ret.set_size_of_zero_fill(tls_directory_data.SizeOfZeroFill);
-	ret.set_characteristics(tls_directory_data.Characteristics);
-
-	if(tls_directory_data.StartAddressOfRawData && tls_directory_data.StartAddressOfRawData != tls_directory_data.EndAddressOfRawData)
-	{
-		//Read and save TLS RAW data
-		ret.set_raw_data(std::string(
-			pe.section_data_from_va(static_cast<typename PEClassType::BaseSize>(tls_directory_data.StartAddressOfRawData), section_data_virtual, true),
-			static_cast<uint32_t>(tls_directory_data.EndAddressOfRawData - tls_directory_data.StartAddressOfRawData)));
-	}
-
-	//If file has TLS callbacks
-	if(ret.get_callbacks_rva())
-	{
-		//Read callbacks VAs
-		uint32_t current_tls_callback = 0;
-
-		while(true)
-		{
-			//Read TLS callback VA
-			typename PEClassType::BaseSize va = pe.section_data_from_va<typename PEClassType::BaseSize>(static_cast<typename PEClassType::BaseSize>(tls_directory_data.AddressOfCallBacks + current_tls_callback), section_data_virtual, true);
-			if(va == 0)
-				break;
-
-			//Save it
-			ret.add_tls_callback(pe.va_to_rva(va, false));
-
-			//Move to next callback VA
-			current_tls_callback += sizeof(va);
-		}
-	}
-
-	return ret;
-}
-
-//Rebuilder of TLS structures
-//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place
-//If write_tls_data = true, TLS data will be written to its place
-//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string
-//representing raw data content
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-//Note/TODO: TLS Callbacks array is not DWORD-aligned (seems to work on WinXP - Win7)
-template<typename PEClassType>
-const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start, bool write_tls_callbacks, bool write_tls_data, tls_data_expand_type expand, bool save_to_pe_header, bool auto_strip_last_section)
-{
-	//Check that tls_section is attached to this PE image
-	if(!pe.section_attached(tls_section))
-		throw pe_exception("TLS section must be attached to PE file", pe_exception::section_is_not_attached);
-	
-	uint32_t tls_data_pos = pe_utils::align_up(offset_from_section_start, sizeof(typename PEClassType::BaseSize));
-	uint32_t needed_size = sizeof(typename PEClassType::TLSStruct); //Calculate needed size for TLS table
-	
-	//Check if tls_section is last one. If it's not, check if there's enough place for TLS data
-	if(&tls_section != &*(pe.get_image_sections().end() - 1) && 
-		(tls_section.empty() || pe_utils::align_up(tls_section.get_size_of_raw_data(), pe.get_file_alignment()) < needed_size + tls_data_pos))
-		throw pe_exception("Insufficient space for TLS directory", pe_exception::insufficient_space);
-
-	//Check raw data positions
-	if(info.get_raw_data_end_rva() < info.get_raw_data_start_rva() || info.get_index_rva() == 0)
-		throw pe_exception("Incorrect TLS directory", pe_exception::incorrect_tls_directory);
-
-	std::string& raw_data = tls_section.get_raw_data();
-
-	//This will be done only if tls_section is the last section of image or for section with unaligned raw length of data
-	if(raw_data.length() < needed_size + tls_data_pos)
-		raw_data.resize(needed_size + tls_data_pos); //Expand section raw data
-
-	//Create and fill TLS structure
-	typename PEClassType::TLSStruct tls_struct = {0};
-	
-	typename PEClassType::BaseSize va;
-	if(info.get_raw_data_start_rva())
-	{
-		pe.rva_to_va(info.get_raw_data_start_rva(), va);
-		tls_struct.StartAddressOfRawData = va;
-		tls_struct.SizeOfZeroFill = info.get_size_of_zero_fill();
-	}
-
-	if(info.get_raw_data_end_rva())
-	{
-		pe.rva_to_va(info.get_raw_data_end_rva(), va);
-		tls_struct.EndAddressOfRawData = va;
-	}
-
-	pe.rva_to_va(info.get_index_rva(), va);
-	tls_struct.AddressOfIndex = va;
-
-	if(info.get_callbacks_rva())
-	{
-		pe.rva_to_va(info.get_callbacks_rva(), va);
-		tls_struct.AddressOfCallBacks = va;
-	}
-
-	tls_struct.Characteristics = info.get_characteristics();
-
-	//Save TLS structure
-	memcpy(&raw_data[tls_data_pos], &tls_struct, sizeof(tls_struct));
-
-	//If we are asked to rewrite TLS raw data
-	if(write_tls_data && info.get_raw_data_start_rva() && info.get_raw_data_start_rva() != info.get_raw_data_end_rva())
-	{
-		try
-		{
-			//Check if we're going to write TLS raw data to an existing section (not to PE headers)
-			section& raw_data_section = pe.section_from_rva(info.get_raw_data_start_rva());
-			pe.expand_section(raw_data_section, info.get_raw_data_start_rva(), info.get_raw_data_end_rva() - info.get_raw_data_start_rva(), expand == tls_data_expand_raw ? pe_base::expand_section_raw : pe_base::expand_section_virtual);
-		}
-		catch(const pe_exception&)
-		{
-			//If no section is presented by StartAddressOfRawData, just go to next step
-		}
-
-		unsigned long write_raw_data_size = info.get_raw_data_end_rva() - info.get_raw_data_start_rva();
-		unsigned long available_raw_length = 0;
-
-		//Check if there's enough RAW space to write raw TLS data...
-		if((available_raw_length = pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_raw, true))
-			< info.get_raw_data_end_rva() - info.get_raw_data_start_rva())
-		{
-			//Check if there's enough virtual space for it...
-			if(pe.section_data_length_from_rva(info.get_raw_data_start_rva(), info.get_raw_data_start_rva(), section_data_virtual, true)
-				< info.get_raw_data_end_rva() - info.get_raw_data_start_rva())
-				throw pe_exception("Insufficient space for TLS raw data", pe_exception::insufficient_space);
-			else
-				write_raw_data_size = available_raw_length; //We'll write just a part of full raw data
-		}
-
-		//Write raw TLS data, if any
-		if(write_raw_data_size != 0)
-			memcpy(pe.section_data_from_rva(info.get_raw_data_start_rva(), true), info.get_raw_data().data(), write_raw_data_size);
-	}
-
-	//If we are asked to rewrite TLS callbacks addresses
-	if(write_tls_callbacks && info.get_callbacks_rva())
-	{
-		unsigned long needed_callback_size = static_cast<unsigned long>((info.get_tls_callbacks().size() + 1 /* last null element */) * sizeof(typename PEClassType::BaseSize));
-
-		try
-		{
-			//Check if we're going to write TLS callbacks VAs to an existing section (not to PE headers)
-			section& raw_data_section = pe.section_from_rva(info.get_callbacks_rva());
-			pe.expand_section(raw_data_section, info.get_callbacks_rva(), needed_callback_size, pe_base::expand_section_raw);
-		}
-		catch(const pe_exception&)
-		{
-			//If no section is presented by RVA of callbacks, just go to next step
-		}
-
-		//Check if there's enough space to write callbacks TLS data...
-		if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_raw, true)
-			< needed_callback_size - sizeof(typename PEClassType::BaseSize) /* last zero element can be virtual only */)
-			throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space);
-		
-		if(pe.section_data_length_from_rva(info.get_callbacks_rva(), info.get_callbacks_rva(), section_data_virtual, true)
-			< needed_callback_size /* check here full virtual data length available */)
-			throw pe_exception("Insufficient space for TLS callbacks data", pe_exception::insufficient_space);
-
-		std::vector<typename PEClassType::BaseSize> callbacks_virtual_addresses;
-		callbacks_virtual_addresses.reserve(info.get_tls_callbacks().size() + 1 /* last null element */);
-
-		//Convert TLS RVAs to VAs
-		for(tls_info::tls_callback_list::const_iterator it = info.get_tls_callbacks().begin(); it != info.get_tls_callbacks().end(); ++it)
-		{
-			typename PEClassType::BaseSize cb_va = 0;
-			pe.rva_to_va(*it, cb_va);
-			callbacks_virtual_addresses.push_back(cb_va);
-		}
-
-		//Ending null element
-		callbacks_virtual_addresses.push_back(0);
-
-		//Write callbacks TLS data
-		memcpy(pe.section_data_from_rva(info.get_callbacks_rva(), true), &callbacks_virtual_addresses[0], needed_callback_size);
-	}
-	
-	//Adjust section raw and virtual sizes
-	pe.recalculate_section_sizes(tls_section, auto_strip_last_section);
-
-	image_directory ret(pe.rva_from_section_offset(tls_section, tls_data_pos), needed_size);
-
-	//If auto-rewrite of PE headers is required
-	if(save_to_pe_header)
-	{
-		pe.set_directory_rva(image_directory_entry_tls, ret.get_rva());
-		pe.set_directory_size(image_directory_entry_tls, ret.get_size());
-	}
-
-	return ret;
-}
-}

+ 0 - 122
tools/pe_bliss/pe_tls.h

@@ -1,122 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <memory>
-#include <istream>
-#include "pe_base.h"
-#include "pe_directory.h"
-
-namespace pe_bliss
-{
-//Class representing TLS info
-//We use "DWORD" type to represent RVAs, because RVA is
-//always 32bit even in PE+
-class tls_info
-{
-public:
-	typedef std::vector<uint32_t> tls_callback_list;
-
-public:
-	//Default constructor
-	tls_info();
-
-	//Returns start RVA of TLS raw data
-	uint32_t get_raw_data_start_rva() const;
-	//Returns end RVA of TLS raw data
-	uint32_t get_raw_data_end_rva() const;
-	//Returns TLS index RVA
-	uint32_t get_index_rva() const;
-	//Returns TLS callbacks RVA
-	uint32_t get_callbacks_rva() const;
-	//Returns size of zero fill
-	uint32_t get_size_of_zero_fill() const;
-	//Returns characteristics
-	uint32_t get_characteristics() const;
-	//Returns raw TLS data
-	const std::string& get_raw_data() const;
-	//Returns TLS callbacks addresses
-	const tls_callback_list& get_tls_callbacks() const;
-
-public: //These functions do not change everything inside image, they are used by PE class
-	//You can also use them to rebuild TLS directory
-
-	//Sets start RVA of TLS raw data
-	void set_raw_data_start_rva(uint32_t rva);
-	//Sets end RVA of TLS raw data
-	void set_raw_data_end_rva(uint32_t rva);
-	//Sets TLS index RVA
-	void set_index_rva(uint32_t rva);
-	//Sets TLS callbacks RVA
-	void set_callbacks_rva(uint32_t rva);
-	//Sets size of zero fill
-	void set_size_of_zero_fill(uint32_t size);
-	//Sets characteristics
-	void set_characteristics(uint32_t characteristics);
-	//Sets raw TLS data
-	void set_raw_data(const std::string& data);
-	//Returns TLS callbacks addresses
-	tls_callback_list& get_tls_callbacks();
-	//Adds TLS callback
-	void add_tls_callback(uint32_t rva);
-	//Clears TLS callbacks list
-	void clear_tls_callbacks();
-	//Recalculates end address of raw TLS data
-	void recalc_raw_data_end_rva();
-
-private:
-	uint32_t start_rva_, end_rva_, index_rva_, callbacks_rva_;
-	uint32_t size_of_zero_fill_, characteristics_;
-
-	//Raw TLS data
-	std::string raw_data_;
-
-	//TLS callback RVAs
-	tls_callback_list callbacks_;
-};
-
-//Represents type of expanding of TLS section containing raw data
-//(Works only if you are writing TLS raw data to tls_section and it is the last one in the PE image on the moment of TLS rebuild)
-enum tls_data_expand_type
-{
-	tls_data_expand_raw, //If there is not enough raw space for raw TLS data, it can be expanded
-	tls_data_expand_virtual //If there is not enough virtual place for raw TLS data, it can be expanded
-};
-
-
-//Get TLS info
-//If image does not have TLS, throws an exception
-const tls_info get_tls_info(const pe_base& pe);
-
-template<typename PEClassType>
-const tls_info get_tls_info_base(const pe_base& pe);
-	
-//Rebuilder of TLS structures
-//If write_tls_callbacks = true, TLS callbacks VAs will be written to their place
-//If write_tls_data = true, TLS data will be written to its place
-//If you have chosen to rewrite raw data, only (EndAddressOfRawData - StartAddressOfRawData) bytes will be written, not the full length of string
-//representing raw data content
-//auto_strip_last_section - if true and TLS are placed in the last section, it will be automatically stripped
-const image_directory rebuild_tls(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-
-template<typename PEClassType>
-const image_directory rebuild_tls_base(pe_base& pe, const tls_info& info, section& tls_section, uint32_t offset_from_section_start = 0, bool write_tls_callbacks = true, bool write_tls_data = true, tls_data_expand_type expand = tls_data_expand_raw, bool save_to_pe_header = true, bool auto_strip_last_section = true);
-}

+ 0 - 86
tools/pe_bliss/resource_bitmap_reader.cpp

@@ -1,86 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <cmath>
-#include "resource_bitmap_reader.h"
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_bitmap_reader::resource_bitmap_reader(const pe_resource_viewer& res)
-	:res_(res)
-{}
-
-//Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_name(const std::wstring& name, uint32_t index) const
-{
-	return create_bitmap(res_.get_resource_data_by_name(pe_resource_viewer::resource_bitmap, name, index).get_data());
-}
-
-//Returns bitmap data by name and language (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_name(uint32_t language, const std::wstring& name) const
-{
-	return create_bitmap(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_bitmap, name).get_data());
-}
-
-//Returns bitmap data by ID and language (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_id_lang(uint32_t language, uint32_t id) const
-{
-	return create_bitmap(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_bitmap, id).get_data());
-}
-
-//Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_bitmap_reader::get_bitmap_by_id(uint32_t id, uint32_t index) const
-{
-	return create_bitmap(res_.get_resource_data_by_id(pe_resource_viewer::resource_bitmap, id, index).get_data());
-}
-
-//Helper function of creating bitmap header
-const std::string resource_bitmap_reader::create_bitmap(const std::string& resource_data)
-{
-	//Create bitmap file header
-	bitmapfileheader header = {0};
-	header.bfType = 0x4d42; //Signature "BM"
-	header.bfOffBits = sizeof(bitmapfileheader) + sizeof(bitmapinfoheader); //Offset to bitmap bits
-	header.bfSize = static_cast<uint32_t>(sizeof(bitmapfileheader) + resource_data.length()); //Size of bitmap
-
-	//Check size of resource data
-	if(resource_data.length() < sizeof(bitmapinfoheader))
-		throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
-	{
-		//Get bitmap info header
-		const bitmapinfoheader* info = reinterpret_cast<const bitmapinfoheader*>(resource_data.data());
-
-		//If color table is present, skip it
-		if(info->biClrUsed != 0)
-			header.bfOffBits += 4 * info->biClrUsed; //Add this size to offset to bitmap bits
-		else if(info->biBitCount <= 8)
-			header.bfOffBits += 4 * static_cast<uint32_t>(std::pow(2.f, info->biBitCount)); //Add this size to offset to bitmap bits
-	}
-
-	//Return final bitmap data
-	return std::string(reinterpret_cast<const char*>(&header), sizeof(bitmapfileheader)) + resource_data;
-}
-}

+ 0 - 50
tools/pe_bliss/resource_bitmap_reader.h

@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_bitmap_reader
-{
-public:
-	resource_bitmap_reader(const pe_resource_viewer& res);
-
-	//Returns bitmap data by name and language (minimum checks of format correctness)
-	const std::string get_bitmap_by_name(uint32_t language, const std::wstring& name) const;
-	//Returns bitmap data by name and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_bitmap_by_name(const std::wstring& name, uint32_t index = 0) const;
-	//Returns bitmap data by ID and language (minimum checks of format correctness)
-	const std::string get_bitmap_by_id_lang(uint32_t language, uint32_t id) const;
-	//Returns bitmap data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_bitmap_by_id(uint32_t id, uint32_t index = 0) const;
-
-private:
-	//Helper function of creating bitmap header
-	static const std::string create_bitmap(const std::string& resource_data);
-
-	const pe_resource_viewer& res_;
-};
-}

+ 0 - 75
tools/pe_bliss/resource_bitmap_writer.cpp

@@ -1,75 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "resource_bitmap_writer.h"
-#include "pe_resource_manager.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_bitmap_writer::resource_bitmap_writer(pe_resource_manager& res)
-	:res_(res)
-{}
-
-//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-//timestamp will be used for directories that will be added
-void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	//Check bitmap data a little
-	if(bitmap_file.length() < sizeof(bitmapfileheader))
-		throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
-	resource_directory_entry new_entry;
-	new_entry.set_id(id);
-
-	//Add bitmap
-	res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(id), language, codepage, timestamp);
-}
-
-//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-//timestamp will be used for directories that will be added
-void resource_bitmap_writer::add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage, uint32_t timestamp)
-{
-	//Check bitmap data a little
-	if(bitmap_file.length() < sizeof(bitmapfileheader))
-		throw pe_exception("Incorrect resource bitmap", pe_exception::resource_incorrect_bitmap);
-
-	resource_directory_entry new_entry;
-	new_entry.set_name(name);
-
-	//Add bitmap
-	res_.add_resource(bitmap_file.substr(sizeof(bitmapfileheader)), pe_resource_viewer::resource_bitmap, new_entry, resource_directory::entry_finder(name), language, codepage, timestamp);
-}
-
-//Removes bitmap by name/ID and language
-bool resource_bitmap_writer::remove_bitmap(const std::wstring& name, uint32_t language)
-{
-	return res_.remove_resource(pe_resource_viewer::resource_bitmap, name, language);
-}
-
-//Removes bitmap by name/ID and language
-bool resource_bitmap_writer::remove_bitmap(uint32_t id, uint32_t language)
-{
-	return res_.remove_resource(pe_resource_viewer::resource_bitmap, id, language);
-}
-}

+ 0 - 47
tools/pe_bliss/resource_bitmap_writer.h

@@ -1,47 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_bitmap_writer
-{
-public:
-	resource_bitmap_writer(pe_resource_manager& res);
-
-	//Adds bitmap from bitmap file data. If bitmap already exists, replaces it
-	//timestamp will be used for directories that will be added
-	void add_bitmap(const std::string& bitmap_file, uint32_t id, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-	void add_bitmap(const std::string& bitmap_file, const std::wstring& name, uint32_t language, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-	//Removes bitmap by name/ID and language
-	bool remove_bitmap(const std::wstring& name, uint32_t language);
-	bool remove_bitmap(uint32_t id, uint32_t language);
-
-private:
-	pe_resource_manager& res_;
-};
-}

+ 0 - 521
tools/pe_bliss/resource_cursor_icon_reader.cpp

@@ -1,521 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include "resource_cursor_icon_reader.h"
-#include "pe_structures.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_cursor_icon_reader::resource_cursor_icon_reader(const pe_resource_viewer& res)
-	:res_(res)
-{}
-
-//Helper function of creating icon headers from ICON_GROUP resource data
-//Returns icon count
-uint16_t resource_cursor_icon_reader::format_icon_headers(std::string& ico_data, const std::string& resource_data)
-{
-	//Check resource data size
-	if(resource_data.length() < sizeof(ico_header))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	//Get icon header
-	const ico_header* info = reinterpret_cast<const ico_header*>(resource_data.data());
-
-	//Check resource data size
-	if(resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	//Reserve memory to speed up a little
-	ico_data.reserve(sizeof(ico_header) + info->Count * sizeof(icondirentry));
-	ico_data.append(reinterpret_cast<const char*>(info), sizeof(ico_header));
-
-	//Iterate over all listed icons
-	uint32_t offset = sizeof(ico_header) + sizeof(icondirentry) * info->Count;
-	for(uint16_t i = 0; i != info->Count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-
-		//Fill icon data
-		icondirentry direntry;
-		direntry.BitCount = group->BitCount;
-		direntry.ColorCount = group->ColorCount;
-		direntry.Height = group->Height;
-		direntry.Planes = group->Planes;
-		direntry.Reserved = group->Reserved;
-		direntry.SizeInBytes = group->SizeInBytes;
-		direntry.Width = group->Width;
-		direntry.ImageOffset = offset;
-
-		//Add icon header to returned value
-		ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(icondirentry));
-
-		offset += group->SizeInBytes;
-	}
-
-	//Return icon count
-	return info->Count;
-}
-
-//Returns single icon data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_icon_by_id_lang(uint32_t language, uint32_t id) const
-{
-	//Get icon headers
-	std::string icon_data(lookup_icon_group_data_by_icon(id, language));
-	//Append icon data
-	icon_data.append(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, id).get_data());
-	return icon_data;
-}
-
-//Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_icon_by_id(uint32_t id, uint32_t index) const
-{
-	pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_icon, id));
-	if(languages.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
-	//Get icon headers
-	std::string icon_data(lookup_icon_group_data_by_icon(id, languages.at(index)));
-	//Append icon data
-	icon_data.append(res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, id, index).get_data());
-	return icon_data;
-}
-
-//Returns icon data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_name(const std::wstring& name, uint32_t index) const
-{
-	std::string ret;
-
-	//Get resource by name and index
-	const std::string data = res_.get_resource_data_by_name(pe_resource_viewer::resource_icon_group, name, index).get_data();
-
-	//Create icon headers
-	uint16_t icon_count = format_icon_headers(ret, data);
-
-	//Append icon data
-	for(uint16_t i = 0; i != icon_count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-		ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data();
-	}
-
-	return ret;
-}
-
-//Returns icon data by name and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_name(uint32_t language, const std::wstring& name) const
-{
-	std::string ret;
-
-	//Get resource by name and language
-	const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, name).get_data();
-
-	//Create icon headers
-	uint16_t icon_count = format_icon_headers(ret, data);
-
-	//Append icon data
-	for(uint16_t i = 0; i != icon_count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-		ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data();
-	}
-
-	return ret;
-}
-
-//Returns icon data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_id_lang(uint32_t language, uint32_t id) const
-{
-	std::string ret;
-
-	//Get resource by language and id
-	const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, id).get_data();
-
-	//Create icon headers
-	uint16_t icon_count = format_icon_headers(ret, data);
-
-	//Append icon data
-	for(uint16_t i = 0; i != icon_count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-		ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon, group->Number).get_data();
-	}
-
-	return ret;
-}
-
-//Returns icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_icon_by_id(uint32_t id, uint32_t index) const
-{
-	std::string ret;
-
-	//Get resource by id and index
-	const std::string data = res_.get_resource_data_by_id(pe_resource_viewer::resource_icon_group, id, index).get_data();
-
-	//Create icon headers
-	uint16_t icon_count = format_icon_headers(ret, data);
-
-	//Append icon data
-	for(uint16_t i = 0; i != icon_count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-		ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_icon, group->Number, index).get_data();
-	}
-
-	return ret;
-}
-
-//Checks for icon presence inside icon group, fills icon headers if found
-bool resource_cursor_icon_reader::check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data)
-{
-	//Check resource data size
-	if(icon_group_resource_data.length() < sizeof(ico_header))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	//Get icon header
-	const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_resource_data.data());
-
-	//Check resource data size
-	if(icon_group_resource_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	for(uint16_t i = 0; i != info->Count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_resource_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-		if(group->Number == icon_id)
-		{
-			//Reserve memory to speed up a little
-			ico_data.reserve(sizeof(ico_header) + sizeof(icondirentry));
-			//Write single-icon icon header
-			ico_header new_header = *info;
-			new_header.Count = 1;
-			ico_data.append(reinterpret_cast<const char*>(&new_header), sizeof(ico_header));
-
-			//Fill icon data
-			icondirentry direntry;
-			direntry.BitCount = group->BitCount;
-			direntry.ColorCount = group->ColorCount;
-			direntry.Height = group->Height;
-			direntry.Planes = group->Planes;
-			direntry.Reserved = group->Reserved;
-			direntry.SizeInBytes = group->SizeInBytes;
-			direntry.Width = group->Width;
-			direntry.ImageOffset = sizeof(ico_header) + sizeof(icondirentry);
-			ico_data.append(reinterpret_cast<const char*>(&direntry), sizeof(direntry));
-
-			return true;
-		}
-	}
-
-	return false;
-}
-
-//Looks up icon group by icon id and returns full icon headers if found
-const std::string resource_cursor_icon_reader::lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const
-{
-	std::string icon_header_data;
-
-	{
-		//List all ID-resources
-		pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_icon_group));
-
-		for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it)
-		{
-			pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it));
-			if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
-				&& check_icon_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data))
-				return icon_header_data;
-		}
-	}
-
-	{
-		//List all named resources
-		pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_icon_group));
-		for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it)
-		{
-			pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_icon_group, *it));
-			if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
-				&& check_icon_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, *it).get_data(), icon_id, icon_header_data))
-				return icon_header_data;
-		}
-	}
-
-	throw pe_exception("No icon group find for requested icon", pe_exception::no_icon_group_found);
-}
-
-//Returns single cursor data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const
-{
-	std::string raw_cursor_data(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, id).get_data());
-	//Get cursor headers
-	std::string cursor_data(lookup_cursor_group_data_by_cursor(id, language, raw_cursor_data));
-	//Append cursor data
-	cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */));
-	return cursor_data;
-}
-
-//Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_single_cursor_by_id(uint32_t id, uint32_t index) const
-{
-	pe_resource_viewer::resource_language_list languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor, id));
-	if(languages.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-	
-	std::string raw_cursor_data(res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, id, index).get_data());
-	//Get cursor headers
-	std::string cursor_data(lookup_cursor_group_data_by_cursor(id, languages.at(index), raw_cursor_data));
-	//Append cursor data
-	cursor_data.append(raw_cursor_data.substr(sizeof(uint16_t) * 2 /* hotspot position */));
-	return cursor_data;
-}
-
-//Helper function of creating cursor headers
-//Returns cursor count
-uint16_t resource_cursor_icon_reader::format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index) const
-{
-	//Check resource data length
-	if(resource_data.length() < sizeof(cursor_header))
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	const cursor_header* info = reinterpret_cast<const cursor_header*>(resource_data.data());
-
-	//Check resource data length
-	if(resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group) * info->Count)
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	//Reserve needed space to speed up a little
-	cur_data.reserve(sizeof(cursor_header) + info->Count * sizeof(cursordirentry));
-	//Add cursor header
-	cur_data.append(reinterpret_cast<const char*>(info), sizeof(cursor_header));
-
-	//Iterate over all cursors listed in cursor group
-	uint32_t offset = sizeof(cursor_header) + sizeof(cursordirentry) * info->Count;
-	for(uint16_t i = 0; i != info->Count; ++i)
-	{
-		const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-
-		//Fill cursor info
-		cursordirentry direntry;
-		direntry.ColorCount = 0; //OK
-		direntry.Width = static_cast<uint8_t>(group->Width);
-		direntry.Height = static_cast<uint8_t>(group->Height)  / 2;
-		direntry.Reserved = 0;
-
-		//Now read hotspot data from cursor data directory
-		const std::string cursor = index == 0xFFFFFFFF
-			? res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data()
-			: res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data();
-		if(cursor.length() < 2 * sizeof(uint16_t))
-			throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-		//Here it is - two words in the very beginning of cursor data
-		direntry.HotspotX = *reinterpret_cast<const uint16_t*>(cursor.data());
-		direntry.HotspotY = *reinterpret_cast<const uint16_t*>(cursor.data() + sizeof(uint16_t));
-
-		//Fill the rest data
-		direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t);
-		direntry.ImageOffset = offset;
-
-		//Add cursor header
-		cur_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry));
-
-		offset += direntry.SizeInBytes;
-	}
-
-	//Return cursor count
-	return info->Count;
-}
-
-//Returns cursor data by name and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_name(uint32_t language, const std::wstring& name) const
-{
-	std::string ret;
-
-	//Get resource by name and language
-	const std::string resource_data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, name).get_data();
-
-	//Create cursor headers
-	uint16_t cursor_count = format_cursor_headers(ret, resource_data, language);
-
-	//Add cursor data
-	for(uint16_t i = 0; i != cursor_count; ++i)
-	{
-		const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-		ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t));
-	}
-
-	return ret;
-}
-
-//Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_name(const std::wstring& name, uint32_t index) const
-{
-	std::string ret;
-
-	//Get resource by name and index
-	const std::string resource_data = res_.get_resource_data_by_name(pe_resource_viewer::resource_cursor_group, name, index).get_data();
-
-	//Create cursor headers
-	uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index);
-
-	//Add cursor data
-	for(uint16_t i = 0; i != cursor_count; ++i)
-	{
-		const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-		ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t));
-	}
-
-	return ret;
-}
-
-//Returns cursor data by ID and language (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_id_lang(uint32_t language, uint32_t id) const
-{
-	std::string ret;
-
-	//Get resource by ID and language
-	const std::string resource_data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, id).get_data();
-
-	//Create cursor headers
-	uint16_t cursor_count = format_cursor_headers(ret, resource_data, language);
-
-	//Add cursor data
-	for(uint16_t i = 0; i != cursor_count; ++i)
-	{
-		const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-		ret += res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor, group->Number).get_data().substr(2 * sizeof(uint16_t));
-	}
-
-	return ret;
-}
-
-//Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-const std::string resource_cursor_icon_reader::get_cursor_by_id(uint32_t id, uint32_t index) const
-{
-	std::string ret;
-
-	//Get resource by ID and index
-	const std::string resource_data = res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor_group, id, index).get_data();
-
-	//Create cursor headers
-	uint16_t cursor_count = format_cursor_headers(ret, resource_data, 0, index);
-
-	//Add cursor data
-	for(uint16_t i = 0; i != cursor_count; ++i)
-	{
-		const cursor_group* group = reinterpret_cast<const cursor_group*>(resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-		ret += res_.get_resource_data_by_id(pe_resource_viewer::resource_cursor, group->Number, index).get_data().substr(2 * sizeof(uint16_t));
-	}
-
-	return ret;
-}
-
-//Checks for cursor presence inside cursor group, fills cursor headers if found
-bool resource_cursor_icon_reader::check_cursor_presence(const std::string& cursor_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data)
-{
-	//Check resource data length
-	if(cursor_group_resource_data.length() < sizeof(cursor_header))
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_resource_data.data());
-
-	//Check resource data length
-	if(cursor_group_resource_data.length() < sizeof(cursor_header) + sizeof(cursor_group))
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	//Iterate over all cursors listed in cursor group
-	for(uint16_t i = 0; i != info->Count; ++i)
-	{
-		const cursor_group* group = reinterpret_cast<const cursor_group*>(cursor_group_resource_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-
-		if(group->Number == cursor_id)
-		{
-			//Reserve needed space to speed up a little
-			cur_header_data.reserve(sizeof(cursor_header) + sizeof(cursordirentry));
-			//Write single-cursor cursor header
-			cursor_header new_header = *info;
-			new_header.Count = 1;
-			cur_header_data.append(reinterpret_cast<const char*>(&new_header), sizeof(cursor_header));
-
-			//Fill cursor info
-			cursordirentry direntry;
-			direntry.ColorCount = 0; //OK
-			direntry.Width = static_cast<uint8_t>(group->Width);
-			direntry.Height = static_cast<uint8_t>(group->Height)  / 2;
-			direntry.Reserved = 0;
-
-			if(raw_cursor_data.length() < 2 * sizeof(uint16_t))
-				throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-			//Here it is - two words in the very beginning of cursor data
-			direntry.HotspotX = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data());
-			direntry.HotspotY = *reinterpret_cast<const uint16_t*>(raw_cursor_data.data() + sizeof(uint16_t));
-
-			//Fill the rest data
-			direntry.SizeInBytes = group->SizeInBytes - 2 * sizeof(uint16_t);
-			direntry.ImageOffset = sizeof(cursor_header) + sizeof(cursordirentry);
-
-			//Add cursor header
-			cur_header_data.append(reinterpret_cast<const char*>(&direntry), sizeof(cursordirentry));
-
-			return true;
-		}
-	}
-
-	return false;
-}
-
-//Looks up cursor group by cursor id and returns full cursor headers if found
-const std::string resource_cursor_icon_reader::lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const
-{
-	std::string cursor_header_data;
-
-	{
-		//List all ID-resources
-		pe_resource_viewer::resource_id_list ids(res_.list_resource_ids(pe_resource_viewer::resource_cursor_group));
-
-		for(pe_resource_viewer::resource_id_list::const_iterator it = ids.begin(); it != ids.end(); ++it)
-		{
-			pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it));
-			if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
-				&& check_cursor_presence(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data))
-				return cursor_header_data;
-		}
-	}
-
-	{
-		//List all named resources
-		pe_resource_viewer::resource_name_list names(res_.list_resource_names(pe_resource_viewer::resource_cursor_group));
-		for(pe_resource_viewer::resource_name_list::const_iterator it = names.begin(); it != names.end(); ++it)
-		{
-			pe_resource_viewer::resource_language_list group_languages(res_.list_resource_languages(pe_resource_viewer::resource_cursor_group, *it));
-			if(std::find(group_languages.begin(), group_languages.end(), language) != group_languages.end()
-				&& check_cursor_presence(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, *it).get_data(), cursor_id, cursor_header_data, raw_cursor_data))
-				return cursor_header_data;
-		}
-	}
-
-	throw pe_exception("No cursor group find for requested icon", pe_exception::no_cursor_group_found);
-}
-}

+ 0 - 84
tools/pe_bliss/resource_cursor_icon_reader.h

@@ -1,84 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_cursor_icon_reader
-{
-public:
-	resource_cursor_icon_reader(const pe_resource_viewer& res);
-
-	//Returns single icon data by ID and language (minimum checks of format correctness)
-	const std::string get_single_icon_by_id_lang(uint32_t language, uint32_t id) const;
-	//Returns single icon data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_single_icon_by_id(uint32_t id, uint32_t index = 0) const;
-
-	//Returns icon data of group of icons by name and language (minimum checks of format correctness)
-	const std::string get_icon_by_name(uint32_t language, const std::wstring& icon_group_name) const;
-	//Returns icon data of group of icons by name and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_icon_by_name(const std::wstring& icon_group_name, uint32_t index = 0) const;
-	//Returns icon data of group of icons by ID and language (minimum checks of format correctness)
-	const std::string get_icon_by_id_lang(uint32_t language, uint32_t icon_group_id) const;
-	//Returns icon data of group of icons by ID and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_icon_by_id(uint32_t icon_group_id, uint32_t index = 0) const;
-	
-	//Returns single cursor data by ID and language (minimum checks of format correctness)
-	const std::string get_single_cursor_by_id_lang(uint32_t language, uint32_t id) const;
-	//Returns single cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_single_cursor_by_id(uint32_t id, uint32_t index = 0) const;
-
-	//Returns cursor data by name and language (minimum checks of format correctness)
-	const std::string get_cursor_by_name(uint32_t language, const std::wstring& cursor_group_name) const;
-	//Returns cursor data by name and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_cursor_by_name(const std::wstring& cursor_group_name, uint32_t index = 0) const;
-	//Returns cursor data by ID and language (minimum checks of format correctness)
-	const std::string get_cursor_by_id_lang(uint32_t language, uint32_t cursor_group_id) const;
-	//Returns cursor data by ID and index in language directory (instead of language) (minimum checks of format correctness)
-	const std::string get_cursor_by_id(uint32_t cursor_group_id, uint32_t index = 0) const;
-
-private:
-	const pe_resource_viewer& res_;
-
-	//Helper function of creating icon headers from ICON_GROUP resource data
-	//Returns icon count
-	static uint16_t format_icon_headers(std::string& ico_data, const std::string& resource_data);
-	
-	//Helper function of creating cursor headers from CURSOR_GROUP resource data
-	//Returns cursor count
-	uint16_t format_cursor_headers(std::string& cur_data, const std::string& resource_data, uint32_t language, uint32_t index = 0xFFFFFFFF) const;
-
-	//Looks up icon group by icon id and returns full icon headers if found
-	const std::string lookup_icon_group_data_by_icon(uint32_t icon_id, uint32_t language) const;
-	//Checks for icon presence inside icon group, fills icon headers if found
-	static bool check_icon_presence(const std::string& icon_group_resource_data, uint32_t icon_id, std::string& ico_data);
-
-	//Looks up cursor group by cursor id and returns full cursor headers if found
-	const std::string lookup_cursor_group_data_by_cursor(uint32_t cursor_id, uint32_t language, const std::string& raw_cursor_data) const;
-	//Checks for cursor presence inside cursor group, fills cursor headers if found
-	static bool check_cursor_presence(const std::string& icon_group_resource_data, uint32_t cursor_id, std::string& cur_header_data, const std::string& raw_cursor_data);
-};
-}

+ 0 - 447
tools/pe_bliss/resource_cursor_icon_writer.cpp

@@ -1,447 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <algorithm>
-#include <string.h>
-#include "resource_cursor_icon_writer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_cursor_icon_writer::resource_cursor_icon_writer(pe_resource_manager& res)
-	:res_(res)
-{}
-
-//Add icon helper
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
-	//Check icon for correctness
-	if(icon_file.length() < sizeof(ico_header))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	const ico_header* icon_header = reinterpret_cast<const ico_header*>(&icon_file[0]);
-
-	unsigned long size_of_headers = sizeof(ico_header) + icon_header->Count * sizeof(icondirentry);
-	if(icon_file.length() < size_of_headers || icon_header->Count == 0)
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	//Enumerate all icons in file
-	for(uint16_t i = 0; i != icon_header->Count; ++i)
-	{
-		//Check icon entries
-		const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]);
-		if(icon_entry->SizeInBytes == 0
-			|| icon_entry->ImageOffset < size_of_headers
-			|| !pe_utils::is_sum_safe(icon_entry->ImageOffset, icon_entry->SizeInBytes)
-			|| icon_entry->ImageOffset + icon_entry->SizeInBytes > icon_file.length())
-			throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-	}
-
-	std::string icon_group_data;
-	ico_header* info = 0;
-
-	if(group_icon_info)
-	{
-		//If icon group already exists
-		{
-			icon_group_data = group_icon_info->get_data();
-			codepage = group_icon_info->get_codepage(); //Don't change codepage of icon group entry
-		}
-
-		//Check resource data size
-		if(icon_group_data.length() < sizeof(ico_header))
-			throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-		//Get icon header
-		info = reinterpret_cast<ico_header*>(&icon_group_data[0]);
-
-		//Check resource data size
-		if(icon_group_data.length() < sizeof(ico_header) + info->Count * sizeof(icon_group))
-			throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-		icon_group_data.resize(sizeof(ico_header) + (info->Count + icon_header->Count) * sizeof(icon_group));
-		info = reinterpret_cast<ico_header*>(&icon_group_data[0]); //In case if memory was reallocated
-	}
-	else //Entry not found - icon group doesn't exist
-	{
-		icon_group_data.resize(sizeof(ico_header) + icon_header->Count * sizeof(icon_group));
-		memcpy(&icon_group_data[0], icon_header, sizeof(ico_header));
-	}
-
-	//Search for available icon IDs
-	std::vector<uint16_t> icon_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_icon, mode, icon_header->Count));
-
-	//Enumerate all icons in file
-	for(uint16_t i = 0; i != icon_header->Count; ++i)
-	{
-		const icondirentry* icon_entry = reinterpret_cast<const icondirentry*>(&icon_file[sizeof(ico_header) + i * sizeof(icondirentry)]);
-		icon_group group = {0};
-
-		//Fill icon resource header
-		group.BitCount = icon_entry->BitCount;
-		group.ColorCount = icon_entry->ColorCount;
-		group.Height = icon_entry->Height;
-		group.Planes = icon_entry->Planes;
-		group.Reserved = icon_entry->Reserved;
-		group.SizeInBytes = icon_entry->SizeInBytes;
-		group.Width = icon_entry->Width;
-		group.Number = icon_id_list.at(i);
-
-		memcpy(&icon_group_data[sizeof(ico_header) + ((info ? info->Count : 0) + i) * sizeof(icon_group)], &group, sizeof(group));
-
-		//Add icon to resources
-		resource_directory_entry new_entry;
-		new_entry.set_id(group.Number);
-		res_.add_resource(icon_file.substr(icon_entry->ImageOffset, icon_entry->SizeInBytes), pe_resource_viewer::resource_icon, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp);
-	}
-
-	if(info)
-		info->Count += icon_header->Count; //Increase icon count, if we're adding icon to existing group
-
-	{
-		//Add or replace icon group data entry
-		res_.add_resource(icon_group_data, pe_resource_viewer::resource_icon_group, new_icon_group_entry, finder, language, codepage, timestamp);
-	}
-}
-
-//Returns free icon or cursor ID list depending on icon_place_mode
-const std::vector<uint16_t> resource_cursor_icon_writer::get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_type type, icon_place_mode mode, uint32_t count)
-{
-	//Search for available icon/cursor IDs
-	std::vector<uint16_t> icon_cursor_id_list;
-
-	try
-	{
-		//If any icon exists
-		//List icon IDs
-		std::vector<uint32_t> id_list(res_.list_resource_ids(type));
-		std::sort(id_list.begin(), id_list.end());
-
-		//If we are placing icon on free spaces
-		//I.e., icon IDs 1, 3, 4, 7, 8 already exist
-		//We'll place five icons on IDs 2, 5, 6, 9, 10
-		if(mode != icon_place_after_max_icon_id)
-		{
-			if(!id_list.empty())
-			{
-				//Determine and list free icon IDs
-				for(std::vector<uint32_t>::const_iterator it = id_list.begin(); it != id_list.end(); ++it)
-				{
-					if(it == id_list.begin())
-					{
-						if(*it > 1)
-						{
-							for(uint16_t i = 1; i != *it; ++i)
-							{
-								icon_cursor_id_list.push_back(i);
-								if(icon_cursor_id_list.size() == count)
-									break;
-							}
-						}
-					}
-					else if(*(it - 1) - *it > 1)
-					{
-						for(uint16_t i = static_cast<uint16_t>(*(it - 1) + 1); i != static_cast<uint16_t>(*it); ++i)
-						{
-							icon_cursor_id_list.push_back(i);
-							if(icon_cursor_id_list.size() == count)
-								break;
-						}
-					}
-
-					if(icon_cursor_id_list.size() == count)
-						break;
-				}
-			}
-		}
-
-		uint32_t max_id = id_list.empty() ? 0 : *std::max_element(id_list.begin(), id_list.end());
-		for(uint32_t i = static_cast<uint32_t>(icon_cursor_id_list.size()); i != count; ++i)
-			icon_cursor_id_list.push_back(static_cast<uint16_t>(++max_id));
-	}
-	catch(const pe_exception&) //Entry not found
-	{
-		for(uint16_t i = 1; i != count + 1; ++i)
-			icon_cursor_id_list.push_back(i);
-	}
-
-	return icon_cursor_id_list;
-}
-
-//Add cursor helper
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
-	//Check cursor for correctness
-	if(cursor_file.length() < sizeof(cursor_header))
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	const cursor_header* cur_header = reinterpret_cast<const cursor_header*>(&cursor_file[0]);
-
-	unsigned long size_of_headers = sizeof(cursor_header) + cur_header->Count * sizeof(cursordirentry);
-	if(cursor_file.length() < size_of_headers || cur_header->Count == 0)
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	//Enumerate all cursors in file
-	for(uint16_t i = 0; i != cur_header->Count; ++i)
-	{
-		//Check cursor entries
-		const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]);
-		if(cursor_entry->SizeInBytes == 0
-			|| cursor_entry->ImageOffset < size_of_headers
-			|| !pe_utils::is_sum_safe(cursor_entry->ImageOffset, cursor_entry->SizeInBytes)
-			|| cursor_entry->ImageOffset + cursor_entry->SizeInBytes > cursor_file.length())
-			throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-	}
-
-	std::string cursor_group_data;
-	cursor_header* info = 0;
-
-	if(group_cursor_info)
-	{
-		//If cursor group already exists
-		{
-			cursor_group_data = group_cursor_info->get_data();
-			codepage = group_cursor_info->get_codepage(); //Don't change codepage of cursor group entry
-		}
-
-		//Check resource data size
-		if(cursor_group_data.length() < sizeof(cursor_header))
-			throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-		//Get cursor header
-		info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]);
-
-		//Check resource data size
-		if(cursor_group_data.length() < sizeof(cursor_header) + info->Count * sizeof(cursor_group))
-			throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-		cursor_group_data.resize(sizeof(cursor_header) + (info->Count + cur_header->Count) * sizeof(cursor_group));
-		info = reinterpret_cast<cursor_header*>(&cursor_group_data[0]); //In case if memory was reallocated
-	}
-	else //Entry not found - cursor group doesn't exist
-	{
-		cursor_group_data.resize(sizeof(cursor_header) + cur_header->Count * sizeof(cursor_group));
-		memcpy(&cursor_group_data[0], cur_header, sizeof(cursor_header));
-	}
-
-	//Search for available cursor IDs
-	std::vector<uint16_t> cursor_id_list(get_icon_or_cursor_free_id_list(pe_resource_viewer::resource_cursor, mode, cur_header->Count));
-
-	//Enumerate all cursors in file
-	for(uint16_t i = 0; i != cur_header->Count; ++i)
-	{
-		const cursordirentry* cursor_entry = reinterpret_cast<const cursordirentry*>(&cursor_file[sizeof(cursor_header) + i * sizeof(cursordirentry)]);
-		cursor_group group = {0};
-
-		//Fill cursor resource header
-		group.Height = cursor_entry->Height * 2;
-		group.SizeInBytes = cursor_entry->SizeInBytes + 2 * sizeof(uint16_t) /* hotspot coordinates */;
-		group.Width = cursor_entry->Width;
-		group.Number = cursor_id_list.at(i);
-
-		memcpy(&cursor_group_data[sizeof(cursor_header) + ((info ? info->Count : 0) + i) * sizeof(cursor_group)], &group, sizeof(group));
-
-		//Add cursor to resources
-		resource_directory_entry new_entry;
-		new_entry.set_id(group.Number);
-
-		//Fill resource data (two WORDs for hotspot of cursor, and cursor bitmap data)
-		std::string cur_data;
-		cur_data.resize(sizeof(uint16_t) * 2);
-		memcpy(&cur_data[0], &cursor_entry->HotspotX, sizeof(uint16_t));
-		memcpy(&cur_data[sizeof(uint16_t)], &cursor_entry->HotspotY, sizeof(uint16_t));
-		cur_data.append(cursor_file.substr(cursor_entry->ImageOffset, cursor_entry->SizeInBytes));
-
-		res_.add_resource(cur_data, pe_resource_viewer::resource_cursor, new_entry, resource_directory::entry_finder(group.Number), language, codepage, timestamp);
-	}
-
-	if(info)
-		info->Count += cur_header->Count; //Increase cursor count, if we're adding cursor to existing group
-
-	{
-		//Add or replace cursor group data entry
-		res_.add_resource(cursor_group_data, pe_resource_viewer::resource_cursor_group, new_cursor_group_entry, finder, language, codepage, timestamp);
-	}
-}
-
-//Adds icon(s) from icon file data
-//timestamp will be used for directories that will be added
-//If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s)
-//(Codepage of icon group and icons will not be changed in this case)
-//icon_place_mode determines, how new icon(s) will be placed
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, const std::wstring& icon_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_icon_group_entry;
-	new_icon_group_entry.set_name(icon_group_name);
-	std::auto_ptr<resource_data_info> data_info;
-
-	try
-	{
-		data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name)));
-	}
-	catch(const pe_exception&) //Entry not found
-	{
-	}
-
-	add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_name), language, mode, codepage, timestamp);
-}
-
-void resource_cursor_icon_writer::add_icon(const std::string& icon_file, uint32_t icon_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_icon_group_entry;
-	new_icon_group_entry.set_id(icon_group_id);
-	std::auto_ptr<resource_data_info> data_info;
-
-	try
-	{
-		data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id)));
-	}
-	catch(const pe_exception&) //Entry not found
-	{
-	}
-
-	add_icon(icon_file, data_info.get(), new_icon_group_entry, resource_directory::entry_finder(icon_group_id), language, mode, codepage, timestamp);
-}
-
-//Adds cursor(s) from cursor file data
-//timestamp will be used for directories that will be added
-//If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s)
-//(Codepage of cursor group and cursors will not be changed in this case)
-//icon_place_mode determines, how new cursor(s) will be placed
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_cursor_group_entry;
-	new_cursor_group_entry.set_name(cursor_group_name);
-	std::auto_ptr<resource_data_info> data_info;
-
-	try
-	{
-		data_info.reset(new resource_data_info(res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name)));
-	}
-	catch(const pe_exception&) //Entry not found
-	{
-	}
-
-	add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_name), language, mode, codepage, timestamp);
-}
-
-void resource_cursor_icon_writer::add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp)
-{
-	resource_directory_entry new_cursor_group_entry;
-	new_cursor_group_entry.set_id(cursor_group_id);
-	std::auto_ptr<resource_data_info> data_info;
-
-	try
-	{
-		data_info.reset(new resource_data_info(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id)));
-	}
-	catch(const pe_exception&) //Entry not found
-	{
-	}
-
-	add_cursor(cursor_file, data_info.get(), new_cursor_group_entry, resource_directory::entry_finder(cursor_group_id), language, mode, codepage, timestamp);
-}
-
-//Remove icon group helper
-void resource_cursor_icon_writer::remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language)
-{
-	//Check resource data size
-	if(icon_group_data.length() < sizeof(ico_header))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	//Get icon header
-	const ico_header* info = reinterpret_cast<const ico_header*>(icon_group_data.data());
-
-	uint16_t icon_count = info->Count;
-
-	//Check resource data size
-	if(icon_group_data.length() < sizeof(ico_header) + icon_count * sizeof(icon_group))
-		throw pe_exception("Incorrect resource icon", pe_exception::resource_incorrect_icon);
-
-	//Remove icon data
-	for(uint16_t i = 0; i != icon_count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(icon_group_data.data() + sizeof(ico_header) + i * sizeof(icon_group));
-		res_.remove_resource(pe_resource_viewer::resource_icon, group->Number, language);
-	}
-}
-
-//Remove cursor group helper
-void resource_cursor_icon_writer::remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language)
-{
-	//Check resource data size
-	if(cursor_group_data.length() < sizeof(cursor_header))
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	//Get icon header
-	const cursor_header* info = reinterpret_cast<const cursor_header*>(cursor_group_data.data());
-
-	uint16_t cursor_count = info->Count;
-
-	//Check resource data size
-	if(cursor_group_data.length() < sizeof(cursor_header) + cursor_count * sizeof(cursor_group))
-		throw pe_exception("Incorrect resource cursor", pe_exception::resource_incorrect_cursor);
-
-	//Remove icon data
-	for(uint16_t i = 0; i != cursor_count; ++i)
-	{
-		const icon_group* group = reinterpret_cast<const icon_group*>(cursor_group_data.data() + sizeof(cursor_header) + i * sizeof(cursor_group));
-		res_.remove_resource(pe_resource_viewer::resource_cursor, group->Number, language);
-	}
-}
-
-//Removes cursor group and all its cursors by name/ID and language
-bool resource_cursor_icon_writer::remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language)
-{
-	//Get resource by name and language
-	const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_cursor_group, cursor_group_name).get_data();
-	remove_cursors_from_cursor_group(data, language);
-	return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_name, language);
-}
-
-//Removes cursor group and all its cursors by name/ID and language
-bool resource_cursor_icon_writer::remove_cursor_group(uint32_t cursor_group_id, uint32_t language)
-{
-	//Get resource by name and language
-	const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_cursor_group, cursor_group_id).get_data();
-	remove_cursors_from_cursor_group(data, language);
-	return res_.remove_resource(pe_resource_viewer::resource_cursor_group, cursor_group_id, language);
-}
-
-//Removes icon group and all its icons by name/ID and language
-bool resource_cursor_icon_writer::remove_icon_group(const std::wstring& icon_group_name, uint32_t language)
-{
-	//Get resource by name and language
-	const std::string data = res_.get_resource_data_by_name(language, pe_resource_viewer::resource_icon_group, icon_group_name).get_data();
-	remove_icons_from_icon_group(data, language);
-	return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_name, language);
-}
-
-//Removes icon group and all its icons by name/ID and language
-bool resource_cursor_icon_writer::remove_icon_group(uint32_t icon_group_id, uint32_t language)
-{
-	//Get resource by name and language
-	const std::string data = res_.get_resource_data_by_id(language, pe_resource_viewer::resource_icon_group, icon_group_id).get_data();
-	remove_icons_from_icon_group(data, language);
-	return res_.remove_resource(pe_resource_viewer::resource_icon_group, icon_group_id, language);
-}
-}

+ 0 - 94
tools/pe_bliss/resource_cursor_icon_writer.h

@@ -1,94 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <vector>
-#include "stdint_defs.h"
-#include "pe_resource_manager.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_cursor_icon_writer
-{
-public:
-	//Determines, how new icon(s) or cursor(s) will be placed
-	enum icon_place_mode
-	{
-		icon_place_after_max_icon_id, //Icon(s) will be placed after all existing
-		icon_place_free_ids //New icon(s) will take all free IDs between existing icons
-	};
-	
-public:
-	resource_cursor_icon_writer(pe_resource_manager& res);
-
-	//Removes icon group and all its icons by name/ID and language
-	bool remove_icon_group(const std::wstring& icon_group_name, uint32_t language);
-	bool remove_icon_group(uint32_t icon_group_id, uint32_t language);
-
-	//Adds icon(s) from icon file data
-	//timestamp will be used for directories that will be added
-	//If icon group with name "icon_group_name" or ID "icon_group_id" already exists, it will be appended with new icon(s)
-	//(Codepage of icon group and icons will not be changed in this case)
-	//icon_place_mode determines, how new icon(s) will be placed
-	void add_icon(const std::string& icon_file,
-		const std::wstring& icon_group_name,
-		uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id,
-		uint32_t codepage = 0, uint32_t timestamp = 0);
-
-	void add_icon(const std::string& icon_file,
-		uint32_t icon_group_id,
-		uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id,
-		uint32_t codepage = 0, uint32_t timestamp = 0);
-	
-	//Removes cursor group and all its cursors by name/ID and language
-	bool remove_cursor_group(const std::wstring& cursor_group_name, uint32_t language);
-	bool remove_cursor_group(uint32_t cursor_group_id, uint32_t language);
-
-	//Adds cursor(s) from cursor file data
-	//timestamp will be used for directories that will be added
-	//If cursor group with name "cursor_group_name" or ID "cursor_group_id" already exists, it will be appended with new cursor(s)
-	//(Codepage of cursor group and cursors will not be changed in this case)
-	//icon_place_mode determines, how new cursor(s) will be placed
-	void add_cursor(const std::string& cursor_file, const std::wstring& cursor_group_name, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0);
-	void add_cursor(const std::string& cursor_file, uint32_t cursor_group_id, uint32_t language, icon_place_mode mode = icon_place_after_max_icon_id, uint32_t codepage = 0, uint32_t timestamp = 0);
-
-private:
-	pe_resource_manager& res_;
-
-	//Add icon helper
-	void add_icon(const std::string& icon_file, const resource_data_info* group_icon_info /* or zero */, resource_directory_entry& new_icon_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp);
-	
-	//Remove icon group helper
-	void remove_icons_from_icon_group(const std::string& icon_group_data, uint32_t language);
-
-	//Add cursor helper
-	void add_cursor(const std::string& cursor_file, const resource_data_info* group_cursor_info /* or zero */, resource_directory_entry& new_cursor_group_entry, const resource_directory::entry_finder& finder, uint32_t language, icon_place_mode mode, uint32_t codepage, uint32_t timestamp);
-
-	//Remove cursor group helper
-	void remove_cursors_from_cursor_group(const std::string& cursor_group_data, uint32_t language);
-
-	//Returns free icon or cursor ID list depending on icon_place_mode
-	const std::vector<uint16_t> get_icon_or_cursor_free_id_list(pe_resource_manager::resource_type type, icon_place_mode mode, uint32_t count);
-};
-}

+ 0 - 48
tools/pe_bliss/resource_data_info.cpp

@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "resource_data_info.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-//Default constructor
-resource_data_info::resource_data_info(const std::string& data, uint32_t codepage)
-	:data_(data), codepage_(codepage)
-{}
-
-//Constructor from data
-resource_data_info::resource_data_info(const resource_data_entry& data)
-	:data_(data.get_data()), codepage_(data.get_codepage())
-{}
-
-//Returns resource data
-const std::string& resource_data_info::get_data() const
-{
-	return data_;
-}
-
-//Returns resource codepage
-uint32_t resource_data_info::get_codepage() const
-{
-	return codepage_;
-}
-}

+ 0 - 48
tools/pe_bliss/resource_data_info.h

@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class resource_data_entry;
-
-//Class representing resource data
-class resource_data_info
-{
-public:
-	//Constructor from data
-	resource_data_info(const std::string& data, uint32_t codepage);
-	//Constructor from data
-	explicit resource_data_info(const resource_data_entry& data);
-
-	//Returns resource data
-	const std::string& get_data() const;
-	//Returns resource codepage
-	uint32_t get_codepage() const;
-
-private:
-	std::string data_;
-	uint32_t codepage_;
-};
-}

+ 0 - 34
tools/pe_bliss/resource_internal.h

@@ -1,34 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-
-#define U16TEXT(t) reinterpret_cast<const unicode16_t*>( t )
-
-#define StringFileInfo U16TEXT("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define SizeofStringFileInfo sizeof("S\0t\0r\0i\0n\0g\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define VarFileInfo U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0")
-#define Translation U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0")
-
-#define VarFileInfoAligned U16TEXT("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0")
-#define TranslationAligned U16TEXT("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0")
-#define SizeofVarFileInfoAligned sizeof("V\0a\0r\0F\0i\0l\0e\0I\0n\0f\0o\0\0\0\0")
-#define SizeofTranslationAligned sizeof("T\0r\0a\0n\0s\0l\0a\0t\0i\0o\0n\0\0\0\0")

+ 0 - 131
tools/pe_bliss/resource_message_list_reader.cpp

@@ -1,131 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "resource_message_list_reader.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_message_list_reader::resource_message_list_reader(const pe_resource_viewer& res)
-	:res_(res)
-{}
-
-//Helper function of parsing message list table
-const resource_message_list resource_message_list_reader::parse_message_list(const std::string& resource_data)
-{
-	resource_message_list ret;
-
-	//Check resource data length
-	if(resource_data.length() < sizeof(message_resource_data))
-		throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
-	const message_resource_data* message_data = reinterpret_cast<const message_resource_data*>(resource_data.data());
-
-	//Check resource data length more carefully and some possible overflows
-	if(message_data->NumberOfBlocks >= pe_utils::max_dword / sizeof(message_resource_block)
-		|| !pe_utils::is_sum_safe(message_data->NumberOfBlocks * sizeof(message_resource_block), sizeof(message_resource_data))
-		|| resource_data.length() < message_data->NumberOfBlocks * sizeof(message_resource_block) + sizeof(message_resource_data))
-		throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
-	//Iterate over all message resource blocks
-	for(unsigned long i = 0; i != message_data->NumberOfBlocks; ++i)
-	{
-		//Get block
-		const message_resource_block* block =
-			reinterpret_cast<const message_resource_block*>(resource_data.data() + sizeof(message_resource_data) - sizeof(message_resource_block) + sizeof(message_resource_block) * i);
-
-		//Check resource data length and IDs
-		if(resource_data.length() < block->OffsetToEntries || block->LowId > block->HighId)
-			throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
-		unsigned long current_pos = 0;
-		static const unsigned long size_of_entry_headers = 4;
-		//List all message resource entries in block
-		for(uint32_t curr_id = block->LowId; curr_id <= block->HighId; curr_id++)
-		{
-			//Check resource data length and some possible overflows
-			if(!pe_utils::is_sum_safe(block->OffsetToEntries, current_pos)
-				|| !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, size_of_entry_headers)
-				|| resource_data.length() < block->OffsetToEntries + current_pos + size_of_entry_headers)
-				throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
-			//Get entry
-			const message_resource_entry* entry = reinterpret_cast<const message_resource_entry*>(resource_data.data() + block->OffsetToEntries + current_pos);
-
-			//Check resource data length and entry length and some possible overflows
-			if(entry->Length < size_of_entry_headers
-				|| !pe_utils::is_sum_safe(block->OffsetToEntries + current_pos, entry->Length)
-				|| resource_data.length() < block->OffsetToEntries + current_pos + entry->Length
-				|| entry->Length < size_of_entry_headers)
-				throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
-			if(entry->Flags & message_resource_unicode)
-			{
-				//If string is UNICODE
-				//Check its length
-				if(entry->Length % 2)
-					throw pe_exception("Incorrect resource message table", pe_exception::resource_incorrect_message_table);
-
-				//Add ID and string to message table
-#ifdef PE_BLISS_WINDOWS
-				ret.insert(std::make_pair(curr_id, message_table_item(
-					std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
-					(entry->Length - size_of_entry_headers) / 2)
-					)));
-#else
-				ret.insert(std::make_pair(curr_id, message_table_item(
-					pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers),
-					(entry->Length - size_of_entry_headers) / 2))
-					)));
-#endif
-			}
-			else
-			{
-				//If string is ANSI
-				//Add ID and string to message table
-				ret.insert(std::make_pair(curr_id, message_table_item(
-					std::string(resource_data.data() + block->OffsetToEntries + current_pos + size_of_entry_headers,
-					entry->Length - size_of_entry_headers)
-					)));
-			}
-
-			//Go to next entry
-			current_pos += entry->Length;
-		}
-	}
-
-	return ret;
-}
-
-//Returns message table data by ID and index in language directory (instead of language)
-const resource_message_list resource_message_list_reader::get_message_table_by_id(uint32_t id, uint32_t index) const
-{
-	return parse_message_list(res_.get_resource_data_by_id(pe_resource_viewer::resource_message_table, id, index).get_data());
-}
-
-//Returns message table data by ID and language
-const resource_message_list resource_message_list_reader::get_message_table_by_id_lang(uint32_t language, uint32_t id) const
-{
-	return parse_message_list(res_.get_resource_data_by_id(language, pe_resource_viewer::resource_message_table, id).get_data());
-}
-}

+ 0 - 49
tools/pe_bliss/resource_message_list_reader.h

@@ -1,49 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "message_table.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-//ID; message_table_item
-typedef std::map<uint32_t, message_table_item> resource_message_list;
-
-class resource_message_list_reader
-{
-public:
-	resource_message_list_reader(const pe_resource_viewer& res);
-
-	//Returns message table data by ID and language
-	const resource_message_list get_message_table_by_id_lang(uint32_t language, uint32_t id) const;
-	//Returns message table data by ID and index in language directory (instead of language)
-	const resource_message_list get_message_table_by_id(uint32_t id, uint32_t index = 0) const;
-
-	//Helper function of parsing message list table
-	//resource_data - raw message table resource data
-	static const resource_message_list parse_message_list(const std::string& resource_data);
-
-private:
-	const pe_resource_viewer& res_;
-};
-}

+ 0 - 109
tools/pe_bliss/resource_string_table_reader.cpp

@@ -1,109 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "resource_string_table_reader.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-resource_string_table_reader::resource_string_table_reader(const pe_resource_viewer& res)
-	:res_(res)
-{}
-
-//Returns string table data by ID and index in language directory (instead of language)
-const resource_string_list resource_string_table_reader::get_string_table_by_id(uint32_t id, uint32_t index) const
-{
-	return parse_string_list(id, res_.get_resource_data_by_id(pe_resource_viewer::resource_string, id, index).get_data());
-}
-
-//Returns string table data by ID and language
-const resource_string_list resource_string_table_reader::get_string_table_by_id_lang(uint32_t language, uint32_t id) const
-{
-	return parse_string_list(id, res_.get_resource_data_by_id(language, pe_resource_viewer::resource_string, id).get_data());
-}
-
-//Helper function of parsing string list table
-const resource_string_list resource_string_table_reader::parse_string_list(uint32_t id, const std::string& resource_data)
-{
-	resource_string_list ret;
-
-	//16 is maximum count of strings in a string table
-	static const unsigned long max_string_list_entries = 16;
-	unsigned long passed_bytes = 0;
-	for(unsigned long i = 0; i != max_string_list_entries; ++i)
-	{
-		//Check resource data length
-		if(resource_data.length() < sizeof(uint16_t) + passed_bytes)
-			throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table);
-
-		//Get string length - the first WORD
-		uint16_t string_length = *reinterpret_cast<const uint16_t*>(resource_data.data() + passed_bytes);
-		passed_bytes += sizeof(uint16_t); //WORD containing string length
-
-		//Check resource data length again
-		if(resource_data.length() < string_length + passed_bytes)
-			throw pe_exception("Incorrect resource string table", pe_exception::resource_incorrect_string_table);
-
-		if(string_length)
-		{
-			//Create and save string (UNICODE)
-#ifdef PE_BLISS_WINDOWS
-			ret.insert(
-				std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way
-				std::wstring(reinterpret_cast<const wchar_t*>(resource_data.data() + passed_bytes), string_length)));
-#else
-			ret.insert(
-				std::make_pair(static_cast<uint16_t>(((id - 1) << 4) + i), //ID of string is calculated such way
-				pe_utils::from_ucs2(u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + passed_bytes), string_length))));
-#endif
-		}
-
-		//Go to next string
-		passed_bytes += string_length * 2;
-	}
-
-	return ret;
-}
-
-//Returns string from string table by ID and language
-const std::wstring resource_string_table_reader::get_string_by_id_lang(uint32_t language, uint16_t id) const
-{
-	//List strings by string table id and language
-	const resource_string_list strings(get_string_table_by_id_lang(language, (id >> 4) + 1));
-	resource_string_list::const_iterator it = strings.find(id); //Find string by id
-	if(it == strings.end())
-		throw pe_exception("Resource string not found", pe_exception::resource_string_not_found);
-
-	return (*it).second;
-}
-
-//Returns string from string table by ID and index in language directory (instead of language)
-const std::wstring resource_string_table_reader::get_string_by_id(uint16_t id, uint32_t index) const
-{
-	//List strings by string table id and index
-	const resource_string_list strings(get_string_table_by_id((id >> 4) + 1, index));
-	resource_string_list::const_iterator it = strings.find(id); //Find string by id
-	if(it == strings.end())
-		throw pe_exception("Resource string not found", pe_exception::resource_string_not_found);
-
-	return (*it).second;
-}
-}

+ 0 - 57
tools/pe_bliss/resource_string_table_reader.h

@@ -1,57 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <string>
-#include <map>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-//ID; string
-typedef std::map<uint16_t, std::wstring> resource_string_list;
-
-class resource_string_table_reader
-{
-public:
-	resource_string_table_reader(const pe_resource_viewer& res);
-
-public:
-	//Returns string table data by ID and language
-	const resource_string_list get_string_table_by_id_lang(uint32_t language, uint32_t id) const;
-	//Returns string table data by ID and index in language directory (instead of language)
-	const resource_string_list get_string_table_by_id(uint32_t id, uint32_t index = 0) const;
-	//Returns string from string table by ID and language
-	const std::wstring get_string_by_id_lang(uint32_t language, uint16_t id) const;
-	//Returns string from string table by ID and index in language directory (instead of language)
-	const std::wstring get_string_by_id(uint16_t id, uint32_t index = 0) const;
-
-private:
-	const pe_resource_viewer& res_;
-
-	//Helper function of parsing string list table
-	//Id of resource is needed to calculate string IDs correctly
-	//resource_data is raw string table resource data
-	static const resource_string_list parse_string_list(uint32_t id, const std::string& resource_data);
-};
-}

+ 0 - 311
tools/pe_bliss/resource_version_info_reader.cpp

@@ -1,311 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include "resource_version_info_reader.h"
-#include "utils.h"
-#include "pe_exception.h"
-#include "resource_internal.h"
-#include "pe_resource_viewer.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-//Root version info block key value
-const u16string resource_version_info_reader::version_info_key(U16TEXT("V\0S\0_\0V\0E\0R\0S\0I\0O\0N\0_\0I\0N\0F\0O\0\0"));
-
-resource_version_info_reader::resource_version_info_reader(const pe_resource_viewer& res)
-	:res_(res)
-{}
-
-//Returns aligned version block value position
-uint32_t resource_version_info_reader::get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key)
-{
-	uint32_t string_length = static_cast<uint32_t>(u16string(key).length());
-	uint32_t ret = pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */
-		+ base_pos
-		+ (string_length + 1 /* nullbyte */) * 2),
-		sizeof(uint32_t));
-
-	//Check possible overflows
-	if(ret < base_pos || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2)
-		throw_incorrect_version_info();
-
-	return ret;
-}
-
-//Returns aligned version block first child position
-uint32_t resource_version_info_reader::get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key)
-{
-	uint32_t string_length = static_cast<uint32_t>(u16string(key).length());
-	uint32_t ret =  pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 /* headers before Key data */
-		+ base_pos
-		+ (string_length + 1 /* nullbyte */) * 2),
-		sizeof(uint32_t))
-		+ pe_utils::align_up(value_length, sizeof(uint32_t));
-
-	//Check possible overflows
-	if(ret < base_pos || ret < value_length || ret < sizeof(uint16_t) * 3 || ret < (string_length + 1) * 2)
-		throw_incorrect_version_info();
-
-	return ret;
-}
-
-//Throws an exception (id = resource_incorrect_version_info)
-void resource_version_info_reader::throw_incorrect_version_info()
-{
-	throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info);
-}
-
-//Returns full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const
-{
-	//Fixed file version info
-	file_version_info ret;
-
-	//Check resource data length
-	if(resource_data.length() < sizeof(version_info_block))
-		throw_incorrect_version_info();
-
-	//Root version info block
-	const version_info_block* root_block = reinterpret_cast<const version_info_block*>(resource_data.data());
-
-	//Check root block key for null-termination and its name
-	if(!pe_utils::is_null_terminated(root_block->Key, resource_data.length() - sizeof(uint16_t) * 3 /* headers before Key data */)
-		|| version_info_key != reinterpret_cast<const unicode16_t*>(root_block->Key))
-		throw_incorrect_version_info();
-
-	//If file has fixed version info
-	if(root_block->ValueLength)
-	{
-		//Get root block value position
-		uint32_t value_pos = get_version_block_value_pos(0, reinterpret_cast<const unicode16_t*>(root_block->Key));
-		//Check value length
-		if(resource_data.length() < value_pos + sizeof(vs_fixedfileinfo))
-			throw_incorrect_version_info();
-
-		//Get VS_FIXEDFILEINFO structure pointer
-		const vs_fixedfileinfo* file_info = reinterpret_cast<const vs_fixedfileinfo*>(resource_data.data() + value_pos);
-		//Check its signature and some other fields
-		if(file_info->dwSignature != vs_ffi_signature || file_info->dwStrucVersion != vs_ffi_strucversion) //Don't check if file_info->dwFileFlagsMask == VS_FFI_FILEFLAGSMASK
-			throw_incorrect_version_info();
-
-		//Save fixed version info
-		ret = file_version_info(*file_info);
-	}
-
-	//Iterate over child elements of VS_VERSIONINFO (StringFileInfo or VarFileInfo)
-	for(uint32_t child_pos = get_version_block_first_child_pos(0, root_block->ValueLength, reinterpret_cast<const unicode16_t*>(root_block->Key));
-		child_pos < root_block->Length;)
-	{
-		//Check block position
-		if(!pe_utils::is_sum_safe(child_pos, sizeof(version_info_block))
-			|| resource_data.length() < child_pos + sizeof(version_info_block))
-			throw_incorrect_version_info();
-
-		//Get VERSION_INFO_BLOCK structure pointer
-		const version_info_block* block = reinterpret_cast<const version_info_block*>(resource_data.data() + child_pos);
-
-		//Check its length
-		if(block->Length == 0)
-			throw_incorrect_version_info();
-
-		//Check block key for null-termination
-		if(!pe_utils::is_null_terminated(block->Key, resource_data.length() - child_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
-			throw_incorrect_version_info();
-
-		u16string info_type(reinterpret_cast<const unicode16_t*>(block->Key));
-		//If we encountered StringFileInfo...
-		if(info_type == StringFileInfo)
-		{
-			//Enumerate all string tables
-			for(uint32_t string_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key));
-				string_table_pos - child_pos < block->Length;)
-			{
-				//Check string table block position
-				if(resource_data.length() < string_table_pos + sizeof(version_info_block))
-					throw_incorrect_version_info();
-
-				//Get VERSION_INFO_BLOCK structure pointer for string table
-				const version_info_block* string_table = reinterpret_cast<const version_info_block*>(resource_data.data() + string_table_pos);
-
-				//Check its length
-				if(string_table->Length == 0)
-					throw_incorrect_version_info();
-
-				//Check string table key for null-termination
-				if(!pe_utils::is_null_terminated(string_table->Key, resource_data.length() - string_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */))	
-					throw_incorrect_version_info();
-
-				string_values_map new_values;
-
-				//Enumerate all strings in the string table
-				for(uint32_t string_pos = get_version_block_first_child_pos(string_table_pos, string_table->ValueLength, reinterpret_cast<const unicode16_t*>(string_table->Key));
-					string_pos - string_table_pos < string_table->Length;)
-				{
-					//Check string block position
-					if(resource_data.length() < string_pos + sizeof(version_info_block))
-						throw_incorrect_version_info();
-
-					//Get VERSION_INFO_BLOCK structure pointer for string block
-					const version_info_block* string_block = reinterpret_cast<const version_info_block*>(resource_data.data() + string_pos);
-
-					//Check its length
-					if(string_block->Length == 0)
-						throw_incorrect_version_info();
-
-					//Check string block key for null-termination
-					if(!pe_utils::is_null_terminated(string_block->Key, resource_data.length() - string_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
-						throw_incorrect_version_info();
-
-					u16string data;
-					//If string block has value
-					if(string_block->ValueLength != 0)
-					{
-						//Get value position
-						uint32_t value_pos = get_version_block_value_pos(string_pos, reinterpret_cast<const unicode16_t*>(string_block->Key));
-						//Check it
-						if(resource_data.length() < value_pos + string_block->ValueLength)
-							throw pe_exception("Incorrect resource version info", pe_exception::resource_incorrect_version_info);
-
-						//Get UNICODE string value
-						data = u16string(reinterpret_cast<const unicode16_t*>(resource_data.data() + value_pos), string_block->ValueLength);
-						pe_utils::strip_nullbytes(data);
-					}
-
-					//Save name-value pair
-#ifdef PE_BLISS_WINDOWS
-					new_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_block->Key), data));
-#else
-					new_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_block->Key)),
-						pe_utils::from_ucs2(data)));
-#endif
-
-					//Navigate to next string block
-					string_pos += pe_utils::align_up(string_block->Length, sizeof(uint32_t));
-				}
-
-#ifdef PE_BLISS_WINDOWS
-				string_values.insert(std::make_pair(reinterpret_cast<const unicode16_t*>(string_table->Key), new_values));
-#else
-				string_values.insert(std::make_pair(pe_utils::from_ucs2(reinterpret_cast<const unicode16_t*>(string_table->Key)), new_values));
-#endif
-
-				//Navigate to next string table block
-				string_table_pos += pe_utils::align_up(string_table->Length, sizeof(uint32_t));
-			}
-		}
-		else if(info_type == VarFileInfo) //If we encountered VarFileInfo
-		{
-			for(uint32_t var_table_pos = get_version_block_first_child_pos(child_pos, block->ValueLength, reinterpret_cast<const unicode16_t*>(block->Key));
-				var_table_pos - child_pos < block->Length;)
-			{
-				//Check var block position
-				if(resource_data.length() < var_table_pos + sizeof(version_info_block))
-					throw_incorrect_version_info();
-
-				//Get VERSION_INFO_BLOCK structure pointer for var block
-				const version_info_block* var_table = reinterpret_cast<const version_info_block*>(resource_data.data() + var_table_pos);
-
-				//Check its length
-				if(var_table->Length == 0)
-					throw_incorrect_version_info();
-
-				//Check its key for null-termination
-				if(!pe_utils::is_null_terminated(var_table->Key, resource_data.length() - var_table_pos - sizeof(uint16_t) * 3 /* headers before Key data */))
-					throw_incorrect_version_info();
-
-				//If block is "Translation" (actually, there's no other types possible in VarFileInfo) and it has value
-				if(u16string(reinterpret_cast<const unicode16_t*>(var_table->Key)) == Translation && var_table->ValueLength)
-				{
-					//Get its value position
-					uint32_t value_pos = get_version_block_value_pos(var_table_pos, reinterpret_cast<const unicode16_t*>(var_table->Key));
-					//Cherck value length
-					if(resource_data.length() < value_pos + var_table->ValueLength)
-						throw_incorrect_version_info();
-
-					//Get list of translations: pairs of LANGUAGE_ID - CODEPAGE_ID
-					for(unsigned long i = 0; i < var_table->ValueLength; i += sizeof(uint16_t) * 2)
-					{
-						//Pair of WORDs
-						uint16_t lang_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + i);
-						uint16_t codepage_id = *reinterpret_cast<const uint16_t*>(resource_data.data() + value_pos + sizeof(uint16_t) + i);
-						//Save translation
-						translations.insert(std::make_pair(lang_id, codepage_id));
-					}
-				}
-
-				//Navigate to next var block
-				var_table_pos += pe_utils::align_up(var_table->Length, sizeof(uint32_t));
-			}
-		}
-		else
-		{
-			throw_incorrect_version_info();
-		}
-
-		//Navigate to next element in root block
-		child_pos += pe_utils::align_up(block->Length, sizeof(uint32_t));
-	}
-
-	return ret;
-}
-
-//Returns full version information:
-//file_version info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const
-{
-	const std::string& resource_data = res_.get_root_directory() //Type directory
-		.entry_by_id(pe_resource_viewer::resource_version)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(1)
-		.get_resource_directory() //Language directory
-		.entry_by_id(language)
-		.get_data_entry() //Data directory
-		.get_data();
-
-	return get_version_info(string_values, translations, resource_data);
-}
-
-//Returns full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-const file_version_info resource_version_info_reader::get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index) const
-{
-	const resource_directory::entry_list& entries = res_.get_root_directory() //Type directory
-		.entry_by_id(pe_resource_viewer::resource_version)
-		.get_resource_directory() //Name/ID directory
-		.entry_by_id(1)
-		.get_resource_directory() //Language directory
-		.get_entry_list();
-
-	if(entries.size() <= index)
-		throw pe_exception("Resource data entry not found", pe_exception::resource_data_entry_not_found);
-
-	return get_version_info(string_values, translations, entries.at(index).get_data_entry().get_data()); //Data directory
-}
-}

+ 0 - 67
tools/pe_bliss/resource_version_info_reader.h

@@ -1,67 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include "file_version_info.h"
-#include "pe_structures.h"
-#include "version_info_types.h"
-
-namespace pe_bliss
-{
-class pe_resource_viewer;
-
-class resource_version_info_reader
-{
-public: //VERSION INFO
-	resource_version_info_reader(const pe_resource_viewer& res);
-
-	//Returns full version information:
-	//file_version_info: versions and file info
-	//lang_lang_string_values_map: map of version info strings with encodings with encodings
-	//translation_values_map: map of translations
-	const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, uint32_t index = 0) const;
-	const file_version_info get_version_info_by_lang(lang_string_values_map& string_values, translation_values_map& translations, uint32_t language) const;
-
-public:
-	//L"VS_VERSION_INFO" key of root version info block
-	static const u16string version_info_key;
-
-private:
-	const pe_resource_viewer& res_;
-	
-	//VERSION INFO helpers
-	//Returns aligned version block value position
-	static uint32_t get_version_block_value_pos(uint32_t base_pos, const unicode16_t* key);
-
-	//Returns aligned version block first child position
-	static uint32_t get_version_block_first_child_pos(uint32_t base_pos, uint32_t value_length, const unicode16_t* key);
-
-	//Returns full version information:
-	//file_version_info: versions and file info
-	//lang_string_values_map: map of version info strings with encodings
-	//translation_values_map: map of translations
-	const file_version_info get_version_info(lang_string_values_map& string_values, translation_values_map& translations, const std::string& resource_data) const;
-
-	//Throws an exception (id = resource_incorrect_version_info)
-	static void throw_incorrect_version_info();
-};
-}

+ 0 - 283
tools/pe_bliss/resource_version_info_writer.cpp

@@ -1,283 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "resource_version_info_writer.h"
-#include "pe_structures.h"
-#include "resource_internal.h"
-#include "utils.h"
-#include "pe_resource_manager.h"
-#include "resource_version_info_reader.h"
-
-namespace pe_bliss
-{
-using namespace pe_win;
-
-resource_version_info_writer::resource_version_info_writer(pe_resource_manager& res)
-	:res_(res)
-{}
-
-//Sets/replaces full version information:
-//file_version_info: versions and file info
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-void resource_version_info_writer::set_version_info(const file_version_info& file_info,
-	const lang_string_values_map& string_values,
-	const translation_values_map& translations,
-	uint32_t language,
-	uint32_t codepage,
-	uint32_t timestamp)
-{
-	std::string version_data;
-
-	//Calculate total size of version resource data
-	uint32_t total_version_info_length =
-		static_cast<uint32_t>(sizeof(version_info_block) - sizeof(uint16_t) + sizeof(uint16_t) /* pading */
-		+ (resource_version_info_reader::version_info_key.length() + 1) * 2
-		+ sizeof(vs_fixedfileinfo));
-
-	//If we have any strings values
-	if(!string_values.empty())
-	{
-		total_version_info_length += sizeof(version_info_block) - sizeof(uint16_t); //StringFileInfo block
-		total_version_info_length += SizeofStringFileInfo; //Name of block (key)
-
-		//Add required size for version strings
-		for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it)
-		{
-			total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*table_it).first.length() + 1) * 2), sizeof(uint32_t)); //Name of child block and block size (key of string table block)
-
-			const string_values_map& values = (*table_it).second;
-			for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it)
-			{
-				total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(sizeof(uint16_t) * 3 + ((*it).first.length() + 1) * 2), sizeof(uint32_t));
-				total_version_info_length += pe_utils::align_up(static_cast<uint32_t>(((*it).second.length() + 1) * 2), sizeof(uint32_t));
-			}
-		}
-	}
-
-	//If we have translations
-	if(!translations.empty())
-	{
-		total_version_info_length += (sizeof(version_info_block) - sizeof(uint16_t)) * 2; //VarFileInfo and Translation blocks
-		total_version_info_length += SizeofVarFileInfoAligned; //DWORD-aligned VarFileInfo block name
-		total_version_info_length += SizeofTranslationAligned; //DWORD-aligned Translation block name
-		total_version_info_length += static_cast<uint32_t>(translations.size() * sizeof(uint16_t) * 2);
-	}
-
-	//Resize version data buffer
-	version_data.resize(total_version_info_length);
-
-	//Create root version block
-	version_info_block root_block = {0};
-	root_block.ValueLength = sizeof(vs_fixedfileinfo);
-	root_block.Length = static_cast<uint16_t>(total_version_info_length);
-
-	//Fill fixed file info
-	vs_fixedfileinfo fixed_info = {0};
-	fixed_info.dwFileDateLS = file_info.get_file_date_ls();
-	fixed_info.dwFileDateMS = file_info.get_file_date_ms();
-	fixed_info.dwFileFlags = file_info.get_file_flags();
-	fixed_info.dwFileFlagsMask = vs_ffi_fileflagsmask;
-	fixed_info.dwFileOS = file_info.get_file_os_raw();
-	fixed_info.dwFileSubtype = file_info.get_file_subtype();
-	fixed_info.dwFileType = file_info.get_file_type_raw();
-	fixed_info.dwFileVersionLS = file_info.get_file_version_ls();
-	fixed_info.dwFileVersionMS = file_info.get_file_version_ms();
-	fixed_info.dwSignature = vs_ffi_signature;
-	fixed_info.dwStrucVersion = vs_ffi_strucversion;
-	fixed_info.dwProductVersionLS = file_info.get_product_version_ls();
-	fixed_info.dwProductVersionMS = file_info.get_product_version_ms();
-
-	//Write root block and fixed file info to buffer
-	uint32_t data_ptr = 0;
-	memcpy(&version_data[data_ptr], &root_block, sizeof(version_info_block) - sizeof(uint16_t));
-	data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-	memcpy(&version_data[data_ptr], resource_version_info_reader::version_info_key.c_str(), (resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t));
-	data_ptr += static_cast<uint32_t>((resource_version_info_reader::version_info_key.length() + 1) * sizeof(uint16_t));
-	memset(&version_data[data_ptr], 0, sizeof(uint16_t));
-	data_ptr += sizeof(uint16_t);
-	memcpy(&version_data[data_ptr], &fixed_info, sizeof(fixed_info));
-	data_ptr += sizeof(fixed_info);
-
-	//Write string values, if any
-	if(!string_values.empty())
-	{
-		//Create string file info root block
-		version_info_block string_file_info_block = {0};
-		string_file_info_block.Type = 1; //Block type is string
-		memcpy(&version_data[data_ptr], &string_file_info_block, sizeof(version_info_block) - sizeof(uint16_t));
-		//We will calculate its length later
-		version_info_block* string_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
-		data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-		uint32_t old_ptr1 = data_ptr; //Used to calculate string file info block length later
-		memcpy(&version_data[data_ptr], StringFileInfo, SizeofStringFileInfo); //Write block name
-		data_ptr += SizeofStringFileInfo;
-
-		//Create string table root block (child of string file info)
-		version_info_block string_table_block = {0};
-		string_table_block.Type = 1; //Block type is string
-
-		for(lang_string_values_map::const_iterator table_it = string_values.begin(); table_it != string_values.end(); ++table_it)
-		{
-			const string_values_map& values = (*table_it).second;
-
-			memcpy(&version_data[data_ptr], &string_table_block, sizeof(version_info_block) - sizeof(uint16_t));
-			//We will calculate its length later
-			version_info_block* string_table_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
-			data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-			uint32_t old_ptr2 = data_ptr; //Used to calculate string table block length later
-			uint32_t lang_key_length = static_cast<uint32_t>(((*table_it).first.length() + 1) * sizeof(uint16_t));
-
-#ifdef PE_BLISS_WINDOWS
-			memcpy(&version_data[data_ptr], (*table_it).first.c_str(), lang_key_length); //Write block key
-#else
-			{
-				u16string str(pe_utils::to_ucs2((*table_it).first));
-				memcpy(&version_data[data_ptr], str.c_str(), lang_key_length); //Write block key
-			}
-#endif
-
-			data_ptr += lang_key_length;
-			//Align key if necessary
-			if((sizeof(uint16_t) * 3 + lang_key_length) % sizeof(uint32_t))
-			{
-				memset(&version_data[data_ptr], 0, sizeof(uint16_t));
-				data_ptr += sizeof(uint16_t);
-			}
-
-			//Create string block (child of string table block)
-			version_info_block string_block = {0};
-			string_block.Type = 1; //Block type is string
-			for(string_values_map::const_iterator it = values.begin(); it != values.end(); ++it)
-			{
-				//Calculate value length and key length of string block
-				string_block.ValueLength = static_cast<uint16_t>((*it).second.length() + 1);
-				uint32_t key_length = static_cast<uint32_t>(((*it).first.length() + 1) * sizeof(uint16_t));
-				//Calculate length of block
-				string_block.Length = static_cast<uint16_t>(pe_utils::align_up(sizeof(uint16_t) * 3 + key_length, sizeof(uint32_t)) + string_block.ValueLength * sizeof(uint16_t));
-
-				//Write string block
-				memcpy(&version_data[data_ptr], &string_block, sizeof(version_info_block) - sizeof(uint16_t));
-				data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-#ifdef PE_BLISS_WINDOWS
-				memcpy(&version_data[data_ptr], (*it).first.c_str(), key_length); //Write block key
-#else
-				{
-					u16string str(pe_utils::to_ucs2((*it).first));
-					memcpy(&version_data[data_ptr], str.c_str(), key_length); //Write block key
-				}
-#endif
-
-				data_ptr += key_length;
-				//Align key if necessary
-				if((sizeof(uint16_t) * 3 + key_length) % sizeof(uint32_t))
-				{
-					memset(&version_data[data_ptr], 0, sizeof(uint16_t));
-					data_ptr += sizeof(uint16_t);
-				}
-
-				//Write block data (value)
-#ifdef PE_BLISS_WINDOWS
-				memcpy(&version_data[data_ptr], (*it).second.c_str(), string_block.ValueLength * sizeof(uint16_t));
-#else
-				{
-					u16string str(pe_utils::to_ucs2((*it).second));
-					memcpy(&version_data[data_ptr], str.c_str(), string_block.ValueLength * sizeof(uint16_t));
-				}
-#endif
-
-				data_ptr += string_block.ValueLength * 2;
-				//Align data if necessary
-				if((string_block.ValueLength * 2) % sizeof(uint32_t))
-				{
-					memset(&version_data[data_ptr], 0, sizeof(uint16_t));
-					data_ptr += sizeof(uint16_t);
-				}
-			}
-
-			//Calculate string table and string file info blocks lengths
-			string_table_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3);
-		}
-
-		string_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3);
-	}
-
-	//If we have transactions
-	if(!translations.empty())
-	{
-		//Create root var file info block
-		version_info_block var_file_info_block = {0};
-		var_file_info_block.Type = 1; //Type of block is string
-		//Write block header
-		memcpy(&version_data[data_ptr], &var_file_info_block, sizeof(version_info_block) - sizeof(uint16_t));
-		//We will calculate its length later
-		version_info_block* var_file_info_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
-		data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-		uint32_t old_ptr1 = data_ptr; //Used to calculate var file info block length later
-		memcpy(&version_data[data_ptr], VarFileInfoAligned, SizeofVarFileInfoAligned); //Write block key (aligned)
-		data_ptr += SizeofVarFileInfoAligned;
-
-		//Create root translation block (child of var file info block)
-		version_info_block translation_block = {0};
-		//Write block header
-		memcpy(&version_data[data_ptr], &translation_block, sizeof(version_info_block) - sizeof(uint16_t));
-		//We will calculate its length later
-		version_info_block* translation_block_ptr = reinterpret_cast<version_info_block*>(&version_data[data_ptr]);
-		data_ptr += sizeof(version_info_block) - sizeof(uint16_t);
-
-		uint32_t old_ptr2 = data_ptr; //Used to calculate var file info block length later
-		memcpy(&version_data[data_ptr], TranslationAligned, SizeofTranslationAligned); //Write block key (aligned)
-		data_ptr += SizeofTranslationAligned;
-
-		//Calculate translation block value length
-		translation_block_ptr->ValueLength = static_cast<uint16_t>(sizeof(uint16_t) * 2 * translations.size());
-
-		//Write translation values to block
-		for(translation_values_map::const_iterator it = translations.begin(); it != translations.end(); ++it)
-		{
-			uint16_t lang_id = (*it).first; //Language ID
-			uint16_t codepage_id = (*it).second; //Codepage ID
-			memcpy(&version_data[data_ptr], &lang_id, sizeof(lang_id));
-			data_ptr += sizeof(lang_id);
-			memcpy(&version_data[data_ptr], &codepage_id, sizeof(codepage_id));
-			data_ptr += sizeof(codepage_id);
-		}
-
-		//Calculate Translation and VarFileInfo blocks lengths
-		translation_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr2 + sizeof(uint16_t) * 3);
-		var_file_info_block_ptr->Length = static_cast<uint16_t>(data_ptr - old_ptr1 + sizeof(uint16_t) * 3);
-	}
-
-	//Add/replace version info resource
-	res_.add_resource(version_data, pe_resource_viewer::resource_version, 1, language, codepage, timestamp);
-}
-
-//Removes version info by language (ID = 1)
-bool resource_version_info_writer::remove_version_info(uint32_t language)
-{
-	return res_.remove_resource(pe_resource_viewer::resource_version, 1, language);
-}
-}

+ 0 - 52
tools/pe_bliss/resource_version_info_writer.h

@@ -1,52 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "version_info_types.h"
-#include "file_version_info.h"
-
-namespace pe_bliss
-{
-class pe_resource_manager;
-
-class resource_version_info_writer
-{
-public:
-	resource_version_info_writer(pe_resource_manager& res);
-	
-	//Sets/replaces full version information:
-	//file_version_info: versions and file info
-	//lang_string_values_map: map of version info strings with encodings
-	//translation_values_map: map of translations
-	void set_version_info(const file_version_info& file_info,
-		const lang_string_values_map& string_values,
-		const translation_values_map& translations,
-		uint32_t language,
-		uint32_t codepage = 0,
-		uint32_t timestamp = 0);
-	
-	//Removes version info by language (ID = 1)
-	bool remove_version_info(uint32_t language);
-
-private:
-	pe_resource_manager& res_;
-};
-}

+ 0 - 45
tools/pe_bliss/stdint_defs.h

@@ -1,45 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#ifdef _MSC_VER
-#if _MSC_VER < 1600
-namespace pe_bliss
-{
-	//stdint.h definitions for MSVC 2008 and earlier, as
-	//it doesn't have them
-	typedef signed char int8_t;
-	typedef short int16_t;
-	typedef int int32_t;
-
-	typedef unsigned char uint8_t;
-	typedef unsigned short uint16_t;
-	typedef unsigned int uint32_t;
-
-	typedef long long int64_t;
-	typedef unsigned long long uint64_t;
-}
-#else
-#include <stdint.h>
-#endif
-#else
-#include <stdint.h>
-#endif

+ 0 - 85
tools/pe_bliss/utils.cpp

@@ -1,85 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <string.h>
-#include "utils.h"
-#include "pe_exception.h"
-
-
-namespace pe_bliss
-{
-const double pe_utils::log_2 = 1.44269504088896340736; //instead of using M_LOG2E
-
-//Returns stream size
-std::streamoff pe_utils::get_file_size(std::istream& file)
-{
-	//Get old istream offset
-	std::streamoff old_offset = file.tellg();
-	file.seekg(0, std::ios::end);
-	std::streamoff filesize = file.tellg();
-	//Set old istream offset
-	file.seekg(old_offset);
-	return filesize;
-}
-
-#ifndef PE_BLISS_WINDOWS
-const u16string pe_utils::to_ucs2(const std::wstring& str)
-{
-	u16string ret;
-	if(str.empty())
-		return ret;
-
-	int len = str.length();
-	
-	ret.resize(len);
-	
-	for(int i=0;i<len;i++) {
-		ret[i]=str[i]&0xFFFF;
-	}
-
-	return ret;
-}
-
-const std::wstring pe_utils::from_ucs2(const u16string& str)
-{
-	std::wstring ret;
-	if(str.empty())
-		return ret;
-
-	int len = str.length();
-	ret.resize(str.length());
-	
-	for(int i=0;i<len;i++) {
-		ret[i]=str[i];
-	}
-
-	return ret;
-}
-#endif
-
-bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2)
-{
-	return guid1.Data1 == guid2.Data1
-		&& guid1.Data2 == guid2.Data2
-		&& guid1.Data3 == guid2.Data3
-		&& !memcmp(guid1.Data4, guid2.Data4, sizeof(guid1.Data4));
-}
-}

+ 0 - 105
tools/pe_bliss/utils.h

@@ -1,105 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <istream>
-#include <string>
-#include "stdint_defs.h"
-#include "pe_structures.h"
-
-namespace pe_bliss
-{
-class pe_utils
-{
-public:
-	//Returns true if string "data" with maximum length "raw_length" is null-terminated
-	template<typename T>
-	static bool is_null_terminated(const T* data, size_t raw_length)
-	{
-		raw_length /= sizeof(T);
-		for(size_t l = 0; l < raw_length; l++)
-		{
-			if(data[l] == static_cast<T>(L'\0'))
-				return true;
-		}
-
-		return false;
-	}
-
-	//Helper template function to strip nullbytes in the end of string
-	template<typename T>
-	static void strip_nullbytes(std::basic_string<T>& str)
-	{
-		while(!*(str.end() - 1) && !str.empty())
-			str.erase(str.length() - 1);
-	}
-
-	//Helper function to determine if number is power of 2
-	template<typename T>
-	static inline bool is_power_of_2(T x)
-	{
-		return !(x & (x - 1));
-	}
-
-	//Helper function to align number down
-	template<typename T>
-	static inline T align_down(T x, uint32_t align)
-	{
-		return x & ~(static_cast<T>(align) - 1);
-	}
-
-	//Helper function to align number up
-	template<typename T>
-	static inline T align_up(T x, uint32_t align)
-	{
-		return (x & static_cast<T>(align - 1)) ? align_down(x, align) + static_cast<T>(align) : x;
-	}
-
-	//Returns true if sum of two unsigned integers is safe (no overflow occurs)
-	static inline bool is_sum_safe(uint32_t a, uint32_t b)
-	{
-		return a <= static_cast<uint32_t>(-1) - b;
-	}
-
-	//Two gigabytes value in bytes
-	static const uint32_t two_gb = 0x80000000;
-	static const uint32_t max_dword = 0xFFFFFFFF;
-	static const uint32_t max_word = 0x0000FFFF;
-	static const double log_2; //instead of using M_LOG2E
-
-	//Returns stream size
-	static std::streamoff get_file_size(std::istream& file);
-	
-#ifndef PE_BLISS_WINDOWS
-public:
-	static const u16string to_ucs2(const std::wstring& str);
-	static const std::wstring from_ucs2(const u16string& str);
-#endif
-
-private:
-	pe_utils();
-	pe_utils(pe_utils&);
-	pe_utils& operator=(const pe_utils&);
-};
-
-//Windows GUID comparison
-bool operator==(const pe_win::guid& guid1, const pe_win::guid& guid2);
-}

+ 0 - 184
tools/pe_bliss/version_info_editor.cpp

@@ -1,184 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <sstream>
-#include <iomanip>
-#include "version_info_types.h"
-#include "version_info_editor.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-//Default constructor
-//strings - version info strings with charsets
-//translations - version info translations map
-version_info_editor::version_info_editor(lang_string_values_map& strings, translation_values_map& translations)
-	:version_info_viewer(strings, translations),
-	strings_edit_(strings),
-	translations_edit_(translations)
-{}
-
-//Below functions have parameter translation
-//If it's empty, the default language translation will be taken
-//If there's no default language translation, the first one will be taken
-
-//Sets company name
-void version_info_editor::set_company_name(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"CompanyName", value, translation);
-}
-
-//Sets file description
-void version_info_editor::set_file_description(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"FileDescription", value, translation);
-}
-
-//Sets file version
-void version_info_editor::set_file_version(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"FileVersion", value, translation);
-}
-
-//Sets internal file name
-void version_info_editor::set_internal_name(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"InternalName", value, translation);
-}
-
-//Sets legal copyright
-void version_info_editor::set_legal_copyright(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"LegalCopyright", value, translation);
-}
-
-//Sets original file name
-void version_info_editor::set_original_filename(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"OriginalFilename", value, translation);
-}
-
-//Sets product name
-void version_info_editor::set_product_name(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"ProductName", value, translation);
-}
-
-//Sets product version
-void version_info_editor::set_product_version(const std::wstring& value, const std::wstring& translation)
-{
-	set_property(L"ProductVersion", value, translation);
-}
-
-//Sets version info property value
-//property_name - property name
-//value - property value
-//If translation does not exist, it will be added
-//If property does not exist, it will be added
-void version_info_editor::set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation)
-{
-	lang_string_values_map::iterator it = strings_edit_.begin();
-
-	if(translation.empty())
-	{
-		//If no translation was specified
-		it = strings_edit_.find(default_language_translation); //Find default translation table
-		if(it == strings_edit_.end()) //If there's no default translation table, take the first one
-		{
-			it = strings_edit_.begin();
-			if(it == strings_edit_.end()) //If there's no any translation table, add default one
-			{
-				it = strings_edit_.insert(std::make_pair(default_language_translation, string_values_map())).first;
-				//Also add it to translations list
-				add_translation(default_language_translation);
-			}
-		}
-	}
-	else
-	{
-		it = strings_edit_.find(translation); //Find specified translation table
-		if(it == strings_edit_.end()) //If there's no translation, add it
-		{
-			it = strings_edit_.insert(std::make_pair(translation, string_values_map())).first;
-			//Also add it to translations list
-			add_translation(translation);
-		}
-	}
-
-	//Change value of the required property
-	((*it).second)[property_name] = value;
-}
-
-//Adds translation to translation list
-void version_info_editor::add_translation(const std::wstring& translation)
-{
-	std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation));
-	add_translation(translation_ids.first, translation_ids.second);
-}
-
-void version_info_editor::add_translation(uint16_t language_id, uint16_t codepage_id)
-{
-	std::pair<translation_values_map::const_iterator, translation_values_map::const_iterator>
-		range(translations_edit_.equal_range(language_id));
-
-	//If translation already exists
-	for(translation_values_map::const_iterator it = range.first; it != range.second; ++it)
-	{
-		if((*it).second == codepage_id)
-			return;
-	}
-
-	translations_edit_.insert(std::make_pair(language_id, codepage_id));
-}
-
-//Removes translation from translations and strings lists
-void version_info_editor::remove_translation(const std::wstring& translation)
-{
-	std::pair<uint16_t, uint16_t> translation_ids(translation_from_string(translation));
-	remove_translation(translation_ids.first, translation_ids.second);
-}
-
-void version_info_editor::remove_translation(uint16_t language_id, uint16_t codepage_id)
-{
-	{
-		//Erase string table (if exists)
-		std::wstringstream ss;
-		ss << std::hex
-			<< std::setw(4) << std::setfill(L'0') << language_id
-			<< std::setw(4) << std::setfill(L'0') << codepage_id;
-		
-		strings_edit_.erase(ss.str());
-	}
-
-	//Find and erase translation from translations table
-	std::pair<translation_values_map::iterator, translation_values_map::iterator>
-		it_pair = translations_edit_.equal_range(language_id);
-
-	for(translation_values_map::iterator it = it_pair.first; it != it_pair.second; ++it)
-	{
-		if((*it).second == codepage_id)
-		{
-			translations_edit_.erase(it);
-			break;
-		}
-	}
-}
-}

+ 0 - 79
tools/pe_bliss/version_info_editor.h

@@ -1,79 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include "version_info_types.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-	//Helper class to read and edit version information
-	//lang_string_values_map: map of version info strings with encodings
-	//translation_values_map: map of translations
-	class version_info_editor : public version_info_viewer
-	{
-	public:
-		//Default constructor
-		//strings - version info strings with charsets
-		//translations - version info translations map
-		version_info_editor(lang_string_values_map& strings, translation_values_map& translations);
-
-		//Below functions have parameter translation
-		//If it's empty, the default language translation will be taken
-		//If there's no default language translation, the first one will be taken
-
-		//Sets company name
-		void set_company_name(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets file description
-		void set_file_description(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets file version
-		void set_file_version(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets internal file name
-		void set_internal_name(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets legal copyright
-		void set_legal_copyright(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets original file name
-		void set_original_filename(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets product name
-		void set_product_name(const std::wstring& value, const std::wstring& translation = std::wstring());
-		//Sets product version
-		void set_product_version(const std::wstring& value, const std::wstring& translation = std::wstring());
-
-		//Sets version info property value
-		//property_name - property name
-		//value - property value
-		//If translation does not exist, it will be added to strings and translations lists
-		//If property does not exist, it will be added
-		void set_property(const std::wstring& property_name, const std::wstring& value, const std::wstring& translation = std::wstring());
-
-		//Adds translation to translation list
-		void add_translation(const std::wstring& translation);
-		void add_translation(uint16_t language_id, uint16_t codepage_id);
-
-		//Removes translation from translations and strings lists
-		void remove_translation(const std::wstring& translation);
-		void remove_translation(uint16_t language_id, uint16_t codepage_id);
-
-	private:
-		lang_string_values_map& strings_edit_;
-		translation_values_map& translations_edit_;
-	};
-}

+ 0 - 38
tools/pe_bliss/version_info_types.h

@@ -1,38 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <string>
-#include "stdint_defs.h"
-
-namespace pe_bliss
-{
-	//Typedef for version info functions: Name - Value
-	typedef std::map<std::wstring, std::wstring> string_values_map;
-	//Typedef for version info functions: Language string - String Values Map
-	//Language String consists of LangID and CharsetID
-	//E.g. 041904b0 for Russian UNICODE, 040004b0 for Process Default Language UNICODE
-	typedef std::map<std::wstring, string_values_map> lang_string_values_map;
-
-	//Typedef for version info functions: Language - Character Set
-	typedef std::multimap<uint16_t, uint16_t> translation_values_map;
-}

+ 0 - 180
tools/pe_bliss/version_info_viewer.cpp

@@ -1,180 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#include <iomanip>
-#include <sstream>
-#include "pe_exception.h"
-#include "version_info_viewer.h"
-
-namespace pe_bliss
-{
-//Default process language, UNICODE
-const std::wstring version_info_viewer::default_language_translation(L"040904b0");
-
-//Default constructor
-//strings - version info strings with charsets
-//translations - version info translations map
-version_info_viewer::version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations)
-	:strings_(strings), translations_(translations)
-{}
-
-//Below functions have parameter translation
-//If it's empty, the default language translation will be taken
-//If there's no default language translation, the first one will be taken
-
-//Returns company name
-const std::wstring version_info_viewer::get_company_name(const std::wstring& translation) const
-{
-	return get_property(L"CompanyName", translation);
-}
-
-//Returns file description
-const std::wstring version_info_viewer::get_file_description(const std::wstring& translation) const
-{
-	return get_property(L"FileDescription", translation);
-}
-
-//Returns file version
-const std::wstring version_info_viewer::get_file_version(const std::wstring& translation) const
-{
-	return get_property(L"FileVersion", translation);
-}
-
-//Returns internal file name
-const std::wstring version_info_viewer::get_internal_name(const std::wstring& translation) const
-{
-	return get_property(L"InternalName", translation);
-}
-
-//Returns legal copyright
-const std::wstring version_info_viewer::get_legal_copyright(const std::wstring& translation) const
-{
-	return get_property(L"LegalCopyright", translation);
-}
-
-//Returns original file name
-const std::wstring version_info_viewer::get_original_filename(const std::wstring& translation) const
-{
-	return get_property(L"OriginalFilename", translation);
-}
-
-//Returns product name
-const std::wstring version_info_viewer::get_product_name(const std::wstring& translation) const
-{
-	return get_property(L"ProductName", translation);
-}
-
-//Returns product version
-const std::wstring version_info_viewer::get_product_version(const std::wstring& translation) const
-{
-	return get_property(L"ProductVersion", translation);
-}
-
-//Returns list of translations in string representation
-const version_info_viewer::translation_list version_info_viewer::get_translation_list() const
-{
-	translation_list ret;
-
-	//Enumerate all translations
-	for(translation_values_map::const_iterator it = translations_.begin(); it != translations_.end(); ++it)
-	{
-		//Create string representation of translation value
-		std::wstringstream ss;
-		ss << std::hex
-			<< std::setw(4) << std::setfill(L'0') << (*it).first
-			<< std::setw(4) << std::setfill(L'0') <<  (*it).second;
-
-		//Save it
-		ret.push_back(ss.str());
-	}
-
-	return ret;
-}
-
-//Returns version info property value
-//property_name - required property name
-//If throw_if_absent = true, will throw exception if property does not exist
-//If throw_if_absent = false, will return empty string if property does not exist
-const std::wstring version_info_viewer::get_property(const std::wstring& property_name, const std::wstring& translation, bool throw_if_absent) const
-{
-	std::wstring ret;
-
-	//If there're no strings
-	if(strings_.empty())
-	{
-		if(throw_if_absent)
-			throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
-		return ret;
-	}
-	
-	lang_string_values_map::const_iterator it = strings_.begin();
-
-	if(translation.empty())
-	{
-		//If no translation was specified
-		it = strings_.find(default_language_translation); //Find default translation table
-		if(it == strings_.end()) //If there's no default translation table, take the first one
-			it = strings_.begin();
-	}
-	else
-	{
-		it = strings_.find(translation); //Find specified translation table
-		if(it == strings_.end())
-		{
-			if(throw_if_absent)
-				throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
-			return ret;
-		}
-	}
-	
-	//Find value of the required property
-	string_values_map::const_iterator str_it = (*it).second.find(property_name);
-
-	if(str_it == (*it).second.end())
-	{
-		if(throw_if_absent)
-			throw pe_exception("Version info string does not exist", pe_exception::version_info_string_does_not_exist);
-
-		return ret;
-	}
-
-	ret = (*str_it).second;
-
-	return ret;
-}
-
-//Converts translation HEX-string to pair of language ID and codepage ID
-const version_info_viewer::translation_pair version_info_viewer::translation_from_string(const std::wstring& translation)
-{
-	uint32_t translation_id = 0;
-
-	{
-		//Convert string to DWORD
-		std::wstringstream ss;
-		ss << std::hex << translation;
-		ss >> translation_id;
-	}
-
-	return std::make_pair(static_cast<uint16_t>(translation_id >> 16), static_cast<uint16_t>(translation_id & 0xFFFF));
-}
-}

+ 0 - 89
tools/pe_bliss/version_info_viewer.h

@@ -1,89 +0,0 @@
-/*************************************************************************/
-/* Copyright (c) 2015 dx, http://kaimi.ru                                */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person           */
-/* obtaining a copy of this software and associated documentation        */
-/* files (the "Software"), to deal in the Software without               */
-/* restriction, including without limitation the rights to use,          */
-/* copy, modify, merge, publish, distribute, sublicense, and/or          */
-/* sell copies of the Software, and to permit persons to whom the        */
-/* Software is furnished to do so, subject to the following conditions:  */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-#pragma once
-#include <map>
-#include <vector>
-#include <string>
-#include "pe_resource_viewer.h"
-#include "pe_structures.h"
-#include "version_info_types.h"
-
-namespace pe_bliss
-{
-//Helper class to read version information
-//lang_string_values_map: map of version info strings with encodings
-//translation_values_map: map of translations
-class version_info_viewer
-{
-public:
-	//Useful typedefs
-	typedef std::pair<uint16_t, uint16_t> translation_pair;
-	typedef std::vector<std::wstring> translation_list;
-
-public:
-	//Default constructor
-	//strings - version info strings with charsets
-	//translations - version info translations map
-	version_info_viewer(const lang_string_values_map& strings, const translation_values_map& translations);
-
-	//Below functions have parameter translation
-	//If it's empty, the default language translation will be taken
-	//If there's no default language translation, the first one will be taken
-
-	//Returns company name
-	const std::wstring get_company_name(const std::wstring& translation = std::wstring()) const;
-	//Returns file description
-	const std::wstring get_file_description(const std::wstring& translation = std::wstring()) const;
-	//Returns file version
-	const std::wstring get_file_version(const std::wstring& translation = std::wstring()) const;
-	//Returns internal file name
-	const std::wstring get_internal_name(const std::wstring& translation = std::wstring()) const;
-	//Returns legal copyright
-	const std::wstring get_legal_copyright(const std::wstring& translation = std::wstring()) const;
-	//Returns original file name
-	const std::wstring get_original_filename(const std::wstring& translation = std::wstring()) const;
-	//Returns product name
-	const std::wstring get_product_name(const std::wstring& translation = std::wstring()) const;
-	//Returns product version
-	const std::wstring get_product_version(const std::wstring& translation = std::wstring()) const;
-
-	//Returns list of translations in string representation
-	const translation_list get_translation_list() const;
-
-	//Returns version info property value
-	//property_name - required property name
-	//If throw_if_absent = true, will throw exception if property does not exist
-	//If throw_if_absent = false, will return empty string if property does not exist
-	const std::wstring get_property(const std::wstring& property_name, const std::wstring& translation = std::wstring(), bool throw_if_absent = false) const;
-
-	//Converts translation HEX-string to pair of language ID and codepage ID
-	static const translation_pair translation_from_string(const std::wstring& translation);
-
-public:
-	//Default process language, UNICODE
-	static const std::wstring default_language_translation;
-
-private:
-	const lang_string_values_map& strings_;
-	const translation_values_map& translations_;
-};
-}