【CrackMe】静态分析详细过程

文章正文
发布时间:2025-10-20 23:52

本帖最后由 逗比_滑稽 于 2024-1-21 17:31 编辑

属实是我干我自己了

,看到这次的参与度还是挺高的

,甚至已经有了两篇动态,静态的分析帖子,为此我也来发篇帖子,补充一下里面的知识点,这次的CrackMe并不难,主要是考验基础知识。

CrackMe:CrackMe

正文:
从进入程序可以得知,密码格式是x-x-x-x,而x是我们要分析的。

随便输入一个密码,得到提示:错误

直接从dex搜索此字符串能直接找到

转成java代码能发现这个toast弹窗并不是if来决定的,而是try catch(Exception),这是异常捕获,如果try{}代码发生Exception的异常,就会捕获这次异常,并执行catch{}里的代码。

所以这段代码里发生了某种异常,而这里只有value方法最有可能是导致异常的关键点,我们输入的密码会交给value方法,value方法返值最后会交给反射处理,如果value的值有问题或者value方法因某种原因发生异常都会提示密码错误。

查看其方法代码,输入的内容会经过\\-字符分割,split方法分割方式是通过正则表达式进行分割,如果是敏感字符?-.$这些都需要用\转义成普通字符,也就说输入的内容通过-字符分割,分割出来的数组长度不为4则返回null,否则将分别传入方法进行验证。

看向这个条件,第一部分的密码传入getInstance方法,接着从index方法返回一个int,这个int必须为1。

跳转进getInstance方法,这里又将密码通过Y字符进行一次分割,且必须是分割成两份。

接着遍历d字段的类实例数组,数组是由a,b,c字段的实例组成的,这三个字段你可以理解都是一个容器,存储着一个String值和int值

接着通过Y字符分割的两部分来与比较是否与字段内容完全符合,也就是与这字段的String值和int一致,如果一致就会返回这个字段实例,如果都不匹配则返回null。

所以我们有三个密码可以选择
AY147
BY258
CY369
但究竟哪个是真密码呢,index方法会给我们答案,它实例化了一个list,并把d字段(a,b,c)的三个实例集合到了list,接着索引当前实例在这个list所在的位置,我们需要让index返回1,所以需要getInstance返回b字段的值(程序从0开始数),所以第一部分的密码是BY258

BY258-x-x-x

复制代码



第二部分密码转换成了int值并传入IF方法,返回一个布尔值,如果布尔值不为true则返回null,我们能肯定第二部分密码是数字。

进入IF方法,int参数分别给了I和I2方法,如果I和I2的返回值一致则返回true

这时查找I方法却发现找到了很多,我们不能直接断定是谁实现的。

这里考验你对抽象类的理解,抽象类不是一个完整的类,类带有abstract修饰词就是抽象类

而方法带abstract就是抽象方法

抽象类的特点:
1.抽象类不能被实例化但抽象类的子类可以
2.抽象类的子类负责重写抽象方法
3.抽象类可以有非抽象方法,非抽象实例方法调用抽象方法可以视为调用子类重写的抽象方法。

也就是说,想找到是哪个子类重写的I和I2方法,我们得知道num字段的实例是哪个子类的

从代码中字段实例的类来看并不能确定是哪个子类实例化的,子类把自身实例化后声明自己是抽象类的实例
(继承关系:子类的类实例可以声明是父类的实例)

而且查一下iput调用特别多

虽然我们可以慢慢分析找出最终是谁实例,但在iput这么多的情况我更建议log打印,主要省事。

输入一遍假密码BY258-1-2-3就打印出来了,最终得知抽象方法由com.doubihuaji.CrackMe.num.D类重写
(继承关系:即使子类实例化后声明自己是父类实例但实际还是子类的实例)

搜索com.doubihuaji.CrackMe.num.D类得到以下代码
一道初中题目:462+a=13a+6,求a值
最终答案为38

BY258-38-x-x

复制代码



第三部分密码就是反射处理了,如果了解过java反射那几个api很容易分析出密码,它反射C字段类中str2的方法,传入了context和密码最终返回一个布尔值,如果值不为true则返回null

反射的类和方法的字符串以byte字节存放

通过解码我们知道反射的目标

搜索com.doubihuaji.CrackMe.M类,得到以下代码

解码一下就是源码了

它获取的自身应用包名,以.分割出三份字符

com.doubihuaji.CrackMe

复制代码


取索引1的字符,并加密成哈希值最终和密码比较是否一致,所以第三部分密码为696619202。

BY258-38-696619202-x

复制代码


第四部分密码,也是最简单的

,有点数据类型常识就能分析出来。
密码传入了J方法,方法最终返回的值强转Integer数据类型,所以说我们需要一个Integer数据类型。

跳转进J方法,不知道有没有人被我骗到


认真看J有多出来一点东西,所以这压根并不是真正的J方法

真正的J方法在哪呢,答案在父类J2
(继承关系:子类可以直接访问父类的public实例方法)

跳转到J2类,得到下面代码。
它遍历了text字段数组,如果取到的字符串与第四部分密码一致则返回当前索引位置的中value的值,否则返回null。

我们需要一个Integer数据类型,所以第四部分密码是8odnnUj59N2Fk
最终我们得到完整密码

BY258-38-696619202-8odnnUj59N2Fk

复制代码


 

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册