手写Andfix热修复(Art篇)

来源:互联网 发布:nginx windows 重启 编辑:程序博客网 时间:2024/06/05 14:26

创建一个art_method.h

#include <string.h>#include <jni.h>#include <stdio.h>#include <fcntl.h>#include <dlfcn.h>#include <stdint.h>    /* C99 */typedef unsigned char u1;typedef unsigned short u2;typedef unsigned int u4;typedef signed char s1;typedef signed short s2;typedef signed int s4;namespace art {    namespace mirror {        class Object {        public:            // The number of vtable entries in java.lang.Object.            uint32_t klass_;            uint32_t monitor_;        };        class Class: public Object {        public:            // Interface method table size. Increasing this value reduces the chance of two interface methods            // colliding in the interface method table but increases the size of classes that implement            // (non-marker) interfaces.            // defining class loader, or NULL for the "bootstrap" system loader            uint32_t class_loader_;            // For array classes, the component class object for instanceof/checkcast            // (for String[][][], this will be String[][]). NULL for non-array classes.            uint32_t component_type_;            // DexCache of resolved constant pool entries (will be NULL for classes generated by the            // runtime such as arrays and primitive classes).            uint32_t dex_cache_;            // Short cuts to dex_cache_ member for fast compiled code access.            uint32_t dex_cache_strings_;            // static, private, and <init> methods            uint32_t direct_methods_;            // instance fields            //            // These describe the layout of the contents of an Object.            // Note that only the fields directly declared by this class are            // listed in ifields; fields declared by a superclass are listed in            // the superclass's Class.ifields.            //            // All instance fields that refer to objects are guaranteed to be at            // the beginning of the field list.  num_reference_instance_fields_            // specifies the number of reference fields.            uint32_t ifields_;            // The interface table (iftable_) contains pairs of a interface class and an array of the            // interface methods. There is one pair per interface supported by this class.  That means one            // pair for each interface we support directly, indirectly via superclass, or indirectly via a            // superinterface.  This will be null if neither we nor our superclass implement any interfaces.            //            // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".            // Invoke faceObj.blah(), where "blah" is part of the Face interface.  We can't easily use a            // single vtable.            //            // For every interface a concrete class implements, we create an array of the concrete vtable_            // methods for the methods in the interface.            uint32_t iftable_;            // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName            uint32_t name_;            // Static fields            uint32_t sfields_;            // The superclass, or NULL if this is java.lang.Object, an interface or primitive type.            uint32_t super_class_;            // If class verify fails, we must return same error on subsequent tries.            uint32_t verify_error_class_;            // Virtual methods defined in this class; invoked through vtable.            uint32_t virtual_methods_;            // Virtual method table (vtable), for use by "invoke-virtual".  The vtable from the superclass is            // copied in, and virtual methods from our class either replace those from the super or are            // appended. For abstract classes, methods may be created in the vtable that aren't in            // virtual_ methods_ for miranda methods.            uint32_t vtable_;            // Access flags; low 16 bits are defined by VM spec.            uint32_t access_flags_;            // Total size of the Class instance; used when allocating storage on gc heap.            // See also object_size_.            uint32_t class_size_;            // Tid used to check for recursive <clinit> invocation.            pid_t clinit_thread_id_;            // ClassDef index in dex file, -1 if no class definition such as an array.            // TODO: really 16bits            int32_t dex_class_def_idx_;            // Type index in dex file.            // TODO: really 16bits            int32_t dex_type_idx_;            // Number of instance fields that are object refs.            uint32_t num_reference_instance_fields_;            // Number of static fields that are object refs,            uint32_t num_reference_static_fields_;            // Total object size; used when allocating storage on gc heap.            // (For interfaces and abstract classes this will be zero.)            // See also class_size_.            uint32_t object_size_;            // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes.            uint32_t primitive_type_;            // Bitmap of offsets of ifields.            uint32_t reference_instance_offsets_;            // Bitmap of offsets of sfields.            uint32_t reference_static_offsets_;            // State of class initialization.            int32_t status_;            // TODO: ?            // initiating class loader list            // NOTE: for classes with low serialNumber, these are unused, and the            // values are kept in a table in gDvm.            // InitiatingLoaderList initiating_loader_list_;            // The following data exist in real class objects.            // Embedded Imtable, for class object that's not an interface, fixed size.            // ImTableEntry embedded_imtable_[0];            // Embedded Vtable, for class object that's not an interface, variable size.            // VTableEntry embedded_vtable_[0];            // Static fields, variable size.            // uint32_t fields_[0];            // java.lang.Class            static void* java_lang_Class_;        };        class ArtField : public Object{        public:            uint32_t declaring_class_;            int32_t access_flags_;            int32_t field_dex_idx_;            int32_t offset_;        };        class ArtMethod: public Object {        public:            // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".            // The class we are a part of. 适配andfix  不能做到这一改            uint32_t declaring_class_;            // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. dex            uint32_t dex_cache_resolved_methods_;            // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.            uint32_t dex_cache_resolved_types_;            // Access flags; low 16 bits are defined by spec.            uint32_t access_flags_;            /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */            // Offset to the CodeItem.            uint32_t dex_code_item_offset_;            // Index into method_ids of the dex file associated with this method.            uint32_t dex_method_index_;            /* End of dex file fields. */            // Entry within a dispatch table for this method. For static/direct methods the index is into            // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the            // ifTable.            uint32_t method_index_;            // Fake padding field gets inserted here.            // Must be the last fields in the method.            struct PtrSizedFields {                // Method dispatch from the interpreter invokes this pointer which may cause a bridge into                // compiled code.java方法   ----》 虚拟机   ----》方法的入口 entry_point_from_interpreter_                //art  解释模式  机器码                void* entry_point_from_interpreter_;                // Pointer to JNI function registered to this method, or a function to resolve the JNI function.                void* entry_point_from_jni_;                // Method dispatch from quick compiled code invokes this pointer which may cause bridging into                // portable compiled code or the interpreter.//                 机器码模式                void* entry_point_from_quick_compiled_code_;            } ptr_sized_fields_;            static void* java_lang_reflect_ArtMethod_;        };    }}
JNIEXPORT void JNICALLJava_com_example_chauncey_ndk_1lsn15_1andfix_DexManager_artReplaceMethod(JNIEnv *env,                                                                         jobject instance,                                                                         jobject wrongMethod,                                                                         jobject rightMethod) {    art::mirror::ArtMethod *wrong = (art::mirror::ArtMethod *) env->FromReflectedMethod(wrongMethod);    art::mirror::ArtMethod *right = (art::mirror::ArtMethod *) env->FromReflectedMethod(rightMethod);    wrong->declaring_class_=right->declaring_class_;    wrong->dex_cache_resolved_methods_=right->dex_cache_resolved_methods_;    wrong->dex_cache_resolved_types_=right->dex_cache_resolved_types_;    wrong->dex_code_item_offset_=right->dex_code_item_offset_;    wrong->method_index_=right->method_index_;    wrong->dex_method_index_=right->dex_method_index_;    wrong->ptr_sized_fields_.entry_point_from_jni_=right->ptr_sized_fields_.entry_point_from_jni_;    wrong->ptr_sized_fields_.entry_point_from_quick_compiled_code_=right->ptr_sized_fields_.entry_point_from_quick_compiled_code_;}

