0
0
0

Android改造者之路 02 · 初探smali功法

文章摘要
|

第 02 章 初探smali功法

原帖标题:【原木文章】Android改造者之路-02.初探smali功法 | 发表于 2021-7-30 18:24:54 | 链接

前情提要

其实光了解apk的形成,还无法成为改造者。

没有招式,没有武功,没有器具,又如何去战?

所以。。。是时候学习武功了。。。

前情提要

Android世界从开拓至今已有十几个年头,最初由Andy Rubin创造于2003年,后由google慧眼识英雄在2005年将android与团队一併收购注资。2008年,第一支以android为主的手机降临于世。2年后,不再低调的它,更以绿铁人的样貌公布于世,决心往泡沫时代掀起一股android热潮。

辗辗转转十几年后的今天,Android世界筑起了六大门派。

开发者: 以创造,创新为主,所有apk程序都由他们创建。

改造者: 以改造,变形为主,对他们来说,apk程序皆可改造。

神造者: 以玩世,DIY 为主,他们喜欢规划android世界的一切。

潜伏者: 以欺骗,破坏为主,暗器毒液是他们的看家本领。

潜造者: 以伪装,潜行为主,他们喜欢潜藏在apk程序里进行窥探。

保卫者: 以维护,持法为主,所有企图破坏android世界秩序的都逃不过他们法眼。

天下武学不外乎2类,内功心法,外门武学。

再配上神兵利器,灵丹妙药,偶尔再来一些机遇。

那么离大师之路就不远了。

然而每个门派,都有无数个子派衍生而来,以自身的经历与领悟形成独树一帜的存在。

但是万变不离其宗,只有掌握好了基础功夫,方能来去自如。

对于改造者来说《逆向》,是主要心法,修的不是招式,技巧或手法。

而是心智上的 洞察,推算,知识,分析,辨别,联想,领悟。

洞察: 通过操作与观察程序的变化,寻找出突破口。

推算: 根据已知数据,符合逻辑规律去推算程序各种保护可能。

知识: 利用对改造的认知,经验与需求,寻找有效的解决方案。

分析: 将程序结构从思维逻辑上有规则性的进行探索并将其简化成可理解的方式。

辨别: 对程序的分析与理解,并进行鉴选与排查,以定位与锁定关键位置。

联想: 结合知识,分析,与对程序的了解等引发出假设性,战略性,逻辑性等思维策略。

领悟: 领悟不是学会了,而是明白了正确的使用姿势,并能在未知的领域发挥效果。

一些试图想成为改造者却又毫无进展的人,或许并非因为自身资历低,其实更多原因就在于只懂其形,却不知其意,只学会了功法,却没领悟心法。才导致只有虚招,没有实感的效果。

对于心法,只可意会,无法言传,只能靠自己用心去揣摩,领悟当中的奥秘。至于未来能走到哪里,生活迟早都会给你答案,所以不必急于求成。

天地初开,万物混沌,清者上天,浊者下地,物竞天择,适者生存,都只不过是时代的产物。

android的世界也是如此,dalvik是一款早期依赖linux内核用于android世界的java虚拟机,执行君dex 全称Dalvik Executable,是为了能在dalvik虚拟机里运行而诞生的产物,直到android 5.0的到来,google为了拥有更好的应用性能,彻底淘汰了dalvik,取而代之的是Art(Android Runtime)。

dex是由java开发,并通过dx编译而成的dalvik字节码。

它存放着开发者所编写的Java代码。

java是一种面向对象的编程,一条狗,一台手机,一片树叶都可以是对象,它就像现实世界的浓缩版。

例: 伸手拿起桌上手机,在代码里都必须编写清楚每一个步骤,每一个细节,而不是伸手就直接手机。

对于改造者来说,想对Java进行修改则必须学会第一套功法

《撕码.利剑流》(smali)。

《撕码.利剑流》撕代码的利剑。

本文会介绍此剑法的12种属性变化,和常用的10种流式功法。

它有着施展的环境,也存在着释放的条件。

反编译后的dalvik汇编代码,就是它独领风骚的舞台。

以下来看看撕码.利剑流的展示环境。

(搬凳子看戏咯~)

小剧场模式

导演: 小杰,最近其他剧组的场景越来越逼真,都很舍得下重本,咱们也不能输人啊。

美术: 好嘞。。。陈导,这一次我们美术组制作的场景环境,您看看是否满意。

美术助理: 陈导,接下来由我给您介绍我们此次的架构。

.class 场景名称,每个场景都会有名称,此场景名为BaseApplication。称为类名。

.super 上级场景,场景与场景之间都会有关联性,super则是继承的上级场景名称。称为父类名。

