更多精彩内容 :http://www.chenchuangfeng.com

QQ:375061590

---------------------------------------------------------------------------------

很久有写过一个广工图书馆主页一个类爬虫的demo(因为没接口,只能扒取静态网页),实现一些图书馆系统的一些功能。但最近发现图书馆系统在html页面上做了手脚,一页html页面中嵌入了几千行的注释,并有了自己的App,应该是为了增加扒取的流量成本来防止别人去扒取网页,不过加注释这手段就不敢恭维了,内网访问速度还行,但外网访问的话体验很差的。

如下图:一堆注释,导致一个网页要2MB

主页上的APP,必然是用了图书馆的后台接口和服务器交互的,从而想试试用反编译的手段来看看APP使用了什么接口。(另外更简单可以通过tcpdump来给Android手机抓包分析其接口,再用Wireshark来分析tcp包,不过你想要知道全部接口的话,可能需要一个个接口去调用,会比较麻烦,采用反编译,可能集中在一个类中找到这些接口)。

首先要准备的工具:(了解更多反编译工具可以去看雪论坛下载或者学习-Link)

APKTool   点击下载

APKTool是GOOGLE提供的APK编译工具,需要JAVA运行环境。可以对APK进行反编译,使用它可以将其反编译成非常接近打包前的原始格式。逆向AndroidManifest.xml、资源文件 resources.arsc以及将dex文件反编译成可以调试的smali文件。修改后,可以将其编译回apk文件。APKTool也可以用来汉化Android软件然后重新打包发布。 
官方:http://code.google.com/p/android-apktool/

找本书APP  点击下载

解压缩APKTool,并把要反编译的APK放入目录中

反编译:

通过CMD进入上面的目录,执行命令: apktool decode ZhaoBenShu.apk outdir

稍等片刻完成反编译,反编译后的文件会在outdir目录下。

---outdir目录结构

res :资源文件,跟adnroid工程目录下的res基本一样,各种UI图片  XML布局文件  values xml文件(多了一个public.xml,有各个资源的id号(R.java中的id))

smail:这个是重点文件夹,里面都是smail格式文件,是Dalvik虚拟机执行的操作码(Dalvik opcodes),这些操作吗有自己的语法,如果有学过JNI的话, 这些语法还是比较容易看懂和理解的。

AndroidManifest.xml:Android工程下的AndroidManifest.xml

apktool.yml:用于重打包。

 

smail语法:(全部语法请link)

  

