菜鳥夜談android反編譯

工具:java

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

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

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

反編譯命令提取資源(smail彙編代碼):apktool d file.apk pathapp

dex2jar反編譯:dex2jar file.apk (or classes.dex)ide

用jd-gui就能夠打開jar看了函數

用jd-gui在windows下沒問題,在linux64下要裝ia32的庫。工具

通常代碼都被混淆過。佈局

都是abcdefg。。。post

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

本人最近反編譯一個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);
相關文章
相關標籤/搜索