Heim > Betrieb und Instandhaltung > Sicherheit > Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

WBOY
Freigeben: 2023-05-12 16:22:13
nach vorne
1651 Leute haben es durchsucht

1.Java-Komplexklasse

Wenn Sie nichts verstehen, lesen Sie bitte: Allgemeine JAVA-Übersicht oder Konstruktionsmethode
Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

Veröffentlichen Sie es hier. Der Code ist sehr einfach und nicht schwierig.

2.smali-Code

Wir müssen Java-Code in Smali-Code konvertieren, Sie können auf Java auf Smali verweisen

# 🎜🎜 #

Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

Schauen wir es uns in Modulen an.

2.1 Das erste Modul - Informationsmodul


Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

Dieses Modul enthält grundlegende Informationen, die darauf hinweisen B. den Klassennamen usw., allein dessen Kenntnis ist für die Analyse nicht sehr hilfreich.

2.2 Das zweite Modul - Konstruktionsmethode


Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

Lassen Sie es uns Satz für Satz analysieren, falls vorhanden previous Das wiederholte Parsen wird nicht wiederholt. Es wird aber ein Link bereitgestellt.


.method public constructor <init>(Ljava/lang/String;I)V</init>
Nach dem Login kopieren
Dieser Satz ist unterteilt in

.methodpublicconstructor<init>(Ljava/lang/String;I)v</init>
Nach dem Login kopieren
2.2.1 .method
means method

#🎜🎜 # 2.2.2 öffentlich

Änderungsmethode, öffentliches Eigentum

2.2.3 Konstruktor

Konstruktor bedeutet hier, dass diese Methode eine Konstruktormethode ist# 🎜🎜 #
2.2.4 <init></init>

