165042b18Sopenharmony_ci/* 265042b18Sopenharmony_ciCopyright (C) 2001-present by Serge Lamikhov-Center 365042b18Sopenharmony_ci 465042b18Sopenharmony_ciPermission is hereby granted, free of charge, to any person obtaining a copy 565042b18Sopenharmony_ciof this software and associated documentation files (the "Software"), to deal 665042b18Sopenharmony_ciin the Software without restriction, including without limitation the rights 765042b18Sopenharmony_cito use, copy, modify, merge, publish, distribute, sublicense, and/or sell 865042b18Sopenharmony_cicopies of the Software, and to permit persons to whom the Software is 965042b18Sopenharmony_cifurnished to do so, subject to the following conditions: 1065042b18Sopenharmony_ci 1165042b18Sopenharmony_ciThe above copyright notice and this permission notice shall be included in 1265042b18Sopenharmony_ciall copies or substantial portions of the Software. 1365042b18Sopenharmony_ci 1465042b18Sopenharmony_ciTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1565042b18Sopenharmony_ciIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1665042b18Sopenharmony_ciFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1765042b18Sopenharmony_ciAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1865042b18Sopenharmony_ciLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 1965042b18Sopenharmony_ciOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2065042b18Sopenharmony_ciTHE SOFTWARE. 2165042b18Sopenharmony_ci*/ 2265042b18Sopenharmony_ci 2365042b18Sopenharmony_ci#include <iostream> 2465042b18Sopenharmony_ci#include <fstream> 2565042b18Sopenharmony_ci#include <sstream> 2665042b18Sopenharmony_ci#include <regex> 2765042b18Sopenharmony_ci 2865042b18Sopenharmony_ci#include <elfio/elfio.hpp> 2965042b18Sopenharmony_ci#include <elfio/elfio_dump.hpp> 3065042b18Sopenharmony_ci 3165042b18Sopenharmony_ciusing namespace ELFIO; 3265042b18Sopenharmony_ci 3365042b18Sopenharmony_ci//------------------------------------------------------------------------------ 3465042b18Sopenharmony_civoid get_translation_ranges( std::ifstream& proc_maps, 3565042b18Sopenharmony_ci const std::string& file_name, 3665042b18Sopenharmony_ci std::vector<address_translation>& result ) 3765042b18Sopenharmony_ci{ 3865042b18Sopenharmony_ci result.clear(); 3965042b18Sopenharmony_ci 4065042b18Sopenharmony_ci const std::regex rexpr( 4165042b18Sopenharmony_ci "([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r]...) ([0-9A-Fa-f]+) (.....) " 4265042b18Sopenharmony_ci "([0-9]+)([[:blank:]]*)([[:graph:]]*)" ); 4365042b18Sopenharmony_ci std::smatch match; 4465042b18Sopenharmony_ci while ( proc_maps ) { 4565042b18Sopenharmony_ci std::string line; 4665042b18Sopenharmony_ci std::getline( proc_maps, line ); 4765042b18Sopenharmony_ci 4865042b18Sopenharmony_ci if ( std::regex_match( line, match, rexpr ) ) { 4965042b18Sopenharmony_ci if ( match.size() == 9 && match[8].str() == file_name ) { 5065042b18Sopenharmony_ci unsigned long start = std::stoul( match[1].str(), 0, 16 ); 5165042b18Sopenharmony_ci unsigned long end = std::stoul( match[2].str(), 0, 16 ); 5265042b18Sopenharmony_ci unsigned long actual = std::stoul( match[4].str(), 0, 16 ); 5365042b18Sopenharmony_ci result.emplace_back( actual, end - start, start ); 5465042b18Sopenharmony_ci } 5565042b18Sopenharmony_ci } 5665042b18Sopenharmony_ci } 5765042b18Sopenharmony_ci} 5865042b18Sopenharmony_ci 5965042b18Sopenharmony_ci//------------------------------------------------------------------------------ 6065042b18Sopenharmony_ciint main( int argc, char** argv ) 6165042b18Sopenharmony_ci{ 6265042b18Sopenharmony_ci if ( argc != 3 ) { 6365042b18Sopenharmony_ci std::cout << "Usage: proc_mem <pid> <full_file_path>" << std::endl; 6465042b18Sopenharmony_ci return 1; 6565042b18Sopenharmony_ci } 6665042b18Sopenharmony_ci 6765042b18Sopenharmony_ci // Process file translation regions for the ELF file from /proc/pid/maps 6865042b18Sopenharmony_ci std::ifstream proc_maps( std::string( "/proc/" ) + argv[1] + "/maps" ); 6965042b18Sopenharmony_ci if ( !proc_maps ) { 7065042b18Sopenharmony_ci std::cout << "Can't open " 7165042b18Sopenharmony_ci << std::string( "/proc/" ) + argv[1] + "/maps" 7265042b18Sopenharmony_ci << " file" << std::endl; 7365042b18Sopenharmony_ci return 2; 7465042b18Sopenharmony_ci } 7565042b18Sopenharmony_ci 7665042b18Sopenharmony_ci // Retrieve memory address translation ranges 7765042b18Sopenharmony_ci std::vector<address_translation> ranges; 7865042b18Sopenharmony_ci get_translation_ranges( proc_maps, argv[2], ranges ); 7965042b18Sopenharmony_ci 8065042b18Sopenharmony_ci // Set address translation ranges prior loading ELF file 8165042b18Sopenharmony_ci elfio elffile; 8265042b18Sopenharmony_ci elffile.set_address_translation( ranges ); 8365042b18Sopenharmony_ci 8465042b18Sopenharmony_ci // The 'load' will use the provided address translation now 8565042b18Sopenharmony_ci if ( elffile.load( std::string( "/proc/" ) + argv[1] + "/mem", true ) ) { 8665042b18Sopenharmony_ci dump::header( std::cout, elffile ); 8765042b18Sopenharmony_ci dump::segment_headers( std::cout, elffile ); 8865042b18Sopenharmony_ci dump::segment_datas( std::cout, elffile ); 8965042b18Sopenharmony_ci } 9065042b18Sopenharmony_ci else { 9165042b18Sopenharmony_ci std::cout << "Can't open " << std::string( "/proc/" ) + argv[1] + "/mem" 9265042b18Sopenharmony_ci << " file" << std::endl; 9365042b18Sopenharmony_ci } 9465042b18Sopenharmony_ci 9565042b18Sopenharmony_ci return 0; 9665042b18Sopenharmony_ci} 97