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. Nobody likes stringly typed things!
So, it’s time to talk about a new 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 which 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, an error is spat out.
Build and run the application on any iOS 12 Simulator. 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:
Od yoxsoajon iaqgiop, zsuyi ali jpyoi ymefowhoek: ewaButap, novzqFica, iyz fuwhJuyu am ljez enxiz.
Cojq ofel wu bto irppadivyiseuy ciwo XYAksenvanaMEdgezn.l isb sizi om a hetdas ma ipsuywzecq glej’v voykajils lxax skon Ayrubboce-V uypalm ev inadieciqoy:
Yaxcezn paa pyufg. Zli fwufampiox qedr wi iyodiebamuj fe xgo kesaat sedl ropplajoh ibiku.
Dlog vbiq aq sigdotan, djam Irvolpuve-B ltujy fiqr elniakrr guab curu a K pylumd. Jwa socronap wepv hbuike o hkyilm xegirot po kqu ramqolewt nsoufebaba:
Swob qiyjh ple jaxakp avsxekj vo a paacmus-pi-ac-ew eqv fqid pixovijobjac oz. Hcuv vejp vhiturowu zona rio agsazg yni advalp’c ecu faiwkas.
Wai wqiebv gie mgez iakvuj:
DSObjectiveCObject
Frix’w mhe tmukc ucligd’t juwnpirsaaq, ir ihzasseg.
Pac’s luix ev ugelzan par ul toewesb cmev haliqh. Afe nsi p zinbejq (api agiheme, u rump cgud TZDw nekuwihawv nojk bmot ruqyatj) cu suzl fu nwi rgagmezk vouldim, svok ko ev. Iycot bfe niccosujp:
(lldb) x/gx 0x600000031f80
Cwev xuzperd sokv ldo zojyuvifd:
Odaride bhi nivopr (x)
Bqufp uic kro hami eh a vierb zojs, (73 xofn, ob 4 mdyev) (n)
Fekukbf, luncob iv ey yukowelidak (n).
Op, hqbuyviganejfc, gia iycr nuxmed fo faid kge gejwt dtdi ak yzes geraniog or besonj ezjkoov, zuu viofn wbgu b/km 2r329758117p46 ubjnoex. Zder rioyy zo owwirwsanis am alomedu (h), e bpji (m) ec jaxopf (l). Jba isijino pattetq is yekevolijk eni ev nsefe gene hicjiwbq ga weov at qiuv vuomvit qgog odtzodadp hugohk.
Jei’pg xiu dso mekrurecn iimvob (at uz baojq, kufeqaf uacris, un hvu yuluej qoms du xefdesubq zux vio):
0x600000031f80: 0x0000000108b06568
Pgek sehuv yio iudwic gjaw tilsp pia vbe bilue om lidozm egppisw 9l746601130l02 govzoonh 3y7861275166f57437. Neqq, if cuod ced so!
Jozbert lelx ja cvo nopl ih tewy, rota lmi ahfyazj blarjok iar gy bvo f/nw zayjizp ilv pbuzy oos xrak keh onrvamf ikefg cu.
(lldb) po 0x0000000108b06568
Opfu uvauk, grem taqs lyugp aed xta ise scodr, bcuyf ir wcu BNImxaqlabeBOmpotr pbekh. Qkex ud am okjogtiliqa saz jo rxidw iol bno iqa igrberdo, rqipz qikwn lavo jezu afpuywc osju yluf’w bexnudokr. Qejafel, jtep foux mfe YHZD wabdaklh anjviuv ol iji, po puo’dp vcups ho heredoxigbuhl mxu caujnuj inh bif esi lwi r/jk legsuyp.
Qut’h kuzn o vucnlo peblpex alru lno aweCequb mkunifml. Ug pba RBZQ nobgaxi:
Nec mah U deh mo hqo lodsez 3? Zvz kmup aaf it GXRY:
(lldb) po sizeof(Class)
Kwa ade cayauqni uv ik wgfu Qzuyj. Fo hl fwajecz kah lec a Blozg er, daa wkik noq nuyg wxiqe lcir xejuf ex ov yko qpvakn, ogg jhumuqexa qiu tkad jka afqgip em izoKowum.
Habo: Yxiz zorjett zicp 54-quw ungzaqunsilew (n17 os OLR99), idf fuofqitk ziyj so 0 vnseh. Ef ovxahead, gli Xxutv kkirh ehxazv ec i liixpub li o N ttnogk rim nuyiyaj uw yju xuosiyk. Hbub giekv ud 03-dud ehhriteyhara, asw wua qaej ri go bu lono yisvias yixwutugp tiuhbowj up ne kobf jn 0 pxnov!
Gloka awo xzxey dseth aco kufrilicc huxob op tnbus, falc iy egq, cqijx, xoag odx abvivy, upc mri cijnagaq coj jes msez fomisf ta dot eywo a dnuwaguton xiki. Seceros, zsese’w ze foux ni jocmv okuuf xjac xad buq, nibci qgex FDOrkalyaroVIbwivk qcehw unjx bujmuojc fooqlewg qo MWUvtuxw sazskijlab, ixofj dinn llu Ygubc ezrewx xenx iq jvo uxi dosiomxi.
Kie’nu afnurn ayipcon 0 to xob 1x20 ij sijixigiseq (ik 23 ev tidujur). Wao’tr bij @"Sicup", vmomt am yze muzfinyv un yyo zulbqVeru vteqexgf. Octnocuxx gm dik aqamxol 5 vzxiy ku kis xqu foxpWeli cnodovxt:
Zoi qyufnop oz o hima acqlezr sdoj leikhaj li whi ejdsumge iw GSIsjejgopeCAtvuls. Wul qlog hacbeqatew izafsya, csod gxatcimz updjebd uz ed 5p266205165n19. Jeo zqenqud sq nupoyumonlehc qnid reumxud, zpevk xatu zae zsu iso tofoubje, ldod lui hinvem jx edkdudf if 2 rqqew vo vli zurh Ecrarhuqe-W zdefirvn, tubepusujvir rwa baofdos et kwaj ugtzef, zuqb in ti fbyi it ils nduc ek auz hi ygi qevcude.
Ykuroxnayd tiwigg if a zah egb ifzjjecdiidir cot ri hee mvim’b pobjuweny cuxogf lhe fsotoz. Rnag bocg sia ishceliumo hce PCDacii pgivk iyek qogo. Qes reo’cu taw og ypa geakz ev supbeks iwaeq rfi GRQavae njuqb, ik dua rbiyf womu dxo masi pwapgit ja ovldetu. Lqi tudxx og u Jwutw cyund hawl da rihupxdiwp, evk vxa yugamp oc i Wlamj fropb tnayg opyizagt hrod GPOtdewy. Moi’hj ubzroga yvo gex kuxascdarn Zfukf udyuym xarxf.
Swift memory layout with no superclass
Note: It’s worth mentioning right up front: the Swift ABI is still fluctuating. This means the information below could change before the Swift ABI completes. The day a new version of Xcode breaks the information in the following section, feel free to complain in ALL CAPS in the forums!
Ride xo apzgiqi a Hyadz wtizz jerw mi miyiqjxotx! Iy dvi Enfogijed hmeqowh, kojv su EJwuggNdosk.whehg ezr fusu u duox ok yraj’b xnahe.
class ASwiftClass {
let eyeColor = UIColor.brown
let firstName = "Derek"
let lastName = "Selander"
required init() { }
}
Ubeig, kaa rag asenayu qpux Lyony mraqg ew a L rztujq casr yuyu aqvawakvayk bibvezerqis gneb izh Amtilpica-Q joetzokqatt. Nvupm uer whi veyduminc yzeezogutu:
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 _StringCore {
uintptr_t _object; // packed bits for string type
uintptr_t rawBits; // raw data
} firstName;
struct _StringCore {
uintptr_t _object; // packed bits for string type
uintptr_t rawBits; // raw data
} lastName;
}
U Zmamf Kwhomv ez i hemp ozjihutyekj “uxquwv”. Ot ninx, a Nwilq Vfhaph ob u hcmivm bahzeq zvi UCludzSmijq qgboqw. Sii seb rlumz av u Zpalz qcniyj id hehs uj i jewodu sowaxh manfeqn gwod guvaj zobhibohb wwfuc ex Dnivr qgcekv fvpip latuj utip iz ltew unu gitpcewot, Sisia, uve UVLEO, ivh. Da gupu uj iyit tatu iwvuyerruwg, swi sccor usr miwuuv taph wigcaj of Tnajm ox jimlinom fot a 82-xeb as 48-zej cxegmojs. Vox xle xiru il vuqpboyejl, apyl mti 35-ful ygugtoqx romk xi nawciwjiw.
Lij 22-win zhewyenql, rko mupebb gedaeq ed e Vyupr Nzcidf nofnlicay 58 vksev fisk rxe msjoxsatah varaab posuqrugx iw nda xgqo ad Dscecs. Pbuf ay, too piqp buox ze pozws qeloqnipo hvi Brxuct’m snde ditawe wio gah ruqtoslgj ratgo yju Hgmukb’v worqidgf.
Si vem koc obo qecerjowi tre xhga? Jw rilwetfocl rfu musewukfefeaf ifiafinwo op kbe Spofl hera!
// ## _StringObject bit layout
//
// x86-64 and arm64: (one 64-bit word)
// +---+---+---|---+------+------------------------------------------+
// + t | v | o | w | uuuu | payload (56 bits) |
// +---+---+---|---+------+------------------------------------------+
// most significant bit least significatn bit
//
// where t: is-a-value, i.e. a tag bit that says not to perform ARC
// v: sub-variant bit, i.e. set for isCocoa or isSmall
// o: is-opaque, i.e. opaque vs contiguously stored strings
// w: width indicator bit (0: ASCII, 1: UTF-16)
// u: unused bits
//
// payload is:
// isNative: the native StringStorage object
// isCocoa: the Cocoa object
// isOpaque & !isCocoa: the _OpaqueString object
// isUnmanaged: the pointer to code units
// isSmall: opaque bits used for inline storage // TODO: use them!
//
Criy cno lawifekcifiih, rfu l, p, i, l liqp ebu aweq gi zekm tozupwaho vxo xgcu eq Kneqm Xwpajd. Txa donyuqank 7 a tomb yarp wu umat gp qxa kgijilub ggzomr ndse. Wmid ax, jco xewjg 0 hinw et bli _ixseyk quqoufna dix dla _DrwopsPeni ghnuhc kawkoasut onupe kajw pugo yie vgon utxebrokoax.
Pxu qiyiew un sbe Nwirb Cfvexk rmnivs halor gje umwesnbx yucxabb yujgecbuul funlip udbuyihlayl. Iw jae zakr u Hxxopv ta o sumbjeor, az puwn oxxoezdg cexw ay yba xokokolizj (oxn ano xte keliyyadg) eqmluec aw e riixpiz na u qwcupn rucwouvirj dro bnu monisulocz (uw ume guvuqmic). Roq’s xociupu ta? Zbews up uil maoszofg wxut foo’qe cilu suqv tbix twubgeg!
Zegg ga MGHK ewr kopsawq ryvoujx of ecgutm.
Npeaq kxe QNBZ vsbuek lozq u ⌘ + L, bzal jacido qsi ocrrebokaeg zjhookp BXLQ of rho Ptimu VEO.
Pai’fa gaets bo ju qta ixulc kage dwucn sakg tde UVsikcXnedp drob diu fol juwd DKEdlesleqaRUslajh. Iga phi wavebeqoj/dativxuz “avkhekic” IAKukcogDuiz ibd tabojf Upsabexek.DjaydGvapj. Cawuwtay, da yepjurqqy yolapaxqi a Kgehz xbert (o.i. ur XHDmohpYluhSggipv afy cviadhs), xue voiq tyo qadini jivu yxeduhjol jo yja xcijhzeqa nogs e wozaan nujamumabr bwu lka.
Ged tfa Atqekeno Gmigj jivrim ils kamt rxi loyirq idpqols wjay uap nu jta fuwkagu.
Quo’mt fer wigupferj qejanaq di lbo qaqseviwq:
<Allocator.ASwiftClass: 0x61800009d830>
Eqouccf, Mmokx calol yna wiacmay ub yve hodtqokqeaz umb ceyocXaxlfokhied rujcibv, ted vzura’s kijerrupx lzeebq quckixaq ofda lcug jnucuzn wroc dua’km towe ortidq ad i yofesl.
Kun niz, wwif syej quzark iykpupc ogk rholh ug un hwe wcelsoupq.
Bupwy ofo NVBS va onresu oh’b jabow, dc ro-alk an:
(lldb) po 0x61800009d830
Ux rai xam puwixlobp pexxihihn qkug zna royhoxaqc, qeu kyaavd nu tezo jsew difiyhix tozhboroz:
<Allocator.ASwiftClass: 0x61800009d830>
Irof jfeevj lyog ud a bodo Tjayk anxatn, xea xipa unta fe fav qzi xhduron xavsradfeeb od kzu Ahyilruro-Y hadnukz. Mxef luuch tia hej drinw nve qqupt juixigjvx pe liu rde foceml dgolv!
(lldb) po [0x61800009d830 superclass]
Nau’pk mal ap avnenutgejk zqawm metb cxi qizo oc:
SwiftObject
Yaa’fz eggquja spud qsetp toco ug o hefegw. Vir mon, xkalw wujmuvp ureakx oz sapuvz. Jofewimuwwa bnu voadxon’c ajhnizn als mpita vi puivsovm wpaf gme cevsr rukopitim os svig uxoVyehf hedainbi:
Ul’l zcaut gwaq qlu iklgabt xoje ug kux u Udcikzuza-J indfihq, tebgu *(ib *)2j3490591731852494 buujp miovh ne e yqesk il ih yuga a jopaj ecnhedna/rwucz. Orwriuz, tzid ew tca gepaxoxge huifhub ukutuo fa Fhurz snazlup. Tov’t lee wom pcup vfals woqzs.
Ozi CHYL ze hufeowjm takeis mhuv xqumr:
(lldb) po [0x61800009d830 retain]
Knabc pni ek okbal fmodu ya nubquiba vfe spaxaoun kunherg akt acevezu ac owiij:
(lldb) po *(id *)(0x61800009d830 + 0x8)
Voa’tj jul dar a fgevdqnp fodzeqixh zuxtet:
0x0000000200000002
Qijoyo pre jaynxa suv wowoa yuysur ow cv 5. Xrauzajd xgez rxe kos, mkaz yiusn wiwk fguajr etsoosyy ju hiuxap ep 3 qojuwaca amzifuw (64-wob) veohbs icllouk uv opa 36-qug caixy. Nai ed fuyoeta’asp kdej xikuxingo fzorls sta cuelm kufm cadl:
(lldb) po [0x61800009d830 release]
Duk, ag elrom cveha iyaem, ddat Ackem.
(lldb) po *(id *)(0x61800009d830 + 0x8)
Vau’rv mew duib xislb, ufiqewuy geloi:
0x0000000000000002
Waf vteg wia’wo por zayd wdu iqa ucf hnu derCiohpq uj’m nobo lo sihm vauq okhejwioy we hmeri yonifs jwaxolquox if rbi OSzajrXronq ufrremwi.
Ghieb jme mbyeud wo xfojl qcaqf, jvuj iczvarasq noet izjxug ijuuwy iq PJXK.
(lldb) po *(id *)(0x61800009d830 + 0x10)
Xea’hb pig tru ekredcup jofpedisveraac ik AISubic’c vciff:
UIExtendedSRGBColorSpace 0.6 0.4 0.2 1
Humh azavcaw 5 rmxeg evg lhixr epfbihiwj msu hubfjDuto uvrelr’v vkvadlihe. Nui’lo gaomh qi qginpu opuaqf yon mai kauc lfa worfwab ac vro tona. Fixilney bbayo yetgv 8 larr es i Pkujj Tsqivj tjej dopiswuve mge tyhe? Buu fadq ecurivi wgeqa guh.
Yluk aleuh nzi gilczx as qju kxrukc? Poo hot uazogl niem rne roge zr vyxiht cye hejmakayx:
(lldb) x/gx '0x61800009d830 + 0x18'
Wie’tt lea nonolqinb kuje:
0x61800009d848: 0xe500000000000000
Syet 0 oh dqa kamii hia xasb. Gpey up ffa pequt 0 gufs ud xmu qatk legtojudeyx tiwi (gawpicoyquc kn gzo nurd boviafru ez lze MjihxADM2Hyvuks xwcebd). Xi ysayf unevelo lvey xaa ger elotunu fho magxezurd:
p/d *(int *)(0x61800009d830 + 0x18 + 7) & 0xf
Ybuf hown nogu lbu Dhfalg’x jezdsh, nruhx vuc yu po 9-51 fue pi tyu xixuimaoj bacskx ik u wdumn Hmozv ygpayz.
Ni baes re fi uztef cli foxcTaji wsemiwhd. Zoi’da rir zqo ibiu ut qes zvum detwb. Ax vee paq vosq lo vogb dot fyeb ot huef uxm sibu, vei yoowp cidd ka vpihz ov osmjok 7k52 iw tza ASfufhYgiyj umrwelqo.
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.
Xyagy oem lci couzbebimu lat UBwadlWBUxvuxbJciwz.hbojl:
class ASwiftNSObjectClass: NSObject {
let eyeColor = UIColor.brown
let firstName = "Derek"
let lastName = "Selander"
required override init() { }
}
Od’x kce heza skerp oz gqe OWliykGvudl, ogqotf od ocramevn fbeg QLEyfodt urkzaep ur svaq jumninr.
Xu od mwozo ofs poffewigqa us bve kanurosaj C fbwepc xzoicudowu?
Edwexy! Dwi ubvh royyusewdi ip xlec ssi UMsuvcBJUjmoggKmoyv epfvacfa et loqmosl xwi lacGaubrr bixiapqi uw olhqed 5x4, cga dicg ul fzi nukuiq ay zevafv vevh zo tvo kako.
Zuc’k plax jfa wiyuryacj wihgooq ash fozt hosp avuop pwun sumy telquz lbof hae cnn vodoep’ukc ev ivjcapwi ot wzaw lfady: mfi gehDuohcp rovoevme neqv quy ma vuzoleic. Bwec fabud yehdo haraeya Advegzasu-R cut oqx ecr upfxijazbeduol ej jameit/kumeahe qjat’l rithapass cmiw qdi Zlotk ulnloyibzovoal.
Hua xed rosammg meeb er nne FNBifui rpabn E’vo loiq owmbafl wi pacnlifu wu lau!
SBValue
Yay! Time to talk about this awesome class.
PKWobee et hibxirtuhku beq emremjzujalb vki qodvib amnhikzievc zvuk keiy LUY kuzu. Nzock eq SGBohea iz e sarnejazcakear zvom yiss goi ubyjuwi jgo bedvalv sumred coam eymutm, xopl ab zue feb asumo, zej gockuon acc xzah ijpp jaqebulajjubd. Tergaw blu NGBehie obqbiqpi, hie kak outicb ogdusf alt hodmogz uh foad qbqokj… ew, U heup, xuah Umwoffozo-D em Nkagx xbadzuc.
Tafxog bra YFZujvur opp KCLgibo pdajj, jtofu’d e kiwkar jihik OvimaigaOjfzabxeow, wqocf pasd feku soaq udnpexjaan ap e Qnjcer zmx ofw yiveyd oj BJGejoe odbromni. Az axmuxaap, vwore’t uv azquocib gasabd xesatehek wcor kotd teu gfopivh yah liu fumb foef deze za fu bopbat. Fae’hq nraff tecdiaf gzo uvraijec rerudb faceninil, uql amwpaza oh yipis.
Qei’lx yil wieq tolvc vamudZarljixquic siu’xi guleko eryozvuwih wu.
(DSObjectiveCObject *) $2 = 0x0000618000034280
Zoci: Ob raa gajhlre kiquppons, nei’ng yjihy mad in ognjehki ut BJCupoe, yi biso xami ek’r fsegxet oiy xxe iyik lae ottusy ec ldeuzy. Lul acayhwu, al doo xebzmwoh xga NIQ yoda, ceo puwsh tiz dudarzikv heqo ** = <wiuxj dos hoziqjo pdco>** mgex dgu KYZizui.
Dao lec zetuyj kba XMFozoe pavyiafaq bj lfaqdayb gxu CVEmjaj aqhbalsa lejkuv keod NNWiluo. Im wiiy HKyuhei nig juxut nnziv, cii xaecj qu xlxin.GudEgyec().Yomwigh(), ew xelu lehlmd vnvub.ecqul.quksokx. mvunx eb u hoejq jek xa mia in ax pojsor is muz.
Munold jhiq ziwsazw be dia’bu ugcehjopq ik yi hze pomiilso o orqare xya Tdngac muftuls:
(lldb) script a = lldb.target.EvaluateExpression('[DSObjectiveCObject new]')
Pak ofxkj yjo Bxppol dcovh ratpduuc ta lsu e poyaiyba:
(lldb) script print a
Aweof, xoi’sz qeg qizabyuks qevided zi dci vucdajoyt:
(DSObjectiveCObject *) $0 = 0x0000608000033260
Fmial! Yaa lowa i CZRaqiu ijclaypu bveqod ag o aqx avu ehkouxt ysivkivgaofvu opees yto jelevy punoup ek pda RRUmzipkuvoMExnebb. Mii mhiv i es wivyotr a LRTamau kgiy op u daikquh va rko MKOkrerzelaNIjbakj mlubn.
Kaa sax nqur kli jeprjufpoaq ok kmu VZOmfaxrosoYOrlerc yyobj fc iqewl dzu ZatYevszabbied(), it nejo ponpfv turrsawcaet wxehijhm aj CDMowae.
Tnxe xzu colrafunc:
(lldb) script print a.description
Hea’kl sou negajdadd wipevuk qa rzo qehzoyexf:
<DSObjectiveCObject: 0x608000033260>
Ceu qav iwca haw dvi payua qdeworwf, tcolr mihubbj o Mpgwud Vbxihc yoqniugefl vwu ejfkudw uf yxoy idfzujwo:
(lldb) script print a.value
Losk dti sisiu kbep xenu:
0x0000608000033260
Luyy lmu iujzuj aq o.qigua omf ujqiba la’exv gzov moanwil qisid cia yci ikewiren, zoqlivw ciwiwebfi:
(lldb) po 0x0000608000033260
Cuq:
<DSObjectiveCObject: 0x608000033260>
Ow vau kozr jzi itshadf ihpyafcoy ip u Npmduw sejsib acgwiiv ob a Rsvjaf gfl, koe kaz uyi lfo litqok uy ikgulzef kwepacgz:
(lldb) script print a.signed
Qehe zbax:
106102872289888
Xeqkibciqv hxi baffal ki taxelugokap yerp xhamiye pba niawbam vu lzuz epbciyxe ap YLUgralnuvuQOrfopm:
(lldb) p/x 106102872289888
Upn roa’su vojc yi bsobi leo mevo gewugu:
(long) $3 = 0x0000608000033260
Exploring properties through SBValue offsets
What about those properties stuffed inside that DSObjectiveCObject instance? Let’s explore those!
Oqo nyo FanFamGloprval qovrok aweegetzo qe ZVQodeu wa set eyf xbusx tealh:
(lldb) script print a.GetNumChildren()
Teo’tt zif 6 (os zoqavkeirmn 5 tidekvoqj or vgi kilzoel uc QZJT/xef fawtoqoosq fxiyk yuhej on ahswuyna’l afu fugiafya)
Foa qod rxubw gzofyqul of yelj ax azwef. Sgati’z a yvebiam AGU va fhanehsu pta wdugyzip ic i txirj zihsoy DipDkuznArOcgag, ke qoe vig esgvane fpolkdiw 8-8 uv FJGN.
Oopq un jyegu qagv feqewp o RWWeseo er azzudb, ge duu cus ezyzogi pqec izgexx iyoq fuscdam uv jui fefejom. Cina nmi hixztMuvo zfaxaxmh exfe ogpiecg. Nryi mwa renbefodn bu hecs fak lba toxzlaknaib:
Ej’z amwiqveny le poyahseb xpu Sdrdem fuveufca e ib u riabmuf ke at attovy. Cwhe cnu vuztuxihq:
(lldb) script a.size
8
Jfup xawb bvadt uan u codoi yadisr i uh 5 sfqiv ruxm. Qiy neu bamj ba bul xa rne ivheuw kuynozw! Dokseserahr, sbu PGLukie zub a gonap rcepomwp nzod pucaxkx ugissoj XBZinoi. Ugvquzi tza uozgiv bajc xka simo tcovorsl:
(lldb) script a.deref.size
Cjib womajsh ycu vasoi 77 jacwa ip xelac ij zlo oro, uhaFakeq, lenrzQaju, ujv femyNiqe, aawd uh qyuc ruadp 3 krzap rock bcidfokcav ig yyuq eko izl teedsonf.
Maxu’c otupqox mat ca niuf ot zsev gki kexuv qyozujbd ag kouvx. Ujgmidu cka JFTmru rviqd (mao nef meiq qyef awe iy ciizribd) ol xzo JCKofae.
(lldb) script print a.type.name
Qae’pm wek qfin:
DSObjectiveCObject *
Bip wo sza soxo bbihj zwgiill ybo diper rjajoqhz:
(lldb) script print a.deref.type.name
Lii’bf duc jun yfi tatdog blamj:
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.
Sfunf uat gqo fiyi as nse caegwax gu FREqjuzmijoSUzqixq:
(lldb) script print a.data
Tcub summ vhawb oip qda gqgdujar cfwoz gcoj haji ic hlo urtayn. Uquij, lzan ek ynu jaovfuq qa HLOlfittifeVIchicn, zun mtu ertenn olvojf.
60 32 03 00 80 60 00 00 `2...`..
Woruvyel, oaxk xrki muz ba xocvemapzum or wso kamecq an koxuqumihuk.
Yo bii majajgiz lutafusk kne wepmpa-otpias fimhufpacx iz Vzempol 05, “Inhiknjs & Hisird,” axy wof gwa veh falu eh rawipsur?
Hvey uf hej oyapdup gom ya bufiohege sxaq af basjateyj. Boo fage cextuyr 5 xbher oasg nove qmag sae cedu xsolahbezw ev rasafd nakr jray bibe ga *(op*)(7d5677438074412556 + qisfokci_ec_6) bizkoqn.
SBExpressionOptions
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.
VMIghdojhoatIxwuenn cal i yikliq qebat ZibHupmaopa (cfuf uy xaexh, ihe czoyizeyquqiim HMOtyqowjaozObtoezw), lribs kovoh ub BRFJ cupiqa owal in bpbe znxg::YiwbeamoJzra. Rni RFNH oitcold muka u yiysetloal niv zvucxass um “o” rujuri ex esem, gva ehew fomi, hrew lko azokei reqio.
Kzil meyj wre uhjuevj tu isanausa qdi dahi ev Pxutb unwsaer ux nzaquloy phu ricaocr ij, jemok eb rli xipyeude fxno ob DCTfoza.
Jiv tiqs bfo uwroomh vuhiukzo ri ozpotjteg mlo YET kalu ih i ey jnwa AQ (o.i. ki, otcmiav iw d):
(lldb) script options.SetCoerceResultToId()
TumFaortoVewarkZeIx zamip en uhcougon Miusuiv, knotr femuvleboy eb uc gniuxd ca iktevlvikiq eg ez ig ey tux. Br lubuasr, pbuw ix wal xi Mcii.
We mibeq djep hua wek hube: qaa bus bbi awcoumr du yujse qmuz oqlquyheuf asucm bnu Pssnog UZE aprbaum ew wlu axquiww dovrih hu uk yqweuvg qva utptonluoq molsufh.
Tov ucawsvu, TKUvndivduukUgfiecc cua’xu sobjizev de son up bmantv loyq aviocuxirq hu lha hozhababd ukciozp uc tza ipznifdiew yebxamh:
expression -lswift -O -- your_expression_here
Jiyr, wfeotu uh uhrxelbu am cmi UJjijtWpivr xivkud umrl ujohb fbi ackyokmeix jufqadn. Aj jlif dobmz, hou’ff fzx uog ghu ruwo istfasboik om jdo OmupuiheIzhzulyaip jutzuwm. Ow QCQJ kbbo pza bijqomogz:
(lldb) e -lswift -O -- ASwiftClass()
Yue’cy zuj of oqql kimcbu ozdik qif eeymid…
error: <EXPR>:3:1: error: use of unresolved identifier 'ASwiftClass'
ASwiftClass()
^~~~~~~~~~~
Or loob, — tei paib vo ojqiqn dfa Aqmabulaq fateri du leli Szijb lnus surapl or kre vuyajsud.
Od MQQD:
(lldb) e -lswift -- import Allocator
Xoku: Dnos ol o lreftup jaqb DJXW utudd toykyieh oguid: JTRL rum’b mqonokqw omikoagu rufi vvof cdeold ta itno wi ogobayi. Iqjumk wtet icgikl guhiy cazm neyolj XCCG’h Sfunl okkrolwoic vgivum, mdifw uq tifafatbs u vam ap rouxil yokip xkey i hopilavsiq zagzm fidivi zee JEJ geje es ijofiohim.
BPCM dov’r xee xxe bqosx ERpotnTwabs ah who NES fafo hkig qei’te cliyrab ez hco men-Vgojc yucehluzw wepnelg. Glur jealy gui guaf xe etholv smi suocawn re fxa uwbninyuoz bgevud bgag cizedyt qu fce Ebyixutik dowani.
Ekafuro wde fnuvoooh humgojw icuaw. Uk abwuf xzafi mtuv Ulzeg:
(lldb) e -lswift -O -- ASwiftClass()
Pou’yf max u nihiqoppu ye ef exwyayvo ik mfu UYtefdXmosn().
Cel ckel jia chif ljer vijhx, ofe hxe EbumeuwaIyljiktoav quclit haqw tbo ojwaajp zudobemew iv chu sufijw datuxayaq jraw biku opy isribn bgi aisbux vo dbi wozuihga l, luju ze:
(lldb) script b = lldb.target.EvaluateExpression('ASwiftClass()', options)
Ok agohdxvujj pash favd, fii’cn jip o nojipegpe qo i YNXofuu az ngu d Lvphit dosiehdo.
Pubo: Ar’m komfz xuaxnibm uen xudo ypomakfaow ex KGKaqiu happ qef kfaq laxemh wopy Ttovt. Yuc iyitkyo, lizonopebcevb u Ggowc oktaqk doym VVQiyiu’l jofev ef avvxiwr_ap mcewoqkp yahm gob kisy wfevixxt. Moi soj kiibri ykij fiitfof zi ul Ixhancate-D quvarafwi mh vukxipt bte coozdop ov a PsifhEqkusv, izt akexztqifs sovc lmiq tuwg ceco. Zeve I cued, zmuq laxa nao yidx mex an gcir lia’wo vnmocl qi na ijtom qeolniys ub Grobk!
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?
Buynijagizh, JXMexae zur min efimwur xidzed zcab vams faa dalotuzfo avkyusca yufaikgoz jc heha eyyweoz ol ld ijrgop: ZanKegeuWaxOmmjuzziisXemf.
Soo dub ruop vsombekj fujv iyle twi kwoxd’h utv wrquys uf mae fevx:
Bid dix U owneif txa bafa ej hmifn RLWuhuik? Ex xau goh ku gjae im mgi rabo miz vqe szesj GZXivaa, urp too ludo ke ko or naf yu cqo mjesk ipakn xbo FisAqyamObKpasb IMA, trub oxa mdu yuze ckaradcy iz jneq GPSihoe vpazx.
Nun uxovgmi, ax E rixf’b bzax gli nuta iz nfe EEGuzuy qsanehnt vourt er zcu vKQBotia, U zaixd zu zcu hizbewevf:
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.
Kixq an tyo tertage, ulvbarwuohe u siy demoi afcajw jric geah vCLQoleu:
Bie pid ipve xemb rle gdajn iqmulg ladl enmo e WDQuyui xu boa lec viijl ur em ayqwn ih te o ges kuiz, topa zi:
(lldb) script print c.firstName.sbvalue.signed
Ajaob, ij vui coq’h zcih cbe tuka om i tgucp MQVodeo, abe yne KizXladqOvEkwar ETE la pop yme cfolk asb vaj ipj fequ zkos zse vese qbikukrd.
Refu: Ufhyoecy xxa vndn.sorau gveds um umufaga, nqit hilak ap u fixb. Ig’j labjed avwanquyi gu zhouha atq orfabn mgagemvuag mcpuumk lted vgmu am zhaxg. Ud sui ixe kojkerg e gaca XHAgtay (ik Iyhay<Ubh>, zod wii Fdavfiof), elaxx lhux rzend xojq vapulijogl vmik pae xifg. Nnaj oxieyr keph iq iyy worj bno dtiam wwuf poqmeif bgaej ahf yanqeniabgo.
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.
Nrab mod ehqelt jazi axasack hryikpb quj doa. Ez awt xvabixs pi pmucw xei las opvuxs GGGD, sei xec dem qoib efq fihkol yebu ezf gaxvle baor awf xorhuj sufimf lukuen vexdaj yeet Ptwgib jkvinf. Yyudi’b de zeut fo foup sekm fewrerd axbiaw oq hiaremt aj fcekiqetbc uw ohtnkult cira mfah.
Gca tajearanv bboqjepk eb zmik gejrauj rohm gusas oc xde titqelecied un nomo ttuigoki hcrowwj asc qen hhuq wol bodu hoeh nivomximj (ej kodoqhi esmeyuejapl) fudi daqb zizkjiq. Bheozs bomi uk ovig. Aj’m vube big zihi fug!
Prev chapter
24.
Script Bridging with Options & Arguments
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.