Android so reverse-object inheritance and virtual functions

Source: Internet
Author: User

0x00

In this section we will discuss the implementation of object inheritance and virtual function assembly.


0x01

Let's look directly at the assembly code:

#include "com_example_ndkreverse6_lesson6.h" #include <android/log.h> #define LOG_TAG "Lesson6" #define ALOGD ( ...) (void) __android_log_print (Android_log_debug, Log_tag, __va_args__)) class Base {public:virtual void display () {//virtual function, Virtual declaration of the function, the object can be transformed upward to call to the subclass of the same name method Alogd ("base:%d, basechar:%d", Base_, Basechar_);} Base (int base) {Base_ = Base;basechar_ = 8; ALOGD ("Base ..."); Virtual ~base () {//virtual destructor, only declared as virtual, the object that is transformed up first calls the destructor of the subclass, and then calls the destructor of the parent class ALOGD ("~base ...");} Private:int Base_;char Basechar_;}; Class Derived:public Base {public:virtual void display () {//override method Alogd for parent class ("derived:%d, derivedchar:%d", Derived_, derive DCHAR_); Base::d isplay (); Using the method of the parent class, because it is overwritten, the same name is used to refer to}derived (int Derived) in this way: Base (Derived) {derived_ = Derived;derivedchar_ = 10; ALOGD ("Derived ..."); ~derived () {alogd ("~derived ...");} Private:int Derived_;char Derivedchar_;}; Jniexport void Jnicall Java_com_example_ndkreverse6_lesson6_main (jnienv * env, Jobject jobject) {Base* d = new Derived (18) ;d->display ();d elete D;} 
Then, the results of the run after execution are as follows:

D/lesson6 (28959): Base ... D/lesson6 (28959): Derived ... D/lesson6 (28959): Derived:18, Derivedchar:10d/lesson6 (28959): Base:18, Basechar:8d/lesson6 (28959): ~Derived ... D/lesson6 (28959): ~base ...


0x02

Below we use IDA to open so and explain the assembly code. The assembly code uses the assembly code in the debug state .

