>  기사  >  운영 및 유지보수  >  Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

WBOY
WBOY앞으로
2023-05-12 16:22:131538검색

1.java complex class

이해가 안 되는 부분이 있으면 JAVA 일반 개요 또는 구성 방법
Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

여기에 코드를 게시하세요. 매우 간단하고 어렵지 않습니다.

2.smali code

java 코드를 smali 코드로 변환해야 합니다. java를 smali

Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

모듈에서 살펴보겠습니다.

2.1 첫 번째 모듈 - 정보 모듈


Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

이 모듈은 기본 정보, 클래스 이름 설명 등입니다. 단순히 알고 있는 것만으로는 분석에 큰 도움이 되지 않습니다.

2.2 두 번째 모듈 - 구성 방법


Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

문장별로 분석해 보겠습니다. 이전 분석에서 반복되는 부분이 있으면 반복하지 않습니다. 그러나 링크가 제공됩니다.

.method public constructor <init>(Ljava/lang/String;I)V</init>

이 문장은

.methodpublicconstructor<init>(Ljava/lang/String;I)v</init>
2.2.1 .method

로 나누어집니다. 방법

2.2.2 public

수정 방법, 공용 속성

2.2.3 생성자

여기서 생성자는 이 방법을 말합니다. 생성 메소드

2.2.4 <init></init><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

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


第三句话。

.prologue

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


第四句话。

.line 10

第10行代码的意思。


第五句话是:

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

首先先分解这句话。

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

就是方法调用的意思。

{p0}

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

Ljava/lang/Object;-><init></init>

调用<init></init>方法

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


第六句话是

iput-object p1, p0, LPerson;->name:Ljava/lang/String;

分解一下

iput-object p1,p0LPerson;->name:Ljava/lang/String;

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

LPerson;->name:Ljava/lang/String;

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


第七句话

iput p2, p0, LPerson;->age:I

这里也分解为两个部分。

iput p2, p0LPerson;->age:I

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

LPerson;->age:I

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

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


第八句话

 sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

分解

 sget-object v0
 Ljava/lang/System;->out:
 Ljava/io/PrintStream;

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

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


第九句话

new-instance v1, Ljava/lang/StringBuilder;

新建一个StringBuilder的类给v1。


第十句话

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

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


第十一句话

const-string v2, "name:"

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


第十二句话

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

分解一下就是

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

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

