代码编译,使用代码如下:

#include <stdio.h>
#include <string.h>
int fun1()
{
	int a;
	int b;
    b=10;
    a=b++;
	return a;
}
int fun2(int a,int b)
{
	return a+b+fun1();
}
int fun3(int a,int b,int c,int d,int e,int f,int g,int h)
{
    if(a+b+c < d+e+f){
        return a+b+c+fun2(a,f);
    }else if(a+b+c > d+e+f){
        return a+b+c+fun2(b,e);
    }else{
        return 0;
    }
}

int main()
{
	int tmp;
    printf("%d",fun3(1,2,3,4,5,6,7,8));
	return 0;
}

makefile文件同之前的基本一致

#设置目录
NDK_ROOT=D:\Androidstudio-sdk\android-ndk-r14b
TOOLCHAINS_ROOT=$(NDK_ROOT)\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)\bin\arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)\lib\gcc\arm-linux-androideabi\4.9.x\include-fixed
PLATFORM_ROOT=$(NDK_ROOT)\platforms\android-14\arch-arm
PLATFORM_INCLUDE=$(PLATFORM_ROOT)\usr\include
PLATFORM_LIB=$(PLATFORM_ROOT)\usr\lib
MODULE_NAME=app6
BUILD_TYPE=c
PATH_ANDROID=/data/local/tmp/
RM=del
FLAGS=-I$(TOOLCHAINS_INCLUDE) \
    -I$(PLATFORM_INCLUDE) \
    -L$(PLATFORM_LIB) \
    -nostdlib \
    -lgcc \
    -Bdynamic \
    -lc    \
    -O0
OBJS=$(MODULE_NAME).o \
    $(PLATFORM_LIB)\crtbegin_dynamic.o \
    $(PLATFORM_LIB)\crtend_android.o
all:
    $(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -c $(MODULE_NAME).$(BUILD_TYPE) -o $(MODULE_NAME).o -pie -fPIE
    $(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -S $(MODULE_NAME).$(BUILD_TYPE) -o $(MODULE_NAME).S -pie -fPIE
    $(TOOLCHAINS_PREFIX)-gcc $(FLAGS) $(OBJS) -o $(MODULE_NAME) -pie -fPIE
clean:
    $(RM) *.o
install:
    adb push $(MODULE_NAME) $(PATH_ANDROID)
    adb shell chmod 755 $(PATH_ANDROID)$(MODULE_NAME)
    adb shell $(PATH_ANDROID)$(MODULE_NAME)

编译后如下,会生成一个无后缀的可执行文件。丢到IDA中。点击main函数,如下:

1562658661016

其中已经简单分析函数参数的引用,开头可以看到,参数[sp],意思是第五个参数引用,若后面还有其他参数则以四个字节为参数引用存储。关于寄存器的含义

r0-r3    用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。
r4-r11   被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。
r12      是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。
r13      是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。
r14      是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复
r15      是程序计数器 PC。它不能用于任何其它用途。

详细介绍参考:https://www.veryarm.com/36274.html

到BL指令,BL指令是有返回的跳转,表示子程序的返回通过LR寄存器保存,保存的地址值就是下一条指令的地址值。如下的fun3函数中,对于多参数并没有使用栈来保存,而是使用R0-R3寄存器来循环的调用。

1562659401125

判断结束后进入不同的分支,走到如图中的两部分分支的时候出现了一个新的子程序调用,fun2。

1562659598100

点击fun2,其中又调用了fun1函数,同样点击fun1。

1562659844246

通过fun1就可以看到函数的具体操作行为,其中最后返回值BX,带状态切换返回,其中的LR则为fun2的函数MOV的地址值,返回到fun2中继续执行。

1562659872641

而fun2中的最后代码也对应了开头的两个汇编语句,恢复sp指令值,将栈内容恢复到寄存器中。获取到参数值后,回到MOV指令中其中注释的fun1和fun2代表当前分支的输入参数。最后都执行到loc_4B8,结果保存到R0中返回,最后也是恢复sp和寄存器。

1562662004752

这时候再看main函数最后执行,获取的fun3返回赋值给R2,至于LDR和ADD,代表了读取unk_5C8标记处的参数字段,点击则可以看到是“%d”,也就是R3代表“%d”,R1代表参数返回值。由printf来输出。最后返回0。结束函数执行。

1562662154590

此汇编分析主要是函数调用和返回之间的联系,希望也可以为后面的读取APP so文件打下基础把。





# Android逆向  

tocToc: