Sunday, April 26, 2015

ඇන්ඩ්‍රොයිඩ් වෙස් මාරුව | Android App Hacking

ඇන්ඩ්‍රොයිඩ් (Android) කිව්වම මේ දවස්වල බොහොම ජනප්‍රිය මාතෘකාවක්නෙ... හැබැයි ඉතිං Android උණ තියෙන ගොඩක් අය කරන්නෙ සුපිරි ජංගමයක් ලොකු ගාණක් දීල අරගෙන ඒකෙන් ඇමතුම් ගන්න එකයි, කෙටි පණිවිඩ යවන එකයි, ජාලයේ සැරිසරන එකයි තමයි. (ඒකෙත් වරදක් නෑ, මොකද ජංගමයක් ගන්නෙ සාමාන්‍යයෙන් ඔය වැඩ ටික කරගන්නනෙ)

හැබැයි බැහැල ම Android ඉගෙන ගන්නවනම් සිරා වැඩ ටිකක් ඉගෙන ගත්තැකි. මම මේ කියන්නෙ ADT හරි Android Studio හරි දාගෙන ජංගම මෘදුකාංග (mobile apps) හදන එක ම නෙවෙයි, ඊට වඩා එහාට යන දෙයක්.

Android කියන්නෙ Linux මෙහෙයුම් පද්ධතියෙ මදය (kernel) ඇසුරින් හදපු එකක්නෙ. Linux කොච්චර සිරා ද කියල දන්න කෙනෙක්ට නම් Android ගැන අමුතුවෙන් අටුවා ටීකා කියන්න ඕනැ නෑ. ආසයි නම් Linux ගැනත් පොඩ්ඩක් කියවල, කරල එහෙම බලන්න. වටින වැඩක්.

Android පද්ධතිය C පරිගණක භාෂාව මුල් කරගෙන ලියල තිබුණට, Android apps සාමාන්‍යයෙන් ලියන්නෙ Java පරිගණක භාෂාවෙන්, දුවන්නෙ සාමාන්‍ය Java සඳහා අපි පාවිච්චි කරන Oracle JVM වගේ Dalvik VM කියල අතාත්ත්වික යන්ත්‍රයක් (virtual machine) උඩ.

Dalvik VM මත දුවන Android app එකක Java බිටු කේතය (bytecode) වෙනස් කළොත් app එකේ හැසිරීමත් ඒ විදිහට වෙනස් වෙනවා. හැබැයි ඉතිං ඒක කරන එක ලේසි නෑ. අනික, app එකේ බිටු කේතය ගොඩක් වෙලාවට dex කියන වර්ගයේ ගොනුවක අඩංගු කරල තියෙන්නෙ; ඒ නිසා ඒක කෙළින් ම බලන්න බෑ.

App එකේ දෘෂ්‍ය සැකැස්ම (layout) තීරණය වෙන්නෙ ඒකෙ res/layout/ කියන නාමාවලියෙ (directory) තියෙන ගොනු එකතුවකින්. හැබැයි මේ ගොනු නම් XML කියන සාපේක්ෂ ව තේරුම් ගන්න ලේසි භාෂාවකින් ලියල තියෙන්නෙ. මේ ගොනුවක් වෙනස් කළොත් app එකේ අදාල පිටුවෙ මුහුණතත් වෙනස් වෙනව. (අදාල මුහුණත කෝකද කියල හොයා ගන්නත් අමාරු නෑ, මොකද ගොඩක් වෙලාවට මුහුණතට අනුරූප නමක් තමයි XML ගොනුවටත් ලැබෙන්නෙ; උදා. මුල් පිටු මුහුණතක් නම් main, home වගේ වචනයක් ගොනුවෙ නමේ තියෙන්න ඕනි.)

මම මේ ක්‍රම දෙක ම කරල බලල තියෙනව. මුල් එක ටිකක් විතර අමාරු වුණත් සෑහෙන ආතල් වැඩක්. අනික නම් ගේමක් නෑ.

