• 菜鸟夜谈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);
  • 相关阅读:
    Handling Errors and Exceptions
    Advanced Features of Delphi DLLs
    How to put a relative path for a DLL statically loaded?
    Delphi DLL制作和加载 Static, Dynamic, Delayed 以及 Shared-Memory Manager
    The useful App Paths registry key : HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionApp Paths
    DLL Dynamic-Link Library Search Order
    Can a windows dll retrieve its own filename?
    Restrict form resize -- Delphi
    Programmer in Google Code
    How to open a web site with the default web browser in a NEW window
  • 原文地址:https://www.cnblogs.com/shendiao/p/3536445.html
Copyright © 2020-2023  润新知