2013.01.29 20:50

android decompile and recompile.


이전 글(소스보기)에 이어 이번에는 소스 수정한 후 다시 컴파일 하는 것까지 해보자.

2013/01/15 - [bring/steal] - 안드로이드 apk 디컴파일(Decompile) / 소스보기



1. 준비물

  • JRE
    • 이건 알아서 설치.
  • APK Extracter
    • 이전 글(소스보기) 참고. 여러가지 방법이 있음. apk 받을 수만 있으면 됨.
  • APK TOOL
  • 텍스트 에디터
    • 알아서.. 아무거나
  • signapk.jar 및 키파일
    • 안드로이드 full source 안에 있다고 함. 따로 분리되어서 인터넷에 떠돌아다니니 찾아 받으셔도 됨. 일반적인 경우 키 파일도 대충 아무거나 생성해서 쓰면 됨.
      signapk.zip



2. 방법

2.1 APK 파일을 받자.

APK 파일 추출기로 받으삼. 참고로 필자는 "MN 앱 관리"라는 국산 제품을 사용했음. 그 프로그램에서는 앱을 길게 누르면 뜨는 메뉴에서 "설치파일 보내기" 누르면 컴퓨터로 옮길 수 있었음.




2.2. PC로 옮긴 APK 파일을 apktool 로 decode 하자.

아래는 naverapp 이라는 폴더로 디코드한 예.

java -jar apktool.jar d com.nhn.android.search-1.apk naverapp