මම කළේ ජනප්‍රිය යතුරු පුවරු (keyboard) app එකක යතුරුවල උස වෙනස් කරන එකයි (නැත්තම් තිරයෙන් 1/2 විතර යතුරු පුවරුවෙන් වැහෙනව), ඒ app එකේ ම පරණ නිකුතුවක් (release) Singlish සැකසුමේ ඉඳන් විජේසේකර (Wijesekara) සැකසුමට වෙනස් කරන එකයි. දෙවෙනියට කියපු වැඩෙත් 100% නැතත් ගොඩක් දුරට සාර්ථක වුණා :)

  1. මේ කොයි වැඩේටත් ඔයාට apktool කියන උපාංගය (tool) ඕනි වෙනව. ඒක මෙතනින් ගන්න පුළුවන්.
  2. මෙතනින් ඔයාට ලැබෙන්නෙ JAR (Java archive) ගොනුවක්. ඒක සාමාන්‍ය JAR ගොනුවක් දුවවන විදිහට ම

    java -jar apktool_JAR_ගොනුවෙ_නම.jar

    විධානයෙන් දුවවන්න පුළුවන්. (පරිගණකයෙ Java තියෙන්න ඕනි කියල අමුතුවෙන් කියන්න ඕනි නෑනෙ? Java නැත්තම් JRE (Java Runtime Environment) දාගන්නෙ නැතුව JDK (Java Development Kit) ම දාගන්න බලන්න; හේතුව ඉස්සරහට තේරෙයි.) නැත්තම් අර පිටුවෙ තියෙන ඇසුරුම් කේතය (wrapper script) පාවිච්චි කරල කෙළින් ම apktool විධානය විදිහට දුවන්නත් පුළුවන් (මම කරල තියෙන්නෙ එහෙමයි).

  3. වැඩේට කලින් app එක වියෝජනය (decompose) කරල, වෙනස් කරන්න පුළුවන් තත්ත්වෙකට ගන්න එපැයි. මේ විධානයෙන් ඒක කරගන්න පුළුවන්:
  4. apktool d APK_ගොනුවෙ_නම.apk

    දැන් app එකේ නමින් නාමාවලියක් (directory) හැදිල ඇති. මේකෙ app එකේ සම්පූර්ණ අන්තර්ගතය තියෙනව; කේතය, මුහුණුවර සැකසුම (layout), පින්තූර, අකුරු රටා, … හැම දෙයක් ම.

  5. දැන් app එකේ කේතයට හරි මුහුණතට හරි කැමති විදිහෙ වෙනස්කමක් කරන්න පුළුවන්.
  6. කේතය තියෙන්නෙ නම් Java වලින් ම නෙවෙයි; smali කියන බිටු කේත (bytecode) මාදිලියෙන්. හැබැයි මේක වුණත් හෙමිහිට කියවල තේරුම් ගන්නත්, වෙනස් කරන්නත් පුළුවන්. වැඩේ පරිස්සමට කළොත් ඇත්තට ම වෙනස් හැසිරීමක් පෙන්වන app එකක් හදා ගන්න පුළුවන්. (අත්දුටුවයි, ප්‍රත්‍යක්ෂයි.)

    හැබැයි ඊට වඩා බොහොම ලේසියෙන් app එකේ මුහුණුවර වෙනස් කරන්න පුළුවන්; මොකද, ඒක තනිකර ම තීරණය වෙන්නෙ XML ගොනු කීපයක් මත. හැදුණ නාමාවලියෙ res/layout/ කියන තැන තමයි මේව සාමාන්‍යයෙන් තියෙන්නෙ.

    ඔයා නිකම් app එකක් (APK ගොනුවක්) ලේඛනාගාර කළමනාකරණ වැඩසටහනකින් (archive manager; WinZip, WinRAR වගේ) විවෘත කරල බැලුවොත් පෙනෙයි, මේ XML ගොනු කියවන්න බැරි බව. App එක හැදෙද්දි මේ ගොනු ද්විමය ස්වරූපයකට (binary format) හැරෙනව. හැබැයි apktool එකට පුළුවන් මේ ද්විමය ගොනුව ආපහු මුල් තත්ත්වයට ගන්න.

  7. මේ කොයි විදිහට වෙනස් කළත් අන්තිමට ආපහු app එක APK ගොනුවකට හරව ගන්න එපැයි! ඒකට තව විධානයක් තියෙනව:
  8. apktool b මුල්_විධානයෙන්_හැදුණ_directory_එකේ_නම

    දැන් APK එක, අර කියපු නාමාවලියෙ dist කියන තැන හැදිල ඇති.

  9. දැන් වැඩේ ගොඩ; මේ app එක අරන් ජංගමය‍ට දාන්නයි තියෙන්නෙ.
  10. ADB (Android Debug Bridge) තියෙනව නම් එක විධානයයි: (Android SDK එක තියෙනව නම් (ගොඩක් වෙලාවට Eclipse ADT හෝ Android Studio දාල තියෙනව නම් මේකත් දාගෙන ඇති; නැත්තම් මෙතනින් බාගන්න පුළුවන්) SDK එකේ මූලයෙ (root directory) platform-tools/ කියන තැන adb වැඩසටහන ඇති)

    adb install -r අලුතෙන්_හැදුණ_APK_ගොනුව.apk

    ADB නැතුව අතින් දානව නම් app එක ජංගමයෙ මතකයට පිටපත් කරගෙන, ගොනු පිරික්සුමකින් (File Browser) ගිහින් ඒක විවෘත (open) කරන්න.

