zoukankan      html  css  js  c++  java
  • 菜鸟夜谈android反编译

    工具:

    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" />
    十进制是2131361796,搜索全文件结果只找到一次,在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);
  • 相关阅读:
    基于Python的人脸动漫转换
    let 与 var的区别
    【LeetCode】汇总
    【HDU】4632 Palindrome subsequence(回文子串的个数)
    【算法】均匀的生成圆内的随机点
    【LeetCode】725. Split Linked List in Parts
    【LeetCode】445. Add Two Numbers II
    【LeetCode】437. Path Sum III
    【LeetCode】222. Count Complete Tree Nodes
    【LeetCode】124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/shendiao/p/3536445.html
Copyright © 2011-2022 走看看