2020
2121namespace fakelinker {
2222
23+ static std::string FormatProt (int prot) {
24+ std::string result (4 , ' \0 ' );
25+ result[0 ] = (prot & kMPRead ) == kMPRead ? ' r' : ' -' ;
26+ result[1 ] = (prot & kMPWrite ) == kMPWrite ? ' w' : ' -' ;
27+ result[2 ] = (prot & kMPExecute ) == kMPExecute ? ' x' : ' -' ;
28+ if (prot & kMPShared ) {
29+ result[3 ] = ' s' ;
30+ } else if (prot & kMPPrivate ) {
31+ result[3 ] = ' p' ;
32+ } else {
33+ result[3 ] = ' -' ;
34+ }
35+ return result;
36+ }
37+
38+ static std::string FormatPageProtect (const PageProtect &pp) {
39+ std::string result;
40+ char tmp[18 ];
41+ auto IntToHex = [&tmp](Address addr) -> const char * {
42+ sprintf (tmp, " 0x%08" SCNx64, addr);
43+ return tmp;
44+ };
45+ result.append (IntToHex (pp.start )).append (" - " ).append (IntToHex (pp.end ));
46+ result.append (" " ).append (FormatProt (pp.old_protect ));
47+ result.append (" " ).append (IntToHex (pp.file_offset ));
48+ result.append (" " ).append (std::to_string (pp.inode ));
49+ return result;
50+ }
51+
2352MapsHelper::MapsHelper (const char *library_name) { GetLibraryProtect (library_name); }
2453
2554MapsHelper::~MapsHelper () { CloseMaps (); }
@@ -38,7 +67,7 @@ bool MapsHelper::GetMemoryProtect(void *address, uint64_t size) {
3867 continue ;
3968 }
4069 if (start_address_ >= end) {
41- return !page_ .empty ();
70+ return !pages_ .empty ();
4271 }
4372 PageProtect page;
4473 page.start = start_address_;
@@ -47,7 +76,7 @@ bool MapsHelper::GetMemoryProtect(void *address, uint64_t size) {
4776 page.old_protect = FormatProtect ();
4877 page.inode = inode_;
4978 page.path = path_;
50- page_ .push_back (page);
79+ pages_ .push_back (page);
5180 }
5281 return false ;
5382}
@@ -71,11 +100,12 @@ bool MapsHelper::ReadLibraryMap() {
71100 // Strictly check if library is correct, a library must have at least read-execute memory segment
72101 if ((protect & (kMPRead | kMPExecute )) == (kMPRead | kMPExecute )) {
73102 break ;
74- } else {
75- started = false ;
76- protect = 0 ;
77- page_.clear ();
78103 }
104+ // continue searching for the next mapping
105+ started = false ;
106+ protect = 0 ;
107+ pages_.clear ();
108+ continue ;
79109 }
80110 if (inode_ == 0 ) {
81111 continue ;
@@ -88,9 +118,9 @@ bool MapsHelper::ReadLibraryMap() {
88118 page.file_offset = file_offset_;
89119 page.inode = inode_;
90120 page.path = path_;
91- page_ .push_back (page);
121+ pages_ .push_back (page);
92122 }
93- if (page_ .empty ()) {
123+ if (pages_ .empty ()) {
94124 // File has been read completely
95125 return true ;
96126 }
@@ -103,30 +133,32 @@ bool MapsHelper::GetLibraryProtect(const char *library_name) {
103133 }
104134 MakeLibraryName (library_name);
105135 do {
106- page_ .clear ();
136+ pages_ .clear ();
107137 } while (!ReadLibraryMap ());
108- if (!page_ .empty ()) {
138+ if (!pages_ .empty ()) {
109139 LOGD (" find library: %s\n %s" , library_name, ToString ().c_str ());
110140 }
111- return !page_ .empty ();
141+ return !pages_ .empty ();
112142}
113143
114144bool MapsHelper::UnlockAddressProtect (void *address, uint64_t size) {
115145 if (!GetMemoryProtect (address, size)) {
116146 return false ;
117147 }
118- PageProtect &page = page_ [0 ];
148+ PageProtect &page = pages_ [0 ];
119149
120150 if ((page.old_protect & kMPWrite ) == kMPWrite ) {
121151 page.new_protect = page.old_protect ;
122152 return true ;
123153 }
124154 page.new_protect = page.old_protect | kMPRead | kMPWrite ;
125155 // only change rwx protect
126- if (mprotect (reinterpret_cast <void *>(page.start ), page.end - page.start , page.new_protect & kMPRWX ) == 0 ) {
127- return true ;
156+ if (int code = mprotect (reinterpret_cast <void *>(page.start ), page.end - page.start , page.new_protect & kMPRWX )) {
157+ LOGE (" change protect memory failed: %s, new %s, error: %d" , FormatPageProtect (page).c_str (),
158+ FormatProt (page.new_protect ).c_str (), code);
159+ return false ;
128160 }
129- return false ;
161+ return true ;
130162}
131163
132164Address MapsHelper::FindLibraryBase (const char *library_name) {
@@ -160,13 +192,13 @@ Address MapsHelper::FindLibraryBase(const char *library_name) {
160192}
161193
162194bool MapsHelper::CheckAddressPageProtect (const Address address, uint64_t size, uint8_t prot) {
163- if (page_ .empty ()) {
195+ if (pages_ .empty ()) {
164196 return false ;
165197 }
166198 Address start = address;
167199 Address end = address + size;
168200 LOGI (" check memory protect 0x%" PRIx64 " - 0x%" PRIx64, start, end);
169- for (PageProtect &pp : page_ ) {
201+ for (PageProtect &pp : pages_ ) {
170202 if (pp.start > end || pp.end < start) {
171203 continue ;
172204 }
@@ -182,12 +214,12 @@ bool MapsHelper::CheckAddressPageProtect(const Address address, uint64_t size, u
182214}
183215
184216Address MapsHelper::GetLibraryBaseAddress () const {
185- if (page_ .empty ()) {
217+ if (pages_ .empty ()) {
186218 return 0 ;
187219 }
188220 uint64_t minoffset = UINT64_MAX;
189221 Address start = 0 ;
190- for (const PageProtect &pp : page_ ) {
222+ for (const PageProtect &pp : pages_ ) {
191223 if (pp.inode == 0 ) {
192224 continue ;
193225 }
@@ -219,7 +251,7 @@ std::string MapsHelper::GetLibraryRealPath(const char *library_name) {
219251}
220252
221253std::string MapsHelper::GetCurrentRealPath () const {
222- for (auto &page : page_ ) {
254+ for (auto &page : pages_ ) {
223255 if (!page.path .empty () && page.inode != 0 ) {
224256 return page.path ;
225257 }
@@ -231,45 +263,26 @@ std::string MapsHelper::ToString() const {
231263 std::string result = GetCurrentRealPath () + " :" ;
232264 char tmp[16 ];
233265
234- auto IntToHex = [&tmp](Address addr) -> const char * {
235- sprintf (tmp, " 0x%08" SCNx64, addr);
236- return tmp;
237- };
238-
239- auto ProtToStr = [&tmp](int prot) -> const char * {
240- tmp[0 ] = (prot & kMPRead ) == kMPRead ? ' r' : ' -' ;
241- tmp[1 ] = (prot & kMPWrite ) == kMPWrite ? ' w' : ' -' ;
242- tmp[2 ] = (prot & kMPExecute ) == kMPExecute ? ' x' : ' -' ;
243- if (prot & kMPShared ) {
244- tmp[3 ] = ' s' ;
245- } else if (prot & kMPPrivate ) {
246- tmp[3 ] = ' p' ;
247- } else {
248- tmp[3 ] = ' -' ;
249- }
250- tmp[4 ] = ' \0 ' ;
251- return tmp;
252- };
253266
254- for (const PageProtect &pp : page_) {
255- result.append (" \n " ).append (IntToHex (pp.start )).append (" - " ).append (IntToHex (pp.end ));
256- result.append (" " ).append (ProtToStr (pp.old_protect ));
257- result.append (" " ).append (IntToHex (pp.file_offset ));
258- result.append (" " ).append (std::to_string (pp.inode ));
267+ for (const PageProtect &pp : pages_) {
268+ result.append (" \n " ).append (FormatPageProtect (pp));
259269 }
260270 return result;
261271}
262272
263273bool MapsHelper::UnlockPageProtect (MapsProt prot) {
264- if (page_ .empty () || prot == MapsProt::kMPInvalid ) {
274+ if (pages_ .empty () || prot == MapsProt::kMPInvalid ) {
265275 return false ;
266276 }
267- for (PageProtect &pp : page_ ) {
277+ for (PageProtect &pp : pages_ ) {
268278 if ((pp.old_protect & prot) != prot) {
269279 pp.new_protect = pp.old_protect | prot;
270- if (mprotect (reinterpret_cast <void *>(pp.start ), pp.end - pp.start , pp.new_protect & kMPRWX ) < 0 ) {
280+ if (int code = mprotect (reinterpret_cast <void *>(pp.start ), pp.end - pp.start , pp.new_protect & kMPRWX )) {
281+ LOGE (" change protect memory failed: %s, new %s, error: %d" , FormatPageProtect (pp).c_str (),
282+ FormatProt (pp.new_protect ).c_str (), code);
271283 return false ;
272284 }
285+ LOGD (" change memory protect success" );
273286 } else {
274287 pp.new_protect = pp.old_protect ;
275288 }
@@ -278,12 +291,14 @@ bool MapsHelper::UnlockPageProtect(MapsProt prot) {
278291}
279292
280293bool MapsHelper::RecoveryPageProtect () {
281- if (page_ .empty ()) {
294+ if (pages_ .empty ()) {
282295 return false ;
283296 }
284- for (PageProtect &pp : page_ ) {
297+ for (PageProtect &pp : pages_ ) {
285298 if (pp.old_protect != pp.new_protect ) {
286- if (mprotect (reinterpret_cast <void *>(pp.start ), pp.end - pp.start , pp.old_protect & kMPRWX ) < 0 ) {
299+ if (int code = mprotect (reinterpret_cast <void *>(pp.start ), pp.end - pp.start , pp.old_protect & kMPRWX )) {
300+ LOGE (" change protect memory failed: %s, new %s, error: %d" , FormatPageProtect (pp).c_str (),
301+ FormatProt (pp.new_protect ).c_str (), code);
287302 return false ;
288303 }
289304 pp.new_protect = pp.old_protect ;
@@ -375,12 +390,13 @@ bool MapsHelper::MakeLibraryName(const char *library_name) {
375390 *
376391 */
377392bool MapsHelper::VerifyLibraryMap () {
378- for (auto &page : page_ ) {
393+ for (auto &page : pages_ ) {
379394 // ARM libraries found under emulator have no executable permissions
380395 if ((page.old_protect & (kMPExecute | kMPWrite )) != 0 ) {
381396 return true ;
382397 }
383398 }
399+ pages_.clear ();
384400 return false ;
385401}
386402
0 commit comments