smail中的数据类型签名跟java中的是一样的,如下。

  • B---byte
  • C---char
  • D---double
  • F---float
  • I---int
  • J---long
  • S---short
  • V---void
  • Z---boolean
  • [XXX---array
  • Lxxx/yyy---object

   smail代码例子:

初看smail文件,可能会觉得有一些凌乱。不过只要把几种语法弄懂了,就可以很好地阅读smail文件。

smail比较常用语法 ( 非全部)分为: 赋值,取值,函数调用,if语句,返回值等。

赋值取值:
    例子: iget-object v6, p0, Lcom/zbsh/code/clas/ClassSystem$9;->val$vBarCodes:Ljava/util/ArrayList;

分析:

iget个取值操作,i=instance,是用来instance filed(实例变量),object是类的意思。 v6是本地寄存器,p0在这里是代表this(在非static函数正代表this,在static函数中

代表第一个参数)。Lcom/zbsh/code/clas/ClassSystem是表示包路径为 Lcom/zbsh/code/clas下的ClassSystem类,->相当于C/C++的箭头操作符,后面是类中的变量或者方

法vBarCodes是ClassSystem中的一个变量,Ljava/util/ArrayList是vBarCodes这个变量的类型 (是java中类的签名)

作用:

把ClassSystem中vBarCodes的值存放在寄存器v6中,vBarCodes的类型必须是对象,且是实例变量非静态变量。

其中object可以是替换成基本数据类型:iget-boolean   iget-byte  iget-char   iget-short等等。

同样的:

sget- [type]用来获取static变量。(少了一个p0,因为静态变量是没有this的)

aget-[type]用来获取array类型。

[x]get vx, vy,把寄存器vy中的值赋给vx。

赋值:

        同样都有以下几种:
        iput-[type]

sput-[type]

aput-[type]

也支持寄存器和寄存器之间的赋值,寄存器和变量之间的赋值。

函数调用:
        invoke-direct 调用private函数
        invoke-super 调用父类函数
        invoke-static 调用静态函数
        invoke-virtual 用于调用protected或public函数(相当于C++的虚函数,java的重载函数,只有protect和public能够重载)
        还有一种比较特殊的:invoke-xxxxx/range:参数多于5个的时候,要加/rang

例子:

invoke-virtual {v4, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

v4是this,代表 Ljava/lang/String的一个实例,v1是函数的第一个参数,在这里是调用放在V4寄存器中类型为Ljava/lang/String的实例的equal ()方法,并传入参数v1,返回的结果是Z类型,也就是boolean类型。

如果是invoke-static{v4, v1}, 不同遇在于invoke-virtual {v4, v1}的是v4不是this,而是第一个参数。v1是第二个参数,所调用的方法需要两个参数。

 

返回值:

获取返回值:

move-result vx :把上一个方法返回的值,存在寄存器 vx中。

返回返回值:
               return-void   没返回。

return vx       返回寄存器中vx的值  。

if语句:

if-eq vx,vy,target:eq:equal  如果vx==xy 跳转到target目标代码,否则执行顺序执行下一句代码

if-ne vx,vy,target:nq :not equal  如果vx!=xy 跳转到target目标代码,否则执行顺序执行下一句代码

if-eqz vx,target:eqz : equal zero  如果vx==0 跳转到target目标代码,否则执行顺序执行下一句代码     
        if-nez vx,target:nez :not equal zero   如果vx!=0 跳转到target目标代码,否则执行顺序执行下一句代码

读smail,找接口:
   

     

 以搜索接口为例子:

根据文件命名找到GropZbshFind.smali这个文件,应该就是搜索Activity。

在其中有一段代码:

# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 3
.parameter "savedInstanceState" .prologue
.line 13
invoke-super {p0, p1}, Lcom/zbsh/code/thrd/GroupActivity;->onCreate(Landroid/os/Bundle;)V .line 14
const-class v0, Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v0}, Ljava/lang/Class;->getName()Ljava/lang/String; move-result-object v0 new-instance v1, Landroid/content/Intent; const-class v2, Lcom/zbsh/code/ZbshFindMain; invoke-direct {v1, p0, v2}, Landroid/content/Intent;->(Landroid/content/Context;Ljava/lang/Class;)V invoke-virtual {p0, v0, v1}, Lcom/zbsh/code/GropZbshFind;->startChildActivity(Ljava/lang/String;Landroid/content/Intent;)V .line 15
return-void
.end method

很明显是通过startActivity来启动ZbshFindMain这个Activity,

在ZbshFindMain中找到Onclick方法。


     # virtual methods
.method public onClick(Landroid/view/View;)V
.........省略一坨代码...........
iget-object v0, v5, Lcom/zbsh/code/clas/ClassSystem;->ipAddress:Ljava/lang/String; .line 199
.local v0, ipAddress:Ljava/lang/String;
new-instance v5, Ljava/lang/StringBuilder; invoke-static {v0}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String; move-result-object v6 invoke-direct {v5, v6}, Ljava/lang/StringBuilder;->(Ljava/lang/String;)V const-string v6, "Find/GetBookList.aspx?a=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "gdut" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&b=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v6 iget-object v5, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v5}, Lcom/zbsh/code/ZbshFindMain;->getApplication()Landroid/app/Application; move-result-object v5 check-cast v5, Lcom/zbsh/code/clas/ApplZbsh; iget-object v5, v5, Lcom/zbsh/code/clas/ApplZbsh;->iSystem:Lcom/zbsh/code/clas/ClassSystem; iget-object v5, v5, Lcom/zbsh/code/clas/ClassSystem;->searchType:Ljava/lang/String; invoke-virtual {v6, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&c=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v6 iget-object v5, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v5}, Lcom/zbsh/code/ZbshFindMain;->getApplication()Landroid/app/Application; move-result-object v5 check-cast v5, Lcom/zbsh/code/clas/ApplZbsh; iget-object v5, v5, Lcom/zbsh/code/clas/ApplZbsh;->iSystem:Lcom/zbsh/code/clas/ClassSystem; iget-object v5, v5, Lcom/zbsh/code/clas/ClassSystem;->inputKeywords:Ljava/lang/String; invoke-virtual {v6, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&d=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 sget v6, Lcom/zbsh/code/clas/ClassDataParameter;->count:I invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&e=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 sget v6, Lcom/zbsh/code/clas/ClassDataParameter;->page:I invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; move-result-object v5 invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v3 .line 201
.local v3, urlPath:Ljava/lang/String;
iget-object v5, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v5}, Lcom/zbsh/code/ZbshFindMain;->getApplication()Landroid/app/Application; move-result-object v5 check-cast v5, Lcom/zbsh/code/clas/ApplZbsh; iget-object v5, v5, Lcom/zbsh/code/clas/ApplZbsh;->iSystem:Lcom/zbsh/code/clas/ClassSystem; iget-object v6, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; iget-object v6, v6, Lcom/zbsh/code/ZbshFindMain;->mUIHandler:Landroid/os/Handler; invoke-virtual {v5, v0, v3, v6}, Lcom/zbsh/code/clas/ClassSystem;->GetFindOnThread(Ljava/lang/String;Ljava/lang/String;Landroid/os/Handler;)V

