工具:

apktool:https://code.google.com/p/android-apktool/

dex2jar: https://code.google.com/p/dex2jar/

jd-gui: http://jd.benow.ca/

反编译命令提取资源(smail汇编代码):apktool d file.apk path

dex2jar反编译:dex2jar file.apk (or classes.dex)

用jd-gui就可以打开jar看了

用jd-gui在windows下没问题,在linux64下要装ia32的库。

一般代码都被混淆过。

都是abcdefg。。。

下面讲讲本人的一些小技巧。

本人最近反编译一个aide,菜鸟抄抄别人的实现。

一般都是从布局入手,找出相应关键的view类:如<com.aide.ui.AIDEEditorPager 。。。

可以在代码文件里找到AIDEEditorPager这个类,下面贴点代码:

package com.aide.ui;

import android.content.Context;
import android.graphics.Rect;
import android.os.Build.VERSION;
import android.support.v4.view.ViewPager;
import android.support.v4.view.aa;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import com.aide.common.c;
import com.aide.engine.SyntaxError;
import com.aide.ui.util.k;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import rg;
import rh;
import ri; public class AIDEEditorPager
extends ViewPager
implements ri
{
private boolean DW;
private f FH;
private boolean Hw;
private List j6 = new ArrayList();
private l v5; public AIDEEditorPager(Context paramContext)
{
super(paramContext);
sG();
} public AIDEEditorPager(Context paramContext, AttributeSet paramAttributeSet)
{
super(paramContext, paramAttributeSet);
sG();
} private void DW(boolean paramBoolean)
{
int i = 4;
View localView1 = getRootView();
int j;
View localView3;
if (localView1 != null)
{
View localView2 = localView1.findViewById(2131427448);
if (localView2 != null)
{
if (!paramBoolean) {
break label62;
}
j = 0;
localView2.setVisibility(j);
}
localView3 = localView1.findViewById(2131427446);
if (localView3 != null) {
if (!paramBoolean) {
break label68;
}
}
}
for (;;)
{
localView3.setVisibility(i);
return;
label62:
j = i;
break;
label68:
i = 0;
}
} private int Hw(String paramString)
{
for (int i = 0;; i++)
{
if (i >= this.j6.size()) {
i = -1;
}
while (v5(i).d_().equals(paramString)) {
return i;
}
}
} private void Sf()
{
postDelayed(new Runnable()
{
public void run()
{
AIDEEditorPager.DW(AIDEEditorPager.this).v5();
}
}, 50L);
}

这么乱的代码,想找到自己想要的代码真是不容易。但是有一点不可能变的是,函数之间的调用关系是不变的。

比如AIDEEditorPager和MainActivty之间有几个混淆的类,有时一个功能会有几十个方法调用,但是只要猜解关键方法的功能,其他的根据效果进行分析,基本上8,9不离十。

方法唯一的标志就是参数。可能一个类会有几个j6(。。。)这样的方法,但是他们的参数类型都不是不同的。

如想提取actionbar tab的相关代码:
首先搜索MainActivity文件addTab
结果:
public void j6(final String paramString)
{
if ((Build.VERSION.SDK_INT > 10) && (m.nw()))
{
ActionBar localActionBar = getActionBar();
final ActionBar.Tab localTab = localActionBar.newTab().setText(com.aide.ui.util.l.v5(paramString));
localActionBar.addTab(localTab, false);
}
}
其实看以看得出这个是一个addTab。
要找到谁是调用j6这个函数,首先找类中有没调用,找不到,就全文件搜索
一般先搜索哪里引用了MainActivity,找到AIDEEditorPager(当然可能有好几个引用了,这个看运气咯),如
private MainActivity ef()
{
return (MainActivity)getContext();
}
同样的找到调用ef()的,
public rh DW(String paramString)
{
View localView = LayoutInflater.from(getContext()).inflate(2130903059, null);
AIDEEditor localAIDEEditor = (AIDEEditor)localView.findViewById(2131427405);
rh localrh = localAIDEEditor.j6(paramString);
DW(true);
ef().j6(paramString);
Sf();
this.j6.add(localView);
DW().FH();
return localrh;
}
这个方法,首先,两个id可以找出相应的资源文件,从public.xml找到对应的id名,然后搜索相应的id名,个人用notepad++,在多文件中进行查找,第一个id,应该是一个布局文件(R.layout.xxx),第二个自然是一个view,不用说前面的暂时没什么影响,DW(true)暂时不解,ef().j6(paramString);就是了。
DW().FH()经查找是原来的getAdpter().notifyDataChanged().
Sf(),DW()暂时不解。
同理找出removetab();
接着tab点击支持弹出菜单功能
在资源文件里面有个filetab_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@id/editorMenuClose" android:title="Close" />
<item android:id="@id/filetabMenuCloseOthers" android:title="Close Others" />
<item android:id="@id/filetabMenuCloseAll" android:title="Close All" />
</menu>
从app里可以看到这三个菜单。找到filetab_menu的id,如
<public type="menu" name="filetab_menu" id="0x7f0a0004" />
十进制是,搜索全文件结果只找到一次,在MainActivity里。
this.j3 = new l(this, 2131361796);
找来找去找不到this.j3,或MainActivity.j3...

下面讲讲反编译代码相关的东西:

从程序使用效果就是弹出菜单onTabReselected,

  public void j6(final String paramString)
{
if ((Build.VERSION.SDK_INT > 10) && (m.nw()))
{
ActionBar localActionBar = getActionBar();
final ActionBar.Tab localTab = localActionBar.newTab().setText(com.aide.ui.util.l.v5(paramString));
localTab.setTabListener(new ActionBar.TabListener()
{
public void onTabReselected(ActionBar.Tab paramAnonymousTab, FragmentTransaction paramAnonymousFragmentTransaction)
{
if (localTab == paramAnonymousTab) {
MainActivity.j6(MainActivity.this).j6(MainActivity.j6(MainActivity.this, paramAnonymousTab), true);
}
}t public void onTabSelected(ActionBar.Tab paramAnonymousTab, FragmentTransaction paramAnonymousFragmentTransaction)
{
if ((localTab == paramAnonymousTab) && (!paramString.equals(j.tp().Hw()))) {
j.tp().v5(paramString);
}
} public void onTabUnselected(ActionBar.Tab paramAnonymousTab, FragmentTransaction paramAnonymousFragmentTransaction) {}
});
localActionBar.addTab(localTab, false);
}
}
MainActivity.j6(MainActivity.this).j6(
  MainActivity.j6(MainActivity.this, paramAnonymousTab), true);

这一句MainActivity.j6(MainActivity.this)其实是调用MainActivity.j6();

MainActivity.j6(MainActivity.this, paramAnonymousTab)其实是使用了j6(ActionBar.Tab tab)这个原型

但第二个找到,第一个找不到MainActivity.j6();

private View j6(ActionBar.Tab paramTab)
{
return findViewById(2131427444);
}

查找id,发现main.xml

<LinearLayout android:orientation="horizontal" android:id="@id/mainActionBarPopupAnchor" ...

从popup就可以看出这个弹出的区域。一下子全解了,之前一直不知道tab怎么可以popupmenu,因为popupmenu需要view,而这个popupAnchor正好是那个view

上文提到this.j3 = new l(this, 2131361796);
找来找去找不到this.j3,或MainActivity.j3...

突然想起匿名类[new ActionBar.TabListener(){...}] 取得主类[MainActivity]私有成员变量也是用方法(反汇编出来是调用主类的一个方法。

记得见过this$0,this$400()...与这些的道理是一样的。

那么是取得哪一个呢。j3是也。可能性很高。

从new l(this, 213...)找到l的源码。

public void j6(View paramView, boolean paramBoolean)
{
if (Build.VERSION.SDK_INT < 11)
{
j6(paramBoolean);
return;
}
DW();
this.Hw = paramBoolean;
PopupMenu localPopupMenu = new PopupMenu(this.DW, paramView);
localPopupMenu.getMenuInflater().inflate(this.j6, localPopupMenu.getMenu());
j6(localPopupMenu.getMenu());
localPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem paramAnonymousMenuItem)
{
l.j6(l.this, paramAnonymousMenuItem);
return true;
}
});
localPopupMenu.show();
}
MainActivity.j6(MainActivity.this).j6(
  MainActivity.j6(MainActivity.this, paramAnonymousTab), true); 其实就是
