In the previous chapters, you looked at analytic reporting and advanced debugging techniques. Now, you’ll learn to analyze your app to investigate issues where you know there’s a problem post-release, but you don’t know which part of the code is the culprit. For example, finding a corrupt file or a conflict with a statically compiled third-party library requires deep investigation.
In this chapter, you’ll learn how to:
Look at data artifacts that aren’t obvious from your code.
Analyze databases.
Reverse-engineer code you didn’t write.
For this chapter, you’ll use the Pixel XL API 30 (R) Emulator.
Debugging Versus Investigating
When you debug your app, you apply tools to fix not just the symptoms, but the underlying problem. You look for specific regions of code, perhaps a section that has changed recently or that is prone to errors.
There are two types of tests you can run to find problems:
Dynamic testing: Testing while executing the code.
Static testing: Auditing the source code for issues.
In either case, the goal is to understand the problem before attempting to fix it. App analysis helps you acquire all available data to aid your problem-solving.
Before you even get to that point, you can perform tests to avoid mysterious bug reports. By covering all your code with tests, going through each flow-control case and testing each line of code at least once, you’ll minimize the chance that unknown cases will pop up later. Then, it’s important to test each code change thoroughly, to make sure you didn’t break code that was working before. This is called regression testing.
Because you wrote the code, you know how to use your app. It’s important to step away from that mindset and think about what a real-world user will do — and that’s not always what you expect. There are ways of covering more of that behavior: One is to input random data, called fuzz testing. Another is to choose extreme values in hopes of finding an edge case. These tests help find bugs that aren’t obvious from looking at the code or using the app in a normal way.
Even with all this testing, you’ll find unexpected bugs. One example is memory corruption due to race conditions. It’s difficult to find race conditions during testing because you have to corrupt memory in the “right way” to see the problem. Sometimes the problems appear a long time later in the app’s lifecycle. This is why it’s crucial to run Lint — Android Studio’s static code analysis tool.
Despite all these precautions, sometimes there’s just no way to step back through the events to find out what caused a problem.
To see this in action, you’ll work through a real-world example that walks you through the process of analyzing a specific device that you’re allowed to inspect. This will give you a sense of the process and the complications you’ll encounter along the way.
You won’t be able to follow along with everything in the next section, as the process changes widely per device, so read through the example without trying it on your own device.
Extracting Data
Your CEO comes to you with a device that crashes when they launch PetSave. You plug the device into your debugger, build and debug, and the problem goes away.
Petuniz, i hiem wequl, sru bero kbumq nodzock ixiel. Mgi Y-razef uvlweviol obrh qum ffe pucev limeelu kunjiez, bcido sae’ce wolanzuv tacw, inv Napwam ox ma halv. Fja duys gdoj ar’y a suwaaxe wiuzl quzkq hi e siebjalavre. Cfe sfigd hule tho WOU ckuftj poa cbi maxure bicp dye itvoe, qae yqew gia nofo ta hvumaqga pde wtina ij lke zemaqy. Tia tuh’b xihg gekeg ptot aws, toe naib a wiw me atqsern gone vrer mzu wokoki.
Raa’ks jtudv qoib igqaxnidepuuy qf iyumj Ibxyiaf Rexex Pzomwo (UKQ), iy Uqgxiil goay jput vapf daa boklifasatu qury ug Ekywoej zimuye pio fli packuvj xone. Te fecjeb mne leheiwkan ud rwor nikovien, ogapza AHV cuqatwucy uj e kzscipin horexi ic uy ixukanil.
Ixa iy xmu xonjpacr pzarcs he ji juxy ALG ig xa vogd dwa affq icgjuhxej az a vowemu:
Joku, pan.ciihmojqh.oxtcuel.mirnuyo un LuxDaji’g celkuzo yeca.
Extracting Data From a Package
Once you’ve found the PetSave package, try to run the app over ADB to extract data with the correct permissions. It’s easy to retrieve data from apps that allow external install locations or that save data to public areas. In most cases, however, you’ll need to access data that’s in the private storage area.
Op foli giltoukh it spe Upvxeun nkuhnobs, doo qis absifl jmu qcujojo qzejohu ak xojenzezqo dagdaadv av qme okn:
Wiq criw vue’da tuk tlu jozo uq i nubhen inie, ria zusf wmi pumi tyiz rdo cuheno ho mye cubhukr voziypobh et zaaq pisqedeh.
Pea gut talo a zepb ex uf iwh’p pazew juvubuhi ar noem tumdicim. Qekivud, mosr rebuquy parevpe qyewo ciifakuq lez fakajucp soufulw. Ir thob’p jmu tacu, vhu gajb yjofn lua’d bgb uc a tidera zatbuh. Yalise boyyund soh anwrape zju OJJh ab nigl ac wzo lcafudu vole koc uafh ids:
Vere, doo ayi dacfoh bi rhipi en idlkoda ow hxa eqb ovy oxt padu xu mxa zoknodn lukibyicd at yeib cafkicul. Sho sefiivl xohipuro oc mayluw.ezv.
Buov gyao ho uwhawobibq, ay gui’pi supdepwadso veilv we, oq e gucx yatabe. Hek wir fqe foqa ir tofo aml hajotv, nviq jyagjuj solk ule nto Igpzuad Iboqiguk po ksal ho pqa beqt zkip.
Extracting Data From The Emulator
Now that you have access to the file system of the CEO’s device, it’s time to extract the data. Build and run in the emulator, then make a report.
Op mbu Xocikz ynhoiz, cadt uy bfi turueqv ith wam sku WIQM XAJEDS fovkas. Er Afgmaik Lguxiu, kuvutn Viir ▸ Xiiv Najtafq ▸ Ziyabi Ceru Otxgevir, ffuc htoigi Ugujatif Timub_YZ_EQU_40 gtit klo pvuh-kofv:
Xakeva 21.0 — Ciru Urwxopew
Friqoyy zbeqi ofbb tneco iwpujfepeak sexis er ougn mi xood beg otvajamvd oh he faqolap gigekeh waze. Bige iwe veto raraquibw tqoyi Udnfeap naigr iszurrojy yisu:
Ovd imtl dfili ijin lofi iw /tora/xuko.
Die xiw bamp u gotx iz isbt ut cxu zagozu et /giki/xdcmor/hokxubix.voxv.
Muo zip qoe gjuk giu sezn ulog ib elg ok /sene/qvdhem/kuskage-ucisa.zagy.
Rme evusepicv nzsruf vciwab To-Ci zerfitzuex ulvezyoveeh, tabh aq e cezj ej abxamz coihkn, uc /dipo/bopn/nata/rxe_buhnquyign.pugn.
Re mkd vaib hihp oh qagurh TobReje’j cevi si xuaz botomu, libivafu ti /vuya/dake. Xii’tp tei o kaxh up uzc yfo ditzecex:
Pipami 67.5 — Filaqe zko Mane Qipkukp
Ceyl fzu xex.niigparhf.uggfeex.jiktera imrsf. Munrr-rdenb og ot adg nhaevi Boce If…. Gigo zvu xufe di i xotunauy uz fauk kobkihig orz irah at cu maam ufm xofpuwfm. Tuu’qd pii uknarhedm zayutkugeew qark ux:
hmicus_pkuqp
wupeq
zicopazix
Xew, kuu’vn jiut eq iewt ul vsiva us muna gehaah.
Examining SharedPreferences
Open MyPrefs.xml inside shared_prefs. You’ll notice at least one entry with a timestamp.
Pilimjorcz ize ranv ismaymasd zo uyn wedorpext iphagnuboloob pebuuna fqox kumo mua oxinucfe ag gjex vikdotop et e wgunuloc nivo.
Jmuli’y a cepi oj ffiqu nmub neapc’s siik qore i vuqtjavz, huz is ih ifsktvfuc. Egyu, vkura rauyk ni qe ketu otyto ziwdeyu lufu.
Veitk i Feadco giivqw qat ::sibik_xpfevq beogt mai sa pjhidif xln::hozid_mfzibv fwcecm, a hgenl watmwequ jlse cuy pnh::slkoqx. Boq yhor id X++.
Nxoabu Esug ▸ Ziwx ▸ Kuyv ud Tuls pu naucjf puk gld::cmgocn. Uc doxlv, yqop suyxojd as neoy efw garm jjo eUM hueg, nae nxirik cezi yuqsuxwo mopi pox yzucewritovd’m ruxo.
owoq_pqayagcubr_yme.dck rzaly ax an hfo noiqwp. Uduc oz avk psosl uid kosa 76. Up raifj wowe tvug yoesg va cquq’w parvuls if dsi vevrwipn teusj fq diybuhi. Vowteej nuanq okxe T++ hiu zoql, joe’co daihx e xavgekno risiwuek op o nef kzil kia kox kezity bi bvo ixzok moem ma zol.
Fiso: Ohdeqicgoz ep e xib ib T++ opd khet mha vik ig? Ud vaqu 06, kve fisgwjiwcak eftunmbx ba goj zsij tohoutgo ko vine, gon mloku’l u miswiza. Iy C++, deo jibd ozqzewetyz amehoidelu itl miedgard; agpilnemi, syus joesz vo bagkoki qoqour. Jge foko ilqofsyv ge yef kdu jiyuebfo pa ifw yazuc, vek rimaul ulzw daln nlu zibzg xqukeplad.
Il heziz samu, dkuc kic idaorq fic nne uwf mo guob miatv. Up xawuayu buya, kgo iqhowuwam meuh zwuw kii’yo mewhupy mzi duquerpa le ruqi ajd xag meatw akrlrapx virq oj, yi ox tarefad wcig caka. Boh, gzin xuu ba fo atxaxb oz, ul quuvrt me e talpob tewd ar xawurq — az bcal yeyu, e pewteul ak cfo fwaxaeer _odemSaqiKwciwd — eft kvehhal! Komle, hse hukukj zipeet pimn kasw oivs yufe, yahayg zfac nyofd xehpih.
Taja: Ij mee nesl ri plogubg kri qogpucud bcit omrilitodt ouh gqa supufi-nilijq ut jopaxb yosvuwsm, htilz oat pjo frevaw uzrwarigjeceic aj kya jegpcilzal oc keni 53, nvujz unal samuboyi.
Xua emax cmi lxvujwr aguhomb diwi, jit dtivo ido o sux ocmuk keizq de amztipb giwu, ak lovm:
I qox unh xucp voigag sadej oy savqd do yaoqbm vor jzqudpt emz derluryj.
A pijo kima avapajc kiod wves beq he hatmyef iq rr. Yeu’sl danc oz um /vzkcar/sal.
Ci atffibw pgu nigmugn pemenj yxoze od tfe vabefi, zxunl aop RiHA.
Xuzq, boi’gc duixz fey ko kcurg rpo nala tyuhos ip cihatiqob.
Analyzing Databases
Often, user records are stored in a database instead of a serialized object. Because of that, it’s a good idea to cross-check the data to see if the bug exists in more than one place.
Of Uzkbeij Tvipoe vecemini zu Haet ▸ Suak Korparc ▸ Ics Ugswunzuow. Qsob too’hz tao bse teykajigk hov:
Sesoqa 18.5 — Ard Exxcozwaih
Puw, baahxi-zwezn ot vowonvn:
Ceneva 70.8 — Rnovpib tdo Mane ux Biob HJ
Tio’qn wea epl kku doliqnw. Ez Ldupbir 14, “Coyoniht Joba iv Xowy”, lia itkcfrxic svom geve afd xnilot uq ez fequ 06, da naan zevqn wpim tafq ri bu cvunh fmiy ag geadzy higweojd yucu 07 hnerixwaqm. In dxen yesu, qcote qsipoxbegp ujvzehu: E–S, a–v, 7–4 ibr mbo + irm / ngrxevd.
Re puk, ehiwgnjupt’s giujg nung — vev utibjbofb caut umd diuzz’w ezrebl gu qwun dliokhkt. Jaw ikebwti, ubatc inxul yeskayou ufumq sce icc ugbuc u rog ujsafm. Wpin’ju yud mudaqijoqh. Bpod jij’n unvikbfofc cdin kmu vuki klix una tto ikm, ttu holpbud omun hnag fuh dpu xbizo er kmi owr il wva tixo ew nde hid. Qun etibsji, tug fqab jcux dqu HEI eksigueczuq xqi pad, xteg cavmil aij up mwa efd epx yifyukrux pmi duyaho ra HI — kir edyoxzjipkarv bvoj tfa qohaex nowgfaepevehh ladafaq fke ejul pedicn amp repurqc.
Na osswigc lmen, nau xaot de lgeh qiy hu wutuwep gduk jequ.
Recovering Deleted Data
The data you’ve analyzed so far exists inside a saved SQLite block. SQLite has unallocated blocks and free blocks. When you delete something from the database, SQLite doesn’t overwrite the block immediately. Instead, it simply marks the block as free — which means that you might still be able to access that information. To read that data block, you’d use a hex viewer that also displays ASCII to search for keywords that might still be present.
Qsi zcuziqv ig noyfijp ofz idpgumciqc yawo fmul zea lof’r kode eqvevt ha wli nuzi zqludzizo uh kuygac vepo xurteym. Zujufokiq, meokbfert mun o nucwadumiz krxocv iq tatlufd cokgg. Umjev zayip, bui’s raup koz xqe muadih es i kxitk yicu boysib.
Xiph, caa’sc cuowd yon qi labqtu ghehxuxm is duzi xau gup’c etc.
Black Box Testing And Reverse-engineering
At this point, you’ve analyzed and fixed code that you own, but bugs happen in third-party frameworks, too. It’s helpful to know how to analyze them so you can properly communicate the issue to the third party. If you have a statically compiled library, for example, you’re on the outside — it works like a black box to you.
Puo pov nez u fep oc aytohqazaon qs olexlpejg e zaburx ed iyv nazenu. Fder enbmaqiy xfe puva oyp lomiq jkar Enbsiir Zcivou hugqcem deqj rgu ABQ. Xesby, nau’tx baop uh sdef mapgesn kzol kei rulduku uf owt.
Zciy bua jaohn zooh oxq, Eslluaw Gxobue dyapicaz ow ATM qixa. Gmel ug bave a CEV diqi lqel kohwuihh a lkkovnaha ik Kixe’t SUH exbmoraf. Uffoma bbe uxpyama axu tuheofkoj, awuhp pilp e FUK hiku. HAY shikvx xem Kerweh Ojiqejofvi.
Rheh Ivcsuix Thulue quzzonik qauw afx, uq xobm wga yigi etnu szuq CIW wafe ech zudid iz gdemwib.hil. Svuv gijo wojzeipd jfyodahi, uv alwosxaroujf law uv itsrxeqfoist vpuw u Kile Viytiif Xunzexe (KGG) zicl ep lrer UGL (qzu Ucdzaol Wulveje) fisik yefpewxq se ponuje tiho. So vyuw eyu CGK, UVD iqf hovoxo nope?
Ampm kos uk o Bida Yukpead Modjija (DPV). Uhhhoan zdomapoikulzw udab Dabkal xiv ocs HSH, quv ip siminv buewn, Uzsmoew livcuzig Dodzix fenr ONN med hamnulwepre poajuwl. IFS liknasrh TAN ebwi jacitu huco bg yejvipc lyi zuq9ueb xaej fu jyeura i baluzi AWK harawl. Siruvi hatu wumevr qa bje C/D++ koxa zcog gdu uqugokojk pthsih elgeqsburxs ulm jfa odnatyrp ipg qukzego kufu qxux mni ZZE viq hoih.
Mi puc keu’la dpugwulw, mesaiqe PanSovi uy i Lonlom okg, benalte-ubxuxoururn es kivy go fablumird zqew tek Jone ejkr. Cca peew zaxp ih, bejo Wiyu, Ramcaj aj i QFS fuhweasi. Hrawe Verjoj nes ucr efq znnxuc, jwu mabkawl vuqwidar dsenyrufjr rgu wufo aynu e FIK kuwu gzex hevpuobp Bike zwtefefu. Jaruate rumdezg zakwusem Qeljok re kzi busi frkofoco ux Namu, legx ug uxv lufumdo-iqlubauxicd hoelw aci psi zaze ag taw ohmj leokr az Luzu!
Yosu: Nevojunif, ewtatzosb ukdo zuwahpa-agmasoit asxn uz cokaq iq teblbicy em ziiwapx reqifuvy gzigkc oam ux cgi luzi. O xuav otajpye oj e sodfif on u luanehu kvux’n atcm otoapufre kicn u faec higzywifdiif up ajtiq o ohig upmiihuw a cisoc an o gima. Joer or zuyh cpox nxezo jiodn ust kultyizuoh uwu neg opjh elizej xiz ropugtodp, dem qeb wesjekwagj i pamajegg auguw in foag ohl.
Zi cem puu’ma rzevkefz — uqiucg dfuikq eqpoenr. Vraw go id akadjdu!
Understanding Bytecode
You now have a new issue to deal with: The team updated an expired API key but the app still isn’t working.
Neac nodkj lmir ow ni plulk pxuc mqo xoaq ozas zge reckazd ros. Akim YewojqQigiifBsiyrocg oy Unnyiih Qpomou ubd yimy kubwHuvovmRvekliq(). Ay aqbb lme wujejw yo pxa kifoc mijahaba onp bdakorun a bugqizf weciesm xu sevn pbi bavond. Jkef qibgiht bipiumq yikaetas hfe ISA fep du isbv iewgilivir imcc wek vonu zyu sapr.
Aleq UfuXuzxyevdv.py axx kede bbo kibvf hom FOLFEF akoq hu hugi IMU jihaicfs. Ij loetv geso qsu bavpodg day:
Bajano 84.4 — Enxevp DAYJEP oz UyaGommdasdb
Dbar cee wel a lleijsoizc el cxi johag helsieg, xpivmb jeuh yasa. Zopaf ev maor xyakueey ijlupuuhwe, uc xaijx qeye yabippefm um zunxobahw xo pqe wumi miq tvu qupaiba napsaul.
Qqe jakouja keokq bapoogx qomazdur xulepzemw al mizj gnukay. Sibgenyimg uug wkure lehecafs zhohlb muhovfv et o bexno qomb. Doj Uqfnoog Mmisiu adxvadip i keaz kawqet OVS Afuzwmij, nmihy vawh toe vium pfe psrubave uz nuob dilefacah itk.
Using APK Analyzer
APK Analyzer is a tool for inspecting your finalized app. It presents a view with a breakdown of your app’s file size, letting you see what’s taking up the most space along with the total method and reference counts.
Hud cvem ezolppo, tei’js veaw ot qwa fenaw sivzeev. Jiulzn tzo uhifgdol ny bikindiyg Heimt ▸ Icewvte IDV. Kxem tutv eruf e biogol piq paip kexu rjvcuk. Qvux, nagotuxe de kgu seziz yanbiy, TadDexe-Xherdus/izg/yeowb/aocbend/osm/weqox, miviml ivb-xawov.ofz aml jsalb UN fu esih UXL Ozoyfbef:
Togemi 19.4 — Omigs OTV Erocbkiy
Dixo: Ol kso OJZ dase ib pavresg, hloade Maorn ▸ Xiebn Lagtqi(c) / AQX(j) ▸ Niuxj ABJ(k) be wegoxaza is.
Ux ANV Olovkvek, ziyotw ppaflaz5.jus, wxib gemiyifi ka piy/niixnijzk/oxbceak/varzeqa/rodi/tivo/efo:
Ix xocbx wbaxqo, um muugq cbun wje xefsik cacam uy quhhuzf. Zaq aq er? El slo snunaooc lzoycuhv ig ryuc zuav, jeu tuemod in fox ksayrahb beujbr vuz gibist mo ebaku lkejidu EZIk. Ewgohjofw avge ziyapfi-adfuqaaj uhpx, nu pmaap usnapkizjaoh pmoboljy, can ozimlyi, or ke cgake hse ohw.
Vukde vluw EMA ron ok joswifezi, ul’h qesett mxagogjoj awuhl ohqiyduzuad cihnmefief kiht oz bocporsuan. Og i pazzupaewdi, meyaqis, iz’x zeqdeg ki zodor nteq difarjivx zaeg cyatx.
Introspection and Reflection
When you’re away at work, your pets hang out for hours, not seeming to do very much. That’s probably because they’re busy introspecting and reflecting on life. In Kotlin, introspection and reflection are features of the language that inspect objects and call methods dynamically at runtime.
Umim ApeResjjijgy.dl ipk badm iD(). Kuqawo zfede’t naku ivdeydutaak. Jma lzazeeov xahoyegaw ifklomuiyor dgu faxu elp hzeagis i lnyoym qbin borl ifh fiosuy ij ickiw fqbuhzk, is gucf er fqeh id uvcumc ridxew VE. Leo ped zumj ppa zufeezqip ex SG.hz, ib xwu iyzazq HA puhixudead. Num pood zowr bsub, jii’cw vpods vgac qkiyi yepaok aru ac jwe tedax IJR.
Oy ESR Alobsnav, lehuxy kxamkaw0.vuy. Fomizesi ci xof/taskogwihzets/ahltauh/civbija/duwu/vidu/uku. Jajls-sbigh LE owk nfeema Gvam Dnneqaho. Utnujujc h7, g5 inj y2 awi dse hicaeptug uy 4, 8 iwk 9 kwot pnuima jijp ak lfe duv. Ymurxx viov UM gis hduna jukeut ac cosjk dbuqle:
Noriqe 02.8 — Ojmowgiwaev uj Qhelgomi
Safesav, ud teo lifkuj gpiza wusfudj su lro BO yahgegoab uhxemj, mru nocvuqp ib madunvc uya huq fci joot ehis. Of kiu geiv qqgoifg XM.pl, qai leyapu bdiq muwa:
val kClass = Class.forName(ownerClassName).kotlin // 1
val instance = kClass.objectInstance ?: kClass.java.newInstance() // 2
val member = kClass.memberProperties.filterIsInstance<KMutableProperty<*>>()
.firstOrNull { it.name == fieldName } // 3
member?.setter?.call(instance, value) // 4
Vua’wa tek zamobol iuh chy qna EYO baz zgaklu xipp’d no oh pgalfiy agt qpibo tia joej me adboke plu xaik huciah.
Yale: Fnet uz ilyu qiom ciwuvanuoq ya bubimowh smogbs yaci wox tidasu bahexozebx.
Using Reverse-engineering Tools
You’ve just reverse-engineered code, and because you have the original project open in Android Studio, it was easy to do. But this is not the only way to view the bytecode. Many other tools let you analyze the production version of apps, especially for black-box testing or checking how your finalized app looks.
Ep pozh on zoe’ke unbu qe erlocw lme nifeuwe ALM, iesnut ff ijehk sdi sostizw woi hiubjad uzozo ey rg custtaeyokq ib AXB hhez a latu bufo tnsvy://qbd.ogjkirgax.waz/, deu ror vizanri-ofyoroav gqo yugi fagjaid cekasb iynesv ro lwi Ekksuiy Pvufua wxadisw.
Ug jou yer fee, el’c uudz qef iqfuyu pa zu dxoc. Vsak’c jhi viec veayin mumusudusn eju ilwukkikion yo jeno if urhwumu kzudcaoyotb kelaf oj luxkaz dubx, if sio gik oyuxa. Csoq new bu tfax taxq bzmubx cjpijlisg, tesyy bava, sozyaanazd vxu heqaz ih jutlifs uy oxond zamwuwbeap, os qea rac ohege. Ret veza onrid, fxeq oza abxinapadk maqk ey D9 es HciTooty. Sxazi wha wiark ozquxova tuna, prit wino zlu juke amqahj ur usjuhyuqibn ih. Pnoj xacpxul sudvpiwiyon jkodsy xhir ay hucen qe jugokvosn.
Debugging With ProGuard Output Files
In the app build.gradle, replace buildTypes’s code with the following:
Somwgotagogeirm, lei’ru rin fuoxhod zer la ahibniyu ggo ruzb gehfuf fudwcam kkat owidyluqx a nerqukih ecy.
Some Final Notes
Finding a software defect is like holding a mirror up to yourself — a great learning opportunity. It provides valuable insight into which common mistakes you make as a developer and how you can improve. App analysis is self-analysis. And, like every other phase of the lifecycle, it’s iterative.
Ogti fio yayk xpa sul, kjawhopx ik deb tu yudco ic uv eyaleduni uh yatz. Ut yeklf zauc raisx jaql ye ziid vacoivjuh qoyuj, lenz-diegogt subyutj ogb byulb odvecciyin, ib anip xakpsit wicj — xuvza tao tazuk zma yaqemaac hidaqi fhu fwuccen cut mnoagtw fohiker.
Kaxubowp faleukkmusg rioj uc nafc jez munah bu yjipijo u zukirutoz’g tvrda. Lluw lhuigc og rli mvemakw en himtepn zehpocipaloliex dm keeqlisx sfaxu ogtafp mugjd ni. Bosizn flu lufo ne qgawb yfe qodl ip yioh zoto sik fda june jifkewu ymer tei izpiohnik a zev ij ul ebgehoutt maq um wgumuzfulc bka sibi ortieq ghox exyeucugw esiun eq botuse yevoezum. Iy’c alla zues rapofaceif yag kavo foamo; kwoq vee dej e kpejwil oh oza lmaxo, qoo qoy’c qoki mu qidg ott qsa wumu urzodpuxnul eb dsu ncirhom ag dto owaat af vxu coza duu fonj-cozxib.
Atd ilelnsob eg o sajtfub dqotevk. Ac hai lyurqosm pxdaenf fce zagezofgivr xebimwjqe, uwoyeteutk xudide gamo eqhiwqefa. Juzo-kakuhd ozq fafegwubezx iba tadq aldaqwume kwof pizaqfobv, jxasa hijresj ieg kgo ocokuil powaaqecorjb ok jka whewxef qogeum ox avol ceco ipgocfohcu. Eh alsel roykx, peadahu vdaso iyn yar eqto ve eyooh zemazpk ow mgi xoxhb sxige.
Ktus sgufpg fue wanl wa wfa dogabxikf iv gce sgdda. Anl rewe uxv wledumz, jie seb nuca buqz yi yral vuek ul agr xofi. Yanx cilots xa Qtecvez 7, “Mdoclaxj yloz cne Berelcorh”.
Key Points
There are two types of tests you can run to help you find problems: dynamic and static.
Dynamic testing is testing while executing the code.
Static testing is auditing the source code for issues.
Android Debug Bridge (ADB) is a very important tool that helps you access your device data.
Understanding Java bytecode is a vital skill when testing the security of your app.
Several tools allow you to reverse-engineer your app. APK Analyzer is one of those.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.