. text:00003088 EXPORT java_com_example_ndkreverse6_lesson6_main.text:00003088 Java_com_example_ndkreverse6 _lesson6_main.text:00003088 PUSH {r4-r6,lr}.text:0000308a MOVS R0, #0x14; The unsigned int R0 is assigned as 20, which represents the memory unit to allocate 20 bytes. text:0000308c BL _znwj; operator new (UINT) allocates 20 byte-sized memory units. text:00003090 LDR R3, = (_ztv4base_ptr-0x3098); The constructor that calls base directly. text : 00003092 MOVS R6, #0x12; R6 is initialized to 18.text:00003094 ADD R3, PC; _ztv4base_ptr.text:00003096 LDR R3, [R3]; ' vtable for ' base takes out the virtual table pointer of base, pointing to. data.rel.ro, i.e. 0x70428960.text:00003098 MOVS R4, R0; R0 is the first address of a memory unit of just 20 bytes allocated, and is now assigned to r4.text:0000309a ADDS R3, #8; R3+8 to r3,r3 points to 0x70428968.text:0000309c STR R3, [R0]; assigns 0x70428968 to the first address of the memory unit that was just allocated (the memory unit pointed to). Tex    t:0000309e MOVS R3, #8      ; R3 is assigned a value of 8.text:000030a0 ldr R5, = (ALESSON6-0X30AA). Text:000030a2 Ldr R2, = (AB                 ase____0-0x30b0). text:000030a4 STR R6, [R0, #4]; assigns 18 to the first address of the newly allocated memory unit +4.TEXT:000030A6 ADD R5, PC;                 The "Lesson6" R5 points to the lesson6.text:000030a8 MOVS R1 in the. Rodata segment, R5; assigns R5 to R1 as a parameter. TEXT:000030AA STRB R3, [R0, #8]; Assigns a value of 8 to the first address of the memory unit just allocated +8.text:000030ac add R2, PC; "Base ..." R2 points to the base in the. Rodata section .... text:000030ae MOVS R0, #3; R0 is initialized to 3.text:000030b0 BL j_j___android_log_print; output base .... text:000030b4 LDR R 3, = (_ZTV7DERIVED_PTR-0X30BE); start calling the derived constructor. Text:000030b6 LDR R2, = (aderived____0-0x30c2). Text : 000030b8 MOVS R1, R5; R1 is assigned a value of R5, pointing to Lesson6.text:000030ba ADD R3, PC, located in the. Rodata segment; _ztv7derived_ptr.text:000030BC LDR R3, [R3]; The ' vtable for ' Derived takes out the virtual table pointer of the Derived, pointing to the. data.rel.ro, which is 0x70428978.text:000030be ADD R2, PC; "Derived ..."                 R2 points to the derived.text:000030c0 STR R6 in the. Rodata segment, [R4, #0xC]; assigns 18 to the first address of the newly allocated memory unit +12.TEXT:000030C2 ADDS R3, #8; The R3 is assigned the virtual table pointer of derived +8, which is 0x70428980.text:000030c4 STR R3, [R4]; assigns 0x70428980 to the first address of the memory unit just allocated. text:000 030c6 MOVS R3, #0xA; assign R3 to 10.text:000030c8 MOVS R0, #3; assign R0 to 3.tex T:000030CA STRB R3, [R4, #0x10]; Assign 10 to the first address of the newly allocated memory unit +16.text:000030cc BL J_j___andr Oid_log_print; currently r0,r1,r2 are initialized to the correct values, start calling j_j___android_log_print.text:000030d0 LDR R3, [R4]; remove The virtual table pointer, which is located at the address of the. data.rel.ro segment 0x70428980.text:000030d2 MOVS R0, R4; assigns R0 to R4 as the first parameter, R4 as the first address of the memory unit just allocated , which is the this pointer. Text:000030d4 LDR R3, [R3]; Remove the content that the virtual table pointer points to, that is, the address of the derived display method. text:000030d6 BLX R3; jumps to derived display method.                 Text:000030d8 LDR R3, [R4]; Remove the virtual table pointer, which is the address of the. Data.rel.ro segment 0x70428980.text:000030da MOVS R0, R4; assigns R0 to R4 as the first argument, R4 is the first address of the memory unit just allocated, the this pointer. TEXT:000030DC LDR R3, [R3, #8]; A virtual table pointer + 8 points to the address of the derived ~derived method. text:000030de BLX R3; jump to derived ~derived method. text:000 030E0 POP {R4-R6,PC}
. text:704220e4 off_704220e4 DCD _ztv4base_ptr-0x70422098.text:704220e4; DATA xref:java_com_example_ndkreverse6_lesson6_main+8r.text:704220e8 off_704220e8 DCD alesson6-0x704220aa.text : 704220E8; DATA Xref:java_com_example_ndkreverse6_lesson6_main+18r.text:704220e8;                                         "Lesson6". Text:704220ec off_704220ec DCD Abase____0-0x704220b0.text:704220ec ; DATA Xref:java_com_example_ndkreverse6_lesson6_main+1ar.text:704220ec;                                         "Base ...". text:704220f0 off_704220f0 DCD _ztv7derived_ptr-0x704220be.text:704220f0 ; DATA xref:java_com_example_ndkreverse6_lesson6_main+2cr.text:704220f4 off_704220f4 DCD aDerived____0- 0X704220C2.TEXT:704220F4; DATA Xref:java_com_example_ndkreverse6_lesson6_main+2er.teXT:704220F4; "Derived ..."
.got : 70428f24 area. Got, Data.got:70428f24; ORG 0x70428f24.got:70428f24 _ztv4base_ptr DCD _ztv4base; DATA xref:base::~base () +ao.got:70428f24; Base::~base () +cr .... got:70428f24; ' vtable for ' base.got:70428f28 _ztv7derived_ptr DCD _ztv7derived; DATA xref:derived::~derived () +ao.got:70428f28; Derived::~derived () +cr .... got:70428f28; ' vtable for ' Derived 
. data.rel.ro:70428960; ' vtable for ' base.data.rel.ro:70428960 _ztv4base DCB 0; DATA xref:base::~base () +co.data.rel.ro:70428960;                 Java_com_example_ndkreverse6_lesson6_main+eo. data.rel.ro:70428961 DCB 0.data.rel.ro:70428962           DCB 0.data.rel.ro:70428963 DCB 0.data.rel.ro:70428964 DCD _zti4base ; ' TypeInfo for ' base.data.rel.ro:70428968 DCD _zn4base7displayev+1.data.rel.ro:7042896c DCD _zn4based2ev+1.data.rel.ro:70428970 DCD _zn4based0ev+1.data.rel.ro:70428974 ALIGN 8.DATA.R el.ro:70428978 WEAK _ztv7derived.data.rel.ro:70428978; ' vtable for ' derived.data.rel.ro:70428978 _ztv7derived DCB 0; DATA xref:derived::~derived () +co.data.rel.ro:70428978; Java_com_example_ndkreverse6_lesson6_main+34o. Data.rel.ro:70428979 DCB 0.data.rel.ro:7042897a DCB 0.data.rel.ro:7042897b DC B 0.data.rel.ro:7042897c DCD _zti7derived;                 ' TypeInfo for ' derived.data.rel.ro:70428980 DCD _zn7derived7displayev+1.data.rel.ro:70428984 DCD _zn7derivedd2ev+1.data.rel.ro:70428988 DCD _zn7derivedd0ev+1
. rodata:704267b0; ' TypeInfo name for ' base.rodata:704267b0 _zts4base DCB "4Base", 0; DATA XREF:. Data.rel.ro:_zti4base+4o.rodata:704267b6 ALIGN 4.rodata:704267b8 WEAK _zts7der Ived.rodata:704267b8; ' TypeInfo name for ' derived.rodata:704267b8 _zts7derived DCB "7Derived", 0; DATA XREF:. data.rel.ro:_zti7derived+4o.rodata:704267c1 ALIGN 4.rodata:704267c4 aLesson6 DCB "Lesso N6 ", 0; DATA xref:base::d isplay (void) +eo.rodata:704267c4;. text:off_70421fd4o .... rodata : 704267CC abasedbasechard DCB "base:%d, basechar:%d", 0.rodata:704267cc; DATA xref:base::d isplay (void) +10o.rodata:704267cc;. text:off_70421fd8o.rodata:70 4267E1 aderiveddderive DCB "derived:%d, derivedchar:%d", 0.rodata:704267e1;      DATA xref:derived::d isplay (void) +eo.rodata:704267e1                                   ;. TEXT:OFF_70422000O.RODATA:704267FC abase___ DCB "~base ...", 0;  DATA xref:base::~base () +10o.rodata:704267fc;. text:off_7042202co.rodata:70426806 aderived___ DCB "~derived ...", 0; DATA xref:derived::~derived () +10o.rodata:70426806;. text:off_70422060o.rodata:70 426813 abase____0 DCB "Base ...", 0; DATA xref:java_com_example_ndkreverse6_lesson6_main+24o.rodata:70426813;. text:o ff_704220eco.rodata:7042681c aderived____0 DCB "Derived ...", 0; DATA xref:java_com_example_ndkreverse6_lesson6_main+36o.rodata:7042681c;. text:o Ff_704220f4o

