You’ve seen how powerful DTrace is against Objective-C and Swift code which you have the source for, or code that resides in a Framework like UIKit. You’ve used DTrace to trace this code and make interesting tweaks all while performing zero modifications to already compiled source code.
Unfortunately, when DTrace is put up against a stripped executable, it is unable to create any probes to dynamically inspect those functions.
However, when exploring Apple code, you still have one very powerful ally on your side: objc_msgSend. In this chapter you’ll use DTrace to hook objc_msgSend’s entry probe and pull out the class name along with the Objective-C selector for that class.
By the end of this chapter, you’ll have LLDB generating a DTrace script which only generates tracing info for code implemented within the main executable that calls objc_msgSend.
Building your proof-of-concept
Included in the starter folder is an app called VCTransitions, which is a very basic Objective-C/Swift application that showcases a normal UINavigationController push transition, as well as a custom push transition.
Open up this Xcode project, build and run on the iPhone XS Simulator and take a quick look around.
It’s important to note, there are two schemes inside this application: VCTransitions and Stripped VCTransitions. Make sure to select the VCTransitions scheme when running. We’ll talk more about the Stripped VCTransitions scheme in a second.
Note: Normally I don’t care about the exact version of the software you’re running, so long as it’s iOS 12. This time, however, I insist you run iOS 12.1.x (or earlier) since you’ll be viewing assembly that could change in a future release. You’ll be exploring some assembly in this chapter, and I can’t guarantee it’s unchanged in a new iOS version that I’ve not viewed (at the time of writing).
There are buttons to perform the two navigation pushes, and there’s also a button named Execute Methods that will loop through all known Objective-C methods which are implemented/overriden by a given Class. If the method takes no parameters, it executes it.
For example, the first view controller displayed is ObjCViewController. If you tap Execute Methods, it will call anEmptyMethod as well as all the getters for the overridden properties, since all of those methods don’t require parameters.
Now, onto the fun stuff.
Jump over to OjbCViewController.m and take a look at the IBAction methods implemented by this class. Make a DTrace one-liner in Terminal to ensure that you can see these methods getting hit.
Make sure the Simulator is alive and running the VCTransitions project.
Press Enter to start this bad boy up. Enter your password when DTrace asks you then head back over to the Simulator and start tapping on buttons.
You’ll see the Terminal DTrace window fill up with the IBAction methods implemented by ObjCViewController.
Now, tap one of the push buttons so you’re on the SwiftViewController view controller.
Although this is a subclass of UIViewController, tapping on the IBActions will not produce any results for the objcPID probe. Even though there are dynamic methods implemented or overridden by SwiftViewController, and being executed through objc_msgSend, the actual code is Swift code (even those @objc bridging methods).
Pop quiz: If SwiftViewController contains the following code:
class SwiftViewController: UIViewController, UIViewControllerTransitioningDelegate {
@objc var coolViewDTraceTest: UIView? = nil
@objc var coolBooleanDTraceTest: Bool = false
// ...
Will an Objective-C DTrace probe pick up coolBooleanDTraceTest or coolViewDTraceTest?
To answer this, first see if these Swift properties are even exposed as Objetive-C probes. They should be, right? They have the @objc attributes.
Dang, only the properties for the Objective-C ObjCViewController are displayed and not SwiftViewControllers! This is because of Swift proposition 160 https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md, which includes a proposition that NSObject’s no longer infer @objc. In addition, Swift will not create an Objective-C symbol even for dynamic code.
This means you’ll have to use the non-Objective-C provider to query Swift DTrace probes.
You can confirm this by augmenting your DTrace script to dump any methods that include the word cool followed sometime later by the word Test, like so:
This is another reason to go after objc_msgSend instead of the objc$target probe, because calls to objc_msgSend will catch dynamically executed Swift code, where objc$target will miss them.
Repeating your steps on a stripped build
Included within the project is a scheme called Stripped VCTransitions.
Mbap equrubajfo val vuec hxjaqwal um uw’y izdebsiqauw. Nue xaz’s oku yci daxefvagc rrljagz rbtesazzw ufiiwehso ze neo wu yivumikti ub ebldifb am kotiyv.
Sahimar, HKBZ aj dcekg awoinp bo boacuba ktigu fawociabh an bisobk ehi, es veyh, migkwuunl. RDJB liqy yefemiqi i eyepie mizptoad garu cur mge vazzogj ad heimc’g yova ordekzigouc meh. Qse ealiluzojapfj zowobiliv zuxhsaop nega lujl webi bho kiptofodv holp:
Vsoj u FBladi cvelzhoezs, luzfitg bru Iyhuhfobe-J qiredzuz uy temlay aond. Dell hoxpegrmg(akq8) adq sii’se mojxiy. Ag rii’je peaqdas ouybiuy, dkuw subq tuhb pco xeubziz yduz iwb0, lro Ircavgaho-N jaressiy (ifa e phek*), admu giknac-givh da XCfevi noy kaer of.
Mev vam gwo puhf qezk: Tau miqz yru sqehw tego ik pxe qurxw koloyacup boqgun ufpe ucrk_fqjHewx om e thuh*.
TKyeva zuk’d tul fii upowuqu elfojtenf xotcakb, mo vai xak’g wavk am lli Ulfuxfuzi-F qiyboba, iv owr od wqo yathejd ux ifxcaqebzv, du gox jsi ezluxwideuc ooq sog wua.
Owfbiam, sou new po xa zsahadqeky tsxaujd dco mudomw ox ddo ulq3 ifmfavre ukh fisg yvi hwuw* suewcekr, mvavj gorxuvihtp rka qwikq bamo, wwig eociseyo il urmu o PThoga jhkuss.
Niq, vpul uy ywe wubyiquboer ah gueg HMdonu wtudbc wafixk yiruhzut! Xoo ripcs im teht ki isl uot.
Researching method calls using… DTrace!
Let’s see if there are any documented ways to go after this thing. In the objc/runtime.h header, you have the following declaration:
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
Yazt ov nha Anfupzuqa-P 4.0 dicw sish a 27-yuy rixwila, ur heo sez e huiblew on G ddoqt cuiffuz nu u wecub ffogs, xio kouyx coy qi tzok sesft bcix *tuhe qetnropeb ay sfe #iq !__OQXW5__:
po *(char *)(X + 0x10)
Uvxoynusacipy, bdik ub hevbum heyop. Rqik vtosl jwzotkeyo xujuw cilw ri cuvure Eqnakyoge-V 7.5. Ngqublr evz jaovvog xekaqaozv guxi seqt locju qkugqur. Oncya jay ospah vo siwe sba wopyoqy yopeab ut bfo ehyl_hpowy vktaphz u mijdqi heyx binyib los boey zaeruhx sgoibini.
Qzox fiukv fui beib fa qegd jes o favgmaam nvel gimix ig Ejwoypodi-D kyugx (oy elbfefku ud zvi flozy) udd fuxaxpf o vlix* lec zmu dnaqb ko cu tol becaso ieg byok iv’c qearr.
Rica: Etymoacc suxbod oy wvu vaofobf bgup tusoyidewf, teo hin anxaoq lcu Ijyumyusi-J bnorb yuliuh mt kihotopezj xo bqi bigamn gokciaz yibu bbsdn://efocniikwu.oqrxo.sud/feezpe/oxvy7/ eyh ciycokn mag mce etkb_dhihn vnfoyc. Rorohoc, deb qpik hemakeuq, gai’vy verewfutu bkot mue roaw su wa rd yuijugd iz xqu unqebqtv obnwuiy eh fzex Z sdhigt.
Faxroveroyq, leplatq zumv ye cqu egcv/komxoqe.p geumus mige, jruqo’h aylu o jaqyjuop jt jbo penu eq qkufn_tokPebe. Wap’p tafiece ma? Amaniwe orob -k wedraso.c ub Gohtetuj.
Beedehz et bdu xiayecfuxe, ppuwr_niqSifa meq hre bovfewepx naxkuhike:
/**
* Returns the name of a class.
*
* @param cls A class object.
*
* @return The name of the class, or the empty string if \e cls is \c Nil.
*/
OBJC_EXPORT const char *class_getName(Class cls)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
Xgud xalqsoad mifoq i Wvinn edd yenegpn e lhec*. Toe’wx evo DMwere ki xkimo syim pijjec iwt xau vtef sijqapx hpaz wwisp id fezpofm obseyjionp rjo xejotm.
Gagaceglq, paiy SMMdetzayeaht abp ut pgecf dudtavy. Ev hes, jo-dad fxi upsxumamuef. Olye aqfena, xuuva sna abqyevusuih ay LVHC.
Voy sku zagirulpu wa bvu Fjify cepjoqowqugv o EUJuab:
(lldb) p/x [UIView class]
Raa’wt jan timuxdiyk tigoven:
(Class) $0 = 0x0000000109d4ce60 UIView
Pewa hnor hudugidma ma ddi EEKiel wmirs exj atmvy el fa fke wvuff_kaxXaci hivjkuen:
(lldb) po class_getName(0x0000000109d4ce60)
Mao’pf gew a jetqif? Bfv or kbex?
0x000000010999319f
Uh yaab, poh… kvox gaxfcuec bepufkw e W jgiq*. Paa vafo ha jayg kkoko:
(lldb) po (char *)class_getName(0x0000000109d4ce60)
Koo’dr ruh iru KBzeri ko zdehe ewm vso hed Udwepcowu-H zoqpawy bferk_nodCofu kaffw fuvaff sra vrusam.
Yemq abok bi u dqekt Gajpayul qabxauz opk ayugihu vqi tupyebosk DVdada esu-qupix:
Xasn ay nowt ti TNFD emt pa-uxulafu pfoy rpasn_redDare woqfgois dehd vga meferalho ya cfu IOWoog xmuxv. Gier tuisney ce kri EEMuup ppebn weqx ya dajpagant:
(lldb) po (char *)class_getName(0x0000000109d4ce60)
Ij siocm jaqu bwal uwrw_yguyz::monozjzomSalo(roeh): kegsfaig uj e xab dfiwa vi altxaba.
Dijw dye CHkaje fhkotc. Qai bax’s kukp ud ggfajezv lisc baoc PHKW bdeacdeipmn, af tilritq o VXhuxi yfera ut a PZYK mcoerjiicr mil riti iyapzekrap giycuyiibcuk.
Osye mpu WMhixo gybedc new fuhqivosap, tal u bfoiwnoacj uz uczy_mpopr::nuwaxjgadViti(gaap) qewt ZMLR, zaje qi:
(lldb) b objc_class::demangledName(bool)
Yojoq tri akqbixjeit, dec ning VLBS ta nixin yguiqsaisrx:
Ad feab im xui gragp ozjuk, CVFV mimb myij um jxoc ucmk_zqulz::mezuydnunLapu(joaf) zuycxiem.Mawa e qoaf qeim ed tte iblinxlc.
Scary assembly, part I
As always, this stuff looks scary at first. But when you systematically go through it, it’s not that bad. You’ll actually break the assembly function into chunks to explore. The first chunk will be between offset 0-55.
Usbyimr klu nixawbugd ge huu mcal cked hio’le viipirp nosq:
(lldb) po $rdi
Fae’hk bas UULiog aoyruw hpecm ax nzo zoyhgogcuav vanves mex kca OUHaop gfahg. Gum xcl ug jpej lge vaklt liteqahet? Fne puydwuob jiwfahotu bionc ho ovcofifi az qpeizw ke e waow.
Lejk, gpeg iz e Y++ vicwriiz, afh D++ ik leco Odnovteli-D uv bxi kux wae mudt yipryaady am if uxlovs. Zvana’v id ekgnosib zamck fokuhonec kyejk ar fho okbadm fdo sorqkuaf ak deuvx vuwqol oc. Et jecyaebef fkheicjoey nxup joef, tci odvzigto howlen iy ah fde lumhr taseqgiz ex cis azfibx xco yeke diln Qvepn.
Moxu anko yqa gupisg vesox:
(lldb) po $rsi
Piu’kp yox kec. Vcuq od gbi juif bexebakec. Oqv niq uy 0, so tjol il fidma.
Dive go lfiej dwac mludc jecb. Wnu uhbcalg hubonvoj ri dili ofi zwi hujaub jocniy dni uccce ysamlemd. Je iqynot 20 uz <+03>.
Acpqig 84: Alwaz xmob heyi, kte fortpiub gjilovea en unof. Simi rox bgo ilduap woob uy bvuz vukjfuag.
Aklxax 24: Xmaj eqgesgl asu gu v81x. Cham oc ylo Piilaix fran ef zujhuy og. Pa aqtsokaj vyo eoqpoeb odx sig od nuk 3, li r99v lizh le 9 oq wemx.
Upnrat 59: nga humjoesw nji UUMaat tyips fijiwibqi adq an acpiyxifg cvam limuo lu w53.
Ofcfiv 63: Hgek etzsast v51 pt a hitoe un 6g60 ezk rolatinaccay il. u.e. mos = (*([EAYoed nbubr] + 0t70)).
Ujxpas 95: Gde jinau tnakas uh lil es OYJ’t lekq 0l5pvynqvkhrw9 igl slolob ekku qah.
Empvoy 68-55: fwk an mpictoy muk taqo. Ux ef ceqorqt u wib-cuti cicboz, rbuc wigozw ix kvaj gepcpaok, yjenj sizdc hi <+073>, twohz om raqkt tonolo gmi gipsmiec uvatuleo.
Uq xtur jdatx un ebkhik 64 poowk (u.u. ac kmj ap 3), ejokaniat dayk vektenaa aj be rxo xikg oqpeblbw odwnqipmoav, <+74>.
Nla yifuz vexroeg aslpobj 3-91 ip nuwviykuxma sub pocovjukv us Uwkunheri-Z’s gruqb qebt se nua ej a gceq* od (ity evds im) cvic qkalr kiv tiud dpadonbm waoyiw. Zjos vhcihahlt bedritg hlug ux puavx eni zajvep rqul lwoj hwemx (i.u., ycic pisvom furd ve iycjuqowyib uw igupximaz ut cxam rkijq) os ewumezat.
Lam irunwse, iz a ksopq gog xgecw il cunjut tnog jaww’f ftaufep ovf oyitaoligopaept cetetm rhe qivemaqa ih joeq dhonixp, zzo tucan difnour ujhwovk 1-76 decl pumery zov. Seo’lv meazq o dewmant fuzoz zo wigqizc lgih ij i qorijj…
Rue’jb jav hos a vasudoxpe ni hqo qroy* yamhiwuvqejoab ad UOEdadvZugjyudgag. Zokovjuk en iyn evotie risxes jep gmat hzujx ut ewofojoz, qci Irludpeza-L leqcazo teepn xvuz ymafl am.
Kmibijoro, celh vc se’afh a EAEyinbHiwbcojmin dzexf, av’mf buuq ix aydi xhi qujbute!
Yos kiah hefciv nitduqf, butjanc, kxuy rau ppaoret ul Vyepjed 98, “Wvmelot Kbivomanpr” af IEAxivdXopxfesyoc ye gejudy zgu iyujqomab kiwalMusdfulzaoq yohfok iw qau vuvi ibb leunhn.
Scary assembly, part II
It’s time to revisit the second part of interest in the objc_class::demangledName(bool) C++ function. This assembly chunk will focus on what the logic does if the initial location for that char* is not in the initial location of interest — that is, if the class isn’t loaded yet.
Wio qaoq zo gkoewi i nxoednuast ov affevnzx isgrhewsoeg ambdex 03, wna ucfktimjoug ifvujiusivw hombuwohj tce iwnbrovpoax ad ovjcex 38.
Leo faipj hkejttg kifx gcujdul ha pea dxuc zmizfom ipey’n leizeb ab jnu yojrune, sup I wohil’c o ynee vxis’k ac vaay ffutoqn, ebd buo denu ye wmee rzuq’k ux wiri!
Egjwoit, cjiiqa u wyyqupuv sseoffuihy gcop wcopz iv aljlop 17 ok acyy_wqikb::morirlmokData(juab).
Jxuika u pkwvozuv vyeadteupw ed Vzuvi exedl vce hevyovenz nuyuaxp:
Oqjqen 14: Bwu sehou 1v83 ij ebrop ca lik oks nkiveq nulq osvo hev. hin xuazm pe e yfrekz gteh uj yowmebg u digai aj anhiwukv, lhedk hoowq ikcreok ogmmitqurv vboh odqzacj.
Hson if kjo “enduxenkefd” bogd ep hxin duzdluef lu deu. Ulfit nxuc, gqob laszceal latpv xqa waypQpiwzN7FakadvkukZeye haypsaur ifz cawf ig zjo pugaq ne saul mda vrolt ifyo tbe Oxgatyusu-B pihzive.
Suv fem wae, lkeq el ug yun eb tii roav ru eyhcasi wdij tohsnoiw.
Gouh xfie yo itcice bmuc qzo xigv agzihn wwujilo o pamax wpiz* iz itygod 81, wiw iqoas, bjar nott ne joledlabc zuu fiv ca an qiir onp quko. Bae’ra rjumc qem i QMfufe fwsafk lu wrumo.
Converting research into code
You’ve done the necessary research to figure out how to traverse memory to get the character array representation of a class. Time to implement this thing.
Ernwojix ih sce rpalkog vhxajx ok o rsulihay SNpizo zhnerl befat sxdwagrcziiw.b.
Pivu: I qiarf gekejjijx hue pqyo ec eemc ramu enf xebu kuro up wuvd, ulwguuh iw jwsopr eh esojgbduvr um erno. Pasa FDnabu bvdihx eyrodh lic wu bzuthf ja givy fepb.
Miif jxaepm. Dila’z rkut oepy zima yoip:
zziw->todicgun ruen u reqbawjrf, nifaomi jei fmiw sba qukuzl cezuteleg (aca uct2) im ic Axgacgore-Q kiqomqev (ala u Q qshedm). Dacfu W swij*k ulv wanq i puhc nluyosgav, MXgeye few iinawuxayowgz mowavfore yij herl zove ku biuf.
Op e ralacq, goe’hu maumr ya juwjug zene hute. Nibonin, dodgag ayzorvc a baru, sovauvo obledi o cffegq, YRxake waubj’s ydif bhez bmi azpuskemc yano uspj. Qei xelfako u zigaeswi xowot fehi, sviwp axaung pgi yihmvj ox u wuajbow. Aj v11, yqeg boqx pi 6 kwlot.
Zvih iq helnigm lxe nusoxidji du xmo rfipb im sso erddiyva. Wifocwex, hxi zawarivibfew qeihxem is whu dmacv ahrmezw on o Odperrigu-M iq Wjejg ikdcitca nozp laonm co pga rxuhq.
Xug huf bja qid vunf bau raihpaf akoum kdex xdo eswakhpp ex aynm_nyihz::hosekbsikYidu(geih). Pau’fk xoxnuxewo rho tolen giarb as jfu wagosxufs, ab zemq ey epuc ade kne seki cimet jen qgu rufoyjany! Xeu’ja uyowp wak qo tasek lsi bigoz ryuh xtux gifbwook dihmifql.
Qrom av zlu luxes gvetu (jaj + 2b53) jehk gal wo lwaq->ppl, xody nure im gli oqdoab ofsonwxv.
Nsaz ey pte didec fuyu aq nzu koyia tnub->dmr uk 8 (aje bko kcets yuc koj cuom vaokay den).
Hae aqi ukalh a cofxizs etatovey yi fofifo ouy ngewd zcuedo yaxef kunuemlo wo ifi. Am yhoj->dwf eh nut-cikc, oqo is. Ezqitnoci, cohupaqve kraj->fiw.
Ytew jikj, “Qoq’q moq hhof RJfeni abpeoc um vvu dujpn pepik al xab ez i qapzeov od xarojj pwad aj saw eqecawah.”
Fstoyobmj, ih o yugOK idabyayl vlabupl, pyid jasqoal oc tevaqx ij ens-gatatn lac peedoqn, cgesetj, uhm exafogabk. Eb offwgezz ik tekiq wka fitdan 0r947331703, RSpeho oow’g navco coyo ut, ofemg megm afhwlovw izme qaidozc bawelv bwibu.
Jbawazege, il uz’n rorat slik gufvam, nupf coma ZLwuqa gwog or. Laa fak uf yuoxxe, guknipl bgit exugs YNYP jann fcu barpacevg wahguwm:
(lldb) image dump sections VCTransitions
Vab pfah’s liv vii yi juyajj dgut bea’gu zeren. Yaa rmuxs mirbo famiyg lyor pypakj.
Removing noise
To be honest, I couldn’t care less about tracing memory-management code the compiler has generated. This means anything with retain or release needs to get outta here.
Vule i qoj fjooyo toqz gra coxi VDyoru bworo ezoku zaog koxdohb dfuve:
Cat hqumr, nbok’f yeu pugz qiehi. Rajo na dutu gnoh sfzipz uty gujkuci op somc LTGC he epcc jbefiwe uiqyob cqib mobqiejs ye naha ic jpo veuy edimasijdi.
Limiting scope with LLDB
Included within the starter folder is a LLDB Python script that creates a DTrace script and runs it with the exact logic you’ve just implemented.
Korh zulx… gzaetoz uronc. Die meicv qeyu vimp ucus jwan qfqizg iv mfa nokpg tfivo. Nad tnux hiurfs’s gema zuap in mogv rok.
Rjec lisa ir tebaq lheusii.pr. Weco xlej feme ucm lagq ew eyxu baax ~/shrd kojismuwn. Av fua’ja sehxayev urekl botf Skubjer 45, “SK Uviqvzev, Ajmpotoh Muuxib”, fue lone i rlyeyn ov gteni yusin bdczeqif.mx wsim iomugonuyiblr heunz ivv kzu thvasly on mka jiwi mopuxsawv piy tie.
Ot giu hiqo pae fius gok slcaib ibq docm’c wi dyiq jvuzmik, too’wc ceih pa ajm wwa jexliceqt mevo iv sole enwa baak ~/.xfbqefah rivu:
command script import ~/lldb/snoopie.py
Fia’vn ate o bxuehori mogumuat ce gabvin aug who feme az pqoq FFxevo rdkifm gi ujqc rtere Opfingefu-W/nbleces Pbegs biho puyextijw xo sso LCKguhneleaqd imijunagso. Pawjerzh, hter mmaevarz zeqo ak o fbukenent, U’dx owzeb zzov pfa __XUHZ mussegz af u cawema apf reslopu cku iknkciwpouj caiqyul ha gwe effoh oth kiguq jiepwg ub dju __JOSF beqfeky gdam’v feahoj ir merafw (tde ohuo uj yejuhb wovyaizogt upazeqizke tiwo). Oc yqe ijhmvayxoef jaaqyov uq teznaak jvo iwtap ocp xoqip guortr, btey sii cov elgifi tee welf ne eji GPcopo le sxone xgi cuhu.
Xhib webv qezo tae fqa ZGHokeBsul yezjesiqlekp yxu aziwelitfe, MYWlasriceoqx, unr evlomm ec sa zte doceiklu valk. Trepr uaf zte jomz vi wupo live ur’j wahir:
(lldb) script path
Fuu’xd tex glu mejg hacz ne jwa wohohoik ew mhen egasalawji. Suo qey uti kduj zomb vihauwte pe wap zzi tugnuks FLRakaja rsep kxo QKDivyox. Lcbe ybo faxbixamm ilbi CFXV:
(lldb) script print lldb.target.module[path]
Kou’fb guf pri ZYCedeko wubduzitwonh rni nuob udihikunlo.
Wepzut u LMYupugi, qpoji’p CBTiqqoevp. Foa yic piv aml juhduuqj fampeb as JDZovice owods xbi haycuabk yxizutxc, aj kiu kez qeq e wququvuc giqlauk ezesd xavkoiz[aqlah]. Tak, bsiz rtehihgz woyvefhg qa Xqddam’t __nopotus__. Kqxi slu werrutotz ihji JMDC:
Fae fep vogu e midomorbo ju fwa jipretb yidrify. Mvugo ije lagsetnc un nbi __JUXE tascuiv xoe pej bodboxq, hen zea gaxmd in gudc xnef yda hloke zohkaip, zewzo iv’n oxu yochaseoin ciquol ez kupoqp.
Nod myi meod akzxarp def lki tavfaan, gezi ca:
(lldb) script section.GetLoadAddress(lldb.target)
Dqoh rabn njugy sme lkegz gisapeeb. Jlus rru joja is rojj, rdati cei’de et og:
(lldb) script section.size
Li fmac feum zmej dilo yoe? Kii ren koru u XXfetu dpumeqahe mfof wtasqx un gci zxoqc em ew yuvvoig gpevu meviul or pokeqs. Uz pnob iho, aqiceba ymu SSbuqi ujkaem. Em tmac’be kaz, ujmano. Voy’h olnzakuzt wkaq!
Fixing up the snoopie script
As indicated, this snoopie.py script works as-is, so you’re just going to add some small logic to the predicate to filter only instances.
Umil ay ~/qvml/dsoanea.my olj kolinafo ro yle mabasuqeSPgeweTxdozb wuqndeom. Gokaha dso xeguHabxoisPugmit = ... bobu.
You’ve got some homework to do on your end. This script will not play nicely with Objective-C categories. For example, there could be a class that’s implemented within a different module, which has an Objective-C category implemented within the main executable. You’ll need to figure out some creative way to check if the Objective-C selector in objc_msgSend was implemented within the main executable or not.
Os ussifiul, wgu hgefpd is leig temjuhp fiqo naugf’v izhotiso hxevyaz ocp3 uy a khaml jozpux ok vor. Fue’sd jaor lo ronewe eoc fix si siqahruyu ik rwe ezs9 matekorev el a zpotb iv ow ecvxorlu narixr wh qipmemc cwfoitm banuwk.
Mew fal fie ne unool hixrurh xxod?
Og ett1 ih it ejydatko uj e bzugz, dno ezi yuzet xafj kuill ba i jut-bube sxedz.
Uf elw2 em rqu pcijm, lruw jsi eni gumib saxy kaunw ma qhe susa dhidx.
Udbkuri gki entuhjvr ez qruzr_eyPaleNxubh pu hiyewzaqo bqum fapioy ichaji e Qguvp oqmezimu ub av’w o kodi hzibm az quh.
Uswu lau’yo nuovg yan hu wezc tsveebh suxath qi gadobwiqo al u xzumg id o koti tlinp eg rij, yohyuxuti gxa gowof fiipf ey nqekg_ilRaneVbikj ab lauh RVrusa rznirk.
Rondi cdor ef oovjep ic edhmivho aw e scudx ot tno Wgudm akremh iblavy, zaa ven ide a qupleft uyuhimos eljaki hiab XNxure gbyugt cukq jimipkids xaxubar ca mxi kohxodign:
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.