Android SO逆向-数组与指针

    0x00

    这一节主要分析一维数组、二维数组、数组指针和指针数组的汇编实现。


    0x01

    我们先直接看C++代码:

#include "com_example_ndkreverse3_Lesson3.h"
#include <android/log.h>
#define LOG_TAG "lesson3"
#define ALOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))

//参考http://blog.csdn.net/jltxgcy/article/details/17756391
JNIEXPORT void JNICALL Java_com_example_ndkreverse3_Lesson3_main
  (JNIEnv * env, jobject jobject) {
	int a[] = {1,2,3,4,5,6};
	for(int i = 0; i< 6; i++) {
		ALOGD("a=%d\n", a[i]);
	}
}

JNIEXPORT void JNICALL Java_com_example_ndkreverse3_Lesson3_main1
  (JNIEnv * env, jobject jobject) {
	int b[][3]={
  {1,2},{3,4,5}};
	for(int i = 0; i< 2; i++) {
		for(int j = 0; j < 3; j++) {
			ALOGD("b=%d\n", b[i][j]);
		}
	}
}

JNIEXPORT void JNICALL Java_com_example_ndkreverse3_Lesson3_main2
  (JNIEnv * env, jobject jobject) {
	char *d[] = {"12","345","6789"};
	for(int i = 0; i< 3; i++) {
		for(int j = 0; j < 4; j++) {
			ALOGD("d=%d\n", *(*(d + i) + j));
		}
	}
}

JNIEXPORT void JNICALL Java_com_example_ndkreverse3_Lesson3_main3
  (JNIEnv * env, jobject jobject) {
	int a[] = {1,2,3,4,5,6};
	int *p = a;
	for(int i = 0; i< 6; i++) {
		ALOGD("p=%d\n", *(p + i));
	}
}

JNIEXPORT void JNICALL Java_com_example_ndkreverse3_Lesson3_main4
  (JNIEnv * env, jobject jobject) {
	int b[][3]={
  {1,2},{3,4,5}};
	int (*p)[3] = b;
	for(int i = 0; i< 2; i++) {
		for(int j = 0; j < 3; j++) {
			ALOGD("p=%d\n", *(*(p + i) + j));
		}
	}
}


    0x01

    下面我们用ida打开so,分别对不同函数的汇编形式的代码做出解释。

    Java_com_example_ndkreverse3_Lesson3_main:

.text:00000EC8                 EXPORT Java_com_example_ndkreverse3_Lesson3_main
.text:00000EC8 Java_com_example_ndkreverse3_Lesson3_main
.text:00000EC8
.text:00000EC8 var_2C          = -0x2C
.text:00000EC8 var_14          = -0x14
.text:00000EC8
.text:00000EC8                 PUSH    {R4-R6,LR}
.text:00000ECA                 SUB     SP, SP, #0x20 ;开发了0x20个地址空间作为存储堆栈的位置
.text:00000ECC                 ADD     R4, SP, #0x30+var_2C ;R4赋值为SP+4
.text:00000ECE                 MOVS    R1, R4               ;R1和R4的值一样
.text:00000ED0                 LDR     R2, =(__stack_chk_guard_ptr - 0xED6) ;位于.got段中__stack_chk_guard_ptr相对于下一条PC指令的偏移,取出来赋值给R2
.text:00000ED2                 ADD     R2, PC ; __stack_chk_guard_ptr       ;R2中存放的是位于.got段中__stack_chk_guard_ptr的地址
.text:00000ED4                 LDR     R2, [R2] ; __stack_chk_guard         ;取地址中的内容,我们看下面代码,这个地址是__stack_chk_guard,这个地址运行时分配的
.text:00000ED6                 LDR     R3, [R2]                             ;取这个地址中的内容,我在动态调试状态下得到的内容为6BCAA164
.text:00000ED8                 STR     R3, [SP,#0x30+var_14]                ;把这个值6BCAA164存放在SP+0x1C的位置
.text:00000EDA                 LDR     R3, =(unk_226C - 0xEE0)              ;位于.rodata,unk_226C相对于下一条PC指令的偏移,取出来赋值给R3
.text:00000EDC                 ADD     R3, PC ; unk_226C                    ;R3存放的是位于.rodata段中unk_226C的地址
.text:00000EDE                 LDMIA   R3!, {R0,R5,R6}      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值