.source 素材名称,场景的原稿名,此原稿名是BaseApplication.java。称为源名。

.field 容器名称, 有些场景会需要使用一些容器存放物品,就会在这里注明报备。称为变量。

.method 场景内的片段,每个method都是一个片段的入口。称为方法名。每个片段都是环环相扣,片段与片段之间的连贯才会是一部完整的戏剧。

.register 小片段存在的人数,这里会记录此片段有多少人参与,不可多也不可少,除非修改register的总人数。称为寄存器。

蓝色字体 演出的流程,这片段怎么演都是依照这些流程。

(一般改造就是将流程原来的演绎,修改成自己喜欢的剧情)

v0/p0 v=临员,临员只在小片段里需要。p=主角,主角会从一个片段到另一个片段中穿梭,甚至可以在其他场景中穿梭。p称为参数。

return 片段演出完毕。

.end method 片段出口,方法名的结束。

表示声明。

美术: 陈导,我们还把场景设置为三大类,这样可以更有效率的加快拍摄进度。

public: 公共场景,可以从不同场景自由进出。

protected: 权限场景,只有继承于它的场景才能使用,类似一间家,厨房,房间,客厅都属于家的范围,就可以自由使用。

private: 私有场景, 只提供给自身使用,外人都不可进入。

导演: 不错不错,今晚给你们全组加鸡腿。

美术:(齐声) 谢谢陈导。

小剧场模式

撕码.利剑流释放条件不仅仅只是蓝色部分,它还可以对整个dex都释放招式以符合改造者的需求,并且还可以自定义增加新的场景,新的片段。

撕码.利剑流的12种属性变化分别有

1.void-无属性,标记为v (无返回值)

2.boolean-真假属性,标记为Z (返回0或1)

3.byte-字节属性(8bit),标记为B (返回字节)

4.short-短整数属性(16bit),标记为S (返回数字)

5.int-整数属性(32bit),标记为I (返回数字)

6.long-长整数属性(64bit),标记为J (返回数字)

7 char-字符属性,标记为C (返回字符)

8.string-文本属性,标记String (返回字符)

9.float-单浮点属性(32bit),标记为F (返回数字)

10.double-双浮点属性(64bit),标记为D (返回数字)