컴파일 후 Java는 바이트코드 파일에 인스턴스 생성자라고 불리는 메소드를 생성합니다. 명령문 블록, 변수 초기화, 상위 클래스의 생성자 호출 및 기타 작업을 수렴 순서(여기에서는 비정적 변수 및 명령문 블록만 논의함)는 다음과 같습니다. list-paddingleft -2">

  • 부모 클래스 변수 초기화

  • 부모 클래스 명령문 블록

  • 부모 클래스 생성자🎜
  • 🎜하위 클래스 변수 초기화🎜
  • 🎜하위 클래스 문 블록🎜
  • 🎜하위 클래스 생성자🎜
  • 🎜 소위 메소드로의 수렴은 Put; 이러한 작업을 로 실행🎜🎜2.2.5(Ljava/lang/String;I)🎜🎜괄호 안의 내용은 먼저 Ljava/lang/String입니다. 이는 첫 번째 매개변수가 문자열 유형임을 의미합니다. 🎜; 뒤에 I가 있습니다. 이는 Ljava/lang에도 속하고 여기에 int 유형 매개변수가 있음을 의미합니다. 🎜🎜2.2.6 v🎜🎜마지막 v는 무효를 의미합니다. 즉, 반환값 유형이 없습니다. 🎜🎜🎜두 번째 문장의 의미를 살펴보겠습니다. 🎜
    move-result-object v1
    🎜등록 6. 여기의 레지스터는 v0-v5부터 시작됩니다. 이것은 이해하기 쉽습니다. 🎜🎜🎜세 번째 문장입니다. 🎜
    .method public constructor <init>()V    .registers 1
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
        return-void
    .end method</init></init>
    🎜오프닝, 프로그램의 시작을 의미합니다. 🎜🎜🎜네번째 문장입니다. 🎜
    public class Demo{
        public static void main(String[]args)    {
            Person p=new Person("zhuzhu",14);
        }
    }
    🎜코드 10번째 줄의 의미입니다. 🎜🎜🎜다섯 번째 문장은 🎜
    javac -source 1.6 -target 1.6 *.java
    🎜먼저 이 문장을 분해해 보겠습니다. 🎜
    dx --dex --output=demo.dex *.class
    .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>
    🎜는 메소드 호출을 의미합니다. 🎜
    new-instance v0, LPerson;
    🎜p0이 첫 번째 매개변수입니다. 그러나 여기에는 첫 번째 매개변수가 없습니다. 여기서 기본값은 p1부터 계산되기 시작하는 매개변수입니다. 🎜
    const-string v1, "zhuzhu"
    🎜<init></init> 메소드 호출 🎜🎜()에는 내용이 없습니다. 이는 매개변수가 없음을 의미합니다. v는 void와 동일하며 여기서는 반복하지 않습니다. 🎜🎜🎜여섯 번째 문장은 🎜
    const/16 v2, 0xe
    🎜Break it down🎜
    invoke-direct {v0, v1, v2}, LPerson;-><init>(Ljava/lang/String;I)V</init>
    🎜iput-object p1, p0은 p1의 내용을 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>
    🎜이 문장의 의미는 Person 클래스에서 name이라는 속성을 취하고 String을 입력한다는 것입니다. 이는 p0을 수정하는 것입니다. 사실은 this.name입니다.🎜🎜🎜일곱 번째 문장🎜rrreee🎜도 두 부분으로 나누어져 있어요. 🎜rrreee🎜iput p2, p0, 여기서는 p2의 값을 p0🎜rrreee🎜에 넘겨주는 것으로 age의 데이터 타입이 int임을 알 수 있습니다. 🎜🎜여기서 두 속성을 호출하는 것이 다르다는 것을 알 수 있습니다. 이는 String이 기본 데이터 유형이 아니기 때문입니다. 따라서 기본 데이터 유형이 iput인 경우 iput-object가 사용됩니다. 🎜🎜🎜8번째 문장 🎜rrreee🎜Decomposition🎜rrreee🎜sget-object v0은 나중에 만날 것을 얻어서 v0에 주는 것입니다. 🎜🎜Ljava/io/PrintStream;이는 이 클래스에 Ljava/lang/System;->out: 메서드가 있음을 의미합니다. 🎜🎜🎜9번째 문장🎜rrreee🎜v1용 새 StringBuilder 클래스를 만듭니다. 🎜🎜🎜열 번째 문장🎜rrreee🎜은 이전 문장과 유사하며 생성자에서 v1을 호출합니다. 🎜🎜🎜열한 번째 문장🎜rrreee🎜const-string 상수 문자열입니다. v2, 콘텐츠 이름은 다음과 같습니다.🎜🎜🎜12번째 문장🎜rrreee🎜구분하면🎜rrreee🎜invoke-virtual {v1, v2}는 가상 메서드 🎜->append(Ljava/lang/String)를 호출합니다. ; )Ljava/lang/StringBuilder;append라는 메소드를 호출합니다. 매개변수는 String 유형이고 반환 값은 StringBuilder 유형입니다. 🎜🎜🎜열세 번째 문장🎜rrreee🎜은 이전 문장의 결과를 v1 레지스터에 제공하는 것입니다. 🎜

    之后的内容就是相似的了。
    Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

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

    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>

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

    编译成jar文件进行查看。


    Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

    0x02 smali类相互调用

    1. java代码

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

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

    代码很简单。

    2.smali代码

    这里我们要使用

    javac -source 1.6 -target 1.6 *.java

    编译所有.java文件

    然后使用

    dx --dex --output=demo.dex *.class

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


    Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

    我们来主要看看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>
    new-instance v0, LPerson;

    新建一个类,v0

    const-string v1, "zhuzhu"

    然后定义一个常量 v1。

    const/16 v2, 0xe

    定义一个16位的常量

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

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

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

    3.总结

    我们调用其他类的时候。

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

    0x03 小练习(甜点)

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

    Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석

    然后是手写的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>

    위 내용은 Android 리버스 엔지니어링의 smali 복합 클래스 예제 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제