티스토리 뷰

Smali 코드 분석

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
.class public Lcom/example/tribal/filereader/MainActivity;
.super Landroid/support/v7/app/AppCompatActivity;
.source "MainActivity.java"
 
 
static fields
.field public static final ReadFilePath:Ljava/lang/String= "C:\\TagFile"
 
 
# direct methods
.method public constructor <init>()V
    .locals 0
 
    .prologue
    .line 13
    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;-><init>()V
 
    return-void
.end method
 
 
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
    .locals 9
    .param p1, "savedInstanceState"    # Landroid/os/Bundle;
 
    .prologue
    .line 18
    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V
 
    .line 19
    const v6, 0x7f04001b
 
    invoke-virtual {p0, v6}, Lcom/example/tribal/filereader/MainActivity;->setContentView(I)V
 
    .line 21
    new-instance v2, Ljava/io/File;
 
    const-string v6, "C:\\TagFile"
 
    invoke-direct {v2, v6}, Ljava/io/File;-><init>(Ljava/lang/String;)V
 
    .line 22
    .local v2, "fhandle":Ljava/io/File;
    invoke-virtual {v2}, Ljava/io/File;->length()J
 
    move-result-wide v4
 
    .line 24
    .local v4, "fsize":J
    :try_start_0
    new-instance v3, Ljava/io/FileReader;
 
    invoke-direct {v3, v2}, Ljava/io/FileReader;-><init>(Ljava/io/File;)V
 
    .line 25
    .local v3, "fread":Ljava/io/FileReader;
    long-to-int v6, v4
 
    new-array v0, v6, [C
 
    .line 27
    .local v0, "Tag":[C
    const/4 v6, 0x0
 
    long-to-int v7, v4
 
    invoke-virtual {v3, v0, v6, v7}, Ljava/io/FileReader;->read([CII)I
 
    move-result v6
 
    int-to-long v6, v6
 
    cmp-long v6, v4, v6
 
    if-eqz v6, :cond_0
 
    .line 28
    const/4 v6, -0x1
 
    invoke-static {v6}, Ljava/lang/System;->exit(I)V
 
    .line 31
    :cond_0
    sget-object v6, Ljava/lang/System;->out:Ljava/io/PrintStream;
 
    new-instance v7, Ljava/lang/StringBuilder;
 
    invoke-direct {v7}, Ljava/lang/StringBuilder;-><init>()V
 
    const-string v8, "Logger Tag : "
 
    invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
 
    move-result-object v7
 
    invoke-virtual {v7, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/Object;)Ljava/lang/StringBuilder;
 
    move-result-object v7
 
    invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
 
    move-result-object v7
 
    invoke-virtual {v6, v7}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V
 
    .line 33
    invoke-virtual {v3}, Ljava/io/FileReader;->close()V
    :try_end_0
    .catch Ljava/io/FileNotFoundException; {:try_start_0 .. :try_end_0} :catch_0
    .catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_1
 
    .line 39
    .end local v0    # "Tag":[C
    .end local v3    # "fread":Ljava/io/FileReader;
    :goto_0
    return-void
 
    .line 34
    :catch_0
    move-exception v1
 
    .line 35
    .local v1, "e":Ljava/io/FileNotFoundException;
    invoke-virtual {v1}, Ljava/io/FileNotFoundException;->printStackTrace()V
 
    goto :goto_0
 
    .line 36
    .end local v1    # "e":Ljava/io/FileNotFoundException;
    :catch_1
    move-exception v1
 
    .line 37
    .local v1, "e":Ljava/io/IOException;
    invoke-virtual {v1}, Ljava/io/IOException;->printStackTrace()V
 
    goto :goto_0
.end method
 
cs



원본 Java 소스 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.tribal.filereader;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
public class MainActivity extends AppCompatActivity {
    public static final String ReadFilePath = "C:\\TagFile";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        File fhandle = new File(ReadFilePath) ;
        long fsize = fhandle.length();
        try {
            FileReader fread = new FileReader(fhandle);
            char[] Tag = new char[((int) fsize)];
 
            if(fsize != fread.read(Tag, 0, ((int) fsize))) {
                System.exit(-1);
            }
 
            System.out.print("Logger Tag : " + Tag);
 
            fread.close() ;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
cs



Smali 코드 분석(Smali 코드 라인별 분석)

- 1번째 줄 : 클래스 명과 상속, 패키지 경로를 나타낸다.

- 2번째 줄 : MainActivity Class가 받는 상속 클래스를 나타낸다.

- 3번째 줄 : 원본 파일의 이름을 나타낸다.

- 7번째 줄 : 클래스 내부 static 변수와 자료형, 값을 나타낸다.


- 10번째 줄 : 메소드 호출이 direct인지 virtual인지를 나타낸다.

- 11번째 줄 : 메소드는 constructor로 표시되어 있고, <init>라는 이름으로 클래스의 생성자를 나타낸다.

- 12번째 줄 : .locals는 메소드 내부에서 사용되는 레지스터의 갯수인데 0개이다.

- 14번째 줄 : 메소드 내부의 코드 시작을 나타낸다.

- 15번째 줄 : 실제 자바 소스 코드와 매칭되는 line 넘버이다.

- 16번째 줄 : 오브젝트 android/support/v7/app/AppCompatActivity의 생성자인 <init>() 함수를 direct 호출하는 것을 나타낸다.

- 18번째 줄 : 함수의 반환 값 타입을 나타낸다.

- 19번째 줄 : 해당 함수의 종료를 나타낸다.

- 따라서 기본적인 생성자를 호출하고, 특별한 과정이 없었음을 알 수 있다.


- 22번째 줄 : 해당 함수가 virtual method라는 것을 나타낸다.

- 23번째 줄 : onCreate 함수가 android/os/Bundle을 인자로 하고, Void형을 반환한다.

- 24번째 줄 : 사용되는 레지스터의 갯수가 9개인 것을 나타낸다.

- 25번째 줄 : 인자 p1이 android/os/Bundle 타입이고, 변수 명이 "savedInstanceState" 임을 나타낸다.

- 29번째 줄 : 상속된 AppCompatActivity의 onCreate 함수를 p1을 인자로 호출한다.

- 32번째 줄 : 상수 v6의 값은 0x7f04001b이다.

- 34번째 줄 : MainActivity의 setContentView 함수를 v6을 인자로 호출한다.


- 37번째 줄 : java/io/File에 대해 새로운 instance v2를 생성한다.

- 39번째 줄 : 상수 문자열 v6은 "C:\\TagFile"이다.

- 41번째 줄 : 생성한 java/io/File 인스턴스의 생성자를 호출하는데 v6을 인자로 한다.

- 44번째 줄 : java/io/File 인스턴스 v2에 "fhandle"이라는 이름을 명명한다.

- 45번째 줄 : v2를 매개체로 length() 함수를 호출하고, 반환 값은 long 형이다.

- 47번째 줄 : long 형(8 byte) 반환 값을 v4에 저장한다.

- 50번째 줄 : long v4를 "fsize"라는 이름으로 명명한다.

- 51번째 줄 : try_start_0이라는 라벨로 try 구문의 시작을 나타낸다.

- 52번째 줄 : java/io/FileReader 인스턴스 v3를 생성한다.

- 54번째 줄 : 생성한 java/io/FilreReader 인스턴스의 생성자를 호출하는데 v2를 인자로 한다.


- 57번째 줄 : 인스턴스 v3에 "fread"라고 명명한다.

- 58번째 줄 : v4에 저장된 파일 크기를 long에서 int로 캐스팅하여 v6에 저장

- 60번째 줄 : v6에 저장된 값만큼 char형 배열 v0 생성

- 61번째 줄 : 0x0을 v6 레지스터에 저장

- 63번째 줄 : 배열 v0을 "Tag"라고 명명

- 66번째 줄 : v4에 저장된 파일 크기를 long에서 int로 캐스팅하여 v7에 저장

- 68번째 줄 : java/io/FileReader의 read 함수 호출, 인자는 버퍼(v0), 오프셋(v6), 크기(v7)이 전달된다.

- 70번째 줄 : 결과 값을 v6 레지스터에 저장

- 72번째 줄 : v6의 값을 int에서 long으로 캐스팅하여 v6에 저장

※ FileReader.read의 fsize는 long이 아닌 int로 캐스팅되어 전달됨


- 74번째 줄 : v4와 v6를 비교하여, 결과 값을 v6에 저장(1번 operand가 destination, 2번과 3번 operand는 source)

- 76번째 줄 : v6의 값을 0과 비교, 같으면 jmp

- 79번째 줄 : v6에 -0x1을 32bits 만큼 확장하여 저장

- 81번째 줄 : v6의 값을 인자로 static 함수인 java/lang/System의 exit 함수 호출

- 84번째 줄 : 76번째 줄의 jmp와 관련된 분기문

- 85번째 줄 : java/lang/System->out의 java/io/PrintStream에 해당하는 필드 id를 가져와 v6에 저장

- 87번째 줄 : java/lang/StringBuilder 인스턴스 v7 생성한다.

- 89번째 줄 : java/lang/StringBuider의 생성자 호출

- 91번째 줄 : 상수 문자열 v8에 "Logger Tag : " 저장


- 93번째 줄 : java/lang/string인 v8을 인자로 java/lang/StringBuilder->append 함수 호출

- 95번째 줄 : 결과 값을 v7에 저장

- 97번째 줄 : java/lang/Object인 v0을 인자로 java/lang/StringBuilder->append 함수 호출

- 96번째 줄 : 결과 값을 v7에 저장

- 101번째 줄 : java/lang/stringBuilder->toString() 함수 호출

- 103번째 줄 : 결과 값을 v7에 저장

- 105번째 줄 : java/io/PrintStream 오브젝트인 v6을 통해 v7을 인자로 print 함수 실행


- 108번째 줄 : v3을 매개체로 close 함수 호출

- 109번째 줄 : 51번째 줄의 try 실행 중 예외가 발생했을 때 예외처리 실시

- 110번째 줄 : 파일이 존재하지 않을 경우, FileNotFoundException을 가지고 catch_0로 이동

- 111번째 줄 : 입출력 예외 발생, IOException을 가지고 catch_1로 이동

- 114번째 줄 : char 배열 v0를 해제

- 115번째 줄 : FileReader 인스턴스 v3을 해제

- 116번째 줄 : goto_0 라벨

- 117번째 줄 : void 반환, 함수 종료

- 120번째 줄 : catch_0 라벨, FileNotFoundException 예외 발생 시 여기로 이동

- 121번째 줄 : v1에 FileNotFoundException 예외 전달

- 124번째 줄 : v1을 "e"라고 명명

- 125번째 줄 : v1을 매개체로 printStackTrace 함수 호출

- 127번째 줄 : goto 구문, goto_0 라벨인 116번째 줄로 이동

- 130번째 줄 : FileNotFoundException인 v1을 "e"라고 명명

- 131번째 줄 : catch_1 라벨, IOException 예외 발생 시 여기로 이동

- 132번째 줄 : v1에 FileNotFoundException 예외 전달

- 135번째 줄 : IOException인 v1을 "e"라고 명명

- 136번째 줄 : v1을 매개체로 printStackTrace 함수 호출

- 138번째 줄 : goto 구문, goto_0 라벨인 116번째 줄로 이동

- 139번째 줄 : method 종료



분석 완료 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.example.tribal.filereader;
 
import android/support/v7/app/AppCompatActivity;
import android/os/Bundle
import java/lang/System
import java/lang/StringBuilder
import java/io/PrintStream
import java/io/File
import java/io/FileReader
import java/io/IOException
import java/io/FileNotFoundException
 
public class MainActivity extends AppCompatActivity {
    public static final String ReadFilePath = "C:\\TagFile";
 
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(0x7f04001b);
 
        File fhandle = new File("C:\\TagFile");
        long fsize = fhandle.length();
 
        try {
            FileReader fread = new FileReader(fhandle);
 
            char[] Tag = new char[((int)fsize)];
 
            if(fsize != ((long)fread.read(Tag, 0, fsize))) {
                System.exit(-0x1);
            }
 
            v6 = out:java/io/PrintStream;
            StringBuilder v7 = new StringBuilder();
            v8 = "Logger Tag : ";
 
            v7 = v7.append(v8);
            v7 = v7.append(Tag);
            v7 = v7.toString();
            v6.print(v7);
 
            fread.close()
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }
}
 
 
cs

※ 28번째 줄 : FileReader.read의 fsize는 long이 아닌 int로 캐스팅되어 전달됨


참고 : 



'Reversing' 카테고리의 다른 글

Ida Plugin 리스트 및 사용법  (0) 2017.10.03
[Android] Main Activity 검색 스크립트  (2) 2017.08.23
Windbg 사용법 정리  (0) 2017.07.16
C++ 클래스 멤버 함수  (0) 2016.07.01
구조체 핸드레이  (0) 2016.04.26
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31