හුටා!

Install blocked
For security, your phone is set to block installation of apps obtained from unknown sources.

සාමාන්‍යයෙන් Android ජංගමයක්, Play Store එකෙන් ඇරෙන්න වෙන විදියකින් දාන app එකක් ඇතුළත් කරගන්නෙ නෑ. මේක වෙනස් කරන්න නම්, ජංගමයෙ Settings > Security පිටුවට ගිහින් Device Administration යටතෙ තියෙන Unknown sources අයිතමයට හරියක් (tick) දාන්න ඕනි. (Gingerbread වගේ පරණ මෙහෙයුම් පද්ධතියක් නම් සමහර විට මේක Settings > Application වගේ තැනක ඇති.)

දැන් ආයෙත් app එක දාල බලමු:

ආයෙත් හුටා!

App not installed.

(ADB නම්
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] )

මේ මොකෝ?

App එකක් ජංගමයට දානකොට, ජංගමයෙන් ඒ app එක හොරට වෙනස් කරපු (tampered) එකක් ද කියල හොයල බලනව. මේකට අංකිත අත්සන (digital signature) කියල සංකල්පයක් පාවිච්චි වෙනව. (මේක නිකම් ලියුමක අත්සන හරි ද බලනව වගේ වැඩක්.)

apktool අපේ app එක ලස්සනට හදල දුන්නට, පොරට අර කියපු අත්සන හදන්න බෑ. ඒ නිසා දැන් අපි ළඟ තියෙන්නෙ අත්සනක් නැති පත්වීම් ලිපියක් වගේ එකක්; මේක දුන්නට ජංගමයෙන් ඒක ඇත්ත (සහතික කළ; certified) app එකක් විදිහට ගණන් ගන්නෙ නෑ.

දැන් මේ වැඩේ ගොඩ දාගන්න නම් අපි හොර අත්සනක් ගහල app එක සහතික කරගන්න ඕනි. (ඇත්තට ම මේක හොර අත්සනක් කියන්නත් බෑ, මොකද අපි කරන්නෙ මුල් වැඩසටහන්කරු (developer) වෙනුවට මේක අපි කරපු වැඩක් හැටියට අපේ ම අත්සනක් ගහල සහතික කරගන්න එකයි.)

