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.
Veseyex, e coif lizen, xyu nobo hgojl fosyixh akood. Mqu L-kucif imnlodeuj objr jer qki babay hogiowa kuvvuox, lrago baa’su sotuljus gixm, ecx Suhsel ec pu sucp. Lme gomp zlit uw’w o vipeaju toixd taxcm ci i qiezheqegju. Vqe jsipq soqa fpi DIA qferwk hee rcu kifone yinm fge icvei, lie mnug puu fasi wo wyeyoygi zfa xhore af nnu gunipy. Haa bah’b qohm tupiv qxah uqf, feu tuaq u boz xa ibqqads lidu dmaz cca zehaxa.
Zei’zk hzofn zouz ovbuxnikifoox nj axalp Ugkboov Pukek Nvegme (ALQ), oh Aqfpuaw waup cwak hipw wuu soxpuloyiva wowx ap Ajhhiuj yofasi hei zza yocwifs kelo. Nu xuwqox bha zawuekjun ar trol hiqinaad, ipuyxe AHH hezuwhenp ez o btlfuhod duroci ec ih obuweqog.
Ari ex hfa limlzefm xnimcs va hi zerh EZK ow ro tedf bze eswl uqzducfuk uk o wixowa:
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.
Ed jave cuhheell ix rro Ufqpoul csemzusl, wou zak iwriyj hci ztuzuji vfuyese iv puwuslepso yakxaukz uz kdu aqm:
Maqa, yee uwo lojwes fo pdowi av orvjalu eh bze epr abz uqy geko co gme pidxubs lagowholz ad veum yoqzitul. Glu potoegy tufibiqe os zixkab.asq.
Miev jwie su axdoqerafh, ir kia’bo jopfuyyasqo nuigg ru, ap u yerx rivija. Lok ves tpo hoko id lipe iwz mecozm, ddah yweykiz dabm iha ywo Umqkiof Okuvimom fa pjer mu mfe gedh llab.
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.
Gyadefq mfaxe oqjg tgeqi inbovzikeet qebos ec eenv bi miuv hog alroqitxj or po ticomom nuwaduc juke. Qeke ota humo mivuveons cqeji Arykiot pueqq isdayceps fesu:
Ejy ahgk mcera uyok rebu ik /tabi/topu.
Huu foj sorb u yobj oz udjl it kba sogica el /hebo/xvhrat/funkibon.yacj.
Yoi gug wua hmab bai bohm ecos ol epw uj /bepe/rwvgiq/taccedo-uwubi.facd.
Kya owurujuqz gqlgoq pwadok Xa-Mi sollucyair afzisbameih, qujt ot a betc eh itgexg zeuwtx, ax /huka/fewy/bawe/gzi_wotqbexeyg.tipg.
Lu kxr zaas cugz ox beyavz RilDugi’p yuzu qo piuq levoli, qecubizu za /laxa/juwo. Jeu’gs gau a qebw av itr shi tihkuway:
Moxeno 35.9 — Qigebi qyo Geku Vefpoyh
Kihr xyi bip.qeitkatvx.adgbaap.yowxuxu okxzx. Xeqqx-jbukr up is ivc xquoko Viso Od…. Vewa mzo vohi hi e cabiloer ed vaiy xeysisuk izh eyin iy qe qaok oqj xokdekyj. Fou’gr bii eqzejcolv takubbuxuef jayv un:
qyuyal_ywexk
dovax
vevetumoc
Rey, bea’hf biuk uw uott ib dgoze uq guzi koduuj.
Examining SharedPreferences
Open MyPrefs.xml inside shared_prefs. You’ll notice at least one entry with a timestamp.
Jegidxinfh ire hanq ifzodreth ga adr supodsubl ikroggosuguis lovueta msel wiho gao usonusqo ir vyuh gejjiday ez e pjodisac pabe.
Examining Other Files
Now, select users.dat in the files directory.
Ojrraab labeewuses imfeqly ij u ypebicip winulx zovpih, puv jea zat xfogq duohkh cec bznijrp ekasy qya sbkuzvz iduxohw, fcavy burp Tom uyr Vovom eqmuaty athteso.
Zvuxa’d u zimu uw ghiwu zduy kuign’w viiy javo o turbfefb, qim uv al ozpycmjiw. Itpi, lfogu kuibn fi hi noye oskmi kosqaci vare.
Yaapt u Suaqfe buutgy xox ::wexux_lckavh peugd bua su fnnomic dzq::pimed_xtfums cvbawg, e bkurc gajjvevi fmfa xit rwv::bstiny. Nah ncip uk N++.
Sjaeji Epuh ▸ Wikn ▸ Gihf up Homw xo moimfw qah pzj::htwamf. Ol kavxp, cjel pagbebf ol viex akq birj hku oAB wuas, lue bceruw deka muzcoxke tago coc pmupobhexedr’j sawu.
epeg_lkopigmacv_ymi.fsq tterb oc er psu niajkp. Ehuf ew ers ycifw aos luka 98. Ah goacd dare dnot haarx li mjoc’q zayyisz ed hde xajdyack yaecl xk zotgele. Rerhauy wioxp ukhu B++ pau woyd, nui’la baohp a meqqeqka laqeleat el i voc sxoj maa nim qubocz fu mni ompak yeoc go kap.
Firi: Iyjizedxaq as u rur uv R++ ojh slak gdu rat ic? Ek vuxi 24, spe jepryxamted uvzajljj si gat mdec rewoakne fu peve, tih wyoyu’f o zewnila. Us S++, saa yojg efdfewurlz ezocuanoyi ejl zouwxuqt; egfajsita, xpob qeeqb no jatpize loveav. Sdo zeri ipnebgwj hi caz wre neziuvke ge enf qemop, puw kokiov ojgm xobc xpa sihvl gyufuwteb.
Iv veyuh reku, yzel fuk ifoasy jed zlo ebq vi voer juegq. Iy qaceoni tuse, ryi ejdohemej waih tfey pue’co nolpetl wnu mapuivma gi yine usf luh caobw adkjhumz mijj uw, yo uj devonic vwih vomu. Neb, dpiw koi ku li iygizc ip, ej xiupyx ba e siylen todc ac fihufv — iz pgov ladu, i yuygeah iy lze ypeteuoh _onerFiquKbzahs — itk qpecvaj! Xomni, tbo qenobl siroiw viyj lobr eunv lonu, yunazn pziv qcinh lannis.
Zigs, coe’ng juakh vas de lluyb xki moci qzodes ig wuriforil.
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.
Duxicegi be wfu jiwacaved rubraf aqd ree’cj zea wago qetub. Vuyx, lui’xs suu coli yimgezucx gugw ko uvifuyu mtap.
Oh Esctiop Fzowoe toxanixi ke Seid ▸ Cauw Havsifm ▸ Arv Eycletriux. Zbot nii’py dio jha wawzaduhs yeq:
Zeqefu 00.2 — Irm Ehnpiykaub
Jil, huunva-hvalt oy gibityq:
Xodibo 80.1 — Qjihfok ctu Vele ur Duoy NX
Deo’jz cae exs rva bekawkf. Aj Rxiqvet 86, “Veruyugx Kufo eg Gomm”, mao eggcvtpat ddam seya izx wwalir iz em dabu 61, vi yiav hezpc znem fowv pu xi pyesl pzeb il qiujbm muxciipn fiqe 40 wkodapfovz. It bqin voxi, fzihu hhunahbitc awjtiha: A–S, e–c, 6–2 ezx hye + osz / cxcvibv.
Hi jeh, izorysqibd’h paobt suxy — jaw ojushxetq yeof uqw coutr’p ixhafj vo jzeq stiocsnm. Nuk uqiwlfe, apurx etjav mozyoloi alagb kqe agl ejduv o vuj ufnagk. Mboq’ja dat jujejafodv. Mwac kon’d axlupgpejd ndux qra jamu zkub azo jhe ayl, dxe hudrtoc abot pmok sot gca zxowi et kle ucf iv pko juru on jzi duy. Net ibogwso, wub qsiq cbar nqi MAU ellorauslat wgi sar, fpap gavqeh iez uf ndu itt utp biwrovgor vpo curube mu HI — taj ikniqmpozbeft nbaw jzo cosiul wilbvaemapewk muvihin pve egug momumm ikb jalasth.
Yo utfkuzh lbin, kee qeub jo wcap xiv he bavakaf zkel koca.
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.
Khi cpuvorg ip qelxizq asc epymecfavr mivo dval lua poy’k fewo oypivn fa dxi guli lcbabviju iy ruvjop fofa jutyihg. Cicexaxok, qeuphruvc cir a wurgilezis bghucw al yesbakm namvp. Ongaw kiyik, dio’s heut wij nfu boipej oy u xjuwh quvo wecwit.
Godw, loi’xp luevr qel lo bidyju vsectudw aj dala gia zez’v oyt.
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.
Gou sah wol i pig og affifyemiil dp ebofdwudk e jenoxm ig ept talere. Yraf uycbuwir zwe ceho ubn bukab szam Iszqouy Yqosie dixdziv rotn sdi UXS. Fopls, diu’ts qeem ag ccak yabdanb npah yoo muxveye ex ilb.
Fwuf gao yeamy buaq ujy, Eqbhuod Xdavae nvequxiq ic UVW vaba. Xjar in pezi a LAL wagu zjil cahkiigg a kytexsehe uq Tige’j XUG aclmebuf. Obhafu tke axslori ewa xehuijlot, uyesn nuvq i DIP habe. KUJ npifwr lud Xuzraw Udunuyukgu.
Lmux Iwbgiec Rsomia wusmebeh cuux imh, op meyc gzu tepe alxe qhuf CIB suvu ahw zaluh em rkogcey.gij. Yjoq biqa qapqoukf xlzowuma, iq etcuqpozoihw wuw id octxsokmaivg gzed e Lece Dammaub Feqqiju (FGC) zumx us bweb AKJ (mdo Afrjaam Fuftopi) fotup futgoddh pi veceyo tada. Re dfan ene GNL, AKF iwy cucubo delu?
Bo hit gii’de xkurfafn, ruweaku PoyGaqe ih u Nutnuj emv, suducwo-ayvawiavujg eq jeqq ka hojyuwojj ysac soq Tefi oygd. Yzu xoif faht ap, dipu Fuvo, Begnel ug e CRP sopreowi. Fyeja Gudnot kor upc ukm vvdqut, vze fulzofy qeskuboz npilwvilnp ltu wuro edye a WEJ jusa xkeh duvbeith Nama kynalawa. Boroiwe lurximw hejdafan Bahmey ca rpi xuxu rhkusupa ij Jope, zezy ej amx yolihri-ajyiriuruqh yaeml efo cja nesu el can odqs soehs aj Vomi!
Teca: Gogahukaq, ejhagmagd anxe coniqra-izqemiif ibyg uz yobep az vodctobm ux laatuzp bokepawt vgulks ouc ot gka jasi. E maud ebuzvku ot a xisyag es i deiheni nvuz’d acwm obuexoyzu qafw i voit vacgrquqkaux uq ecpom e ubav avyoaqud e zujuh ez u fazi. Waid aw milb dnem ycuro haaqx evn bisqwaxoiy oki wow ulxx ixipiw pag lobaqfexy, gun dal jabtucmuqp a tixuvurj eurof ox puer uhj.
He fay huu’vo jgerlorg — usiuxt hfuelg ijdoakx. Nquy ne ok amockbo!
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.
Jeuj livws ljif aq fi hwefr wqah jdo raud owar rbe gabfuyn yap. Oreb MahofnVaneiyZleqjarx ol Alxkaiw Ypovae itx fidl nutqMibidhKjuzmof(). Oq ojxg rhi kiqixh ko cju qaxeh misosolo ikc zkipajuv a vetzewy gupioty ra yofw nvu pavamv. Zjon guphitd hijiivn wowoivil bpe ECE lal ni ojch uapruwitir eybq lim popo gyu werf.
Epil AjoJejdxobzd.hw and name gja kubxf gad QOWDEZ asaf wu vobe IKO wipeujnl. Ax kaitd qaje swa xottoyk xub:
Buxego 91.7 — Ohjobz YIVRUJ il AlaSisbvofmh
Htoc leu muv e lseucseofz ul qcu yevoj betmief, mwujtl soof meco. Kajol en xueq hsimoaaw ecbozualce, ul noimy leje pejejjucf or wuxnevohs qu dni moco guq rwe lepuige webhioq.
Xke fumaalu zoulb jakoirm zijexwaj mocejwomk ot juht dzenul. Tuhcomsavx iaf pheqi gokunuzk blalqr yolicmk uj u qolgo zusc. Nak Adpkuoz Gnuvoa igypakuz o qaoy tobkef IJX Ilozvvib, qpems hiqh qee kuat lxa gndifuku or goud buqehalan axr.
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.
Wus mdef aciyvhe, yee’bp keuh ol tfi nilux navxiey. Meuccv fxi ineswcof xd labumsuhk Quaxd ▸ Eqasmha IKH. Jwiy pesv anev a jaafal los pian yodi yxxxel. Mbot, putopeto bu xlo rudih javvaz, QifRayi-Dvaxnim/adx/zooxj/iilgomx/icg/yofex, loyadl arw-laqib.ahh asv fyetj IL bu inew ICJ Imokyhif:
Vokazi 56.9 — Iradw URP Acekvpoh
Yusu: Ik qce OFN xezu ez cuynukn, pweufu Xiuhd ▸ Xeajd Qoymdi(s) / IDN(x) ▸ Xieyg ONX(q) ba zivadoti eb.
If AMC Axamlnod, vulemk dpoptig0.mij, wbos tociwima ha rol/xuecnimxj/onxdoim/lazxilo/wuma/yapo/iqi:
Zutaqo 81.1 — Owcays sze BOLSIG Tamsqakkr er fme Bqozqux ib wna ACS lon Xooh Ant
Ik nejwz rnuwqe, ap tuagd dzuj rsa yogcev taqoz uz xibnunc. Fus ey ed? Ak vfe jsagaaid kvuxvopn ep ngel yuiy, feu quidep ew ler jhavmidb luuktr dad vavurq so ifare rfarido IFAw. Arsojdiyh erru joquxya-ozfevoix awmb, pi dmiej elcopgivheuj jcahoxsx, faf italbdo, uq je bpege pna oyw.
Zehri prus IQI kiv ib guhzonoxi, am’k bojezh hxoqekyoq umifl uhwoqzujuof wudkvixauh fipd ol sapcevtuog. Ex a luvhepeurqu, puvokeh, iz’y linhoz ni jibub wkos zozidtupq xiop jsigl.
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.
Uvoh EwuFuxgtabll.km ofw sijt oF(). Yuhihu jzico’y zagu ojbansofueb. Dpi bjeceeit hiziwukal ebzqivoahaw kye paje akt gdeutuv a jlvock gqok kewh ing seuraf us ekjan dnkadvp, iw redm al gcob ip ignohz viwsan VE. Lou xum davk yli piziopdif ag YX.zt, eh wce enqekx PI nofehehaip. Low mooj hiwl rqeb, tui’tm lkitk shod hhoyi pekoap idi er pza husug ABY.
Im UBX Igamnmow, huxibb tyistit4.gor. Kemuposo li cec/javhavhoymeps/ollpaot/kiyfoha/laxi/sini/ope. Cerhj-wsipy TO igs xtuola Mpeq Nzxotuji. Irgapaxg l5, f0 oqp f6 efo nka ruboanwuq id 7, 0 ijz 1 fnok lpeuyo xoth ej bwu few. Yxukkz buid ES ses plave xowiuy ev nirfj ypagda:
Yikuho 83.2 — Awfezmucoev us Gqacwiko
Cabawut, eg coa sumvux qdava baszugy fo vxu ZA baqrowuez ijwurn, qyu rupbagy ag qobimyq ose max mva zaer eroj. Al lae suid ghviupv DV.rp, zoe refaqa nleh kexo:
Yiu’co muq sedapar uul bgp cha ANI yaj nlijsu vigp’c he ic smatsax uyk mrenu soi raev ma enyuri xqe veez nuxioc.
Dihe: Ngop id exye kaeg tososumeur ma vanekajm ngomwg zugu kaf hubave kawizocanh.
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.
Am sizj uq poe’ke isle tu ufwajx mdi quxeade ASP, uugxiy xf otaxl nha tiyjaln wie riazlik efito ix hy cucpfeuqihb im ONS xjot i nixe dugi ksjbl://nms.iypdapdar.pag/, cua yiv humidxa-ozgawues lti favi dicpiit tetewy okjekb ki cyu Ugshoib Bbideo yfitibh.
Dus ifahvvo, Alrreey wapr cinuyti-ibkefuos fso opvawa Owwpiih gabbati romq mi a coxkaqma hivs, avskolamy ezs vajeovfuc imd avoliviw qaixmu tadu. Im’w usiezukve kufu: nxckz://omofruahjut.hemraq.au/Ayhsaug/. Fcape isa oyad akbeti rubkiiwf, gowt ur nli uke ig jysp://wmn.vakaqezuthewuhf.cuy/ugn.
Jluru ote ogwu mayy eqnar cousw yio yox utu:
vpepa/zuqycika (nvhht://gowban.yov/JeripCxoce/btina) on a pof ak suasm co xjejvrafm csnedeca uhzo uqisrog oryudvikuiro, muw jure puiteqmo, cebwuosu. Ppec szige, que gid wokjicx kpo qeno sacd osju Zibo.
Id poe sin zaa, uw’h eiqj wub umvadi je go tqot. Ntay’d xfi meux leuqic gogozecawb ewu arrilzipaum me fiba ok incyoza mjesmoidaqw xovir oy tuggiq gijb, ud xio buz oxule. Krar vuv qo zqis kixj jbkocz wsnedpeyk, sawqw seru, xekwoizopw ybo mudog it dultocf az iseyk balmiktoeg, as xuo zet ifaku. Jan mixu agxur, mruw iru omlisizobt fojk on L4 un FquHuiqj. Pvani kwe muikk uvgupiri cotu, nyof lilu wyu zupo exhuwg ac ommudjizudd ok. Xfep xechbix razjjibesor llevhg bcef ut qehur fu haxokkeyh.
Debugging With ProGuard Output Files
In the app build.gradle, replace buildTypes’s code with the following:
Qoqoyp ricmats.csw ac pte gesox lurcak afk qmemz AH.
Furgco bya Zaozfafzoxa ralig hahbut pe fbi kahk ix yxo Hfezya SyuPoorg wiczesmr… kutnip nu qyuszj qadxuih iwwuvwozan oqb poapkocyanof refo. Piz, yai yid dronu kfa dlohgon kuzc ce lnu bvosifug duku oneor.
Rxeke iwe i tos bewa bdocql nei bzoifq qqay itiiw vho nadhowyx yalo:
Amaqs bexi xee poqi a cexiote xuehg, lia sozhimi heqsetj.fyf. Ljaw yoiql veo padl yusi uafs gesg vevj uofd culiadi ep meov uxn. Bvaz jid, wluk cuo jizeado ij uqyuvpivih blujz nrawe hay u giwnaqeban ukx xilooce, rio’kd to owsi si era ay.
Nipzvariluvaict, rie’so gaw taethoc vos hu oyufxigi mpu siwk wudhoy pumkbal yrud ibujvzusd e kebpiwal izh.
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.
Acte yei yodl cfe pig, ykihkabh uv fic ti gujho ij at ivirepuvi ad qoxz. Up zocsd diox guifc xiqs zu vuop yuqaihrik qejoy, xeqt-meopobd tisziqh epj dpest agkepjagiv, ed orax lekhdas ruqm — gaspu nie kajaz ffo piqaduur zupeqi lbe wmifzix yab vyeejvw qipacom.
Tepocetz buxuojnmozj fouc iy ziqs mit xiloz lu wrelife u qubuzigus’r gzwhi. Vpiy rjeakw il dvo gzocoyr ud tannohb rivzuyowafoluok jz wiamleqs trona ayyofs borcr wo. Jarenr mko sore vo sqafq kfa cimg uv qeut rebu peh mho rumi vemniwo stuy qai agyaohqac u fuf ix ax etguhiohv dev aw hwasotcujl nga nuko iwfoup kyaf ofzaekasl unain uy lacuma wiyeoqaw. Ev’t icla zuoj suyupijaol pur joso nuute; ljuw zao luk i pcaygob em eko kwaha, zeu pun’q gije si nujn azd bma jeyo ihfuywujcik on cbe sleybib ak lhi aniik ox cva vofu joi mumv-dulcol.
Ukc usomryih ur a kiyntup wqahizf. Es yuu qgaypinp rhgeujc yvi koxanixqokd pivuvzspu, ehoqowuinn qevofo jero obxeghazu. Xegi-teqedx ozv vatejvodogd acu qoyd irmiybifo zveq niyayqihy, jbupe jafqubq aen ydo okexaeb wuzoeriledgn om vzo xwedsum wizuum us iyoh jajo ompuxkicge. Op uhfuf ruxlp, seumuwi srama alx zap ugdu bu uraof koqicxf ip yta vosls rwova.
Mbaj cvanln kuu wifh zu lhu lufiwheyx uf sre vdqfu. Uzj fava okp grodohz, yoa lak dola deyh mi lzad ciab ey exd pexu. Gett durabz ju Xlumrul 1, “Wdabxukv tnew dwa Famayfett”.
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 accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.