上面这段代码,实现的是通过StringBuilder,通过append方法,拼成一个地址出来,再调用ClassSystem;->GetFindOnThread这个方法,传入参数,进行一个异步图书搜索的任务。

再从ClassDataParameter.smali中找到一些定义host地址常量。

  .line 20
const-string v0, "http://59.41.253.11:7778/" sput-object v0, Lcom/zbsh/code/clas/ClassDataParameter;->IPADDRESS_TEL:Ljava/lang/String; .line 21
const-string v0, "http://222.200.98.173:7778/" sput-object v0, Lcom/zbsh/code/clas/ClassDataParameter;->IPADDRESS_EDU:Ljava/lang/String

我们可以拼出图书搜索的接口是:http://222.200.98.173:7778/Find/GetBookList.aspx?a=&b=1&c=java&d=40&e=100

返回的是Json数据格式化下:

 {
"error": "0",
"findtotal": "1612",
"findcache": "20131124024041.htm",
"find_list": [
{
"CtrlNo": "70658",
"Isbn": "7-301-03477-6 ",
"Title": "Java教程(Internet面向对象程序设计)",
"Author": "Mary Campione",
"Edition": " ",
"Publisher": "北大版",
"PubDate": "97.12"
},
{
"CtrlNo": "70657",
"Isbn": "7-301-03476-8 ",
"Title": "Java类手册",
"Author": "Patrick Chan",
"Edition": " ",
"Publisher": "北大版",
"PubDate": "97.12"
},
{
"CtrlNo": "605337",
"Isbn": "978-7-115-30271-7 ",
"Title": "Java 7基础教程= Java 7 for absolute beginners",
"Author": "(美) Jay Bryant著;李鹏, 韩智译",
"Edition": " ",
"Publisher": "人民邮电出版社",
"PubDate": "2013.01"
},
{
"CtrlNo": "604835",
"Isbn": "978-7-302-30346-6 ",
"Title": "Java改错学习法 [专著]",
"Author": "朱福喜编著",
"Edition": " ",
"Publisher": "清华大学出版社",
"PubDate": "2013"
}
]
}

    其次:
        

            还可以通过反编译更强大的用处是用来修改smali代码,再重打包apk,来破解一些收费软件,去除广告之类,或者了解一些优秀软件的实现逻辑。

--------------------------------------------------------------------------------

更多精彩内容 :http://www.chenchuangfeng.com

QQ:375061590

---------------------------------------------------------------------------------

