我查查 6.6 去校验分析

其实我是不用这个软件的,不过受烈火之托,就看了看这个校验,据说在.so文件中。

首先呢,用VTS打开apk文件,经过初步分析,判断是否被修改全部根据下面这个位于com/wochacha/datacenter/DataProvider中的函数的返回值

.method private native init()I
.end method

这是个native函数,所以确实是在.so文件中的。 经过搜索,发现libe.so文件中Java_com_wochacha_datacenter_DataProvider_init函数,果断IDA打开libe.so。

EXPORT Java_com_wochacha_datacenter_DataProvider_init
Java_com_wochacha_datacenter_DataProvider_init
PUSH    {R4,LR}
BL      _Z9checkSignP7_JNIEnvP8_jobject ; checkSign(_JNIEnv *,_jobject *)
POP     {R4,PC}
; End of function Java_com_wochacha_datacenter_DataProvider_init

这个函数直接跳转到checkSign(_JNIEnv *,_jobject *)函数,这个函数名敢再直白一点吗?

稍微看了一下,这个checkSign函数,就只是先是检查了一下com/wochacha/util/WccConstant的DEBUG常量,然后计算并对比了一下apk签名的MD5,并没有什么特殊操作。

本着一切从简的原则,能不改.so就不改.so。

于是回到DataProvider.smali,搜索了一下init()I这个函数只在这一个地方被调用了,于是干脆把调用函数以及判断返回结果的代码全部注释掉,让他直接把1写入initResult:Z。

修改之后代码如下:

#.line 108
#invoke-direct {p0}, Lcom/wochacha/datacenter/DataProvider;->init()I

#move-result v0

#.line 109
#if-nez v0, :cond_29

#.line 110
#const/4 v0, 0x0

#iput-boolean v0, p0, Lcom/wochacha/datacenter/DataProvider;->initResult:Z

#.line 113
#:goto_28
#return-void

#.line 112
#:cond_29
iput-boolean v1, p0, Lcom/wochacha/datacenter/DataProvider;->initResult:Z
return-void
#goto :goto_28

重新编译,测试一下,本来以为没什么问题了,可惜后来发现不管扫什么条形码都说没有收录。

果然没这么简单,搜索PackageManager,发现libgcbarcode_j.so里面居然有,嗯,很可疑,IDA之。

找到Gc_func_ab函数,果然有校验,不过貌似只是对比了一下包名和软件名,不过管它呢,虽然我不需要改动这些,但是既然见到了校验怎么能不去掉呢。

所有的几个对比失败了都会跳转到这里。

MOV     R0, #0
LDMFD   SP!, {R3-R11,PC}

#0改成#1即可。

只好继续找了,我又尝试搜索了几个常见的关键词,都没有什么收获。那就只好从问题入手分析了。

首先找到显示条形码没有收录的界面的函数是com/wochacha/compare/CommodityCompareResultActivity的showInValidInfo(Ljava/lang/String;)V。

会调用这个函数是因为barcodeErrorType:Ljava/lang/String;是255,这个变量的值是从Lcom/wochacha/datacenter/BarcodeInfo;->ErrorType:Ljava/lang/String;得到的,而唯一修改ErrorType的函数就是BarcodeInfo中的setErrorType(Ljava/lang/String;)V。

经过搜索,又回到了DataProvider.smali。分析发现这个错误代码来自一个json数据,而这个json是从网络获取的。此时我有点绝望,但仔细分析构建url的代码后,发现url中的barcode参数实际上是加了密的,并且还有一个参数是b_en就是用来加密的,把它也传给服务器说明也可以用它来解密。这时思路顿时清晰了,下面来看看加密过程吧。

这里必须要插一句,看了这个url的参数我算是体会到这款软件是有多么流氓了,完全没有考虑用户隐私,就一个查询条形码的请求,参数中居然包括了UDID(就是你的IMEI),MAC地址,连接方式(wifi或者3G), 最恐怖的是,如果定位信息可用的话还会把GPS的经纬度坐标也发给服务器。

回到barcode加密,实际调用的是Lcom/wochacha/datacenter/DataProvider;->convertData([BII)Ljava/lang/String;函数。看到函数的原型我笑了。

.method private native convertData([BII)Ljava/lang/String;
.end method

果然又是native啊(喂喂不是naive啊看清楚你想什么呢)。搜索显示这个函数也在libe.so,可是这个文件很小,总共也只有不到十个函数,如果有这个函数我之前怎么会没看到呢?再次打开IDA,果然函数列表中没有这个函数,看上去应该是IDA的bug。

看了半天convertData,实际上关键部分不在这里,而是在wcc_encode函数,这个函数之前我也有看到,但是没有找到任何地方会调用这个函数(都怪IDA),于是也没注意。

wcc_encode

这回仔细看一下,函数开头读取了内存中的一个值,和1比较,之后会有两种不同的encode算法,这两种算法绝大部分都一样,只是其中一个算法在某一步读取内存时多加了个0xC的偏移。

再看了看,之前比较的那个值貌似就是checkSign函数最后保存的。于是我修改了几个指令让checkSign函数所有情况都会返回并且保存1。

测试一下,居然还是不行!才想起来最开始的修改直接把调用init()I的代码注释掉了,导致checkSign函数根本没运行,从而也无法将1保存到内存中。

这次把最开始的修改恢复成原始的样子,打包,测试。

终于没问题了,剩下的去广告之类的工作就交给烈火吧。

写这篇文章也算是让自己记住这次教训,本来很容易的一件事,绕了一大圈最后还是回到原地解决。

您可能还喜欢...

发表评论

您的电子邮箱地址不会被公开。