【Android 逆向】ARM CPP 类对象

#include <stdio.h>

class aclass{
	private:
		int m;
		char c;
	public:
		aclass(int i, char ch) {
			printf("Constructor called.\n");
			this->m = i;
			this->c = ch;
		}
		~aclass() {//定义析构函数   
			printf("Destructor called.\n");
		}
		int getM() const {
			return m;
		}
		void setM(int m) {
			this->m = m;
		}
		char getC() const{
			return c;
		}
		void setC(char c) {
			this->c = c;
		}
		int add(int a, int b) {
			printf("%d\n", a+b);
		}
};

int main(int argc, char* argv[]){
	aclass *a = new aclass(3, 'c');
	a->setM(5);
	a->setC('a');
	a->add(2, 8);
	printf("%d\n", a->getM());
	delete a;
	return 0;
}
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_ARM_MODE := arm
LOCAL_MODULE    := cpp1
LOCAL_SRC_FILES := cpp1.cpp
include $(BUILD_EXECUTABLE)
text:00008600
.text:00008600 
.text:00008600
.text:00008600 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00008600 main                                    ; CODE XREF: j_main↑j
.text:00008600 ; __unwind {
.text:00008600                 PUSH    {R4-R6,LR}      ; 保存现场
.text:00008604                 MOV     R0, #8          ; unsigned int
.text:00008608                 BL      _Znwj           ; 调用new 创建一个8字节的内存区域
.text:0000860C                 MOV     R4, R0
.text:00008610                 LDR     R0, =(aConstructorCal - 0x8620) ; "Constructor called"的偏移
.text:00008614                 LDR     R5, =(aD - 0x862C) ; “%d\n”的偏移
.text:00008618                 ADD     R0, PC, R0      ; 获取“Constructor called" 首地址
.text:0000861C                 BL      puts            ; 打印“Constructor called”
.text:00008620                 MOV     R3, #5
.text:00008624                 ADD     R5, PC, R5      ; 获取“%d\n”字符串首地址
.text:00008628                 STR     R3, [R4]        ; 把R3的值5,保存到R4对象的前四个字节
.text:0000862C                 MOV     R3, #0x61 ; 'a'
.text:00008630                 STRB    R3, [R4,#4]     ; 把R3的值a,保存到R4所指对象的后四个字节
.text:00008634                 MOV     R1, #0xA        ; R1 = 10,这里编译器直接优化2+8为10
.text:00008638                 MOV     R0, R5          ; format
.text:0000863C                 BL      printf          ; 传入R0 和R1 分别是 “%d\n" 和10
.text:00008640                 LDR     R1, [R4]        ; R1 = 5对象的前四个字节,即字段m的值
.text:00008644                 MOV     R0, R5          ; format
.text:00008648                 BL      printf          ; printf 两个入参 R0 R1
.text:0000864C                 LDR     R0, =(aDestructorCall - 0x8658) ; "Destructor called."
.text:00008650                 ADD     R0, PC, R0      ; 获取“Destructor called" 首地址
.text:00008654                 BL      puts            ; 打印,一个参数编译器会把printf优化为puts
.text:00008658                 MOV     R0, R4          ; void *
.text:0000865C                 BL      _ZdlPv          ; _Zdlpv 为系统调用删除对象 ,R0为对象首地址
.text:00008660                 MOV     R0, #0
.text:00008664                 POP     {R4-R6,PC}      ; 恢复现场
.text:00008664 ; End of function main
.text:00008664
posted @ 2022-03-19 12:27  明月照江江  阅读(42)  评论(0编辑  收藏  举报