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
'bring/steal' 카테고리의 다른 글
abe.jar 활용 코드 (2) | 2015.12.23 |
---|---|
smali 언어 체험 (3) | 2013.01.30 |
안드로이드 apk 디컴파일(Decompile) 후 다시 컴파일(Recompile) / 소스수정 (12) | 2013.01.29 |
안드로이드 apk 디컴파일(Decompile) / 소스보기 (21) | 2013.01.15 |
소프트웨어 만들 때 쓰는 시간.. (4) | 2012.04.20 |
JOB INTERVIEW QUESTIONNAIRE (0) | 2012.04.17 |
댓글을 달아 주세요
곰티비 앱(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
비밀댓글입니다
어떤 부분이 이해가 안가시는지 -ㅁ-aa
smail 코드 분석은 어떻게하시나요..?
컴파일 - 디컴파일을 반복해보면 알 수 있어요..
비밀댓글입니다
비밀댓글입니다
비밀댓글입니다
비밀댓글입니다
이렇게 나오는데 어떻게 해야 디컴파일이 잘되나요?
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/
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
디컴파일후 다시 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