├── .appveyor.yml ├── CMakeLists.txt ├── README.md └── main.cpp /.appveyor.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - Visual Studio 2015 3 | 4 | platform: 5 | - x64 6 | 7 | branches: 8 | only: 9 | - master 10 | 11 | install: 12 | - set PATH=C:\Program Files\CMake\bin;%PATH% 13 | 14 | build: 15 | verbosity: detailed 16 | 17 | configuration: 18 | - Release 19 | 20 | environment: 21 | artifactName: $(APPVEYOR_PROJECT_NAME)-$(APPVEYOR_REPO_COMMIT)-$(CONFIGURATION) 22 | matrix: 23 | - env_arch: "x64" 24 | - env_arch: "x86" 25 | 26 | before_build: 27 | - mkdir build 28 | - cd build 29 | - if [%env_arch%]==[x64] ( 30 | cmake .. -A x64 ) 31 | - if [%env_arch%]==[x86] ( 32 | cmake .. ) 33 | - cmake -DCMAKE_INSTALL_PREFIX:PATH=%APPVEYOR_BUILD_FOLDER%/%APPVEYOR_REPO_COMMIT% .. 34 | 35 | build_script: 36 | - cmake --build . --config %CONFIGURATION% --target install 37 | 38 | after_build: 39 | - mkdir %artifactName% 40 | - cp %APPVEYOR_BUILD_FOLDER%/%APPVEYOR_REPO_COMMIT%/* %artifactName% 41 | 42 | artifacts: 43 | - path: build\%artifactName% 44 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required ( VERSION 2.8 ) 2 | 3 | project ( tag_converter ) 4 | 5 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") 6 | 7 | set (srcs 8 | main.cpp 9 | ) 10 | 11 | set (hdrs 12 | ) 13 | 14 | add_executable ( ${PROJECT_NAME} ${hdrs} ${srcs} ) 15 | 16 | INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX} COMPONENT ${PROJECT_NAME} ) 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tag_converter 2 | [![Build status](https://ci.appveyor.com/api/projects/status/f5kckoebkq0cuw9l?svg=true)](https://ci.appveyor.com/project/hasherezade/tag-converter) 3 | 4 | Convert the `.tag` files - generated i.e. by [PE-sieve](https://github.com/hasherezade/pe-sieve), [Tiny Tracer](https://github.com/hasherezade/tiny_tracer), [PE-bear](https://github.com/hasherezade/pe-bear-releases) - into scripts that can load them into other (otherwise unsupported) analysis tools. 5 | 6 | Currently supported: 7 | - 8 | + [x64dbg](https://x64dbg.com) - read [HOWTO](https://github.com/hasherezade/tag_converter/wiki/Loading-tags-into-x64dbg) 9 | 10 | Download: 11 | - 12 | Stable builds are available in [releases](https://github.com/hasherezade/tag_converter/releases). 13 | 14 | Test builds can be downloaded from [the build server](https://ci.appveyor.com/project/hasherezade/tag-converter) (click on the build and choose the "Artifacts" tab) 15 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define VERSION "1.0" 8 | 9 | #define TAG_DELIM ';' 10 | 11 | bool is_numerical(const std::string &str) 12 | { 13 | if (str.length() == 0) return false; 14 | 15 | for (size_t i = 0; i < str.length(); i++) { 16 | char c = tolower(str[i]); 17 | if (c >= '0' && c <= '9') continue; 18 | if (c >= 'a' && c <= 'f') continue; 19 | return false; 20 | } 21 | return true; 22 | } 23 | 24 | bool process_file(const std::string &in_file, const std::string &out_file, const std::string &module_name) 25 | { 26 | std::ifstream infile(in_file); 27 | if (!infile.is_open()) { 28 | return false; 29 | } 30 | std::ofstream outfile(out_file); 31 | if (!outfile.is_open()) { 32 | return false; 33 | } 34 | 35 | std::map rva_to_cmt; 36 | 37 | std::string line; 38 | while (std::getline(infile, line)) { 39 | if (line.length() == 0) continue; 40 | 41 | size_t pos = line.find(TAG_DELIM, 0); 42 | if (pos == std::string::npos || pos >= (line.length() - 1)) continue; 43 | 44 | std::string rva_str = line.substr(0, pos); 45 | std::string cmt_str = line.substr(pos + 1, line.length()); 46 | if (rva_str.length() == 0 || cmt_str.length() == 0) continue; 47 | 48 | if (!is_numerical(rva_str)) continue; //skip lines that don't start from RVA 49 | DWORD rva = std::stoi(rva_str, nullptr, 16); 50 | rva_to_cmt[rva] = cmt_str; 51 | } 52 | infile.close(); 53 | 54 | if (module_name.length() == 0) { 55 | std::cerr << "Module name is missing!\n"; 56 | return false; 57 | } 58 | outfile << "$base=" << "\"" << module_name << ":base\"" << std::endl; 59 | std::map::iterator itr; 60 | for (itr = rva_to_cmt.begin(); itr != rva_to_cmt.end(); itr++) { 61 | const std::string cmt_str = itr->second; 62 | const DWORD rva = itr->first; 63 | outfile << "cmt $base+" << std::hex << rva << "," << "\"" << cmt_str << "\"" << std::endl; 64 | outfile << "bookmark $base+" << std::hex << rva << std::endl; 65 | } 66 | outfile.close(); 67 | return true; 68 | } 69 | 70 | std::string fetch_module_name(std::string filename) 71 | { 72 | size_t pos = filename.find_last_of("\\/"); 73 | if (pos != std::string::npos) { 74 | filename.erase(0, pos + 1); 75 | } 76 | pos = filename.find(".tag", 0); 77 | if (pos == std::string::npos) return ""; 78 | 79 | return filename.substr(0, pos); 80 | } 81 | 82 | int main(int argc, char* argv[]) 83 | { 84 | if (argc < 2) { 85 | std::cout << "Tag Converter v" << VERSION << "\n" 86 | << "URL: https://github.com/hasherezade/tag_converter\n"; 87 | std::cout << "Args: [module_name] [out_file]\n"; 88 | return 0; 89 | } 90 | std::string module_name = fetch_module_name(argv[1]); 91 | std::string out = std::string(argv[1]) + ".x64dbg.txt"; 92 | if (argc >= 3) { 93 | module_name = argv[2]; 94 | } 95 | if (argc >= 4) { 96 | out = argv[3]; 97 | } 98 | std::cout << "Module Name: " << module_name << "\n"; 99 | std::cout << "Output file: " << out << "\n"; 100 | process_file(argv[1], out, module_name); 101 | return 0; 102 | } 103 | --------------------------------------------------------------------------------