මේකටත් තියෙනව jarsigner කියල පොඩි උපාංගයක්. මේක JDK (Java Development Kit) ඇතුළත් කරද්දි ලැබෙන එකක් කියල තමයි කියන්නෙ. ඒ නිසා දැනට JDK දාගෙන නැති අයට ඒකත් දාගන්න වෙයි.

jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore keystore_නම.keystore -storepass keystore_අවසර_පදය අලුතෙන්_හැදුණ_APK_ගොනුව.apk keystore_alias_නම

අප්පට සිරි... sigalg, digestalg, keystore, alias_නම… මොකද්ද මේ සීන් එක? අත්සනක් ගැහිල්ල මෙච්චර අමාරු ද?

ටිකක් විතර මහන්සි වෙන්න ඕනි තමයි, හැබැයි එක පාරයි.

මුලින් ම අත්සන ගහන්න අත්සනක් හදං ඉන්නෙපැයි. මේක තමයි keystore කියන්නෙ. හරියට කාර්යාලයක යතුරු සේරම සේප්පුවක දාල වහනව වගේ keystore එකක අපේ යතුරු (keys) ගබඩා කරල තියන්න පුළුවන්. ඒක හදන්නත් තියෙනව (JDK එක්ක එන) keytool කියල විධානයක්.

keytool -genkeypair -keystore keystore_නම.keystore -alias keystore_alias_නම -storepass keystore_අවසර_පදය -keyalg RSA

විධානයෙ කොටස් ගැන පොඩි විස්තරයක් කළොත්,

  • genkeypair: පොදු (public) සහ පෞද්ගලික (private) යතුරු (keys) දෙකක් එක්ක keystore එකක් හදන්න
  • keystore: keystore එකට දිය යුතු නම
  • alias: keystore එක තුළ අපේ යතුරට (key) ලැබෙන නම
  • storepass: keystore එකේ අවසර පදය (යතුරු ටික දාන සේප්පුවෙ අගුලු රටාව වගේ)
  • keyalg: යතුරු හදන්න පාචිච්චි කරන ක්‍රමය (algorithm)

මතක ඇතුව හැම විධානයක ම ඇල අකුරින් තියෙන තැන් වලට ඔයාට කැමති අගයන් දාගන්න. මේ වැඩේදි, දාගන්න අගයන් එච්චර ම වැදගත් නෑ. හැබැයි බලාගෙනයි! අවසර පදය එහෙම නැති වුණොත් ආයෙ ඒ keystore එකෙන් වැඩක් නෑ.

keystore එක හදද්දි ඔයාගෙ නම, ගම, වැඩ කරන තැන වගේ මගුල් සෑහෙන ගොඩක් අහනව. ඒවට කැමති නම් මොනව හරි දෙන්න, නොදී හිටියත් අවුලක් නෑ. තව password එකකුත් අහයි. ඒකට storepass එකට දුන්න අගය ම තියාගත්තොත් ලේසි නිසා නිකම් ම Enter යතුර ඔබන්න.

සැ.යු.: මෙහෙම සරල විදිහට වැඩේ ගොඩ දාන්නෙ, අපි app එක වෙනස් කරන්නෙ අපේ පාවිච්චියට විතරක් හින්දයි. හරි ආරක්ෂණ පිරිවිතර යටතෙ වැඩේ කරනව නම්, ඒ ගැන වෙන ම බ්ලොග් ලිපියක් ම ලියන්න වෙනව!

keystore එක හදාගෙන ඉවර නම් පරණ jarsigner විධානය (keystore_අවසර_පදය, keystore_නම, keystore_alias_නම එහෙම හරියට දාල) ආයෙ ගහල, ඊට පස්සෙ app එක ආයෙ ජංගමයට දාල බලන්න. දැන් නම් වැඩේ හරියන්න ඕනි.

වැඩේ තාම අවුල් නම්, කලින් තිබුණ මුල් (original) app එක තව ම ජංගමයෙ තියෙනව ද බලල ඒක අයින් කරල දාන්න. (මුල් app එක ඒක හදපු කෙනාගෙ keystore එකෙන් අත්සන් කරල තියෙන නිසා, ඒක තියෙනකම් අපේ අත්සන දාපු අලුත් app එක ජංගමය බාර ගන්නෙ නෑ. පරණ app එක අයින් කරන්න වෙන්නෙ ඒකයි.)

jarsigner විධානයෙ කොටස් ටිකත් keytool වගේ ම තමයි. sigalg, digestalg කියන්නෙ අත්සන හදන්න පාචිච්චි කරන ක්‍රම (algorithms). ඒ ඇරෙන්න ඉතුරු ටික කලින් කියපු විදිහමයි.

දැන් app එක විවෘත කරල බලන්න, බලාපොරොත්තු වුණ වෙනස්කම වෙලා ද කියල.

වැඩේ කෙළ වෙන්න පුළුවන් ගොඩක් තැන් තියෙනව; හැබැයි app එක දුවන්නෙ Dalvik VM එක ඇතුළෙ නිසා ජංගමයට අවුලක් වීමේ ඉඩ බොහොම අඩුයි.

  • Smali කේත මට්ටමට ගිහින් වෙනස් කරනව නම්, දෝෂයක් ආවොත් ගොඩක් දුරට app එක විවෘත කරනකොට හරි දුවනකොට (running) හරි බිඳවැටෙයි (crash).
  • app එක ආපහු හදන වෙලාවෙ (apktool b විධානයෙදි) ගොනුවල වරදක් වෙලා නම් වැඩේ අසාර්ථක (fail) වෙයි.
  • app එක අත්සන් කරන වෙලාවෙ (jarsigner විධානයෙදි) keystore එකේ හරි විධානයෙ හරි වරදක් වෙලා නම් වැඩේ අසාර්ථක (fail) වෙයි.
  • app එක ඇතුළත් කරන (install) වෙලාවෙ ආරක්ෂණ සැකසුම්වල (security settings) හරි අත්සනේ හරි අවුලක් තිබ්බොත් ජංගමය දෝෂයක් පෙන්නල වැඩේ නවත්තයි.

හාකො… ඉතිං දැං මේ ජිල්මාට් එකෙන් වැඩක් ගන්නෙ කොහොම ද?

උදාහරණයක් විදිහට, අර යතුරු පුවරුවෙ මුහුණත මම වෙනස් කරපු හැටි කියන්නම්:

මේක සුපිරි යතුරු පුවරුවක්; හැබැයි පොඩි අවුලකට තිබුණෙ යතුරු (keys) සෑහෙන සිරස් පරතරයක් (vertical padding) ඇතුවයි දාල තිබුණෙ. යතුරු පුවරුව ගත්තම තිරෙන් සෑහෙන කොටසක් වැහෙනව. මට ඕනි වුණේ යතුරු සිරස් ව ළං කරල මේ ඉඩ අඩු කරගන්න.

ඉතිං apktool වලින් app එක දිගෑරල අරන් res/ ඇතුළට ගියාම values/dimens.xml කියන ගොනුවෙ <dimen name="vertical_gap"> කියල සැකසුමක් තිබුණ. (සාමාන්‍යයෙන් මුහුණතේ මිනුම් වගේ දේවල් මේ dimens.xml ගොනුවටත්, වචන හා වාක්‍ය (හරියට කිවුවොත් strings) strings.xml ගොනුවටත් යනව.) මේ සැකසුමේ අගය 0.0dip කරල app එක ප්‍රතිස්ථාපනය (reinstall) කළාම වැඩේ ගොඩ!

එහෙනං ඉතිං තව අටුවා ටීකා මොකට ද? App එකක් හොයාගෙන වැඩේ කරල ම බලන්ටකො!

No comments:

Post a Comment