Nach der Kompilierung generiert Java die -Methode in der Bytecode-Datei, die als Instanzkonstruktor bezeichnet wird. Dadurch werden Anweisungsblöcke, Variableninitialisierung, Aufruf des Konstruktors der übergeordneten Klasse und andere Operationen in die
  • Variableninitialisierung der übergeordneten Klasse<init></init>

    Java在编译之后会在字节码文件中生成方法,称之为实例构造器,该实例构造器会将语句块,变量初始化,调用父类的构造器等操作收敛到方法中,收敛顺序(这里只讨论非静态变量和语句块)为:

    1. 父类变量初始化

    2. 父类语句块

    3. 父类构造函数

    4. 子类变量初始化

    5. 子类语句块

    6. 子类构造函数

    所谓收敛到方法中的意思就是,将这些操作放入到中去执行

    2.2.5 (Ljava/lang/String;I)

    括号里的内容首先是 Ljava/lang/String,这里就是说第一个参数为String类型。
    ; 后面有一个I就是说同样属于 Ljava/lang这里的有一个int型参数。

    2.2.6 v

    最后面有一个v的含义就是void。也就是没有返回值类型。


    我们来看第二句的意思。

    .registers 6
    Nach dem Login kopieren

    寄存器 6个。这里的寄存器就是从v0-v5开始。这个很好理解。


    第三句话。

    .prologue
    Nach dem Login kopieren

    开场,意思是程序的开始。


    第四句话。

    .line 10
    Nach dem Login kopieren

    第10行代码的意思。


    第五句话是:

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V</init>
    Nach dem Login kopieren

    首先先分解这句话。

    invoke-direct{p0}Ljava/lang/Object;-><init>
    ()
    V</init>
    Nach dem Login kopieren
    invoke-direct
    Nach dem Login kopieren

    就是方法调用的意思。

    {p0}
    Nach dem Login kopieren

    p0就是说第一个参数。但是这里并没有第一个参数,这里默认就是this,我们自己传进去的参数从p1开始计数。

    Ljava/lang/Object;-><init></init>
    Nach dem Login kopieren

    调用<init></init>方法

    ()里没有内容就是说没有参数。v相当于void,这里不再重复。


    第六句话是

    iput-object p1, p0, LPerson;->name:Ljava/lang/String;
    Nach dem Login kopieren

    分解一下

    iput-object p1,p0LPerson;->name:Ljava/lang/String;
    Nach dem Login kopieren

    iput-object p1,p0的含义就是把p1的内容给p0。

    LPerson;->name:Ljava/lang/String;
    Nach dem Login kopieren

    这句话的含义就是说把Person类里的一个名为name,类型为String的属性拿过来,这些是为了修饰p0。其实也就是this.name.


    第七句话

    iput p2, p0, LPerson;->age:I
    Nach dem Login kopieren

    这里也分解为两个部分。

    iput p2, p0LPerson;->age:I
    Nach dem Login kopieren

    iput p2, p0,这里就是把p2的值给p0

    LPerson;->age:I
    Nach dem Login kopieren

    说明了age这个数据类型是int。

    这里可能会发现调用两个属性不一样,这里就是因为String并不是一个基本数据类型。所以使用了iput-object,如果是基本数据类型为iput。


    第八句话

     sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    Nach dem Login kopieren

    分解

     sget-object v0
     Ljava/lang/System;->out:
     Ljava/io/PrintStream;
    Nach dem Login kopieren

    sget-object v0 就是获取到后见面的东西给v0。

    Ljava/io/PrintStream;这个的含义就是说由这个类里的一个Ljava/lang/System;->out:这个方法。


    第九句话

    new-instance v1, Ljava/lang/StringBuilder;
    Nach dem Login kopieren

    新建一个StringBuilder的类给v1。


    第十句话

    invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V</init>
    Nach dem Login kopieren

    和之前的类似,从构造方法里调用v1。


    第十一句话

    const-string v2, "name:"
    Nach dem Login kopieren

    const-string 常量字符串。 v2,内容是name:


    第十二句话

     invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    Nach dem Login kopieren

    分解一下就是

    invoke-virtual {v1, v2}Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    Nach dem Login kopieren

    invoke-virtual {v1, v2} 调用虚方法,
    ->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

  • Anweisungsblock der übergeordneten Klasse
    li>
  • Konstruktor der übergeordneten Klasse

  • Variableninitialisierung der Unterklasse

  • #🎜🎜#Anweisungsblock der Unterklasse#🎜🎜#
  • #🎜🎜#Unterklassenkonstruktor#🎜🎜#
  • #🎜🎜#Die sogenannte Konvergenz in die -Methode bedeutet, dass diese Operationen in für die Ausführung #🎜🎜##🎜🎜#2.2.5 (Ljava/lang/String;I)#🎜🎜##🎜🎜#Der Inhalt in Klammern ist der erste Ljava/lang/String, hier bedeutet der erste Parameter ist vom Typ String. #🎜🎜#; Dahinter steht ein I, was bedeutet, dass es auch zu Ljava/lang gehört und es hier einen Parameter vom Typ int gibt. #🎜🎜##🎜🎜#2.2.6 v#🎜🎜##🎜🎜#Die Bedeutung eines v am Ende ist ungültig. Das heißt, es gibt keinen Rückgabewerttyp. #🎜🎜##🎜🎜##🎜🎜# Schauen wir uns die Bedeutung des zweiten Satzes an. #🎜🎜#
    move-result-object v1
    Nach dem Login kopieren
    #🎜🎜#Register 6. Die Register beginnen hier bei v0-v5. Das ist leicht zu verstehen. #🎜🎜##🎜🎜##🎜🎜#Der dritte Satz. #🎜🎜#
    .method public constructor <init>()V    .registers 1
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
        return-void
    .end method</init></init>
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#Eröffnung bedeutet den Beginn des Programms. #🎜🎜##🎜🎜##🎜🎜#Der vierte Satz. #🎜🎜#
    public class Demo{
        public static void main(String[]args)    {
            Person p=new Person("zhuzhu",14);
        }
    }
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#Die Bedeutung der 10. Codezeile. #🎜🎜##🎜🎜##🎜🎜#Der fünfte Satz lautet: #🎜🎜#
    javac -source 1.6 -target 1.6 *.java
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#Zerlegen Sie zunächst diesen Satz auf. #🎜🎜#
    dx --dex --output=demo.dex *.class
    Nach dem Login kopieren
    Nach dem Login kopieren
    .method public static main([Ljava/lang/String;)V
        .registers 4
    
        .prologue
        .line 4
        new-instance v0, LPerson;
    
        const-string v1, "zhuzhu"    const/16 v2, 0xe    invoke-direct {v0, v1, v2}, LPerson;-><init>(Ljava/lang/String;I)V
    
        .line 5    return-void.end method</init>
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜# bedeutet Methodenaufruf. #🎜🎜#
    new-instance v0, LPerson;
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#p0 ist der erste Parameter. Hier gibt es jedoch keinen ersten Parameter. Die von uns übergebenen Parameter beginnen mit der Zählung ab p1. #🎜🎜#
    const-string v1, "zhuzhu"
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#Aufruf der <init></init>-Methode #🎜🎜##🎜🎜#() hat keinen Inhalt, was bedeutet, dass es keine Parameter gibt. v entspricht void und wird hier nicht wiederholt. #🎜🎜##🎜🎜##🎜🎜#Der sechste Satz ist #🎜🎜#
    const/16 v2, 0xe
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#Break it down#🎜🎜#
    invoke-direct {v0, v1, v2}, LPerson;-><init>(Ljava/lang/String;I)V</init>
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#iput-object p1, die Bedeutung von p0 besteht darin, das zu setzen Inhalt von p1 Gebe p0. #🎜🎜#
    .class public LPd;
    .super Ljava/lang/Object;
    .source "Pd.java"# direct methods
    .method public constructor <init>()V
        .registers 1    .prologue
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
        return-void.end method
    
    .method public static main([Ljava/lang/String;)V
    
        .registers 4    .prologue
    
        new-instance v0,LPerson;
    
        invoke-direct {v0}, LPerson;-><init>()V
    
        return-void.end method</init></init></init>
    Nach dem Login kopieren
    Nach dem Login kopieren
    #🎜🎜#Die Bedeutung dieses Satzes besteht darin, ein Attribut namens name und type String aus der Person-Klasse zu übernehmen. Diese dienen dazu, p0 zu ändern. Tatsächlich ist es dieser.Name.#🎜🎜##🎜🎜##🎜🎜#Der siebte Satz #🎜🎜#rrreee#🎜🎜# ist ebenfalls in zwei Teile gegliedert. #🎜🎜#rrreee#🎜🎜#iput p2, p0, hier wird der Wert von p2 an p0 übergeben#🎜🎜#rrreee#🎜🎜#Es zeigt, dass der Datentyp des Alters int ist . #🎜🎜##🎜🎜#Sie werden möglicherweise feststellen, dass der Aufruf der beiden Eigenschaften unterschiedlich ist. Dies liegt daran, dass String kein grundlegender Datentyp ist. Daher wird iput-object verwendet, wenn der Basisdatentyp iput ist. #🎜🎜##🎜🎜##🎜🎜#Der achte Satz#🎜🎜#rrreee#🎜🎜#Decomposition#🎜🎜#rrreee#🎜🎜#sget-object v0 besteht darin, v0 die Dinge zu geben, denen Sie begegnen, nachdem Sie es erhalten haben. #🎜🎜##🎜🎜#Ljava/io/PrintStream;Die Bedeutung davon ist, dass ein Ljava/lang/System;->out: Diese Methode. #🎜🎜##🎜🎜##🎜🎜#Der neunte Satz #🎜🎜#rrreee#🎜🎜#Erstellen Sie eine neue StringBuilder-Klasse für v1. #🎜🎜##🎜🎜##🎜🎜#Der zehnte Satz #🎜🎜#rrreee#🎜🎜# ähnelt dem vorherigen und ruft v1 vom Konstruktor auf. #🎜🎜##🎜🎜##🎜🎜#Der elfte Satz#🎜🎜#rrreee#🎜🎜#const-string konstante Zeichenfolge. v2, der Inhalt ist Name: #🎜🎜##🎜🎜##🎜🎜#Der zwölfte Satz #🎜🎜#rrreee#🎜🎜#Aufgeschlüsselt ist er #🎜🎜#rrreee#🎜🎜#invoke-virtual {v1, v2} Rufen Sie eine virtuelle Methode auf, #🎜🎜#->append(Ljava/lang/String;)Ljava/lang/StringBuilder;Rufen Sie eine Methode namens append auf, der Parameter ist vom Typ String und die Der Rückgabewert ist vom Typ StringBuilder. #🎜🎜##🎜🎜##🎜🎜#Der dreizehnte Satz#🎜🎜#rrreee#🎜🎜#besteht darin, das Ergebnis des vorherigen Satzes an das v1-Register zu übergeben. #🎜🎜#

    之后的内容就是相似的了。
    Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

    有兴趣可以自己继续向下分析。

    2.3 方法模块

    这个模块在之前的一篇文章里已经说过了,这里就不再啰嗦了。

    2.4 练习

    这个练习我们就自己添加一个构造方法。

    .method public constructor <init>()V    .registers 1
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
        return-void
    .end method</init></init>
    Nach dem Login kopieren
    Nach dem Login kopieren

    这个是我们自己写的一个构造方法。无参无返回值。

    编译成jar文件进行查看。


    Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

    0x02 smali类相互调用

    1. java代码

    在0x01的前提上我们再写一个调用demo。

    public class Demo{
        public static void main(String[]args)    {
            Person p=new Person("zhuzhu",14);
        }
    }
    Nach dem Login kopieren
    Nach dem Login kopieren

    代码很简单。

    2.smali代码

    这里我们要使用

    javac -source 1.6 -target 1.6 *.java
    Nach dem Login kopieren
    Nach dem Login kopieren

    编译所有.java文件

    然后使用

    dx --dex --output=demo.dex *.class
    Nach dem Login kopieren
    Nach dem Login kopieren

    把所有的.class文件编译成dex文件。


    Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

    我们来主要看看main函数。

    .method public static main([Ljava/lang/String;)V
        .registers 4
    
        .prologue
        .line 4
        new-instance v0, LPerson;
    
        const-string v1, "zhuzhu"    const/16 v2, 0xe    invoke-direct {v0, v1, v2}, LPerson;-><init>(Ljava/lang/String;I)V
    
        .line 5    return-void.end method</init>
    Nach dem Login kopieren
    Nach dem Login kopieren
    new-instance v0, LPerson;
    Nach dem Login kopieren
    Nach dem Login kopieren

    新建一个类,v0

    const-string v1, "zhuzhu"
    Nach dem Login kopieren
    Nach dem Login kopieren

    然后定义一个常量 v1。

    const/16 v2, 0xe
    Nach dem Login kopieren
    Nach dem Login kopieren

    定义一个16位的常量

    invoke-direct {v0, v1, v2}, LPerson;-><init>(Ljava/lang/String;I)V</init>
    Nach dem Login kopieren
    Nach dem Login kopieren

    调用Person类的构造方法,然后把v0,v1,v2当做参数传进去。

    其实类之前的交互调用其实并不难。

    3.总结

    我们调用其他类的时候。

    1.new-instance 实例化一个对象
    2.invoke-direct 调用构造方法

    0x03 小练习(甜点)

    首先来看看我们写的程序。

    Analyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering

    然后是手写的smali代码。

    .class public LPd;
    .super Ljava/lang/Object;
    .source "Pd.java"# direct methods
    .method public constructor <init>()V
        .registers 1    .prologue
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
        return-void.end method
    
    .method public static main([Ljava/lang/String;)V
    
        .registers 4    .prologue
    
        new-instance v0,LPerson;
    
        invoke-direct {v0}, LPerson;-><init>()V
    
        return-void.end method</init></init></init>
    Nach dem Login kopieren
    Nach dem Login kopieren

    Das obige ist der detaillierte Inhalt vonAnalyse kleiner komplexer Klassenbeispiele im Android-Reverse-Engineering. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Verwandte Etiketten:
    Quelle:yisu.com
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage