好友
阅读权限 40
听众
最后登录 1970-1-1
芽衣
发表于 2020-11-29 11:59
本帖最后由 芽衣 于 2020-11-29 12:28 编辑
软件为当前最新版9.11.5,用起来正如其名,卡机相机。137MB的巨无霸只有国内才会有这种体积,还很耗电,拍照效果由于没有使用太久不做评价。
准备工具:
1、32位IDA
2、反编译工具
没有成品,用完就删。只是签名校验,一些广告、布局等没什么意思,不做分析。
由于比较简单,不设权限了。
先来个老手法,进行重签名。
安装后出现了盗版弹窗,提示“请在安卓应用商店下载并使用正式版本”。按照一般的套路根据字符串来源搜索dex的代码,然后删掉。实际上并不推荐这个方法,因为这样会影响你的判断。之前我发过扫描全能王过签,如果你直接把弹窗屏蔽掉了,就会出现各种问题,比如不能联网识别。屏蔽盗版弹窗的做法有点像掩耳盗铃。屏蔽弹窗只适用于广告、更新、一些跳转。
那现在来试一下直接删掉字符串来源会怎么样。
如上图,文字来源这里,现在把onViewCreated代码全删,看看会变成什么样。
现在变成这样了,失败的破解。
现在换另一种思路,打印签名日志。搜索关键词>signatures,定位到com/linecorp/b612/android/utils/DeviceInfo。这里有获取签名值的行为,在方法.method public static l()Ljava/lang/String;
这里获取了签名的哈希值,打印结果得到了字符串1148720986 ,直接写死到代码里。
.method public static l()Ljava/lang/String;
.locals 7
const-string v0, "1148720986"
return-object v0
.end method
我本以为到这里就结束了,回编译测试,但……还是弹出了盗版弹窗
根据以往经验,基本上能确定so还是有问题的。so搜索字符串signatures,没结果,继续搜索META-INF,出现了1个结果,在libstunning。看来没得跑,原因就出在这个so。
ida加载so,查看so输出表,输入java,结果只有1个。Java_com_linecorp_b612_android_utils_SignatureChecker_isThisMe
然后看一下smali代码,看看这个输出属于什么数据类型。
可以看到这个native方法属于Z类,说得简单点就判断真和假。1真、0假应该是最基础的知识。所以改法就是直接在这里赋值1,把so的输出给堵住。
.method public final isThisMe(Landroid/content/Context;)Z
.locals 2
const/4 v0,0x1
return v0
.end method
回编译测试,成功!
还有一种情况,这个判断不在dex,在so里面的话怎么办?现在简单介绍一下在so里面怎么改。
进入输出表之后,有个分支j_getSignatureFromNative,先进去看看他在做什么。
int __fastcall getSignatureFromNative(int a1)
{
int v1; // r5
char *v2; // r0
char *v3; // r10
int v4; // r6
void *v5; // r8
int v6; // r4
bool v7; // zf
int v8; // ST0C_4
int v9; // r11
int v10; // ST04_4
int v11; // r9
int v12; // ST08_4
int (__fastcall *v13)(int, int, int, int); // r4
int v14; // r0
int v15; // r11
int v16; // r9
int v17; // ST0C_4
int (__fastcall *v18)(int, int, int, int, _DWORD); // r4
int v19; // r0
int v20; // r0
int result; // r0
int v22; // [sp+10h] [bp-28h]
int v23; // [sp+14h] [bp-24h]
int v24; // [sp+18h] [bp-20h]
v1 = a1;
v2 = j_pathHelperGetPath();
v3 = v2;
v4 = 0;
if ( v2 )
{
v22 = 0;
v23 = 0;
v5 = j_unzipHelperGetCertificateDetails(v2, &v23);
if ( v5 )
{
usleep(0x1F4u);
v6 = j_pkcs7HelperGetSignature(v5, v23, &v22);
v7 = v6 == 0;
v4 = 0;
if ( !v6 )
v7 = v22 == 0;
if ( !v7 )
{
v8 = (*(*v1 + 704))(v1, v22);
(*(*v1 + 832))(v1, v8, 0, v22, v6);
v9 = (*(*v1 + 24))(v1, "java/security/MessageDigest");
v10 = (*(*v1 + 132))(v1, v9, "update", "([B)V");
v11 = (*(*v1 + 452))(v1, v9, "getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;");
v12 = (*(*v1 + 132))(v1, v9, "digest", "()[B");
v13 = *(*v1 + 456);
v14 = (*(*v1 + 668))(v1, "SHA1");
v15 = v13(v1, v9, v11, v14);
(*(*v1 + 244))(v1, v15, v10, v8);
v16 = (*(*v1 + 24))(v1, "android/util/Base64");
v17 = (*(*v1 + 452))(v1, v16, "encodeToString", "([BI)Ljava/lang/String;");
v18 = *(*v1 + 456);
v19 = (*(*v1 + 136))(v1, v15, v12);
v20 = v18(v1, v16, v17, v19, 0);
v4 = (*(*v1 + 676))(v1, v20, 0);
}
free(v5);
free(v3);
j_pkcs7HelperFree();
}
else
{
free(v3);
v4 = 0;
}
}
result = _stack_chk_guard - v24;
if ( _stack_chk_guard == v24 )
result = v4;
return result;
}
伪代码如上,他在这里验证了签名值,j_unzipHelperGetCertificateDetails 读取了签名文件夹下的rsa文件,所以刚才搜索到的META-INF文件夹就是在这里面。回到isThisMe,改法如下:
打叉的地方肯定是不能走的,只能走左边。所以要把红线的跳转全部nop掉,然后MOVS R0, #0还得赋值1。
当然你也可以直接写个汇编直接返回1。
ADD R7, SP, #0xC改成MOVS R0, #1
然后直接出栈。
.text:000041D8
.text:000041D8 ; =============== S U B R O U T I N E =======================================
.text:000041D8
.text:000041D8
.text:000041D8 EXPORT Java_com_linecorp_b612_android_utils_SignatureChecker_isThisMe
.text:000041D8 Java_com_linecorp_b612_android_utils_SignatureChecker_isThisMe
.text:000041D8 ; DATA XREF: LOAD:00000258↑o
.text:000041D8 ; __unwind {
.text:000041D8 PUSH {R4-R7,LR}
.text:000041DA MOVS R0, #1
.text:000041DC POP.W {R4-R7,PC}
.text:000041DC ; End of function Java_com_linecorp_b612_android_utils_SignatureChecker_isThisMe
.text:000041DC
游戏结束~~
免费评分
查看全部评分