11.array-数组属性,标记为[ (返回数组)

12.object-对象属性,标记为Lxxx/xxx/xxx (返回对象)

撕码.利剑流的10种流式功法分别有

1.定义法 const

代码重定术,它可以重写任何属性内容,修改成自己需要的结果。

此术一共有四式

第一式 const,重写整数属性,真假属性内容,只能是数字类型。

第二式 const-string,重写文本属性内容,可以是任何语文或数字。

第三式 const-wide,重写长整数类型,多用于修改到期时间。

第四式 const-class,用于对象属性,获取一个object的引用数据。

2.调用法 invoke

代码追踪术,需要靠它追踪程序的来龙去脉,穿梭在任何场景与片段之间,掌握程序的代码流程。

此术一共有五式

第一式 invoke-direct,用于追踪构造函数,即代码的init初始化,和私有函数,即private场景里的片段。

第二式 invoke-static,用于追踪静态函数,所有有声明static的片段都使用此招式。

第三式 invoke-vitrual,所有场景里的片段都是虚函数,如果没有声明static,final,private的都使用此方式进场。

第四式 invoke-super,用于追踪父函数,即上级场景。

第五式 invoke-interface,用于追踪抽象函数,即abstract或android库接口。

3.操作法 move

代码转移术,一般invoke的结果会通过move保存到寄存器,配合代码重定术可修改寄存器结果。

此术一共有四式

第一式 move aa,bb,转移bb里的数据到aa,称为赋值。

第二式 move-object,用于转移对象类型。

第三式 move-result,转移invoke结果到寄存器,对于整数属性使用move-result,长整数属性使用move-result-wide,其他属性使用move-result-object。

第四式 move-exception,将异常信息保存到指定寄存器。

4.操作法 get/put

代码勾转术,开发者通常喜欢使用容器存放数据,然后通过get/put去读取/存储。改造者很多时候会配合代码重定术去调换里面内容以达到改造效果。

此术一共四式

第一式 iget,勾取容器的数据。

第二式 iput,调换容器的数据。

第三式 sget,用于静态容器的勾取。

第四式 sput,用于静态容器的调换。

5.运算法 math

代码解密术,常用于数据的解密运算,通过运算还原出加密数据的明文结果,同时亦可用于改造过程,const 是将数据结果写死,运算法则可以让数据结果按需求产生变化。常见有游戏里伤害倍数的修改。

此术一共有三式

第一式 算法运算,也就是加减乘除,java里符号为(+ - * /),在smali里则是,add(+),sub(-),mul(*),div(/),另外还有个rem(%),求余数。

第二式 逻辑元算,与and(&),或or(|),异或xor(^),将2组数字以2进制方式进行运算,2进制里只有0和1,0一般表示假,1一般表示真,and当两组都为1则真,or只要一组为1则真,xor两组不同为真。

第三式 位移运算,(有符号位移) shl(<<)相当于以2的倍数相乘,10<<2=1022,shr(>>)相当于以2的倍数相除,10>>2=10/2/2,

有符号运算不可大于32位,否则就会变负数(-)。

(无符号位移),ushl(<<<),ushr(>>>),与有符号基本一样,唯一不同可大于32位运算。

6.比较法 cmp

代码权衡术,改造中比较少用,用于权衡2组数据是否满足指定条件。

此术一共有三式

第一式 cmp,权衡2组数字是否一样,按定义数字类型的属性进行比较。

第二式 cmpl aa,bb,cc,这里l=litter(小于),如果bb小于cc则为1,相等则为0,大于则为-1。

第三式 cmpg aa,bb,cc,这里g=garden(大于),如果bb大于cc则为1,相等则为0,小于则为-1。

7.返回法 return

代码掌控术,return是小片段的结束,以通知其他片段此处已完成表演,并且返回表演进度,以让其他片段继续演出。改造者如果可以掌控关键片段的表演进度,即可影响全局剧情的变化。

此术一共有一式

第一式 return,按照不同的属性,所返回的数据属性必须和片段入口属性一样,可以看此篇文章唯一的图,method为v,即void的标记,就得使用renturn-void。

8.转换法 to/tostring/valueof/parse

代码变化术,常用于数据的属性转换,有时候在改造上会遇到通过对象的引用,这时候就得通过代码变化术或代码同化术去修改obeject数据。又或者有时候需要打印日志便于调式,这时候就得将其转换成文本属性。

此术一共有三式

第一式 to,int-to-long,float-to-int等,将数字属性强制输出为其他数字属性。

第二式 valueof,将原本属性封装成对象属性,文本属性。

第三式 parse,可以直接对数字属性转换为其他数字属性。

第四式 tostring,将封装的对象属性以文本方式输出。

9.跳转法 if

代码控制术,它可以控制所有场景里片段的剧情发展。绕过多余剧情,或改变剧情方向,甚至可以固定剧情走向,是改造者最常使用的招式之一。

此术一共有十四式

第一式 if-eq,全称equal(a==b),比较寄存器ab内容,相同则跳。

第二式 if-ne,全称not equal(a!=b),ab内容不相同则跳。

第三式 if-lt,全称little then(a<b),a小于b则跳。

第四式 if-gt,全称garden then(a>b),a大于b则跳。

第五式 if-le,全称little equal(a<=b),a小于或等于则跳。

第六式 if-ge,全称garden equal(a>=b),a大于或等于则跳。

第七式 if-eqz,全称equal zero(a==0),z即是0的标记,a等于0则跳。

第八式 if-nez,全称not equal zero(a!=0),a不等于0则跳。

第九式 if-ltz,全称little then zero(a<0),a小于0则跳。

第十式 if-gtz,全称garden then zero(a>0),a大于0则跳。

第十一式 if-lez,全称little equal zero(a<=0),a小于或等于0则跳。

第十二式 if-gez,全称garden equal zero(a>=0),a大于或等于0则跳。

第十三式 switch,分支跳转,一般会有多个分支线,并根据指令跳转到适当位置。

第十四式 goto ,霸体模式,无条件跳到指定位置。

10.实例法 instance

代码窥探术,常在江湖走,怎可以没有保命技能,此术可以窥探敌营情况并加以使用,驯化,布局,让其成为自己的一把利器。

此术一共有四式

第一式 new-instance,实例化一条已加载的对象属性, 这样就可以对此对象进行读取,添加,替换等操作。

第二式 instance-of,判断对象是否为指定类型,是则返回1,否则0。

第三式 check-cast,将对象引用转换为指定属性,成功转换则赋值,失败则抛出异常。

第四式 new-array,创建指定属性的数组。

第五式 fill-array-data,用指定数据添加到new-array数组里。

终于学会了一招半式,总算可以下山闯荡江湖了。

幻想中(山珍海味,美女如云。。。hohoho)

出发咯~~~

(走着。。。走着。。。)

咦~ 好像少了些什么。。。

对了,剑呢?

居然忘了拿剑,差点白学了。

ermmm。。。记得师傅说过藏兵阁收藏着不少神兵利器。

哟,那去藏兵阁走一回吧。。。

未完待续。。。

(注: 有空再更新。。。)

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

评论

欢迎来到我的博客!