Android7.0以上

#include <string.h>#include <jni.h>#include <stdio.h>#include <string>#include <memory>#include <sys/mman.h>#include <fcntl.h>#include <dlfcn.h>#include <stdint.h>    /* C99 */typedef unsigned char u1;typedef unsigned short u2;typedef unsigned int u4;typedef signed char s1;typedef signed short s2;typedef signed int s4;namespace art {    namespace mirror {        class Object {        public:            static uint32_t hash_code_seed;            uint32_t klass_;            uint32_t monitor_;        };        class Class: public Object {        public:            enum Status {                kStatusRetired = -2, // Retired, should not be used. Use the newly cloned one instead.                kStatusError = -1,                kStatusNotReady = 0,                kStatusIdx = 1, // Loaded, DEX idx in super_class_type_idx_ and interfaces_type_idx_.                kStatusLoaded = 2,  // DEX idx values resolved.                kStatusResolving = 3,  // Just cloned from temporary class object.                kStatusResolved = 4,  // Part of linking.                kStatusVerifying = 5,  // In the process of being verified.                kStatusRetryVerificationAtRuntime = 6, // Compile time verification failed, retry at runtime.                kStatusVerifyingAtRuntime = 7,  // Retrying verification at runtime.                kStatusVerified = 8,  // Logically part of linking; done pre-init.                kStatusInitializing = 9,  // Class init in progress.                kStatusInitialized = 10,  // Ready to go.                kStatusMax = 11,            };            // A magic value for reference_instance_offsets_. Ignore the bits and walk the super chain when            // this is the value.            // [This is an unlikely "natural" value, since it would be 30 non-ref instance fields followed by            // 2 ref instance fields.]            // Interface method table size. Increasing this value reduces the chance of two interface methods            // colliding in the interface method table but increases the size of classes that implement            // (non-marker) interfaces.            // 'Class' Object Fields            // Order governed by java field ordering. See art::ClassLinker::LinkFields.            uint32_t annotation_type_;            // Defining class loader, or null for the "bootstrap" system loader.            uint32_t class_loader_1;            // For array classes, the component class object for instanceof/checkcast            // (for String[][][], this will be String[][]). null for non-array classes.            uint32_t component_type_;            // DexCache of resolved constant pool entries (will be null for classes generated by the            // runtime such as arrays and primitive classes).            uint32_t dex_cache_;            // The interface table (iftable_) contains pairs of a interface class and an array of the            // interface methods. There is one pair per interface supported by this class.  That means one            // pair for each interface we support directly, indirectly via superclass, or indirectly via a            // superinterface.  This will be null if neither we nor our superclass implement any interfaces.            //            // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".            // Invoke faceObj.blah(), where "blah" is part of the Face interface.  We can't easily use a            // single vtable.            //            // For every interface a concrete class implements, we create an array of the concrete vtable_            // methods for the methods in the interface.            uint32_t iftable_;            // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName            uint32_t name_;            // The superclass, or null if this is java.lang.Object or a primitive type.            //            // Note that interfaces have java.lang.Object as their            // superclass. This doesn't match the expectations in JNI            // GetSuperClass or java.lang.Class.getSuperClass() which need to            // check for interfaces and return null.            uint32_t super_class_;            // If class verify fails, we must return same error on subsequent tries. We may store either            // the class of the error, or an actual instance of Throwable here.            uint32_t verify_error_;            // Virtual method table (vtable), for use by "invoke-virtual".  The vtable from the superclass is            // copied in, and virtual methods from our class either replace those from the super or are            // appended. For abstract classes, methods may be created in the vtable that aren't in            // virtual_ methods_ for miranda methods.            uint32_t vtable_;            // Access flags; low 16 bits are defined by VM spec.            // Note: Shuffled back.            uint32_t access_flags_;            // Short cuts to dex_cache_ member for fast compiled code access.            uint64_t dex_cache_strings_;            // instance fields            //            // These describe the layout of the contents of an Object.            // Note that only the fields directly declared by this class are            // listed in ifields; fields declared by a superclass are listed in            // the superclass's Class.ifields.            //            // ArtFields are allocated as a length prefixed ArtField array, and not an array of pointers to            // ArtFields.            uint64_t ifields_;            // Pointer to an ArtMethod length-prefixed array. All the methods where this class is the place            // where they are logically defined. This includes all private, static, final and virtual methods            // as well as inherited default methods and miranda methods.            //            // The slice methods_ [0, virtual_methods_offset_) are the direct (static, private, init) methods            // declared by this class.            //            // The slice methods_ [virtual_methods_offset_, copied_methods_offset_) are the virtual methods            // declared by this class.            //            // The slice methods_ [copied_methods_offset_, |methods_|) are the methods that are copied from            // interfaces such as miranda or default methods. These are copied for resolution purposes as this            // class is where they are (logically) declared as far as the virtual dispatch is concerned.            //            // Note that this field is used by the native debugger as the unique identifier for the type.            uint64_t methods_;            // Static fields length-prefixed array.            uint64_t sfields_;            // Class flags to help speed up visiting object references.            uint32_t class_flags_;            // Total size of the Class instance; used when allocating storage on gc heap.            // See also object_size_.            uint32_t class_size_;            // Tid used to check for recursive <clinit> invocation.            pid_t clinit_thread_id_;            // ClassDef index in dex file, -1 if no class definition such as an array.            // TODO: really 16bits            int32_t dex_class_def_idx_;            // Type index in dex file.            // TODO: really 16bits            int32_t dex_type_idx_;            // Number of instance fields that are object refs.            uint32_t num_reference_instance_fields_;            // Number of static fields that are object refs,            uint32_t num_reference_static_fields_;            // Total object size; used when allocating storage on gc heap.            // (For interfaces and abstract classes this will be zero.)            // See also class_size_.            uint32_t object_size_;            // The lower 16 bits contains a Primitive::Type value. The upper 16            // bits contains the size shift of the primitive type.            uint32_t primitive_type_;            // Bitmap of offsets of ifields.            uint32_t reference_instance_offsets_;            // State of class initialization.            Status status_;            // The offset of the first virtual method that is copied from an interface. This includes miranda,            // default, and default-conflict methods. Having a hard limit of ((2 << 16) - 1) for methods            // defined on a single class is well established in Java so we will use only uint16_t's here.            uint16_t copied_methods_offset_;            // The offset of the first declared virtual methods in the methods_ array.            uint16_t virtual_methods_offset_;            // TODO: ?            // initiating class loader list            // NOTE: for classes with low serialNumber, these are unused, and the            // values are kept in a table in gDvm.            // InitiatingLoaderList initiating_loader_list_;            // The following data exist in real class objects.            // Embedded Imtable, for class object that's not an interface, fixed size.            // ImTableEntry embedded_imtable_[0];            // Embedded Vtable, for class object that's not an interface, variable size.            // VTableEntry embedded_vtable_[0];            // Static fields, variable size.            // uint32_t fields_[0];            // java.lang.Class            static uint32_t java_lang_Class_;        };        class ArtField {        public:            uint32_t declaring_class_;            uint32_t access_flags_;            uint32_t field_dex_idx_;            uint32_t offset_;        };        class ArtMethod {        public:            // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".            // The class we are a part of.            uint32_t declaring_class_;            // Access flags; low 16 bits are defined by spec.            uint32_t access_flags_;            /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */            // Offset to the CodeItem.            uint32_t dex_code_item_offset_;            // Index into method_ids of the dex file associated with this method.            uint32_t dex_method_index_;            /* End of dex file fields. */            // Entry within a dispatch table for this method. For static/direct methods the index is into            // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the            // ifTable.            uint16_t method_index_;            // The hotness we measure for this method. Incremented by the interpreter. Not atomic, as we allow            // missing increments: if the method is hot, we will see it eventually.            uint16_t hotness_count_;            // Fake padding field gets inserted here.            // Must be the last fields in the method.            // PACKED(4) is necessary for the correctness of            // RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size).            struct PtrSizedFields {                // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.                ArtMethod** dex_cache_resolved_methods_;                // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.                void* dex_cache_resolved_types_;                // Pointer to JNI function registered to this method, or a function to resolve the JNI function,                // or the profiling data for non-native methods, or an ImtConflictTable.                void* entry_point_from_jni_;                // Method dispatch from quick compiled code invokes this pointer which may cause bridging into                // the interpreter.                void* entry_point_from_quick_compiled_code_;            } ptr_sized_fields_;        };    }
JNIEXPORT void JNICALLJava_com_example_chauncey_ndk_1lsn15_1andfix_DexManager_artReplaceMethod(JNIEnv *env,                                                                         jobject instance,                                                                         jobject wrongMethod,                                                                         jobject rightMethod) {    art::mirror::ArtMethod *wrong = (art::mirror::ArtMethod *) env->FromReflectedMethod(wrongMethod);    art::mirror::ArtMethod *right = (art::mirror::ArtMethod *) env->FromReflectedMethod(rightMethod);    wrong->declaring_class_=right->declaring_class_;    wrong->dex_code_item_offset_=right->dex_code_item_offset_;    wrong->method_index_=right->method_index_;    wrong->dex_method_index_=right->dex_method_index_;    wrong->ptr_sized_fields_.entry_point_from_jni_=right->ptr_sized_fields_.entry_point_from_jni_;    wrong->ptr_sized_fields_.entry_point_from_quick_compiled_code_=right->ptr_sized_fields_.entry_point_from_quick_compiled_code_;    wrong->ptr_sized_fields_.entry_point_from_jni_=right->ptr_sized_fields_.entry_point_from_jni_;    wrong->ptr_sized_fields_.dex_cache_resolved_methods_=right->ptr_sized_fields_.dex_cache_resolved_methods_;    wrong->ptr_sized_fields_.dex_cache_resolved_types_=right->ptr_sized_fields_.dex_cache_resolved_types_;    wrong->hotness_count_=right->hotness_count_;}
原创粉丝点击