naverapp 폴더 안에 풀린 리소스들과 smali 파일들이 나타난다. smali 파일에서 원하는 부분을 수정하면 된다. (smali 파일은 dalvik 바이트코드를 디어셈블한 간이 코드, 자세한건 http://code.google.com/p/smali/ 를 참고).


2.3. 수정한 코드를 다시 build 하자.

아래는 naverapp 이라는 폴더를 naverapp.apk 로 다시 빌드한 예.

java -jar apktool.jar b naverapp naverapp.apk



이런.. 에러가 발생했다. 대략 보니 res\values-en\strings.xml:40 위치에 하나와 res\xml 안에 있는 widget 관련 파일들이다. 그냥 수정하고 다시 시도하자. 40 라인은 별 필요없어 보이니 값을 제거하고, widget 관련 파일들은 widgetCategory 라는 attribute 가 문제인듯 싶으니 해당 attribute 를 제거해준다. 그리고 다시 명령어를 실행하면 다행히 성공.



naverapp.apk 가 생성되었다. 하지만 이 apk 를 그대로 폰에 올리면 설치가 안된다. signing 작업을 해줘야함.


2.4. 빌드한 apk 파일을 signapk 로 signing 해주자.

아래는 naverapp.apk 를 naverapp_signed.apk 로 signing 한 예.


java -jar signapk.jar testkey.x509.pem testkey.pk8 naverapp.apk naverapp_signed.apk




2.5 다 된 naverapp_signed.apk 파일을 폰에 올려보자.

이건 여러가지 방법이 있는데 혹시 모르면 알아서 찾아보셈. 참고로 필자는 개인 웹서버에 올려서 모바일 브라우저에서 다운받아 설치하는 방법을 주로 사용하고 있다.



필자가 예제로 빌드한 apk 파일은 용량이 10MB가 넘어서 못 올렸고, 대신 그 스크린 샷만 첨부한다.



필자는 \smali\com\nhn\android\search\ui\main\tab\NaverHomeTabFragment.smali 파일의 2532 라인(상단 왼쪽 NAVER 버튼 등을 누르면 네이버로 이동)과 2561 라인(처음 실행하면 네이버로 이동)을 수정하여 Daum 사이트로 이동하게 수정해 보았다.


    const-string v2, "naver-home"


    const-string v3, "http://m.naver.com?app_page=main"


    invoke-virtual {v1, v2, v3}, Lcom/nhn/android/apptoolkit/AppConfig;->getServerAddress(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;



를 아래처럼 변경.


    const-string v2, "naver-home"


    const-string v3, "http://m.daum.net/"


    invoke-virtual {v1, v2, v3}, Lcom/nhn/android/apptoolkit/AppConfig;->getServerAddress(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;




그럼 즐핵.


ps. 다음앱 같은 일부의 경우 AndroidManifest.xml 파일에 android:sharedUserId="daum.uid.shared" 가 들어있어서 설치시 signing 에러가 발생한다. AndroidManifest.xml 파일의 android:sharedUserId="daum.uid.shared" 을 삭제하고 빌드해야한다.


기타 관련 사이트 :

http://code.google.com/p/smali/

http://netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html




Posted by 아즈키

댓글을 달아 주세요

  1. Favicon of http://dev.azki.org BlogIcon 아즈키 2013.01.30 18:54 신고  댓글주소  수정/삭제  댓글쓰기

    곰티비 앱(com.gretech.gomtv) v.1.2.3 에서 동영상 틀 때 강제 광고 다이얼로그 안뜨게 하는 방법:

    smali\com\gretech\gomtv\module\parser\handler\AdvertisementParserHandler.smali : 84

    ---------- before ----------
    .line 46
    const/16 v0, 0x3e8

    iput v0, p0, Lcom/gretech/gomtv/module/parser/handler/AdvertisementParserHandler;->MILLISECOND:I

    ---------- after ----------
    .line 46
    const/16 v0, 0x1

    iput v0, p0, Lcom/gretech/gomtv/module/parser/handler/AdvertisementParserHandler;->MILLISECOND:I

  2. 2013.06.27 16:37  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  3. Favicon of http://jorryrojer.tistory.com BlogIcon 휘바골드 2014.08.14 02:16 신고  댓글주소  수정/삭제  댓글쓰기

    smail 코드 분석은 어떻게하시나요..?

  4. 2017.11.05 10:39  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  5. 2017.11.05 10:45  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  6. 2017.11.14 00:31  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  7. 2017.11.14 00:32  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  8. Favicon of http://yuninsik.tistory.com BlogIcon mc.레지스탕스 2018.02.07 22:10 신고  댓글주소  수정/삭제  댓글쓰기

    이렇게 나오는데 어떻게 해야 디컴파일이 잘되나요?

    C:\Users\Admin\Desktop\윤채경퀴즈게임>java -jar apktool.jar d com.example.oxgame
    quizgame.apk quizgame
    Apktool v1.5.1 - a tool for reengineering Android apk files
    Copyright 2010 Ryszard Wi?niewski <brut.alll@gmail.com>
    with smali v1.4.1, and baksmali v1.4.1
    Updated by @iBotPeaches <connor.tumbleson@gmail.com>
    Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)

    Usage: apktool [-q|--quiet OR -v|--verbose] COMMAND [...]

    COMMANDs are:

    d[ecode] [OPTS] <file.apk> [<dir>]
    Decode <file.apk> to <dir>.

    OPTS:

    -s, --no-src
    Do not decode sources.
    -r, --no-res
    Do not decode resources.
    -d, --debug
    Decode in debug mode. Check project page for more info.
    -b, --no-debug-info
    Baksmali -- don't write out debug info (.local, .param, .line, etc.)

    -f, --force
    Force delete destination directory.
    -t <tag>, --frame-tag <tag>
    Try to use framework files tagged by <tag>.
    --frame-path <dir>
    Use the specified directory for framework files
    --keep-broken-res
    Use if there was an error and some resources were dropped, e.g.:
    "Invalid config flags detected. Dropping resources", but you
    want to decode them anyway, even with errors. You will have to
    fix them manually before building.

    b[uild] [OPTS] [<app_path>] [<out_file>]
    Build an apk from already decoded application located in <app_path>.

    It will automatically detect, whether files was changed and perform
    needed steps only.

    If you omit <app_path> then current directory will be used.
    If you omit <out_file> then <app_path>/dist/<name_of_original.apk>
    will be used.

    OPTS:

    -f, --force-all
    Skip changes detection and build all files.
    -d, --debug
    Build in debug mode. Check project page for more info.
    -a, --aapt
    Loads aapt from specified location.

    if|install-framework <framework.apk> [<tag>]
    Install framework file to your system.

    For additional info, see: http://code.google.com/p/android-apktool/
    For smali/baksmali info, see: http://code.google.com/p/smali/

  9. Favicon of http://yuninsik.tistory.com BlogIcon mc.레지스탕스 2018.02.08 17:53 신고  댓글주소  수정/삭제  댓글쓰기

    apk 디컴파일은 성공했습니다. 이제 리소스를 수정하고 다시 apk로 컴파일해보려는데 아래의 에러가 납니다. 어떻게 해야 하나요?
    D:\apktool2.3.1\apktool_2.3.1>java -jar apktool_2.3.1.jar b oxquizgame_ok oxquiz
    game_ok.apk
    I: Using Apktool 2.3.1
    I: Checking whether sources has changed...
    I: Checking whether resources has changed...
    I: Building resources...
    S: WARNING: Could not write to (C:\Users\Admin\AppData\Local\apktool\framework),
    using C:\Users\Admin\AppData\Local\Temp\ instead...
    S: Please be aware this is a volatile directory and frameworks could go missing,
    please utilize --frame-path if the default storage directory is unavailable
    W: D:\apktool2.3.1\apktool_2.3.1\oxquizgame_ok\res\values\drawables.xml:4: error
    : Resource entry icon is already defined.
    W: res\drawable\icon.png:0: Originally defined here.
    W:
    Exception in thread "main" brut.androlib.AndrolibException: brut.androlib.Androl
    ibException: brut.common.BrutException: could not exec (exit code = 1): [C:\User
    s\Admin\AppData\Local\Temp\brut_util_Jar_11067200861156385738.tmp, p, --forced-p
    ackage-id, 127, --min-sdk-version, 14, --target-sdk-version, 21, --version-code,
    1000000, --version-name, 1, --no-version-vectors, -F, C:\Users\Admin\AppData\Lo
    cal\Temp\APKTOOL8409698246781990831.tmp, -0, swf, -0, res/raw/rgba8888, -0, res/
    raw/debuginfo, -0, arsc, -I, C:\Users\Admin\AppData\Local\Temp\1.apk, -S, D:\apk
    tool2.3.1\apktool_2.3.1\oxquizgame_ok\res, -M, D:\apktool2.3.1\apktool_2.3.1\oxq
    uizgame_ok\AndroidManifest.xml]
    at brut.androlib.Androlib.buildResourcesFull(Androlib.java:492)
    at brut.androlib.Androlib.buildResources(Androlib.java:426)
    at brut.androlib.Androlib.build(Androlib.java:305)
    at brut.androlib.Androlib.build(Androlib.java:270)
    at brut.apktool.Main.cmdBuild(Main.java:227)
    at brut.apktool.Main.main(Main.java:75)
    Caused by: brut.androlib.AndrolibException: brut.common.BrutException: could not
    exec (exit code = 1): [C:\Users\Admin\AppData\Local\Temp\brut_util_Jar_11067200
    861156385738.tmp, p, --forced-package-id, 127, --min-sdk-version, 14, --target-s
    dk-version, 21, --version-code, 1000000, --version-name, 1, --no-version-vectors
    , -F, C:\Users\Admin\AppData\Local\Temp\APKTOOL8409698246781990831.tmp, -0, swf,
    -0, res/raw/rgba8888, -0, res/raw/debuginfo, -0, arsc, -I, C:\Users\Admin\AppDa
    ta\Local\Temp\1.apk, -S, D:\apktool2.3.1\apktool_2.3.1\oxquizgame_ok\res, -M, D:
    \apktool2.3.1\apktool_2.3.1\oxquizgame_ok\AndroidManifest.xml]
    at brut.androlib.res.AndrolibResources.aaptPackage(AndrolibResources.jav
    a:456)
    at brut.androlib.Androlib.buildResourcesFull(Androlib.java:478)
    ... 5 more
    Caused by: brut.common.BrutException: could not exec (exit code = 1): [C:\Users\
    Admin\AppData\Local\Temp\brut_util_Jar_11067200861156385738.tmp, p, --forced-pac
    kage-id, 127, --min-sdk-version, 14, --target-sdk-version, 21, --version-code, 1
    000000, --version-name, 1, --no-version-vectors, -F, C:\Users\Admin\AppData\Loca
    l\Temp\APKTOOL8409698246781990831.tmp, -0, swf, -0, res/raw/rgba8888, -0, res/ra
    w/debuginfo, -0, arsc, -I, C:\Users\Admin\AppData\Local\Temp\1.apk, -S, D:\apkto
    ol2.3.1\apktool_2.3.1\oxquizgame_ok\res, -M, D:\apktool2.3.1\apktool_2.3.1\oxqui
    zgame_ok\AndroidManifest.xml]
    at brut.util.OS.exec(OS.java:95)
    at brut.androlib.res.AndrolibResources.aaptPackage(AndrolibResources.jav
    a:450)
    ... 6 more

  10. Favicon of http://yuninsik.tistory.com BlogIcon mc.레지스탕스 2018.02.08 20:44 신고  댓글주소  수정/삭제  댓글쓰기

    디컴파일후 다시 apk로 컴파일성공했으나 맨마지막의 sign하는작업이 잘 안되는군요. 아래의 에러를 봐주셨으면 합니다. 어떻게 해야하나요?

    Exception in thread "main" java.lang.NoClassDefFoundError: sun/misc/BASE64Encode
    r
    at com.android.signapk.SignApk.addDigestsToManifest(SignApk.java:169)
    at com.android.signapk.SignApk.main(SignApk.java:325)
    Caused by: java.lang.ClassNotFoundException: sun.misc.BASE64Encoder
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinCla
    ssLoader.java:582)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(C
    lassLoaders.java:185)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
    ... 2 more
    Signing Complete