Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: runtime/vm/precompiler.h

Issue 3003583002: [VM, Precompiler] PoC Obfuscator (Closed)
Patch Set: Fix bad refactoring in NewAtomicRename Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/parser.cc ('k') | runtime/vm/precompiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef RUNTIME_VM_PRECOMPILER_H_ 5 #ifndef RUNTIME_VM_PRECOMPILER_H_
6 #define RUNTIME_VM_PRECOMPILER_H_ 6 #define RUNTIME_VM_PRECOMPILER_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/hash_map.h" 9 #include "vm/hash_map.h"
10 #include "vm/hash_table.h" 10 #include "vm/hash_table.h"
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 void DropTypeArguments(); 391 void DropTypeArguments();
392 void DropScriptData(); 392 void DropScriptData();
393 void DropLibraryEntries(); 393 void DropLibraryEntries();
394 void DropClasses(); 394 void DropClasses();
395 void DropLibraries(); 395 void DropLibraries();
396 396
397 void BindStaticCalls(); 397 void BindStaticCalls();
398 void SwitchICCalls(); 398 void SwitchICCalls();
399 void ResetPrecompilerState(); 399 void ResetPrecompilerState();
400 400
401 void Obfuscate();
402
401 void CollectDynamicFunctionNames(); 403 void CollectDynamicFunctionNames();
402 404
403 void PrecompileStaticInitializers(); 405 void PrecompileStaticInitializers();
404 void PrecompileConstructors(); 406 void PrecompileConstructors();
405 407
406 void FinalizeAllClasses(); 408 void FinalizeAllClasses();
407 void VerifyJITFeedback(); 409 void VerifyJITFeedback();
408 RawScript* LookupScript(const char* uri); 410 RawScript* LookupScript(const char* uri);
409 intptr_t MapCid(intptr_t feedback_cid); 411 intptr_t MapCid(intptr_t feedback_cid);
410 412
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 } else { 471 } else {
470 ASSERT(String::Cast(obj).IsSymbol()); 472 ASSERT(String::Cast(obj).IsSymbol());
471 return String::Cast(obj).Hash(); 473 return String::Cast(obj).Hash();
472 } 474 }
473 } 475 }
474 static RawObject* NewKey(const Function& function) { return function.raw(); } 476 static RawObject* NewKey(const Function& function) { return function.raw(); }
475 }; 477 };
476 478
477 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet; 479 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
478 480
481 #if defined(DART_PRECOMPILER)
482 // ObfuscationMap maps Strings to Strings.
483 class ObfuscationMapTraits {
484 public:
485 static const char* Name() { return "ObfuscationMapTraits"; }
486 static bool ReportStats() { return false; }
487
488 // Only for non-descriptor lookup and table expansion.
489 static bool IsMatch(const Object& a, const Object& b) {
490 return a.raw() == b.raw();
491 }
492
493 static uword Hash(const Object& key) { return String::Cast(key).Hash(); }
494 };
495 typedef UnorderedHashMap<ObfuscationMapTraits> ObfuscationMap;
496
497 // Obfuscator is a helper class that is responsible for obfuscating
498 // identifiers when obfuscation is enabled via isolate flags.
499 //
500 class Obfuscator : public ValueObject {
501 public:
502 // Create Obfuscator for the given |thread|, with the given |private_key|.
503 // This private key will be used when obfuscating private identifiers
504 // (those starting with '_').
505 //
506 // If obfuscation is enabled constructor will restore obfuscation state
507 // from ObjectStore::obfuscation_map()
508 //
509 // Note: only a single instance of obfuscator should exist at any given
510 // moment on the stack because Obfuscator takes ownership of obfuscation
511 // map. ObjectStore::obfuscation_map() will only be updated when
512 // this Obfuscator is destroyed.
513 Obfuscator(Thread* thread, const String& private_key);
514
515 // If obfuscation is enabled - commit accumulated renames to ObjectStore.
516 ~Obfuscator();
517
518 // If obfuscation is enabled return a rename for the given |name|,
519 // otherwise it is a no-op.
520 //
521 // Note: |name| *must* be a Symbol.
522 //
523 // By default renames are aware about mangling scheme used for private names:
524 // '_ident@key' and '_ident' will be renamed consistently. If such
525 // interpretation is undesirable e.g. it is known that name does not
526 // contain a private key suffix or name is not a Dart identifier at all
527 // then this function should be called with |atomic| set to true.
528 //
529 // Note: if obfuscator was created with private_key then all
530 // renames *must* be atomic.
531 //
532 // This method is guaranteed to return the same value for the same
533 // input and it always preserves leading '_' even for atomic renames.
534 RawString* Rename(const String& name, bool atomic = false) {
535 if (state_ == NULL) {
536 return name.raw();
537 }
538
539 return state_->RenameImpl(name, atomic);
540 }
541
542 // Given a constant |instance| of dart:internal.Symbol rename it by updating
543 // its |name| field.
544 static void ObfuscateSymbolInstance(Thread* thread, const Instance& instance);
545
546 // Given a sequence of obfuscated identifiers deobfuscate it.
547 //
548 // This method is only used by parser when resolving conditional imports
549 // because it needs deobfuscated names to lookup in the environment.
550 //
551 // Note: this operation is not optimized because is very infrequent.
552 static void Deobfuscate(Thread* thread, const GrowableObjectArray& pieces);
553
554 // Serialize renaming map as a malloced array of strings.
555 static const char** SerializeMap(Thread* thread);
556
557 private:
558 // Populate renaming map with names that should have identity renaming.
559 // (or in other words: with those names that should not be renamed).
560 void InitializeRenamingMap(Isolate* isolate);
561 void PreventRenaming(Dart_QualifiedFunctionName* entry_points);
562 void PreventRenaming(const char* name);
563 void PreventRenaming(const String& name) { state_->PreventRenaming(name); }
564
565 // ObjectStore::obfuscation_map() is an Array with two elements:
566 // first element is the last used rename and the second element is
567 // renaming map.
568 static const intptr_t kSavedStateNameIndex = 0;
569 static const intptr_t kSavedStateRenamesIndex = 1;
570 static const intptr_t kSavedStateSize = 2;
571
572 static RawArray* GetRenamesFromSavedState(const Array& saved_state) {
573 Array& renames = Array::Handle();
574 renames ^= saved_state.At(kSavedStateRenamesIndex);
575 return renames.raw();
576 }
577
578 static RawString* GetNameFromSavedState(const Array& saved_state) {
579 String& name = String::Handle();
580 name ^= saved_state.At(kSavedStateNameIndex);
581 return name.raw();
582 }
583
584 class ObfuscationState : public ZoneAllocated {
585 public:
586 ObfuscationState(Thread* thread,
587 const Array& saved_state,
588 const String& private_key)
589 : thread_(thread),
590 saved_state_(saved_state),
591 renames_(GetRenamesFromSavedState(saved_state)),
592 private_key_(private_key),
593 string_(String::Handle(thread->zone())),
594 renamed_(String::Handle(thread->zone())) {
595 memset(name_, 0, sizeof(name_));
596
597 // Restore last used rename.
598 string_ = GetNameFromSavedState(saved_state);
599 if (!string_.IsNull()) {
600 string_.ToUTF8(reinterpret_cast<uint8_t*>(name_), sizeof(name_));
601 }
602 }
603
604 void SaveState();
605
606 // Return a rename for the given |name|.
607 //
608 // Note: |name| *must* be a Symbol.
609 //
610 // By default renames are aware about mangling scheme used for private
611 // names: '_ident@key' and '_ident' will be renamed consistently. If such
612 // interpretation is undesirable e.g. it is known that name does not
613 // contain a private key suffix or name is not a Dart identifier at all
614 // then this function should be called with |atomic| set to true.
615 //
616 // Note: if obfuscator was created with private_key then all
617 // renames *must* be atomic.
618 //
619 // This method is guaranteed to return the same value for the same
620 // input.
621 RawString* RenameImpl(const String& name, bool atomic);
622
623 // Register an identity (name -> name) mapping in the renaming map.
624 //
625 // This essentially prevents the given name from being renamed.
626 void PreventRenaming(const String& name);
627 void PreventRenaming(const char* name);
628
629 private:
630 // Build rename for the given |name|.
631 //
632 // For atomic renames BuildRename just returns the next
633 // available rename generated by AtomicRename(...).
634 //
635 // For non-atomic renames BuildRename ensures that private mangled
636 // identifiers (_ident@key) are renamed consistently with non-mangled
637 // counterparts (_ident).
638 RawString* BuildRename(const String& name, bool atomic);
639
640 // Generate a new rename. If |should_be_private| is set to true
641 // then we prefix returned identifier with '_'.
642 RawString* NewAtomicRename(bool should_be_private);
643
644 // Update next_ to generate the next free rename.
645 void NextName();
646
647 Thread* thread_;
648
649 // Saved obfuscation state (ObjectStore::obfuscation_map())
650 const Array& saved_state_;
651
652 // Last used rename. Renames are only using a-zA-Z characters
653 // and are generated in order: a, b, ..., z, A, ..., Z, aa, ba, ...
654 char name_[100];
655
656 ObfuscationMap renames_;
657
658 const String& private_key_;
659
660 // Temporary handles.
661 String& string_;
662 String& renamed_;
663 };
664
665 // Current obfucation state or NULL if obfuscation is not enabled.
666 ObfuscationState* state_;
667 };
668 #else
669 // Minimal do-nothing implementation of an Obfuscator for non-precompiler
670 // builds.
671 class Obfuscator {
672 public:
673 Obfuscator(Thread* thread, const String& private_key) {}
674 ~Obfuscator() {}
675
676 RawString* Rename(const String& name, bool atomic = false) {
677 return name.raw();
678 }
679
680 static void ObfuscateSymbolInstance(Thread* thread,
681 const Instance& instance) {}
682
683 static void Deobfuscate(Thread* thread, const GrowableObjectArray& pieces) {}
684 };
685 #endif // DART_PRECOMPILER
686
479 } // namespace dart 687 } // namespace dart
480 688
481 #endif // RUNTIME_VM_PRECOMPILER_H_ 689 #endif // RUNTIME_VM_PRECOMPILER_H_
OLDNEW
« no previous file with comments | « runtime/vm/parser.cc ('k') | runtime/vm/precompiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698