欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]Android下ARM静态反编译逆向.(小试多玩YY协议)

[原创]Android下ARM静态反编译逆向.(小试多玩YY协议)

标 题: 【原创】Android下ARM静态反编译逆向.(小试多玩YY协议)

    最近有人问到YY协议,好像网上是有人已经搞出来了,不过这不是重点,重点是如何分析.回到主题:
    现在使用android基本上的保护方法都差不多,java部分都基本混淆(类名称混淆,过程混淆,字符混淆,多层继承混淆),其实这基本上都是增加一些难度而已,大部份静态都可以逆向出来的.
    所以很多程序重要的加密部分都使用JNI,放到SO文件里.不过以现在的情况来看,SO里都没有使用混淆或是像PC下的加壳或是VM等东西,所以现在也基本不难,不过ARM使用的是RSIC指令,本来ARM也刚出来几年,所以了解RISC的,还不是很多.
    本帖子也只是小笔记,可能需要一定的基础,太细节的东西可能不会详细说明,敬请谅解.
    本次主要目的是为了逆向 Java_com_duowan_mobile_service_GenKey_generateKey.(函数作用是不清楚,好像跟协议有关,现只是正好拿来讲解)
    首先要到JAVA中找到程序的原型(用JD-GUI),为是查看传入的参数和返回.

参数为byte数组,返回也是byte数组
然后找到在IDA打开libyyjni.so进行反编译.

好了,现在大概了解一下汇编的JNI的东西.为了了解JNI,得自己会写一点JNI.根据上面的函数,也写个大概类似的函数.


在JNI中,
第一个参数为JNIEnv,固定,可以理解为一个类的指针,类里包含了C++与JAVA数据转换的方法,比如把JAVA中的Byte数组转为C++下的jbyteArray
第二个参数为thiz,固定,即相当于JAVA下的this,指向当前类的指针.
第三个才是用户自定的参数, Byte[]在C++下就是jbyteArray.

回到 Java_com_duowan_mobile_service_GenKey_generateKey

R0 是 JNIEnv*
R1  是thiz
R2 是第一个参数


第1行 PUSH    {R4-R7,LR} 如果压入寄存器从R3开始,表示没有参数,从R4则表示有一个或以上.LR是要返回的地址.调用时自动压入LR.
//// 最后一行 POP     {R4-R7,PC},一般是和第一行执行相反的出栈动作.将LR放入到PC,PC是下一条命令的地址,改变它的值也就相当跳转.
第2行 MOV     R7, R8      把R8传给R7,
第3行 PUSH    {R7}        再把R7压入. 相当于把R8也存压入栈,似乎PUSH一次只能压入8个寄存器,所以超过8个要另行压入.
第4行 MOVS    R6, R2   把R2传给R6,即把第一个参数Byte[]再放R6中,注意到第二是MOV,这一行是MOVS,其实都差不多,只MOVS会影响到影响CPSR
第5行 LDR     R2, [R0]   取出R0指针所指向的值放到R2,即取出JNIEnv* ,也就是JNIEnv (JNIEnv*其实是一个指向指针的指针)
第6行 MOVS    R3, #0x2AC     将0x2AC传入到R3中,下面介绍用途
第7行 SUB     SP, SP, #8     SP指当前栈,此处栈的位置减去8,作用不明.
第8行 LDR     R3, [R2,R3]    取出R2即JNIEnv(第5行),并偏移0x2AC所指向的内存的值.放到R3中,JNIEnv+0x2AC指向的是GetArrayLength

见下面(所有的函数在附件中)


第9行 MOVS    R1, R6         这是GetArrayLength第二个参数(第4行),即第一个参数Byte[]
第10行 MOVS    R4, R0         RO一般是放返回值的,调用函数后会被覆盖的,所以复制到R4中
第11行 BLX     R3             调用GetArrayLength, 第一个参数是R0,是JNIEnv,本来就在R0的,所以现在直接调用GetArrayLength,获取数组的长度
第13行  LDR     R2, [R4]       R4就是JNIEnv*(第10行),取出JNIEnv放到R2中
第14行  MOVS    R3, #0x2E0     将0x2E0传入到R3中
第15行  LDR     R3, [R2,R3]    取出JNIEnv+0x2E0指向的值,查表,是GetByteArrayElements
第16行  MOVS    R1, R6         第二参数是本函数的第一个参数Byte[](第4行)
第17行  MOV     R8, R0         R0现在放着是上面GetArrayLength的返回值,为了不被下面的返回值覆盖,要复制到R8中
第18行  MOVS    R2, #0         第三个参数是0
第19行  MOVS    R0, R4         第一个参数是JNIEnv*
第20行  BLX     R3             调用GetByteArrayElements
第21行 MOVS    R7, R0         R0现在放着是上面GetByteArrayElements的返回值,为了不被下面的返回值覆盖,要复制到R7中
第22行 MOVS    R0, #0x10      第一个参数10
第22行 BL      _Znaj           ; operator new[](uint)   即int myint[0x10];

[未完,待续]
先写到这进里, 交流可Q: 3.1.0.4.1.9.0.6.2 (倒序)
-

上传的附件 JNI_ENV_FUNCTIONS.xls
QQ图片20130622232625.jpg
QQ图片20130622231850.jpg
QQ图片20130622233844.jpg
QQ图片20130623010929.jpg

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功