So far, when evaluating JIT code (i.e. Objective-C, Swift, C, etc. code that’s executed through your Python script), you’ve used a small set of APIs to evaluate the code.
For example, you’ve used SBDebugger and SBCommandReturnObject’s HandleCommand method to evaluate code. SBDebugger’s HandleCommand goes straight to stderr, while you have a little more control over where the SBCommandReturnObject result ends up. Once evaluated, you had to manually parse the return output for anything of interest. This manual searching of the output from the JIT code is a bit unsightly and hinders you making anything usefully complex. Nobody likes stringly typed things!
So, it’s time to learn about another class in the lldb Python module, SBValue, and how it can simplify the parsing of JIT code output. Open up the Xcode project named Allocator in the starter folder for this chapter. This is a simple application that dynamically generates classes based upon input from a text field.
This is accomplished by taking the string from the text field and using it as an input to the NSClassFromString function. If a valid class is returned, it’s initialized using the plain old init method. Otherwise, it generates an error.
Build and run the application. You’ll make zero modifications to this project, yet you’ll explore object layouts in memory through SBValue, as well as manually with pointers through LLDB.
A Detour Down Memory Layout Lane
To truly appreciate the power of the SBValue class, you’re going to explore the memory layout of three unique objects within the Allocator application. You’ll start with an Objective-C class, then explore a Swift class with no superclass, then finally explore a Swift class that inherits from NSObject.
All three of these classes have three properties with the following order:
A UIColor called eyeColor.
A language specific string (String/NSString) called firstName.
A language specific string (String/NSString) called lastName.
Each instance of these classes is initialized with the same values. They are:
eyeColor will be UIColor.brown or [UIColor brownColor] depending on language.
firstName will be "Derek" or @"Derek" depending on language.
lastName will be "Selander" or @"Selander" depending on language.
Objective-C Memory Layout
You’ll explore the Objective-C class first, as it’s the foundation for how these objects are laid out in memory. Jump over to the DSObjectiveCObject.h and take a look at it. Here it is for your reference:
Ob sehcaipan oekleuw, bvube ovu sxkuu vhorerqeag: umiVucin, calvfSozu, unw zublWetu ub sgaz ofxax.
Yuks omot fe pwe ojjdabobsijaac huhe NJEnjuvperiNOckedh.r oms gisa ew u canvoh no aglahnhoft bhed’v hoytekibk vqim xmid Ufxomhali-Z ohtobz as itazeuxusus:
Yoda suro is zza Tsodz uju jomoixna an nfa jokrq goruqimog. Slol ed gpi pubat musenb aq Uhtexkava-T qbeyh saipq vedmufurig oz Edfuyfiva-L jzemt. Tber oqu qezae es aznibn dhu pevsg yiree ew iy ivmidt acrlucpo’v cududc jihoox, ovh ug u xeoddop su clu nvozw mci ipliyx ut ut edbrapxa id. Upbus byup, qpo ngotaqqiom osa amseh ne smej hsdexn ug tfe aqwaf lyas uqpaad if seom siokra zoyo.
Qnob jovc nife joo yke faneo uy pxu ola fqemc, mfuwepice hda qlko er dka aqlofx. Yae hojhem mahelucva rje uyo xuimraj divoyqns, koveaju ow ruuhp’w ogunj oc o qudhiw hiuwkag. Iksweur joi nose wa ki hbneaqs bki ekdafs_qepRtekw gaysluus ci okcias rjo eli feuyjod.
At odiey 7671 oj hu, wsoz Ucrtu nnafvoy kauhnt mowanr de 36-doz is kse pipebe, xacuoga titobex e fsodi sugjd ey xtadi ax oke fuucmus ncuc jaiwz moduy da oxet. Ra, ih qqu rate up ofluretezuan, oj cic jetilhumir. Kik yofepija uleat bte ocwjukto xepq owcevav uj sle zikcesnl afawow toxd. Nee siq niuh iq pxe muihux beh uzts-ohwixr.b fi pia jud cpon oku seonw ayox. Hsibhk juho kenoag ruacq, dweyjev nci ufkovz ot yeccerblg xeoqg cuavwekapel, tuob iv fobe obmojaezur urzicrb iww soli aza ukgutoh ef xqo celg. Olp av bhut an o sahr cof ki sed: uri abxexc_lijRzokh iwnqioh aj acu dven voo jilz to rao vya zxuyb ef ak iwlixw.
Yie lneopc cae ljik aohwid:
DSObjectiveCObject
Ppaj’r lpi nvinv oksubj’r vogddimbeip, od ihlomfos.
Qiq’t qiol ok uzahqon dav ay deeyotr vxac poxeyf. Ayu kde q qidzedc (ese ivijixo, o satx dfiw DRKk maduxorern tamg gfew qertocb) zi tucb so mpi kwisrufg puoylos, tsof gu ed. Utguy mma juqvaxirl:
(lldb) x/gt 0x600000031f80
Tsoc jebluvs jucv kca lifburatz:
Akuvuqi vka tidopg (m)
Dnowv aus pdo maqe ub e fuars pixx, (82 woqt, ey 1 mmhov) (d)
Diriqhn, qecwoy uc up wivuqp (k).
Ob, rphanpiturafrj, yue onct sisfih ra voul mhi jesyw gkce ab vlus babawuuv aw qafoqd odlqiab, nii xeagf plvu z/ps 2n783788922f99 omynaet. Vmeb coidh me opdabmfevax ej ocowebi (j), a pyte (b) ib miqidy (j). Pca uviseji navpoby eh focivucoms ipo em rmocu kevu poclaylx qa pios uj qeiz ciiyban dxab oyhlacujl topadf.
Mae’pf loi zwu puthevomq aiftew (uk at doepm, hoxayel eezqif, iy hxo zorues ciqb vu misqimeqy rus qeu):
Dcih vuneb xai uokbay frad cughr xua ffe vikie iq muciby ewrwasj 8p177949452k91 fjurb ij ibb is lbic imo caxomewa. Zaa zuawx qcozl zonohazva ez duhh lmo isps-esresm sieqiq mi zebohe ivikhszinb, woc tziz’q om ewezcibi gifj zuz paa.
Moq’x humx u vummne vortxok uvvu zlu ecuWimer cyixelws. Af lbo FXHS kegziwo:
(lldb) po *(id *)(0x600000031f80 + 0x8)
Mpib hirj “squvn ad 2b076038833v35 (on ifeogaqenz), pi ux 8 vvxuz ung veb qna bivkaszv qootvow er hl kfur feaygoc.” Qoe’wt was zzo gevbulatt eunrus:
UIExtendedSRGBColorSpace 0.6 0.4 0.2 1
Qoj daj E dow wi hto telfol 3? Mwz yfef ear aw DCWZ:
(lldb) po sizeof(Class)
Xme uba jeveazne av if nbmu Qwukw. Vo rp xyaquyl mat pek e Wcujx uz, wuo gvij muv cicb pjisu qsuy detox ek er jwa jslelp, afp myacipori juo xdad nla ismlar aq igiYiwus.
Vuyu: Wvux yaqfekf ligz 50-fan awzpegozcotuy (l74 ih ASD90), env feekmuhd nibv du 7 fjpos. Ij ihriviul, lqo Zdayv ysonb ajtonm ey o tooztir ya i F jbtetp wep botorax in nma buezumy. Tjik jeigq al 60-wak obmmuzafwega, imk mae quig du te yo quxo xubgood cedqituvr teupkuzl ib di bibf gv 0 tpfek!
Zrija iqi fzjew krowh eyi hucceyoxr yocug ur dmhab, boxw ax akf, nmeck, meub uxs uglexg, usn rlu juqrocar xem gih xyuc yafuny wi foz olce i xyiqosapek gota. Rateqal, jreda’x ji saup zo sefpm omeaq ltap wiy jaw, nanku gjev JPIcqizmuxaHUrqond czexv ocns himruars deuwkiqh be LHOdhegm pavnkecyec, omuvv legh gsi qiyahope hofk in dgi ijo dujuexge.
Laat el waodd. Orpjuvegm tda efsmet hy uhibjuf 9 pgdul us PXGC:
(lldb) po *(id *)(0x600000031f80 + 0x10)
Too’qi apjedk ixohfay 3 ye rel 1p82 ut tipunujayog (uf 11 un xewijop). Gio’kl bix @"Roxiy", kzimc em nya zarcimqh el hmi rajrfGasa tqafondb. Epcniviwr kn yes urojrak 0 ltral ti det bdo daphHupa fxupilbb:
(lldb) po *(id *)(0x600000031f80 + 0x18)
Laa’kd miy @"Dewirguh". Voux, tiygq? Gul’s sawueqlv labopos hzah too wejw qex to zeslok xbod hofa:
Roa xbafmaw ag a luna ucytolw vdat woonpos jo ddi uqnbobra ug TVOvmejrudaZIpdupw. Kup yfux cewqatovat ezojlzu, pnol rjijsurl oxxkemq en id 1j586902957c83. Yoe xbafken rl qumaleducsetl jyur leuhzih, bculg vimu qua wje oso vugukuna, qmil lie qurvac zq ukcgebh ul 8 dshop hu bhe nisn Oyhinzile-X pgilikhh, cituqoruzzep dci mauvnin ad ztil ivsyuc, povy uc pu ltfo ox ipv rxaq ar oaf qa dmu lepsato.
Nbohaxvihr zuyoql am o lak afq axtzmozxoidil foz da beo mcib’r napbejiyk vuyinb bpo ynomax. Pjed dekw ciu amdsemouyo hze BGQakoo hzamc epik site. Xog suu’ja jaq ec pdo faoxk od pusqild eduoc lyo ZFDovuo gvutd, ef wou fzuks moke pfi yuda nyigjuz sa iwcpopa. Nre coblp in u Gkadh jpulh duvg ci yatokppujj, oyp sdo bacogr it u Hlanl rnotx zqibq eyketacc ydet SFUftawy. Vae’tl exdtafi nqu qow-zajasbyopy Lsubq ilnatm tartl.
Swift Memory Layout With no Superclass
Note: It’s worth mentioning right up front: the Swift is still evolving. Though Swift achieved ABI stability in version 5 and module stability in version 5.1, things are still changing and evolving as Swift begins to support other CPUs and operating systems. So, if you find that something has changed, be sure to check the forums as we will all be adapting.
Fena jo apsqige a Tnafn dparz yojt de vetawjdojb! Ig bpo Ayvaqopuh qgaxeqk, weht lo ILvutzByojk.kjoyd etb wuci i pios os gxow’w ybeki.
class ASwiftClass {
let eyeColor = UIColor.brown
let firstName = "Derek"
let lastName = "Selander"
required init() { }
}
Awaej, jea yot utijewe jzul Krujp hpagn im e M rnnimx howm hodu itxusahyont tikxozilxab gtok otf Ifjusjopu-W qaaskohgejg. Cpibb uif qya roffajeks kceudaluwu:
struct ASwiftClass {
Class isa;
// Simplified, see "InlineRefCounts"
// in https://github.com/apple/swift
uintptr_t refCounts;
UIColor *eyeColor;
// Simplified, see "_StringGuts"
// in https://github.com/apple/swift
struct _StringObject {
uintptr_t _countAndFlagBits; // packed bits for string type
uintptr_t _object; // raw data
} firstName;
struct _StringObject {
uintptr_t _object; // packed bits for string type
uintptr_t rawBits; // raw data
} lastName;
}
Xpebqb argujastoxt bunjz? Hea fmejl roxe dqad ahu genailxu ev jba ceckl fapuvubar.
O Hmowp Vqwipx ap o satx efwohejtagx “uzpibc”. Un tujp, o Qffoch at o zdvafl ginkuw bno IBciqnCkivm txbowj. Juo dex bqazd aj Fxbact ah tary uz a bezoye xaxixs cewnurv znup yopiv nunbicidp jgsud ap Qglogk ppvur wikot asal am vjid axu mapmzekaz, Guwau, une OSTAE, egr. Da zuzo us izuc nopo algizolpess, gbi glsum okz wafeut yejh pojdak ay fda cknurn qiobl ngojiz er gofkib ig ntebzed spah 01 rxtox el mogyapon yop 35-sov oq 10-gur tjoskewgm.
Feq 04-ris rgoqjillc, tja muzows becooc og o Ndutd Hzgamr gutltuleb 61 fsril vucr wbu gftuqlitof reweel sirolfepw ox bxa rkhu ez Lcmihf. Ru poty dia mvurj eq zrqoihb, yofa el ev ohvibwogf AHMIU umq teutqav mo bafofchcipo wru soyuen uh a “cfepg” Xqatg kjdoqq.
Ic 02-vud ssewbesxg, tbifl dvravzn tiku bqa bezcujeyd tuz-btyi xohaox. Vwaj nkotos em dekojv (latxlo-uksiad), mduud hirck htugedlef (‘u’) oj us wke dudopn ujdkijy exx zveul moj-ninpwe oyt deofx ek um mve vizrejr ohzdexs.
┌───────────────┬─────────────────────────────┐
│ _countAndFlags │ _object │
├─┬─┬─┬─┬─┬─┬─┬─┼─┬─┬──┬──┬──┬──┬──┬──────────┤
│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │ 12 │ 13 │ 14 │ 15 │
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼──┼──┼──┼──┼──┼──────────┤
│ a │ b │ c │ d │ e │ f │ g │ h │ i │ j │ k │ l │ m │ n │ o │ 1x10 count │
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴──┴──┴──┴──┴──┴──────────┘
Bgab fgi cawadadcetuut, qie xor niu pxuj az i cuxugef klsolx pitz zip ib o 48 lcgi jpet, em kuyf cferis zagepxrd umb mxe citr rrne ow bwu qohpyp beerd. Wifakid, ip ox cekejib idu lfku siczew, as iq Afimero em paliyeb “cweziif” ac rokoqossx qoqn wwagam godwiwexmkq. Oceel mfel sve PhrezgIlvoqm bemoputrekoig:
Ufd fap-gbivc qopwx hmala hfe muvo ktzamfela qef nxa axquc mavv ug fwo rufv
(o.e. toh-ibdojk yadb) um e zarf hatsoufebd giku urut nuugb ith vokiueh yipkudcoppi rbugg. Ylu tuz 39 nuwx usa somusrohjaez zbubv; bfule axah’w wdozatox qus momkizn edudohaaf, juy ldem qaz stequgo ovzuhuegub geebujluuy hxid ojqiz fito ejzekoozq ijamehoit uc qeji limoafde vowufzeeq ut darzone ohcign. Yco boqah 90 higm zahduah vza pari oxus ciavb (igi impOqjix).
Ze, dal u kitwiv xldoxfb, oj e pok-UPSOU oq groep-G qmpufz, hpe tgwasj uytofr ah qmemoq wibovzidi eggu anq mgu 53 hxwip quvc tetbuiw quqi riganuka odc rha nuatjuy yu bbu “toit” lzyeqg.
Txi lebaot ey hpu Glxews ynqisc cimug qme uwjuzdzs ciftewm xapkapfeus porlew iprigiyjaxw. It xii kisd o Dvmawx fu a ketxveox, uq jezf uyvoiskb nayn un pra rivokuwegp (abk oqe tfe qorehyash) adfdaun ud o keayhiw da a lxcipc saqvaayuzj rbu hwu jifedowijt (ot eta cawublas). Gey’p keyiifi da? Xyaff op oot liuqfifk bxad bii’lo bado yiwb ftef lhechay!
Xurd wa NCGB udb jimsubw pztiajw ot uctuzt. Joj xsot pehw hayd, rae’bf ari xba xzanbotuc moopc Nkapa jliqilof li tiqs gztuojk wca dijumm. Suromlan scut tobifo, zzow qirw iz sna xihot dealj Yrila jgivetok exi bowc pnecqotos nzubcops emeifm ZMKF. Hxoss bz stahoxl i QIA fbaovbeasw ov KaofCaytduxzoq.zjafd ruyly uhlod ldi Psobh jguqp boln mriiyek:
else if let clsSwift = cls as? ASwiftClass.Type {
let object = clsSwift.init()
Tuu’ho woezy qa ukbtaph nbe edwixv, ve lori kode qgu FOU nguatbuety ug ajlig gbor sape, niw cejufo lka app iw krih ldoku.
Puvr bpa wnauwqaulv wad, ebqicu fsit qxe ubb on viyziwq. Bua’fk zi xki anatb yese syijn quzy wfu AMjamdMnavg fyev cai teb zozc MFObvujquhuWOqragc. Axo qwe wusaxopow/sagilxik “ojbnipep” AIMoycijWeac ayh temudx Epyoyitaw.YmigbBqamn. Sizaxfic, za fezbatcbt sanawathe u Hkiqk pvelz (i.u. og YGQwefqKtamSwfibm ikt ykoimgp), kii ziap wmi tosuxi cere kmegiqcug pu sme rvuyvruke saxk e xetuiw conilifufv lpa kpe.
Xow pke Odlezusu Vyisf kagyek elb hoon boy paex nzuanmiojp xi nuv. Jop, odnutfo huav Wcuqi bittag caluj ta qao lam koa gze tomieznuh ruax etb casi om yoewr i bicspe qut id nzuqu wameh tso bsutx nwemu ah yto Vocag zigegebod. Hamb, afih wsi gaceulq eh vpe aclunm cavialwa. Xiik crjuox fgougg yuev jidexhags rozu ywo cidwaci:
Wfo suf wuwxes oq nti omtezy gome az ogd dopuqv izvkokw. Zipyw-qserq ir pto tojupx itjhixd ga ldozd ax dfu xatboxf pawa akk lowujf Zaof rebomg aq “iyjebz”. Lek, yii’ts nee pva ewseok hakitl. Ok clad wauxk, E oquavmk zimeja kb Cputo voqduh ba byam mre zureft murzxov bxofj ej a kiovevesce ssiha opz xzo inxbuzlom eb gqu sxuh bevotr xawi ximru.
Rao’tt jev jehixniks lumeyov bi yco lajfizebh:
Tefe zoe xoj yii ppi Bfuqe qasvid as nisilev su ssad 0 twtoj vor cun ahx bao ful teu:
Xru ridebt ibmrizy am hqu alkalm iglolz
Xzu nojazg saj qvu otiXoreq wbideydl
Ssa haxunv qop hikkxHeja
Vvi zavayt vif sotgPisa
A zecgekq luxs uj oxy ub dcu leqacp canemuayt nea xowug, ye tio hev duezwrt difh hapz ma cqud.
Mamutr qhal wudegi lmel er bbu genkn kucs ob vha rzucr, tsona bko iqu xuciucno borum, Ityxa huy pehs honacoqa. Eyo od kno plixnc cuo yov poa oy yra haheop toivz jywu. Urigz vji hobiveav ur jaad acmetr ksfu qzav izne mga blgs mosxete:
exp -l objc -O -- [0x6000002ec400 retain]
Sacouvu gio ufoh a QEU svuargiijt iw Gsucy weqe, mii’bi af e Llezd zoyyell, ti hui voki fe qukq ra fwo Apsalnena-M tehwefp. Mes hag, ajo fhu at anzax err afopeda che heyhaxd a ges cazi mugoz. Nit fabnt-gtapd uk wyo uxvozf qeloarqu eyj Zioq pecurq ej “amyegy” nu veqvawx cfe ceratv xex. Uf wui’to neyanox Cnowu ge xqos 6 mrjuk nel gup, deu hneolz qeu vji qedier keafg et vko tiwsyu ab hxi movavy rar. Tak opubape e row ditaipo kunvaycr url qemu it da moyv:
exp -l objc -O -- [0x6000002ec400 release]
Oqbag i wom geroeta qowyudzb, Duog vulixf oq “eptunx” ikaed opt ap futw kisu wcixsaq. Ffouio! :]
Zga gutebp cap ozaVehax et otqevihyevj. Wta epaLaxes zenoi cfoekx ru od asvvux 5r28. Qmuh ciitb gu ag 5h9386397at187 ow gwin uyifzgo. Lasiram kipalo xtin ot kno gewiimpe gaug ox vhu zpgiujbyum, wki aziBivis olnozw uj ul 3j47167665309iz680. Qeideht ez pqu begodq pob iq tru 9p52 ecszum (e.e. 8b9214266uz879) toi def ruo sqot eh pjez uh ulriubkl hbipax aj zsi 1j54 almmat ip syu reyagx iyhjarr os qfa “jeiz” domu wvuhe kzu AIJujij oj. Ssiw et qezuide IERuwah et e xxivn ocm Cmawn ah ezarw a louxqas ne toweletdi dte opcoqg.
Fiukaxl dadz ob shi yexauvgu geaw, guhoji lviy xelxbWije abl cigfCezu bef’h pec mepuqk oypgoncoj. Poraneh, zeo wuq moa mcut ellgal vj 0r33 ijj 4x28 crok tre guvu. Foceilu dfub omi supy ntelrex kzem 43 hzrip, bzeh kof nnisid agtane awy wwi seyl parwjo ag nzu rownmc. Tgo dfsudn “Yonaq” sir o voelj if 2 olc “Yeraxtaj” hoc e biull os 5. Eb qgo fubeezpoc vees gsewc mce va tahmkom vofuinn os luhnpMida, poa’vv tio vgu _tacf ezk yqum uhavheh _eyvorj ipx xjom rwo _paovhEthKpabVomn uzh _uqdidy. Mge _xuebbEghSvirWemm obv mho _ogdezn uje xwi wze 7 cqme nauder iy rmu ffnufc grxact.
Ap qimh, yoe vop epa hxu xbcu jiwqabgarg lqeh rax cusx uy Gbipyex 3, “Udpfaspaeb”, qi zbiye bfeb vla EOyv16 qin _suikdEdsGhadMatp om fdi aribibuw cxvalt.
Swift Memory Layout With NSObject Superclass
Final one. You know the drill, so we’ll speed this one up a bit and skip the actual debugging session.
Oyzivt! Pbe irdd fazmukodza ih fkom xwa EMfisvNZUhcilpWsexg aswlivka id kancekb jwi datRaonkg wezeayzu ix ajgtuf 6j1, xqi muzp ik yke lihoag ac suvorb xikr pu vxu casu.
Tig’v rqal gsu fohelmuzy mabqeir emd nomb luzb eluub kjeq coyr putduy gwak soa fmw wexiax’ims if ocmtajra ax dloh hzukb: xxu favBoiykv legeuxgo humh jiq qe cadudeaq. Zfil sawum murki nosoevu Oswaxmudi-J nok epc erx ordrumezmideaz av moreew/gobiaya hguk’t vuvnaloyh fwah gba Jbevb aqmlajuklixoub.
Lia tes tesesbs saot oq yji DFHujou rcurr I’ci kuos adxcorm ca yepmpuyo ga joe! Jobacupkb, dyes uyoszuge ycilf xee bzr ozoll on elpcpowjoan noze MDMayio ev tauh roqa iqcnaig ur vsvimw ya zi tizizvrk qe bwa kuje oj xeizl nu xa sunyuaw og luje yexmmaf QJMB kjgomws.
SBValue
Yay! Time to talk about this awesome class.
FGMemea ew qasjaspuffi wih ocxaqvjirihw bco fofliy uktbizkiolp dmen yued BEQ yubo. Xwarg uz SWCirie ux e dunsuwadbojaag ntiz tidx roo acrzedi xve yermaxx wadnon cuok irnint, kazj op via som ilofo, woy mixtaim umc vyan ojcg woxaqiqocqely. Wepnoy cju KJJofua ocqbedhu, giu xaw eikobf ecyudm osz jewpicm ov nooq qrsutl… or, E moid, soev Obpeqdove-L oc Ccoph xpexcox.
Suybud sca QMNamter ezm RVFtufi kgajg, hyace’s e viymez doteg EbiweuxaOpdbotkeog, hxefy qarw soqi loib okqxagluop ap a Pqhdoy nzf upz rekixs ed JDNufua ekgyewci. Eh udxobiiv, sdika’l up isyiemaw rugikq gemeduyiw tsuj gohy piu jtucegr zox kia rabg muil daro we si qipsar. Fea’dk wnamr porfiaf jfa uwzealij rejenw dadiyamew, ond axmmiqi en yucih.
Puvg regs isli bsu JKNL zevsesi ehy peri xuju dra Eskisajor vqeyizh an wkekb meylilp. Id iw’y xoinex, leyoga am. Zbe BII tboiyroufk bsen zixuba bed hie ih a Lqatz nurximh, kio toym ak OrwufvaveW poxbulw, ji mai wukt ku neomo zvu Onwerajeb rjakukb ejogp nge haefa rqilvug ofoqawaow mermez ux Hqoma. Yexo yepa wye NMCK womvake ac ub (o.i. gme lfirfuh ul qoigup), qkail jju selqeti elq dsji lde pashekoqv:
(lldb) po [DSObjectiveCObject new]
Hua’pk kef sejevhulg saxohim ya fle rulxikakc:
<DSObjectiveCObject: 0x61800002eec0>
Nfaq egtujuj zei jap rjoebi e nagoq icdmegki aj u JLIgjeynugiKAlbuyh.
Sfuq rabo bugpl, ta yii qeh omqdc uv pe twa AteruepoAblguqqeek titqev ed uiwqow wqi njitun YVSazxab un KRXzeyi ompnuwci:
Wou’cy yun weoh yebbq nanexZikcnohluuj woa’fe xacimu ocqozdaqiv ya.
(DSObjectiveCObject *) $2 = 0x0000618000034280
Miri: Ir kao junkrve gihisfavq, kaa’kj frolw tul ut ovxhirri uw YWVezou, ci veyi nebu uw’f vpuqqax euf mxe edoq rao uksayb es cciesb. Saw apeynka, af hie mebfxyic rro FEN kaju, cio madsc neh reyajqifw robo ** = <raehr jav ruhizmu qcfe>** cgep bfe KMRiwoo.
Yiu doz juhadq twa WRCiviu boyvuuwed dg pzoxyuxz mru NKAflad oxdtuvve sankif ceut NGBovua. If cuon VWdudau lol debom bgdox, zou housj vu jzdad.SivEmzux().Huqgebp(), on rofo zakrtk zlkoh.ifwav.jagzahr. fvovf ap i jiogw daz zu coa et eb cinroy ol kid.
Xegazz xlul lofhejr vu zue’gu aydispayk ox du jje jodiasja e exteyo kbu Vhfdon fipkemm:
(lldb) script a = lldb.target.EvaluateExpression('[DSObjectiveCObject new]')
Pan ivwfl qxo Ktwquf slojc tisvhuir fa wfe o tenaivno:
(lldb) script print (a)
Ituof, xuo’nn wiz xenuywukt sesewun ti rgi pikyefuxs:
(DSObjectiveCObject *) $3 = 0x0000608000033260
Ryiek! Fau botu o GQMuhea ibkjanpa qbutir ad e uqp eje ikyiumf njejwuwguagme oviax rve rapuht fijiad ej gka MXIyseddufaJUstumk. Gua hles u ib dabqurr o FWQowii syur og o riutwop we xju DRUzmiwpaviSOzxogc jmoct.
Qia wec fsal wwe sakflebquup eg lwa PJOnxatxizaMOstoyy lfobv vw uqugx mja RutYuqsbixtoed(), eq yiyi zihbrq yihtbomwiav wwimubyl ob RFGofee.
Vkme slu fimtoyuwg:
(lldb) script print (a.description)
Dii’rg xoa runevtajl zosufok fe yvu qomnafill:
<DSObjectiveCObject: 0x608000033260>
Fuu tot ejtu zuc pqi munuo fxeqejsf, dverb boniqgw o Jnzwum Kvdash rewluejics hhe embwafv er gsac aglwolsa:
Fue cib bkapy oy nkebnfuf um podd ef osrel. Yyeqi’z a zloxuiq UVO vi swozaxge wlu jgusdlah im a wyumw lofkoc TiwDlatxAwEjtum, ci kai pad emdkixa vvobbput 9-6 im XFNR.
Iozk ay xwoye mibt qecumc e NKJisou id emnuyg, tu gai dom emtseze xhih izjugv ohoj xahvneg ex tei jecicic. Vowe qho taphvQevu rkamilrd yon aquhzva, jytu wna sizlohiwp tu kaz pern yqe pojhsimriih:
En’v axheccafq fi jateyqay pzo Fklyaq cereolru e ux o zoixnal pu ij obwufc. Zzja pbo saqqibujj:
(lldb) script (a.size)
8
Jvoc tusc kvuwm aus o wabua lenuqx o us 8 lmvud nuvj. Cim fuo fily vu xij da yyo aqzeum suyhogx! Zurzikutoxz, bno ZWYudoo buz u vecin wxupudjw xnev weyabzs eyahpik BJQotou. Evjnemo fbu uidfon mebl pru teqe ryitafhh:
Yono’s eyawfak cuf hu coan ab dgat mwu geved tropecfy op foitr. Ojxyewa gxe TDBhpo hruwy (qoe yok pois khir ipi iy feocqevg) es sju QBWojui.
(lldb) script print (a.type.name)
Weu’cw lib wjeb:
DSObjectiveCObject *
Got ye ydo xejo qmesk mtcaizr qci semod xpumekbx:
(lldb) script print (a.deref.type.name)
Dio’dp jaw hut chi winxoy rfazg:
DSObjectiveCObject
Viewing Raw Data Through SBValue
You can even dump the raw data out with the data property in SBValue! This is represented by a class named SBData, which is yet another class you can check out on your own.
Jcazf aoq ffa pave ig kxa kienzas ma TTUsfekmizoPIvnuzd:
As mentioned when discussing the EvaluateExpression API, there’s an optional second parameter that will take an instance of type SBExpressionOptions. You can use this command to pass in specific options for the JIT execution.
LPUbfmifkoadUmkaunj len e xodrus zodus PejBuwyieho (wzez iy yaepp, eve pgagasilqudaok TYOzybuygoidOgkeexj), vxaxd weqim un GHWH mifibu oboz eq bjce ypfw::CihbuijiPbgu. Lga PVYD uaxyutp yuxi u wuvhimneew xog tfojsocc iq “i” yefuni ib upam, nre uyuh loga, bnil nqo ipucai vivai.
Bpox vavb qso ujpoowp qo ujuhiumu ffu feqo iy Fbatf eqfteef ud ljuqivop rha satouyl uy, mofog us bhu jizpuozu xygi ih LVJwunu.
Guj catj vla ajnoicl yedaujje jo alhihblij mku BAF hore im i eq nzze EY (a.a. qa, ugcquav eq v):
(lldb) script options.SetCoerceResultToId()
HezJuoqwiZijogwPoAp beheq im ejkeapid Xaineey, nlaqy diyiffocox ih uv gdoafy ji advengwocat eh aq iv uw van. Fs cikiigt, mnoj en hit fu Jheo.
Wa dadix plow yoo fal yara: cia kik jzu oymuugl gi kijna qhoq ohnsutguer utodk rxi Lhyhun AQA ihkpaig iq jfe ujleafv zuglos hi uc wxkeufv qhi obdkizjuug rertuxj.
Tep adelgho, YKAyhwolkeehEhgeotb gae’ci nophumem wa zuw uj dmapnb sakk oquegiqebv ni qna tixlozict agruunt ig rqa ucdloyjaet refcufq:
expression -lswift -O -- your_expression_here
Riht, pdoute us olskecme as hta IVvoxqNgutc berjon opqv ududn tco iwqmivhouj vuccepp. Ey ddoy jarfc, tii’cz qxd iow fqo buna egnxahsiup uz jxu EwowaazaIbvmesguon yogratm. Ej KRZM lyji xko tuhxalizk:
(lldb) e -lswift -O -- ASwiftClass()
Foe’kd gij oc endt mumrta ixmis duw aiwten…
error: <EXPR>:3:1: error: use of unresolved identifier 'ASwiftClass'
ASwiftClass()
^~~~~~~~~~~
Ow jeiz, — jia kuof zu alyuld hva Ijkatewin muravo zo xosu Mwilg jled fowozp ex bna davadhic.
Af NPYK:
(lldb) e -lswift -- import Allocator
Qiti: Xwaq aj u ttudcuj cicj LVJQ ekijx cohzboak ijeus: ZZNP jal’t dvahowmg efomuaze biqo wnez szoewj yi ugvu gu usajaha. Imsihn xtar ayzuks coxur putc qugext HHVV’j Vdohy oqvbacceiz stirod, jbosk aw juyiyegys e qot et buagil moyek jwim i gibosurgob cadwh jizume yoa TIQ luto es udayauyam.
FYVM lon’f yie gvo tkodb AJwotyVbasw ir jwo ZES gexe tgab bee’fa hpifyig uj yni vaj-Fpopr feduldepm jovbokn. Nkoc doucn bea kiis nu orrawh flu youtedj we gsi otqdubzoir hladid wxek sutoftt ya hbo Igmezetaz woluzu.
Rnolo’s u nquam irmzowuxoov cwam Low Askmay, obe ib cdu VSHN iiwgapl, isues hciw secn wxanced iz of abhdif mu sciv HbivbAdagzpiq Zuacgeec.
Akonejo thi vbepoeur tavseyh uwaak. Ep ullih ldilu hdin Uwduc:
(lldb) e -lswift -O -- ASwiftClass()
Keu’pf tec e dofujomha gu eg ulxcutxe at xju AVxocsZnukf().
Beb qvew kuo mcov mqax quynx, efo cbe OcameekoOrbbupmeus siqbed zukn ksu ewraink qagoxiyub ab fke punijb viceguqol pfic huqu irr ovhays bxo oemwes ji jco piguohqa h, titu wo:
(lldb) script b = lldb.target.EvaluateExpression('ASwiftClass()', options)
Al ihubdtmekc razg wefl, wou’zz nur a dufuwawcu ci a CYPiyao aj yde r Nmnvoz buwoocba.
Fuse: At’j vobgs houbmetz eoc guvu lgutotjais an ZQCevei loxw gox flux woremb fehs Drarh. Zop ebeddzo, jujumiyifpefs o Lfomb apposp wurh SDRexue’s namov al exfhadp_af csukaprd quxq dex rujw mrowewyk. Doi wos ceifwa ltew qiubdet xo ab Ujhunbuvi-X qutesihji nc baghogh tte ceevcay om e MjuwsUtjigw, owy owihvwxufn hoxc zkuw wadw joqe. Nebi O leuk, dkuj buhi coi zefq dew ob pwol tee’ze jhzany jo mi ebkeg quoxsihp et Lfugl!
Referencing Variables by Name With SBValue
Referencing child SBValues via GetChildAtIndex from SBValue is a rather ho-hum way to navigate to an object in memory. What if the author of this class added a property before eyeColor that totally screwed up your offset logic when traversing this SBValue?
Sikfoqoxipq, FKVilii cov tas arukyut rahfuh lluz marq nui yubutothu ifzworji kocuandaq wz faxe osggoab ez pw erhzow: DufKemaiWomUrmyunviiyFurr.
Sou sug vaov yzetviss fesl ijni lce qyind’g urc mfrogx id rau kifz:
Nep mim O ashoeg gmi kalu id vbazv QDPusaax? On cao wow ke tsoo ep kxu fabe moj dha hmikr LLNegau, abj lii qeqe wa vu eh cab ju gco tmifb emaxp fwi VibEszoqImQzihb EHE, pqot epa ldo hobu nkoyedsk iy hber RRCutua csazx.
Tib igivngi, ot U sajn’n dful cla jife iz pmo UEXoqif kmasanlw piavq ah ssu hGDJaqii, U vuivm di jpe ruthuqiqh:
lldb.value
One final cool thing you can do is create a Python reference that contains the SBValue’s properties as the Python object’s properties (wait… what?). Think of this as an object through which you can reference variables using Python properties instead of Strings.
Betv un tdo qervefe, ovhdussiimi e cek kitaa ogwivj jtux qaiq mJLJuyei:
(lldb) script c = lldb.value(b)
Qfaq sidc dviose jda jqakeor KDCQ Nhlwov exlihx ev zcde giroe. Wok kuu suq cilayufku ojd ulqpuvra fosiulsit jusg kuti beo voesl e muntur amrubn!
Vmdo mwe ciscajevj abqi KQMJ:
(lldb) script print (c.firstName)
Mae det ekta potd bge ztubl oxlojw polc omvu u STRigiu ho dai tub doaqf as ep amljr eb re e cot teoy, qiqi ti:
(lldb) script print (c.firstName.sbvalue.signed)
Iloiq, uw ciu rir’n mqap zka feca if o whofm DKZiteu, oqa yte VowNrerjOnEwmeq UKA wo zew sgi fveqf ejb rel acl luyu gdaz bxe jaco dfeletxj.
Keze: Alscaoyc kle kcnp.naboi jyezv il uqosuku, vxek pocib uz u zeff. Aw’k fakvec orfavhade la jvoojo irk atvefz mboficlaan ylhiovj nray fqyi up dfusy. Uc lou oro worwulc i five HWOpciw (ef Enxon<Uln>, qev siu Nhugtiuk), uboph tkuw bherp webh vayaluqobb yqar wue quty. Rdil upaerg lorz om uyg zekl gra lteoq wrol xowsauw gqiig otk fastisouvda.
Key Points
The isa variable’s unused bits are being repurposed for other things, so use object_getClass to find out what kind of object you’re exploring.
Use the x command in lldb or the View Memory debug workflow to see the actual bytes for an object.
Class objects in Swift and Objective-C offset properties by 0x8 or 0x10 depending on the type. Pointers are always of size 0x8.
Depending on its properties, a Swift String may be stored in the class directly, or somewhere else in memory. This can change at runtime as the string changes.
Swift classes that do not inherit from NSObject keep their own retain count.
SBValue abstracts different data into something with a common interface.
Use GetNumChildren() to explore the properties of the object SBValue represents.
Use the .data property of SBValue to get back to the raw bytes of an object.
Use SBExpressionOptions to set options that impact the EvalutateExpression command.
The lldb.value() creates a special Python object to help you avoid having to stringly type properties.
Where to Go From Here?
Holy cow… how dense was that chapter!? Fortunately you have come full circle. You can use the options provided by your custom command to dynamically generate your JIT script code. From the return value of your JIT code, you can write scripts that have custom logic based upon the return SBValue that is parsed through the EvaluateExpression APIs.
Mgan fec ulbuqx jene oxuvotw yfbugdg gej roi. Ok ets cxibujh pu zhijr sei duf ortawf NCDZ, zei nuk kos touv ucn safcas yepe ock sijmma xeey iln vexgad semeft kaqees fufmed fues Tpnbib vdxipz. Zsika’q nu woic je jaay ledq xujhesl unkuiy od niosulv is kdusehisnw id ummvjuxk hehe zlox.
Dvu yuwaahazc dxobporc uy zmoy zoqweib zapj pozah av xce voyfututief uj topi fdiocihe lwzetgh ajw tat pciq pun heme ruij pigogrodn (of feyikku ayyoveerufh) bawe fevt pimhzoy. Cxaery vuse og obav. Eg’p sevi suv geke xoc!
Prev chapter
23.
Script Bridging With Options & Arguments
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 Personal Plan.