View v = MainActivity.j6(tab);//int getFileTabMenu()
MainActivity.j3.j6(v, true); //l大概应该是FileTabMenu,这里的j6应该是showTabMenu(View anchor, boolean show);

菜鸟夜谈android反编译的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. Android 反编译

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

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

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

  8. Android 反编译apk 详解

    测试环境: win 7 使用工具: CSDN上下载地址: apktool (资源文件获取)  下载          dex2jar(源码文件获取) 下载        jd-gui  (源码查看)  ...

  9. Android 反编译工具简介

    Android 反编译工具: 所需工具:1 apktool : 用于获取资源文件 2 dex2Jar : 用于将classes.dex转化成jar文件 2 jd-gui: 将jar文件转化成java文 ...

随机推荐

  1. RabbitMQ入门(6)——远程过程调用(RPC)

    在RabbitMQ入门(2)--工作队列中,我们学习了如何使用工作队列处理在多个工作者之间分配耗时任务.如果我们需要运行远程主机上的某个方法并等待结果怎么办呢?这种模式就是常说的远程过程调用(Remo ...

  2. url拼接

    在做网页抓取的时候经常会遇到一个问题就是页面中的链接是相对链接,这个时候就需要对链接进行url拼接,才能得到绝对链接. url严格按照一定的格式构成,一般为如下5个字段: 详细可参考RFC:http: ...

  3. geoserver源码学习与扩展——跨域访问配置

    在 geoserver源码学习与扩展——restAPI访问 博客中提到了geoserver的跨域参数设置,本文详细讲一下geoserver的跨域访问配置. geoserver的跨域访问依赖java-p ...

  4. 通俗易懂讲解IO模型

    前言 说到IO模型,都会牵扯到同步.异步.阻塞.非阻塞这几个词.从词的表面上看,很多人都觉得很容易理解.但是细细一想,却总会发现有点摸不着头脑.自己也曾被这几个词弄的迷迷糊糊的,每次看相关资料弄明白了 ...

  5. Sql Server中的DBCC命令详细介绍

    一:DBCC 1:什么是DBCC 我不是教学老师,我也说不到没有任何无懈可击的定义,全名:Database Console Commands.顾名思义“数据库控制台命令”,说到“控制台“,我第一反应就 ...

  6. EasyUI datagrid 多条件查询

    <script type="text/javascript"> $(function () { $("#dg").datagrid({ url: ' ...

  7. 真正在线编辑的在线web编辑器

    最近正在研究开发一款在线web编辑器架构,这是一款真正傻瓜式的web编辑器,可以在正常浏览页面的情况进行编辑,经过测试,对于一般网页页面来说非常好用方便,操作更简单. 一般的在线web编辑器虽说提供了 ...

  8. 设计模式--状态模式C++实现

    1定义 当一个状态的内在状态改变时允许其行为改变,这个对象看起来像改变了其类 2类图 角色分析 State抽象状态角色,接口或者抽象类,负责状态定义,并且封装环境角色以实现状态切换 ConcreteS ...

  9. python进行linux系统监控

      python进行linux系统监控 Linux系统下: 静态指标信息: 名称 描述 单位 所在文件 mem_total 内存总容量 KB /proc/meminfo disks 磁盘相关信息 - ...

  10. h1标签

    h1标签一.每个网页只能拥有一个<H1>标签 H2,H3,H4可以有多个...但多个H1造成的后果是搜索引擎不知道你这个页面哪个标题内容最重要,会淡化这个页面的标题和关键词.H1用得好的话 ...