吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 20613|回复: 122
上一主题 下一主题

[Android 原创] 简单算法分析

  [复制链接]
跳转到指定楼层
楼主
发表于 2016-1-20 14:31 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 lakshmi 于 2016-1-20 14:52 编辑

刚刚接触Android 动态调试,于是决定用@Ericky 大牛 的帖子练手:http://www.52pojie.cn/thread-454527-1-1.html,第一次分析Android算法,大牛勿喷

首先(大牛都说了没有反调试,就不装逼走过场了)运行apk,随便输入验证码,弹出Sorry, Fish!

接着用JEB分析apk文件查找特征字符串“Sorry, Fish!”,找到验证过程,发现验证函数EatRice

于是在libxy.so, 找到函数如下,动态调试发现程序首先判断 输入字符串的第一个字符是否是 'X'(0x58), 第二个字符是否是'#'(0x23), 字符串长度是否为7, 如果不满足这些条件则等待3s然后 返回0。 由此判断验证码格式应该为:"X#-----", 其中"-"表示暂时未知的字符。此处假定该字符串的名字为szA.

调试程序发现程序会将szA[1:2],szA[2:3], szA[3:4], szA[4:5], szA[5:6]分别进行运算,并与相应的结果进行比较,如果结果都正确,才算成功。
     
szA[1:2] 计算过程   


                                      szA[2:3] 计算过程         
                                      
   
              szA[3:4] 计算过程

   
   
szA[4:5] 计算过程  



                                                                                                                          szA[5:6] 计算过程

具体算法就不描述了,具体看程序吧, 接下来说说破解过程吧,由于算法中涉及到了一些移位和反馈,因此倒推的难度比较高(个人认为), 但算法中是每两位一次进行运算而且每一位都是可见字符(0x21~0x7e),因此,此处的思路是逐位爆破,
此例中,在计算szA[1:2]时,szA[1] = '#'是已知的。则可以爆破出szA[2],  
        在szA[2:3]的计算过程中szA[2]已知, 则可计爆破出szA[3],
        以此类推,则可爆破出每一位的值,
        而计算时间复杂度也应该是O(1), 即最多(0x7e-0x21)*5 = 0x1d1 次运算即可算出答案,
接下来是破解程序:
[C++] 纯文本查看 复制代码
#include "stdafx.h"
#include <Windows.h>

//最后两位计算过程
int  sub_4B27B238(char *a1, int a2)
{
        int v2; // r7@1
        int v3; // r3@1
        int v4; // r4@1
        int v5; // r2@1
        unsigned int v6; // r6@2
        
        v2 = 0;
        v3 = 0;
        v4 = 0;
        v5 = 0;
        while ( a2 )
        {
                v6 = *(BYTE *)a1;
                v4 += (v6 >> 2) * v4 * v6 + 0x2FF54B62;
                v2 += 32 * v6 * v2 * v6 + 0x58ECCC20;
                v3 = v3 + 8 * v6 * v3 * v6 - 0x69C631BE;
                v5 = v5 + 2 * v6 * v5 * v6 - 0x4B4D073E;
                --a2;
                a1++;
        }
        return v4 + v5 + v3 + v2;
}


