앞에서 크롬 앱에 접근한 후에 프리다 CLI에서 자바스크립트 API를 입력하여 실행하는 것을 알아보았다. CLI 환경에서 진행하다보면 오타가 발생하면 긴 코드를 작성하기 까다로울 때가 많다. 따라서 자바스크립트 코드 파일을 직접 생성하여 해당 파일을 로드하여 사용하는 방법을 알아보자.
// class_print.js
Java.perform(function() {
Java.enumerateLoadedClasses( {
"onMatch": function(className) {
console.log(className)
},
"onComplete": function() {}
})
})
자바스크립트 파일 생성 후, -l
옵션을 통해 스크립트 파일을 불러올 수 있다. 명령어를 실행하면 자바스크립트 파일을 로드하여 크롬 앱에 로드된 모든 클래스를 열거한 후 일치하는 항목들을 출력한다.
안드로이드 액티비티 생명 주기를 살펴보면 onCreate()
-> onStart()
-> onResume()
함수를 실행하고나서야 액티비티가 포그라운드 실행상태가 된다. onResume()
는 해당 프로세스가 시작될 때 실행되거나, 홈 화면이나 다른 앱으로 전환했다가 다시 돌아왔을 경우에도 실행된다. 이 onResume()
함수가 실행될 때마다 로그가 출력되도록 자바스크립트 파일을 작성해보자. onResume()
함수는 android.app.Activity
클래스에 존재한다.
// onresume_chrome.js
Java.perform(function() {
var Activity = Java.use("android.app.Activity");
Activity.onResume.implementation = function() {
console.log("[*] onResume() got called!");
this.onResume(); // onResume 함수를 재작성하므로 기존 onResume 함수의 로직이 실행되지 않으면 정상적으로 앱이 실행되지 않는다.
};
})
명령어 실행 후, 녹스 앱플레이어에서 홈 버튼을 누른 후 다시 크롬 앱을 실행시키면 로그가 출력되는 것을 확인할 수 있다.
이번에는 크롬 앱 실행 하기 전에 자바스크립트 파일을 Spawn을 통해 불러오는 방법을 사용해보겠다.
캡처화면을 보면 Process terminated 오류가 발생했음을 알 수 있다. 소스코드에서 자바스크립트 API 중 setImmediate(function)
을 사용하면 해결할 수 있다.
// onresume_chrome.js
setImmediate(function() {
Java.perform(function() {
var Activity = Java.use("android.app.Activity");
Activity.onResume.implementation = function() {
console.log("[*] onResume() got called!");
this.onResume(); // onResume 함수를 재작성하므로 기존 onResume 함수의 로직이 실행되지 않으면 정상적으로 앱이 실행되지 않는다.
};
});
})
Java.choose
API를 사용하여 힙을 스캔한 뒤 View 클래스의 인스턴스를 찾으면 로그 출력하는 자바스크립트 파일을 작성해보자.
// instance_chrome.js
setImmediate(function() {
Java.perform(function() {
Java.choose("android.view.View", {
"onMatch": function(instance) {
console.log("[*] Instance found");
},
"onComplete": function() {
console.log("[*] Finished heap search");
}
});
});
});
크롬 앱에서 사용하는 인스턴스를 찾으면 로그를 출력하고, 힙 스캔이 끝나고 나서 끝났다는 로그를 출력했다. 인스턴스에는 어떤 값이 들어있는지 자바스크립트 파일을 수정해보겠다.
// instance_chrome.js
setImmediate(function() {
Java.perform(function() {
Java.choose("android.view.View", {
"onMatch": function(instance) {
console.log("[*] Instance found: " + instance);
},
"onComplete": function() {
console.log("[*] Finished heap search");
}
});
});
});
방금 전과 마찬가지로 4개의 인스턴스와 그 인스턴스에 대한 정보가 로그에 출력됨을 확인할 수 있다.