JHLBLUE
안드로이드 smali 패치 설명 본문
안드로이드 smali 패치하기에서 smali로 디코딩한 뒤 볼 수 있는 MainActivitry.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 | # 클래스의 이름 및 경로 정보 .class public Ljhlblue/ddns/net/sampleapk/MainActivity; #해당 클래스가 상속받는 클래스 정보 .super Landroid/support/v7/app/AppCompatActivity; #원래 프로젝트의 파일 이름 .source "MainActivity.java" #다이렉트 메소드 정보 #다이렉트 메소드는 private 이거나 생성자(constructor) # direct methods .method public constructor <init>()V #해당 메소드에서 사용할 로컬 레지스터의 개수 #locals가 1 이상일 경우에는 v0부터 v1, v2, ... 등의 레지스터를 사용할 수 있다. #locals의 값을 15 이상으로 설정한 뒤 빌드를 할 경우 Invalid register: v16. Must be between v0 and v15, inclusive라는 에러가 생성된다. # 아래 블로그 내용 참고 # http://blog.rebforpwn.com/index.php/2018/01/23/599/ # http://modapk.tistory.com/13 .locals 0 #실제 자바 코드와 매칭되는 줄번호 .line 7 #direct 메소드 AppCompatActivity 호출 #{p0}은 해당 함수에 전달할 수 있는 파라미터이다. #이 부분에서 p0은 this를 의미한다. invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;-><init>()V return-void .end method # virtual methods #.method 접근지정자 메소드이름(인자정보) 리턴타입 #onCreate라는 메소드의 접근지정자는 protected, 인자로는 android.os.Bundle 하나를 받으며 리턴 타입은 Void이다. .method protected onCreate(Landroid/os/Bundle;)V .locals 1 .line 11 #상위 클래스의 메소드 onCreate를 호출 invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V #p1 레지스터에 데이터 0x7f09001b를 저장 #const 레지스터이름 데이터 const p1, 0x7f09001b .line 12 invoke-virtual {p0, p1}, Ljhlblue/ddns/net/sampleapk/MainActivity;->setContentView(I)V const p1, 0x7f070083 .line 14 #java의 findViewById 함수를 호출하는 부분 #해당 함수의 리턴값이 textview object이다. #java 코드의 TextView textView = findViewById(R.id.textview); invoke-virtual {p0, p1}, Ljhlblue/ddns/net/sampleapk/MainActivity;->findViewById(I)Landroid/view/View; #findViewById 함수의 리턴 타입은 android.view.View이기 때문에 반환된 값을 저장할 레지스터를 지정해야 함 #레지스터 p1에 findViewById 함수의 반환된 값을 저장 #move-result-object 레지스터이름 move-result-object p1 #타입 캐스팅 체크 #check-cast 레지스터, 타입이름 check-cast p1, Landroid/widget/TextView; const v0, 0x7f070084 .line 15 invoke-virtual {p0, v0}, Ljhlblue/ddns/net/sampleapk/MainActivity;->findViewById(I)Landroid/view/View; move-result-object p0 check-cast p0, Landroid/widget/TextView; #레지스터 p0에 string값인 "Input any text to textview2"을 저장 #const와 거의 동일한 방법으로 사용 가능 const-string p0, "Input any text to textview2" .line 17 #java의 setText 함수를 호출하는 부분 #해당함수를 호출한 뒤 textview의 텍스트가 변경된다. #java 코드의 textView.setText("Input any text to textview2"); invoke-virtual {p1, p0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V #메소드 값 반환 부분 #return-void는 void를 반환한다는 뜻 return-void #메소드의 끝부분 .end method | cs |
위의 코드의 58번째 줄과 72번 줄에서 findViewById() 함수를 두 번 호출했고, 각각 호출될 때 사용된 파라미터 데이터가 다르며 (0x7f070083과 0x7f070084) findViewById() 함수 호출 이후에 check-cast Landroid/widget/TextView로 타입 캐스팅 체크 코드가 실행되는 것으로 보아 이 MainActivity에서는 두 개의 TextView가 존재하고, 이 중 하나의 TextView에만 setText 함수를 이용하여 텍스트를 입력했다는 것을 알 수 있다.
또한, 73~77번째 줄의 코드를 살펴보면 두 번째 findViewById() 함수의 결과값이 저장된 레지스터는 p0이지만 81번째 줄에서 레지스터 p0에 const-string 명령으로 텍스트 값을 저장했기 때문에 textview의 객체로 사용할 수 없게 되었다.
따라서 위의 코드에서 텍스트 값을 레지스터 p0이 아닌 다른 레지스터를 사용해야 한다. onCreate에서 사용하는 레지스터는 p0, p1, v0의 총 3개이고, 이 중 p0과 p1은 TextView의 객체정보가 저장되어있기 때문에 v0에 텍스트 값을 저장하도록 한다.
#const-string p0, "Input any text to textview2"
const-string v0, "Input any text to textview2"
텍스트가 저장되는 레지스터를 p0에서 v0으로 변경했기 때문에 이전에 p0를 사용했던 함수의 인자 역시 변경을 해줘야 한다. 87번째 줄의 코드를 아래와 같이 변경한다.
#invoke-virtual {p1, p0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
invoke-virtual {p1, v0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
다음은 setText() 함수를 한번 더 호출하여 원래 텍스트 출력을 하지 않았던 textview에도 텍스트를 출력할 수 있도록 한다.
invoke-virtual {p1, v0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
만약 출력할 텍스트를 변경하고 싶다면 아래의 코드를 추가한 뒤 setText() 함수를 호출하도록 한다.
const-string v0, "text value"
변경된 코드는 아래와 같다.
그 밖에 해당 내용에는 없는 smali 코드에 대한 설명은 안드로이드 dalvik-bytecode나 Mod Apk 블로그 게시물을 확인하면 된다.
'Android' 카테고리의 다른 글
안드로이드 smali 패치하기4 (0) | 2019.02.08 |
---|---|
안드로이드 smali 패치하기3 (0) | 2019.01.28 |
안드로이드 smali 패치하기2 (0) | 2019.01.22 |
안드로이드 smali 패치하기1 (0) | 2019.01.07 |
Android ndk 라이브러리 추가해 사용하기 (0) | 2017.11.04 |