Android反编译基础(apktoos)--广工图书馆APK的更多相关文章

  1. Android apk反编译基础(apktoos)图文教程

    本文主要介绍了Android apk反编译基础,使用的工具是apktoos,我们将用图文的方式说明apktoos工具的使用方式,你可以参考这个方法反编译其它APK试试看了 很久有写过一个广工图书馆主页 ...

  2. Android 反编译 -smali语法

    前言 前面我们有说过android反编译的工具,如何进行反编译.反编译后可以得到jar或者得到smali文件.Android采用的是java语言 进行开发,但是Android系统有自己的虚拟机Dalv ...

  3. Android反编译(三)之重签名

    Android反编译(三) 之重签名 [目录] 1.原理 2.工具与准备工作 3.操作步骤 4.装X技巧 5.问题 1.原理 1).APK签名的要点 a.所有的应用程序都必须有数字证书 ,Androi ...

  4. Android反编译(二)之反编译XML资源文件

    Android反编译(二) 之反编译XML资源文件 [目录] 1.工具 2.反编译步骤 3.重新编译APK 4.实例 5.装X技巧 6.学习总结 1.工具 1).反编译工具  apktool http ...

  5. Android反编译(一)之反编译JAVA源码

    Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具  dex2jar   http://code.go ...

  6. Atitti.java android反编译解决方案-----虚拟机方案

    Atitti.java android反编译解决方案-----虚拟机方案 哈哈,终极解决方案是虚拟机...c++也可以反编译为汇编代码,但无需担心,因为读懂汇编太麻烦..只要不能拿到c++源码就可.. ...

  7. Android反编译工具的使用-Android Killer

    今天百度搜索“Android反编译”搜索出来的结果大多数都是比较传统的教程.刚接触反编译的时候,我也是从这些教程慢慢学起的.在后来的学习过程中,我接触到比较方便操作的Android反编译.在这,我将使 ...

  8. Android 反编译

    Android 反编译 步骤:1.下载apktool 工具,这一步 主要是反编译 xml 文件. 步骤:2 把xx.smali 文件转为java 工具 (单个) 图形界面 下载dex2jar  和xj ...

  9. 转 谈谈android反编译和防止反编译的方法

    谈谈android反编译和防止反编译的方法   android基于java的,而java反编译工具很强悍,所以对正常apk应用程序基本上可以做到100%反编译还原. 因此开发人员如果不准备开源自己的项 ...

随机推荐

  1. Injection Attacks-XML注入

    注入攻击 XML注入 虽然JSON的出现实现了服务器与客户端之间的"轻量级"数据交流,但是,作为另一种流行的可行方案,许多web服务API同时还是继续支持XML.另外,除了web服 ...

  2. c++ 成员指针函数 实现委托----跨平台实现(复杂)

    牛逼: c++ 牵涉到的技术细节太多了,为了实现一个委托,他妈都搞到汇编里面去了... 总结 为了解释一小段代码,我就得为这个语言中具有争议的一部分写这么一篇长长的指南.为了两行汇编代码,就要做如此麻 ...

  3. [itint5]下一个排列

    http://www.itint5.com/oj/#6 首先,试验的时候要拿5个来试,3,4个都太少了.好久没做所以方法也忘了,是先从后往前找到第一个不合顺序的,然后在后面找到比这个大的最小的来交换, ...

  4. module_init宏解析 linux驱动的入口函数module_init的加载和释放

    linux驱动的入口函数module_init的加载和释放 http://blog.csdn.net/zhandoushi1982/article/details/4927579 void free_ ...

  5. matlab 设置横纵坐标刻度的字体!!

    set(gca,'FontSize',16) %%设置横纵坐标字体的大小

  6. 非常实用的15款开源PHP类库

    PHP库给开发者提供了一个标准接口,它帮助开发者在PHP里充分利用面向对象编程.这些库为特定类型的内置功能提供了一个标准的API,允许类可以与PHP引擎进行无缝的交互.此外,开发者使用这些类库还可以简 ...

  7. 【HDOJ】4601 Letter Tree

    挺有意思的一道题,思路肯定是将图转化为Trie树,这样可以求得字典序.然后,按照trie的层次求解.一直wa的原因在于将树转化为线性数据结构时要从原树遍历,从trie遍历就会wa.不同结点可能映射为t ...

  8. 在SQLite中使用索引优化查询速度

    在进行多个表联合查询的时候,使用索引可以显著的提高速度,刚才用SQLite做了一下测试. 建立三个表: create table t1 (id integer primary key,num inte ...

  9. poj 2442 Sequence(优先队列)

    题目:http://poj.org/problem?id=2442 题意:给你n*m的矩阵,然后每行取一个元素,组成一个包含n个元素的序列,一共有n^m种序列, 让你求出序列和最小的前n个序列的序列和 ...

  10. Python开发环境

    --> Python开发环境简备 Python的优点除了其自身的各种特点外,还因为有众多第三方模块,为其扩展了各方面无数的功能. 虽然大多数时候在百度上随便搜都能搜到一大把,pypi (http ...