int _tmain(int argc, _TCHAR* argv[])
{
        //初始化
        CHAR szA[8] = {0};
        szA[0] = 'X';
        szA[1] = '#';


        DWORD dwStartFlag = 0x21;
        DWORD dwEndFlag = 0x7f;
        DWORD dwR6 = 0, dwR0 = 0, dwR2=0, dwR3 = 0;
        DWORD dwR7 = 0x0f8c9;
        DWORD dwR4 = 0, dwR5 = 0, dwR1 = 0;
        DWORD dwIndex;
        
        //计算szA[2] 
        for (DWORD dwTemp = dwStartFlag; dwTemp < dwEndFlag; dwTemp++ )
        {
              
                szA[2] = (CHAR)dwTemp;
                dwIndex = 0;
                dwR7 = 0x0f8c9;
                dwR4 = 0;
                dwR5 = 0;
                dwR1 = 0;
                dwR6 = 0;
                while (dwIndex < 2)
                {

                        dwR6 *= dwR7;
                        dwR6 += szA[1 + dwIndex];

                        //printf("%c\n", szA[1 + dwIndex]);
                        dwR1 = 0x05c6b7;
                        dwR7 *= dwR1;
                        dwIndex++;
                }
                dwR4 = (DWORD)((int)dwR6 >> 0x1f);
                
                dwR5 = dwR6 + dwR4;
                dwR5 = dwR5 ^ dwR4;
                //printf("%x\n", dwR5);
                if (dwR5 == 0x78689F66)
                {
                        printf("%c\n", dwTemp);
                        break;
                        
                }
        }

        //计算szA[3] 
        for (DWORD dwTemp = dwStartFlag; dwTemp < dwEndFlag; dwTemp++ ){
                dwIndex = 0;
                dwR5 = 0x4e67c6a7;
                dwR4 = 0;
                dwR1 = 0;
                dwR6 = 0;
                dwR7 = 0;
                dwR2 = 0;
                szA[3] = (CHAR)dwTemp;
                while(dwIndex < 2){
                        dwR7 = dwR5 << 5;
                        dwR0 = dwR5 >> 2;
                        dwR0 += (dwR7 + szA[2+ dwIndex]);
                        dwR5 ^= dwR0;
                        dwIndex++;
                }
                dwR0 = DWORD((int)dwR5 >> 0x1f);
                dwR2 = dwR5 + dwR0;
                dwR2 ^= dwR0;
                if(dwR2 == 0x5B578B6A)
                {
                        printf("%c\n", dwTemp);
                        break;
                }
                
        }
        //计算szA[4] 
        for (DWORD dwTemp = dwStartFlag; dwTemp < dwEndFlag; dwTemp++ ){
                dwIndex = 0;

                dwR4 = 0;
                dwR1 = 0;
                dwR6 = 0;
                dwR7 = 0;
                dwR5 = ~dwR7;
                dwR2 = 0;
                szA[4] = (CHAR)dwTemp;
                while(dwIndex < 2){
                        dwR0 = dwR7 << 4;
                        dwR6 = dwR0 + szA[3 + dwIndex];
                        dwR0 = 0x0f;
                        dwR2 = dwR0 << 0x1c;

                        
                        if(dwR7 == 0){
                                dwR7 = dwR6;
                        }
                        else
                        {
                                dwR0 = 0xffffffff;
                                dwR6 &= dwR0;
                                dwR7 = dwR7 >> 0x18;
                                dwR7 ^= dwR6;
                        }
                        dwIndex++;
                }
                dwR0 = DWORD((int)dwR7 >> 0x1f);
                dwR4 = dwR7 + dwR0;
                dwR4 ^= dwR0;
                if(dwR4 == 0x2d8){
                        printf("%c\n",dwTemp);
                        break;
                }
        }


        //计算szA[5] 
        for (DWORD dwTemp = dwStartFlag; dwTemp < dwEndFlag; dwTemp++ ){
                dwIndex = 0;
                dwR5 = 0;
                dwR4 = 0;
                dwR6 = 0;
                dwR3 = 0;
                dwR7 = ~dwR4;
                dwR2 = (0x0f << 0x1c);
                //printf("dwR2: %x\n", dwR2);
                szA[5] = (CHAR)dwTemp;
        
                while(dwIndex < 2){
                        dwR5 = szA[4 + dwIndex] + dwR4;
                        dwR6 = dwR5;
                        dwR6 = dwR6 & dwR2;
                        dwR4 = dwR5;
                        //printf("%x\n", dwR5);
                        //("dwR6: %x\n",dwR6);
                        if(dwR6 != 0){
                                dwR4 = dwR6 >> 0x18;
                                dwR4 ^= dwR5;
                        }
                        dwR5= dwR5 | 0x0fffffff;
                        dwR5 ^= dwR2;
                        //printf("dwR5: %x\n", dwR5);
                        dwR5 &= dwR4;
                        dwR4 = dwR4 << 4;
                        //printf("dwR5: %x\n", dwR5);
                        dwIndex++;
                }
                
                dwR3 = DWORD((int)dwR5 >> 0x1f);
                dwR2 = dwR5 + dwR3;
                dwR2 ^= dwR3;
                //printf("%x\n",dwR2);

                if(dwR2 == (0x0f << 6)){
                        printf("%c\n", dwTemp);
                        break;
                }
        }

         //计算szA[6]
        for (DWORD dwTemp = dwStartFlag; dwTemp < dwEndFlag; dwTemp++ ){
                szA[6] = (CHAR)dwTemp;
                dwR0 = 0;
                dwR2 = 0;
        
                dwR0 = (DWORD)sub_4B27B238(szA + 5, 2);
                dwR2 =  DWORD((int)dwR0 >> 0x1f);
                dwR0 = dwR0 + dwR2;
                dwR0 ^= dwR2;
        
                if(dwR0 == 0x2f0c12ec){
                        printf("%c\n", dwTemp);
                        break;
                }
        }

        printf("%s\n", szA);

运行结果:


免费评分

参与人数 31威望 +2 吾爱币 +40 热心值 +30 收起 理由
52lxw + 1 + 1 我很赞同!
siuhoapdou + 1 + 1 谢谢@Thanks!
钱后佛 + 1 + 1 666大神
supperlitt + 1 谢谢@Thanks!
UNCLE + 1 + 1 谢谢@Thanks!
dhs347 + 1 + 1 我很赞同!
wkong、 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
eason_chen + 1 我很赞同!
CLANNADS + 1 + 1 鼓励转贴优秀软件安全工具和文档!
守护神艾丽莎 + 1 热心回复!
Rainy + 2 + 1 我很赞同!
q74330 + 1 + 1 我很赞同!没有看懂但顶一个
mgnptlv + 1 + 1 热心回复!
courageous + 1 + 1 热心回复!
plmm20151111 + 1 + 1 用心讨论,共获提升!
TYHJ_独孤九剑 + 1 + 1 我很赞同!
461688115 + 1 + 1 吊吊吊
ewrest + 1 + 1 我很赞同!
specter + 1 + 1 热心回复!
夜的钢琴曲 + 1 热心回复!
夏日miku + 1 + 1 谢谢@Thanks!
soulovess + 1 + 1 我很赞同!
红尘旧梦~ + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
空人空心空回忆 + 1 + 1 支持技术贴!
EvillenG + 1 + 1 用心讨论,共获提升!
diaojianxiao + 1 + 1 谢谢@Thanks!
noblesport + 1 + 1 我很赞同!
Niuer + 1 + 1 热心回复!
会飞的飞机 + 2 + 1 赞赞赞。写的很详细很流畅,继续加油
Ericky + 2 + 12 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
a656784052 + 1 + 1 鼓励转贴优秀软件安全工具和文档!

查看全部评分

本帖被以下淘专辑推荐:

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复

使用道具 举报

推荐
发表于 2016-1-21 10:38 | 只看该作者
静态的时候可以跟着分析,但是动态调试的时候,找不到libxy.so,也就无法从EatRice函数下断点,楼主可否解答一下

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 1 反对 0

使用道具 举报

推荐
发表于 2016-1-20 15:14 | 只看该作者

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 1 反对 0

使用道具 举报

板凳
发表于 2016-1-20 14:54 | 只看该作者

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

报纸
发表于 2016-1-20 15:33 | 只看该作者
又要出现一个大牛了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

地板
发表于 2016-1-20 16:48 | 只看该作者
好强悍,都玩手机破解了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

7#
发表于 2016-1-20 17:22 | 只看该作者
支持大神 赞一个

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

8#
发表于 2016-1-20 18:17 | 只看该作者
好强悍,玩手机破解

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

9#
发表于 2016-1-20 18:36 | 只看该作者
厉害,我要好好学习了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

10#
发表于 2016-1-21 09:40 | 只看该作者
不错的writeup  还是有算法程序,赞一个

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则


免责声明:
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:Service@52PoJie.Cn

返回顶部 快速回复 收藏帖子 返回列表

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2017-7-28 02:28

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表