When we see the execution of the display method, we first remove the virtual table pointer from the object's first address, then remove the address of the specific display instruction from the memory cell pointed to by the virtual table pointer, and then jump to the corresponding instruction execution.

. TEXT:70421FDC; _dword Derived::d isplay (Derived *__hidden this). TEXT:70421FDC WEAK _ZN7DERIVED7DISPLAYEV.TEXT:70421FDC _ZN 7derived7displayev;                 DATA XREF:. DATA.REL.RO:_ZTV7DERIVED+8O.TEXT:70421FDC.TEXT:70421FDC var_10 = -0X10.TEXT:70421FDC.TEXT:70421FDC PUSH {r0,r1,r4,lr}.text:70421fde MOVS R4, R0; The R4 is assigned to R0, the first address of the memory unit that was just allocated. TEXT:70421FE0 LDRB R3, [R0, #0x10]; Removes the second variable of the subclass from the memory cell, which is the value of Derivedchar. text:7042 1fe2 Ldr R1, = (ALESSON6-0X70421FEC). Text:70421fe4 Ldr R2, = (aderiveddderive-0x     70421FEE). Text:70421fe6 STR R3, [SP, #0x10 +var_10]; stored as a fifth parameter is passed in the stack. Text:70421fe8 ADD R1, PC; "Lesson6". Text:70421fea ADD R2, PC; "Derived:%d, derivedchar:%d". Text:70421fec LDR R3, [R4, #0xC]; The fourth parameter is the first variable of the subclass, which is the value of derived. Text:70421fee MOVS R0,#3. text:70421ff0 BL j_j___android_log_print.text:70421ff4 MOVS R0, R4; This returns the this pointer. Text:70421ff6 BL _zn4base7displayev; Base::d isplay (void). Text:70421ffa POP {r0,r1,r4,pc}

Then, we continue the destructor, the idea and the display method is the same, first remove the virtual table pointer from the object's first address, and then from the virtual table pointer + 8 point to the memory unit to remove the specific derived class destructor address, and then jump to the corresponding instruction execution.

.text : 70422064; _dword __fastcall derived::~derived (Derived *__hidden this). text:70422064 WEAK _zn7derivedd0ev.text:704220 _zn7derivedd0ev;    DATA XREF:. data.rel.ro:_ztv7derived+10o.text:70422064 PUSH {r4,lr}.text:70422066 MOVS R4, R0; The R4 is assigned a value of R0, which is the first address of the object. text:70422068 BL _zn7derivedd2ev; Derived::~derived (). text:7042206c MOVS R0, R4; void * R0 is assigned to the first address of the object. text:7042206e BL _ZDLPV; operator delete (void *) Real free heap space. text:70422072 MOVS R0, R4 
. text:70422030; _dword __fastcall derived::~derived (Derived *__hidden this). text:70422030 WEAK _zn7derivedd2ev.text:704220 _zn7derivedd2ev; CODE xref:derived::~derived () +4p.text:70422030; DATA XREF:. data.rel.ro:_ztv7derived+co.text:70422030 PUSH {R4,LR}; Alternative name is ' derived::~derived () '. text:70422032 MOVS R4, R0;                 The R4 is assigned a value of R0, which is the first address of the object. text:70422034 LDR R3, = (_ztv7derived_ptr-0x7042203e). text:70422036                 Ldr R1, = (alesson6-0x70422042). text:70422038 Ldr R2, = (aderived___-0x70422044). text:7042203a ADD R3, PC; _ztv7derived_ptr.text:7042203c LDR R3, [R3]; The ' vtable for ' Derived R3 takes out the virtual table pointer of Derived, pointing to. data.rel.ro, i.e. 0x70428978.text:7042203e ADD R1, PC;         "Lesson6". text:70422040 ADD R2, PC ; "~derived". text:70422042 ADDS R3, #8; The R3 is assigned the virtual table pointer of derived +8, which is 0x70428980.text:70422044 STR R3, [R0]; assigns 0x70428980 to the first address of the memory unit just allocated. text:704                 22046 MOVS R0, #3. text:70422048 BL j_j___android_log_print.text:7042204c MOVS R0, R4; This R0 is assigned the first address of the object. text:7042204e BL _zn4based2ev;     Base::~base () invokes a destructor for the parent class. text:70422052 MOVS R0, R4; Returns the first address of the object. text:70422054 POP {R4,PC}
. text:70422004; _dword __fastcall base::~base (Base *__hidden this). text:70422004 WEAK _zn4based2ev.text:70422004 _ZN4BaseD 2Ev; CODE xref:derived::~derived () +1ep.text:70422004; Base::~base () +4p.text:70422004; DATA XREF: text:70422004 PUSH {R4,LR}; Alternative name is ' Base::~base () '. text:70422006 MOVS R4, R0;     R4 is assigned to the first address of the object. text:70422008 Ldr R3, = (_ztv4base_ptr-0x70422012). text:7042200a LDR                 R1, = (alesson6-0x70422016). text:7042200c LDR R2, = (abase___-0x70422018). text:7042200e ADD R3, PC; _ztv4base_ptr.text:70422010 LDR R3, [R3]; ' vtable for ' base takes out the virtual table pointer of base, pointing to. data.rel.ro, i.e. 0x70428960.text:70422012 ADD R1, PC; "Lesson6". text:70422014 ADD R2, PC          ; "~base". text:70422016 ADDS R3, #8; R3+8 to r3,r3 points to 0x70428968.text:70422018 STR R3, [R0]; assigns 0x70428968 to the first address of the memory unit that was just allocated (the memory unit pointed to). Tex t:7042201a MOVS R0, #3;          R0 is the first parameter, assigned to 3.text:7042201c BL j_j___android_log_print.text:70422020 MOVS R0, R4 Returns the first address of an object. text:70422022 POP {r4,pc}

0x03

Summary: The members of the parent class are at a low address, the members of the subclass are at the high address, the virtual table pointer is at the first address of the object, the parent class is constructed, the virtual table pointer points to the virtual table of the parent class , and the virtual table pointer points to the virtual table of the child class. When the object is destructor, the child class is first destructor, the virtual table pointer points to the virtual table of the subclass, then the parent class, and the virtual table pointer points to the virtual table of the parent class.

Android so reverse-object inheritance and virtual functions

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.