本帖最后由 落华无痕 于 2014-11-12 17:06 编辑
这个软件已经被XX无数次了,大家也都知道破解本地VIP的方法。
就是修改 picview\meitui\vip\vipMgr.smali 的 getVipType(Landroid/app/Activity;)I 方法 ,让它一直返回 0x12c。
这个破解没什么难度,所以今天重发新版破解前,特意修改了另外一样功能,套图下载。
下载套图前,软件先获取当前账户的流量,如果流量不足以下载当前套图,就不让下载。
贴上 picview\meitui\down\DownAsynTask$AsyncAddtoDown.smali 的部分代码,Unicode码已转中文,并添加部分注释。
[Java] 纯文本查看 复制代码 .method protected varargs doInBackground([Ljava/lang/Void;)Ljava/lang/String;
.locals 8
.param p1, "params" # [Ljava/lang/Void;
.prologue
const-wide/16 v4, 0x0
.line 155
new-instance v1, Ljava/lang/StringBuilder; #新建 StringBuilder 实例
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V #初始化 StringBuilder 实例
const-string v2, "http://42.121.110.83/api/pcdown.ashx?n="
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]
iget-object v2, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v2, v2, Lpicview/meitui/down/DownAsynTask;->m_name:Ljava/lang/String; #取得当前用户名
invoke-static {v2}, Ljava/net/URLEncoder;->encode(Ljava/lang/String;)Ljava/lang/String; #URLEncode编码用户名
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; #调用 append 方法在 v1 后面插入字符串 v2
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名
const-string v2, "&p="
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名&p=
iget-object v2, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v2, v2, Lpicview/meitui/down/DownAsynTask;->m_pass:Ljava/lang/String; #取得用户密码
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名&p=用户密码
const-string v2, "&id="
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名&p=用户密码&id=
iget-object v2, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v2, v2, Lpicview/meitui/down/DownAsynTask;->m_ImgId:Ljava/lang/String; #取得套图ID
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名&p=用户密码&id=套图ID
const-string v2, "&v=1"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名&p=用户密码&id=套图ID&v=1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; #生成最终字符串
move-result-object v1 # [url=http://42.121.110.83/api/pcdown.ashx?n=]http://42.121.110.83/api/pcdown.ashx?n=[/url]用户名&p=用户密码&id=套图ID&v=1
invoke-static {v1}, Lpicview/meitui/common;->sendGetRequest(Ljava/lang/String;)Ljava/lang/String; #调用自定义的sendGetRequest方法,大概作用就是访问某个网址,然后获得返回字符串
move-result-object v6 #返回字符串
.line 159
.local v6, "ret":Ljava/lang/String;
if-eqz v6, :cond_0
invoke-virtual {v6}, Ljava/lang/String;->length()I #计算返回字符串的长度
move-result v1
if-nez v1, :cond_1
.line 160
:cond_0
const-string v6, "无法访问网络"
.line 162
:cond_1
const-string v1, "成功"
invoke-virtual {v6, v1}, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z #判断返回字符串是否存在“成功”字样
move-result v1
if-eqz v1, :cond_4 #如果返回字符串不包含“成功”字样,就跳转到:cond_4。
.line 163
new-instance v0, Lpicview/meitui/down/DownManager;
iget-object v1, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v1, v1, Lpicview/meitui/down/DownAsynTask;->m_a:Landroid/app/Activity;
invoke-direct {v0, v1}, Lpicview/meitui/down/DownManager;-><init>(Landroid/content/Context;)V
.line 164
.local v0, "dManager":Lpicview/meitui/down/DownManager;
iget-object v1, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v1, v1, Lpicview/meitui/down/DownAsynTask;->m_ImgId:Ljava/lang/String; #取得套图ID
iget-object v2, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v2, v2, Lpicview/meitui/down/DownAsynTask;->m_userid:Ljava/lang/String; #取得用户ID
iget-object v3, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget v3, v3, Lpicview/meitui/down/DownAsynTask;->m_count:I #取得套图数量
iget-object v4, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v4, v4, Lpicview/meitui/down/DownAsynTask;->m_type:Ljava/lang/String; #取得套图类型
iget-object v5, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v5, v5, Lpicview/meitui/down/DownAsynTask;->m_dir:Ljava/lang/String; #取得套图目录
invoke-virtual/range {v0 .. v5}, Lpicview/meitui/down/DownManager;->newDown(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)Z #调用自定义的newDown方法,大概作用是保存新建的套图下载任务到数据库里
move-result v1
if-eqz v1, :cond_3
.line 165
const-string v6, "已添加进下载列表.应用首页,按返回键,可进入下载管理,开始下载任务"
.line 166
iget-object v1, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v1, v1, Lpicview/meitui/down/DownAsynTask;->m_a:Landroid/app/Activity;
invoke-static {v1}, Lpicview/meitui/vip/vipMgr;->reLogin(Landroid/app/Activity;)V
.line 179
.end local v0 # "dManager":Lpicview/meitui/down/DownManager;
:cond_2
:goto_0
return-object v6
.line 168
.restart local v0 # "dManager":Lpicview/meitui/down/DownManager;
:cond_3
const-string v6, "添加数据库失败,可能是手机空间不足导致的!"
goto :goto_0
.line 170
.end local v0 # "dManager":Lpicview/meitui/down/DownManager;
:cond_4
const-string v1, "不足"
invoke-virtual {v6, v1}, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z #判断返回字符串中是否存在“不足”字样,即“流量不足”
move-result v1
if-eqz v1, :cond_2 #如果返回字符串不存在“不足”字样,就跳转到:cond_2
.line 172
iget-object v1, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-object v1, v1, Lpicview/meitui/down/DownAsynTask;->m_a:Landroid/app/Activity;
const-string v2, "360meinv"
const/4 v3, 0x0
invoke-virtual {v1, v2, v3}, Landroid/app/Activity;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
move-result-object v7
.line 173
.local v7, "set":Landroid/content/SharedPreferences;
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
const-string v2, "下载本套图,需要"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
iget-object v2, p0, Lpicview/meitui/down/DownAsynTask$AsyncAddtoDown;->this$0:Lpicview/meitui/down/DownAsynTask;
iget-wide v2, v2, Lpicview/meitui/down/DownAsynTask;->m_imgll:J #取得套图大小
invoke-static {v2, v3}, Lpicview/meitui/common;->sizeToString(J)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, ",你的剩余流量:"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, "ll"
invoke-interface {v7, v2, v4, v5}, Landroid/content/SharedPreferences;->getLong(Ljava/lang/String;J)J #取得当前用户剩余流量
move-result-wide v2
invoke-static {v2, v3}, Lpicview/meitui/common;->sizeToString(J)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, ",剩余VIP流量:"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, "vipll"
invoke-interface {v7, v2, v4, v5}, Landroid/content/SharedPreferences;->getLong(Ljava/lang/String;J)J
move-result-wide v2
invoke-static {v2, v3}, Lpicview/meitui/common;->sizeToString(J)Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v6
goto :goto_0
.end method
很明显,如果“.line 163” 上面的 “if-eqz v1, :cond_4”不跳转,就能正常保存下载任务,所以要想下载套图,首先让此处不进行跳转,不然会提示流量不足。
破解方法,在“if-eqz v1, :cond_4”这行前面加#注释掉并保存即可。
接下来,发现就算保存了下载任务,也不能正常下载。抓包发现下载套图时访问的网址如下:
[Java] 纯文本查看 复制代码 http://42.121.110.83/api/imgdown.ashx?u=用户ID&p=图片序号&i=套图ID
直接复制到浏览器里访问,发现看不到图片。考虑服务器端做了判断,不满足条件无法访问图片。
然后想起单张图片可以下载,那么能不能把单张图片的网址弄到套图下载里呢?于是搜索上面网址的调用,定位到:
picview\meitui\down\DownService.smali 的 down()V方法,下面贴出部分代码:
[Java] 纯文本查看 复制代码 .method private down()V
.locals 15
.prologue
#省略
#... ...
#省略
.line 194
new-instance v11, Ljava/lang/StringBuilder;
invoke-direct {v11}, Ljava/lang/StringBuilder;-><init>()V
const-string v12, "http://42.121.110.83/api/imgdown.ashx?u="
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v11, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; #插入用户ID字符串
move-result-object v11
const-string v12, "&p="
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v1}, Lpicview/meitui/down/DownModel;->getCcount()I #取得当前要下载的图片序号
move-result v12
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
move-result-object v11
const-string v12, "&i="
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v1}, Lpicview/meitui/down/DownModel;->getImgid()Ljava/lang/String; #取得套图ID
move-result-object v12
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v11}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v10
.line 198
.local v10, "url":Ljava/lang/String; #注释v10,可删
const/4 v4, 0x0
.line 199
.local v4, "input":Ljava/io/InputStream;
const/4 v0, 0x0
.line 201
.local v0, "connection":Ljava/net/URLConnection;
:try_start_1
new-instance v11, Ljava/net/URL; #新建 URL 实例
invoke-direct {v11, v10}, Ljava/net/URL;-><init>(Ljava/lang/String;)V #初始化 URL 实例
invoke-virtual {v11}, Ljava/net/URL;->openConnection()Ljava/net/URLConnection; #创建[font=arial, courier new, courier, 宋体, monospace][color=#333333]一个URL连接[/color][/font]
move-result-object v0
#省略
#... ...
#省略
.end method
我们现在假想的修改方法是,假设单张图片的下载地址为"http://xxx/xxx/n.JPG",“n”由“getCcount()I”方法给出。那么我们应该把上面的代码改成:
[Java] 纯文本查看 复制代码 .method private down()V
.locals 15
.prologue
#省略
#... ...
#省略
.line 194
new-instance v11, Ljava/lang/StringBuilder;
invoke-direct {v11}, Ljava/lang/StringBuilder;-><init>()V
const-string v12, "http://xxx/xxx/"
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v1}, Lpicview/meitui/down/DownModel;->getCcount()I #取得当前要下载的图片序号n
move-result v12
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; # http://xxx/xxx/n
move-result-object v11
const-string v12, ".JPG"
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; # http://xxx/xxx/n.JPG
move-result-object v11
invoke-virtual {v11}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v10
.line 198
.local v10, "url":Ljava/lang/String; #注释url=v10,可删
const/4 v4, 0x0
.line 199
.local v4, "input":Ljava/io/InputStream;
const/4 v0, 0x0
.line 201
.local v0, "connection":Ljava/net/URLConnection;
:try_start_1
new-instance v11, Ljava/net/URL; #新建 URL 实例
invoke-direct {v11, v10}, Ljava/net/URL;-><init>(Ljava/lang/String;)V #初始化 URL 实例
invoke-virtual {v11}, Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
#创建[font=arial, courier new, courier, 宋体, monospace][color=#333333]一个URL连接[/color][/font]
move-result-object v0
#省略
#... ...
#省略
.end method
现在问题简单了,只要确认了网址"http://xxx/xxx/",就可以下载套图了,由于每个套图的网址都不一样,所以不能单纯的赋值字符串确认网址。
经过查看数据库,发现数据库meitui的db_cached2表里保存有上面说的网址,可以用“套图ID”进行索引,要成功取得这个网址,得添加些数据库查询代码,比较麻烦,放弃。
那还有没有什么地方可以取得上述网址呢?答案是肯定的,只要找到了写入数据库代码的地方,注入代码,把上面的网址输出到文本。
然后根据想法,我先写了个crack.smali放到smali根目录,包含两个方法,get和put,用来读取和写入文本。put方法保存网址到“套图ID.txt”,get方法根据“套图ID”读取保存的网址。
然后在代码里,找到了保存网址"http://xxx/xxx/"的寄存器vx,同时找到保存了“套图ID”的寄存器vy,调用方法: invoke-static {vx, vy}, Lcrack;->put(Ljava/lang/String;Ljava/lang/String;)V
方法作用是保存网址"http://xxx/xxx/" 到文本,文本名为“套图ID.txt”。
那么,上面的代码可以修改成:
[Java] 纯文本查看 复制代码 .method private down()V
.locals 15
.prologue
#省略
#... ...
#省略
.line 194
new-instance v11, Ljava/lang/StringBuilder;
invoke-direct {v11}, Ljava/lang/StringBuilder;-><init>()V
invoke-virtual {v1}, Lpicview/meitui/down/DownModel;->getImgid()Ljava/lang/String; #取得套图ID
move-result-object v12
invoke-static {v12}, Lcrack;->get(Ljava/lang/String;)Ljava/lang/String; #根据套图ID读取保存的网址
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v1}, Lpicview/meitui/down/DownModel;->getCcount()I #取得当前要下载的图片序号n
move-result v12
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; # http://xxx/xxx/n
move-result-object v11
const-string v12, ".JPG"
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; # http://xxx/xxx/n.JPG
move-result-object v11
invoke-virtual {v11}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v10
.line 198
.local v10, "url":Ljava/lang/String; #注释url=v10,可删
const/4 v4, 0x0
.line 199
.local v4, "input":Ljava/io/InputStream;
const/4 v0, 0x0
.line 201
.local v0, "connection":Ljava/net/URLConnection;
:try_start_1
new-instance v11, Ljava/net/URL; #新建 URL 实例
invoke-direct {v11, v10}, Ljava/net/URL;-><init>(Ljava/lang/String;)V #初始化 URL 实例
invoke-virtual {v11}, Ljava/net/URL;->openConnection()Ljava/net/URLConnection;
#创建[font=arial, courier new, courier, 宋体, monospace][color=#333333]一个URL连接[/color][/font]
move-result-object v0
#省略
#... ...
#省略
.end method
crack.smali的get和put方法,可以直接手写smali,但是由于调用方法过多,很容易弄混寄存器,所以还是推荐先写出java代码,编译成apk后再反编译。
示例java代码如下,随便创建个Android Application Project,然后New,class,名称为crack,粘贴下面代码:
[Java] 纯文本查看 复制代码 package picview.meitui;
import java.io.*;
import android.util.Log;
public class crack
{
/*将网址s保存到/sdcard/meinvboqingguan/cache/t.txt,t为套图ID*/
public static void put(String s,String t )
{
try
{
String path= "/sdcard/meinvboqingguan/cache/"+t+".txt";
FileOutputStream outStream = new FileOutputStream(path,false);
OutputStreamWriter writer = new OutputStreamWriter(outStream,"gb2312");
writer.write(s);
writer.flush();
writer.close();
outStream.close();
}
catch (Exception e)
{
Log.e("debug", "file write error");
}
}
/*根据套图ID读取/sdcard/meinvboqingguan/cache/t.txt保存的网址,t为套图ID*/
public static String get(String t)
{
String path = "/sdcard/meinvboqingguan/cache/"+t+".txt";
String str = null;
File f = new File(path);
if (f != null && f.exists())
{
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
return null;
}
InputStreamReader inputStreamReader = null;
try {
inputStreamReader = new InputStreamReader(fis, "gbk");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
BufferedReader reader = new BufferedReader(inputStreamReader);
StringBuffer sb = new StringBuffer("");
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
reader.close();
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
str = sb.toString();
}
return str;
}
}
编译好APK后,反编译该APK,提取crack.smali,把第一行改成“.class public Lcrack;”,这样crack.smali就可以直接放到smali根目录使用。这样做,主要是为了调用方法时写少点代码。
反编译后的crack.smali代码如下:
[Java] 纯文本查看 复制代码 .class public Lcrack;
.super Ljava/lang/Object;
.source "crack.java"
# direct methods
.method public constructor <init>()V
.locals 0
.prologue
.line 7
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method public static get(Ljava/lang/String;)Ljava/lang/String;
.locals 13
.prologue
.line 40
new-instance v11, Ljava/lang/StringBuilder;
const-string v12, "/sdcard/meinvboqingguan/cache/"
invoke-direct {v11, v12}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v11, p0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
const-string v12, ".txt"
invoke-virtual {v11, v12}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v11
invoke-virtual {v11}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v7
.line 41
const/4 v10, 0x0
.line 42
new-instance v2, Ljava/io/File;
invoke-direct {v2, v7}, Ljava/io/File;-><init>(Ljava/lang/String;)V
.line 43
if-eqz v2, :cond_0
invoke-virtual {v2}, Ljava/io/File;->exists()Z
move-result v11
if-eqz v11, :cond_0
.line 45
const/4 v3, 0x0
.line 47
:try_start_0
new-instance v3, Ljava/io/FileInputStream;
invoke-direct {v3, v2}, Ljava/io/FileInputStream;-><init>(Ljava/io/File;)V
:try_end_0
.catch Ljava/io/FileNotFoundException; {:try_start_0 .. :try_end_0} :catch_0
.line 52
const/4 v4, 0x0
.line 54
:try_start_1
new-instance v5, Ljava/io/InputStreamReader;
const-string v11, "gbk"
invoke-direct {v5, v3, v11}, Ljava/io/InputStreamReader;-><init>(Ljava/io/InputStream;Ljava/lang/String;)V
:try_end_1
.catch Ljava/io/UnsupportedEncodingException; {:try_start_1 .. :try_end_1} :catch_1
move-object v4, v5
.line 58
:goto_0
new-instance v8, Ljava/io/BufferedReader;
invoke-direct {v8, v4}, Ljava/io/BufferedReader;-><init>(Ljava/io/Reader;)V
.line 59
new-instance v9, Ljava/lang/StringBuffer;
const-string v11, ""
invoke-direct {v9, v11}, Ljava/lang/StringBuffer;-><init>(Ljava/lang/String;)V
.line 62
:goto_1
:try_start_2
invoke-virtual {v8}, Ljava/io/BufferedReader;->readLine()Ljava/lang/String;
:try_end_2
.catch Ljava/io/IOException; {:try_start_2 .. :try_end_2} :catch_2
move-result-object v6
if-nez v6, :cond_1
.line 70
:goto_2
invoke-virtual {v9}, Ljava/lang/StringBuffer;->toString()Ljava/lang/String;
move-result-object v10
:cond_0
move-object v11, v10
.line 72
:goto_3
return-object v11
.line 48
:catch_0
move-exception v1
.line 49
invoke-virtual {v1}, Ljava/io/FileNotFoundException;->printStackTrace()V
.line 50
const/4 v11, 0x0
goto :goto_3
.line 55
:catch_1
move-exception v1
.line 56
invoke-virtual {v1}, Ljava/io/UnsupportedEncodingException;->printStackTrace()V
goto :goto_0
.line 63
:cond_1
:try_start_3
invoke-virtual {v9, v6}, Ljava/lang/StringBuffer;->append(Ljava/lang/String;)Ljava/lang/StringBuffer;
.line 64
invoke-virtual {v8}, Ljava/io/BufferedReader;->close()V
.line 65
invoke-virtual {v3}, Ljava/io/FileInputStream;->close()V
:try_end_3
.catch Ljava/io/IOException; {:try_start_3 .. :try_end_3} :catch_2
goto :goto_1
.line 67
:catch_2
move-exception v0
.line 68
invoke-virtual {v0}, Ljava/io/IOException;->printStackTrace()V
goto :goto_2
.end method
.method public static put(Ljava/lang/String;Ljava/lang/String;)V
.locals 7
.prologue
.line 13
:try_start_0
new-instance v5, Ljava/lang/StringBuilder;
const-string v6, "/sdcard/meinvboqingguan/cache/"
invoke-direct {v5, v6}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v5, p1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v5
const-string v6, ".txt"
invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v3
.line 15
new-instance v2, Ljava/io/FileOutputStream;
const/4 v5, 0x0
invoke-direct {v2, v3, v5}, Ljava/io/FileOutputStream;-><init>(Ljava/lang/String;Z)V
.line 19
new-instance v4, Ljava/io/OutputStreamWriter;
const-string v5, "gb2312"
invoke-direct {v4, v2, v5}, Ljava/io/OutputStreamWriter;-><init>(Ljava/io/OutputStream;Ljava/lang/String;)V
.line 21
invoke-virtual {v4, p0}, Ljava/io/OutputStreamWriter;->write(Ljava/lang/String;)V
.line 23
invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->flush()V
.line 25
invoke-virtual {v4}, Ljava/io/OutputStreamWriter;->close()V
.line 27
invoke-virtual {v2}, Ljava/io/FileOutputStream;->close()V
:try_end_0
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
.line 37
:cond_0
:goto_0
return-void
.line 30
:catch_0
move-exception v0
.line 34
const-string v5, "debug"
const-string v6, "file write error"
invoke-static {v5, v6}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
goto :goto_0
.end method
get方法注入的地方已经说过,put方法注入的地方,我选择了picview/meitui/thumbnailList$6的onClick方法,具体修改地方为:
[Java] 纯文本查看 复制代码 .method public onClick(Landroid/view/View;)V
.locals 12 #使用的寄存器范围v0-v11,将此处改为.locals 13,以使用新寄存器v12
#省略
#... ...
#省略
invoke-static {v0}, Lpicview/meitui/thumbnailList;->access$100(Lpicview/meitui/thumbnailList;)Landroid/os/Bundle;
move-result-object v0
const-string v1, "type"
invoke-virtual {v0, v1}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;
move-result-object v0 #此处通过log.d注入,发现v0为要找的图片网址
move-object v12, v0 #保存网址到v12寄存器
const-string v1, ".JPG"
invoke-virtual {v0, v1}, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z
#省略
#... ...
#省略
invoke-static {v2}, Lpicview/meitui/thumbnailList;->access$100(Lpicview/meitui/thumbnailList;)Landroid/os/Bundle;
move-result-object v2
const-string v3, "info"
invoke-virtual {v2, v3}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;
move-result-object v2 #此处经过分析知v2为套图ID
invoke-static {v12, v2}, Lcrack;->put(Ljava/lang/String;Ljava/lang/String;)V #String s=v12,String t=v2,调用put方法保存网址。
#省略
#... ...
#省略
.end method
成品:http://www.52pojie.cn/thread-255341-1-1.html
上面帖子关闭,网盘资源被和谐,如需参考成品,看下面链接:
链接: http://pan.baidu.com/s/1jGpAE8Y 密码: s1u3
|