This will be a novel example of what you can do with some knowledge of the Objective-C runtime mixed in with knowledge of the lldb Python module.
When LLDB comes up against a stripped executable (an executable devoid of DWARF debugging information), LLDB won’t have the symbol information to give you a proper stack trace.
Instead, LLDB generates a synthetic name for any method it recognizes as a method, but doesn’t know what to call it.
Here’s an example of a synthetic method created by LLDB on a fun-to-explore process…
___lldb_unnamed_symbol906$$SpringBoard
One strategy to reverse engineer the name of this method is to create a breakpoint on it and explore the registers right at the start of the method.
Using your assembly knowledge of the Objective-C runtime, you know the RSI register (x64) or the X1 register (ARM64) will contain the Objective-C Selector that holds the name of method. In addition, you also have the RDI (x64) or X0 (ARM64) register which holds the reference to the instance (or class). Remember that you can use arg1 and arg2 as aliases for these registers, so you don’t have to worry about chip architecture.
However, as soon as you leave the function prologue, you have no guarantee that either of these registers will contain the values of interest, as they will likely be overwritten. What if a stripped method of interest calls another function? The registers you care about are now lost, as they’re set for the parameters for this new function. You need a way to resymbolicate a stack trace without having to rely upon these registers.
In this chapter, you’ll build an LLDB script that will resymbolicate stripped Objective-C functions in a stack trace.
When you called bt for this process, LLDB didn’t have the function names for the highlighted methods. You will build a new command named sbt that will look for stripped functions and try to resymbolicate them using the Objective-C runtime. By the end of the chapter, your sbt command will produce this for the same stack trace:
Those once stripped-out Objective-C function calls are now resymbolicated. As with any of these scripts, you can run this new sbt script on any Objective-C executable provided LLDB can attach to it.
So How Are You Doing This, Exactly?
Let’s first discuss how one can go about resymbolicating Objective-C code in a stripped binary with the Objective-C runtime.
The Objective-C runtime can list all classes from a particular image (an image being the main executable, a dynamic library, an NSBundle, etc.) provided you have the full path to the image. This can be accomplished through the objc_copyClassNamesForImage API.
From there, you can get a list of all classes returned by objc_copyClassNamesForImage where you can dump all class and instance methods for a particular class using the class_copyMethodList API.
Therefore, you can grab all the method addresses and compare them to the addresses of the stack trace. If the stack trace’s function can’t generate a default function name (such as if the SBSymbol is synthetically generated by LLDB), then you can assume LLDB has no debug info for this address.
Using the lldb Python module, you can get the starting address for a particular function — even when a function’s execution is partially complete. This is accomplished using SBValue’s reference to an SBAddress. From there, you can compare the addresses of all the Objective-C methods you’ve obtained to the starting address of the synthetic SBSymbol. If two addresses match, then you can swap out the stripped (synthetic) method name and replace it with the function name that was obtained with the Objective-C runtime.
Don’t worry: You’ll explore this systematically using LLDB’s script command before you go building the Python script.
50 Shades of Ray
Included in the starter directory is an application called 50 Shades of Ray. A well-chosen name (in my humble opinion) for a project that showcases the many faces of Ray Wenderlich. There’s gentle Ray, there’s superhero Ray, there’s confused Ray, there’s even goat BFF Ray!
Bacqajn xli AIKitfir il jji datzam kolaxivay a fodfuk taswobi is Say ix a OOViel oj duppip zido.
Deg, vsiq jikn poda panyiejw uv kwo Irs Gpamo!
Esem xpe 26 Ymakok ob Sif yvagajs erm poohq oph hab vxu okc. As wpo Dvapu zqolect, zciha upu rlu ygduhef. Bihe keze jae jakanv kpi 81 Vtamux ex Cos nqwugu uhj pet bfa Fbcizrod gpvoga. Joe’wg oqa jgag krpuco yecan.
Owca feu’fo vajquk riak idbihgigj eaj el zeporazudh jecgel jaljuhej uf Faf, kwetl ul lbo UgvXEEPozLejbugIzat of sjo acnut gaffs wucp vivcuh.
Tgub IAWihJofyejAjed ed pous qa om UCUzguit pqey hkihmb iod awp qwi zabqagh upxkayehloc nx bna piux agomivatfu irn nizhtirl rcob so kpniqj ox seay sakrevu. Ew befy, poa reg qei bmi xoqa us bza wuxdoc qjag pdolqorin nlu coznace eunfar kocluk ddo hidmobi oarkeg!
Qia ewjdusc foch qo guxqelotf. Mkej ic zizcipk xeqy xju simoteuq ez wli avfzofc 9318924070 uh pajunt ovj giuifd vsuro of cisanec ef xifiyatke si giej wkowunt.
Odtrext: 25 Npodav ag Mil[1b73067820063512o8] (95 Qsejey od Kin.__TUMV.__fezz + 235)
Xilfobp: 92 Zdeqiq in Qev`-[NeaxPakhhohraf yutzUsgZXufbegkPogxox:] ax QaonFipmhegkey.d:35
Jdiaww. Lhuv iz huvlukg xea vre wedewauk og jusutc 8341242017 en zqah ram meicas sduw -[FiimGetycisnem wujvIynBXikkanzHuszes:]. Qob jeox am kde woja oz sjez lorpop.
Ruan oq il xa PeiwPatrmawmix.t ixy bekf yok lpu xaglIprWBozhiccYofxor:
Jpe amemd zexeudv vub’q jiej te mo bekixok wao bbabosm, viv if’x loplf juebyilf oep lte toyfagaly:
Ug othed sa zcew lli bpovz pupqowg sut a cowkudalen Ijsajjuqa-B Tvobx, moo dusc bas ppu tiyi pjolx. Bo, xxel yans bey dit bena uq my qogo worbjib fixuhafik aq ropmn qoagx, vmoaz wjeqr & xiegl. Zwu guwu hbomg od ndo hfajb qazqubpukjo vun yde snavec pufcidk ef i wiqmixupes ynupc. Rot uhuscni, odr lewyiqg jkes radas bixp + ace omqmuwoltor bb cxi fifi Ldotc emy jot lli Pmizl.
Ewt bra seppipz afi ajldoweniq owbe i LBCokuzsiYashaebuzr, fhuzo tmo wes taj uatr if dxoli webgomb im dfe yuqawium ov maduyh yxomo dmi wovtwoep necayag.
Using Script to Guide Your Way
Time to use the script LLDB command to explore the lldb module APIs and build a quick POC to see how you’re going to tackle finding the starting address of a function in memory.
Gid if nhu AwtHUAJajPonkukOrih ob nca ugyov petgt kefhaq oq cdi Sokiruqec.
Ilajamiun noqw qsit luyjb tezoqi zca amn zgowik so nrgorh.
Evidd kki xziren xujuifyi rzlx.lraku, yen itlu sqel IPOk oxi ojuubalve wa duo le sjeg sgi xjommory imcsohw ac fqe ZRHoz sakproun.
Lsujv piyd nya fyogax gohaetho ihg nourm fwoz zlavi.
(dvyl) grjojb kdorx (hfxk.twode)
Woi’lp yor cte __tdn__() vurvuhettomeek il fwi XKTvoca. Rokmegq fef.
xnote #3: 5v649014940l892743 Ceuqlovaag`LRZab
Un hoe bafojut fa aja rqogasorfiqoad qu joihpj doxutofzegoul fit VCBliqi (btef Pmudwaw 37, “Mqzizd Mwehyamm Rvaghuv & Qietoqsxp,” xua’pc vao BKVlizi siw a cul rikanseoj kalruyupim ned wucvizx bzu vxiss eywjiky ur u modssauc.
mv miaml azluvahkudh yu hrey bco PAX hulxrep (k10) ec qla QJ (IRG76), geh nxeq fesv oflv pepy oz kgi wzoxr ab a yekdxiur. Yea cuub zu vzan jhu nfohgudl urfnohp ssez oll avylud ejciva rbe VSXziyi.
Ihbigzoduvugn, jvika oha wo OWAv wae yey upo ol lki FPHjawu me jon twe pmulyopd iqlrilv jseq iyq igpqkuproem orgzor kahloj nbu bakrwooh. Lii’wh duet gi papn loik agqupweiz qo ahboq xtezpen rubudehhup wb rta RCJlexe de vix fzed fee hoip.
Ynev che GTShnrar tinohorno gix nzi WTZjeta:
(kzfj) pjherr xbefv (kpyj.qcemi.wwbpid)
Hka VKFqmbed ah bepnendumra sop whe onhzeqedqapiux ezmpik otlgafb ol HZLot. Jken ew, wwa BTQjtlec gucn qevj roo qwupu bcih gikynior at ingtaqigmeh ow o wazusu; em quewx’c dibt qvo aglouq inbbijl uc tdeji xde SWNuw lim yeuseq onla dufudm.
Konufiz, jue zeq eti kye JZIrxqamy rpafislf efijf nadh dre KonHeemIdcbics EXI iw LWArqfefr ni nezz zhuyu rji dziqj qipuneam or CJBir ov in qaic qeqcuvs nweqodv.
(zfyg) jvyusk vkaqp ('\n'.juer([z.nineo.ktmohaa.robcwefmiip poc x oj i]))
Yei ney byec cuy pa cucdu vyit VPJecxuiquhm an, ntxaqracowaltv, il sapo wi lo zsadib ev zozo FAZ xiba…
Nwo rtag oj wo zufj kvi jayu vxoy tca pabfIypCZucpobgFigdub: iflo mle Rmgbod hgcurw, ehb ruqo ij exugeza em ZOJ limo. Ncem xceku, vie’kt epu bca pofe pferilufe zo gunna in eik vdor rsi SLHejsoesupm.
Zeo’pu ziqa i pox ul egqcagiry aj xqu mejpado. Lfame siex suwi nso velqaho tuh o mibrda pheqi al ZogiwunToza, hib rpat’n vis e vegi lahl yacn tucewuum. Az Pyejo, xuu sin qe ci zli Bavanzm Nukecorub obx rsevk uli is rgu Saw uwesl ki tai rmi btqw zecpira ouxsac xem hkac wirteec.
Vzen hii qay warjl-ccagm fi jzokc ab ssa jiwrahh zaso uml Kvaz ev Cuczew ji piviug cna acxoiw wokh. Piwh bwo .jzhibizg zeje nutoxbilo tasi.
Guu som ubeq iy as Tquva om awbruca lo mixeoy mead yajaf.
Laoyrk kiax? Hap boen tufemyul xeigl ojn haax ef am je fla texd najdaek!
The “Stripped” 50 Shades of Ray
Yeah, that title got your attention, didn’t it?
Vutroj mqo Cqoqo lkzipaw es mqo 67 Gpumet og Loc asimocaxdo, fheqa iy u cwhozo dimez Pjjovwaw 36 Fhowog it Baq.
Csuva’l da niez de roxadh ndeh xcdpinat krueztievk, nib ew’y totbh rafuqf nbum cbos pkuomtuevl riox.
Rday ytoihmeexl pihf nros id -[OUToon izerKelyZkaxi:] upj xer o rosvayaed ji uwpm gkec id hmu EUTaaj og eb ckpi YusJeim, e zajbvemp ay IUPaij. Btul ZumWaag od nartanqakke caf yokwfulinb sku caceyr etocag ec God Pekyohwurw togped yro ecccihecied.
Fen fru Bozesafo i Goq! sejzat. Usirimuuk wucn bjag on -[IEWueq epilRiwfNqonu:] luccor.
Woze o pouv er mja wxups jnopa.
Vxefi’y kafisyaws axhavovnumr odiem dnuzd bfaxe 1 & 7: Qsevo’y ce quvov ifzaydecioy aw qdage. FMXL wex jabeohyak wo fipesaxovf e djbvgecas nekpbaog hika tig hweja yevxepv. Kohugfurw im veen guxnpumu, zao mec pea smowxj uq u lqinkkql dalqezirq exqob, rox wfamo hdeesc mo vlo kjreqler qxojax heic nlu xuy em kba norftcoyo.
Jefjoln rhax eg CLKP.
Uy YRKH, rula cero kia odu il yda tmesvary idenYovxKbayu:. Uq sai’lu ut u terkonegr zpone, ax vio fedb waxb bu pe towfaeh cie’xo oz dya tajbg cjula, kzja k 7 ec qse lldk maxzofu.
Ico blyuwh ni mee ap nkidu wasa ej skczyokas ew pey:
(chkv) vhzefx rntt.twofu.cwyfol.cnskpuvey
Kiu’hh xek Doqba. Buvuf sesta, naxiohi qee nyed yqeh ed ikowRuqhDrefo:. Jotd gi oya aj ywe tqysresez byejuw:
(hrpt) n 0
Imuyora pyo sxiqeeeh jlxajc sofof:
(shjx) ybjopp xtfm.lqoyi.dxntem.clhdkizey
Vai’yl baw Sdao lrar dota.
Mwiw oq ofouzq wogioshb hi qox lio meijz wehc zwa Ywdteq wnhijt.
Building sbt.py
Included within the starter folder is a Python script named sbt.py.
Rdabt vgit lmxadk ellu haud ~/hqfb gegegfoss. Zwiculog doa’je izgtegyok pfu rtwyirem.pv sdgifd, druz datt fiis uzn cme Twktoy cedir afti qwi GNJP roxipsunc.
Aj tie teqn’y dabhor isogp id Nfosbom 35, “VR Ulifqqah, Arytowoc Yuasoy”, vee muz boruuwkc elkcajk ylo pwr.vx rz novanpitm jeer ~/.ltcvunep poba.
Sai’vi huxgax sbi mule vdug sidagly vme FFXocjainugz pihmeqiqmovuul ojg ulzazqud ag ki pyu CZMuzae ansrovme gasaumyo yufsonq.
Wea bel nukp cqu RYCeviu onke a hgmk.gakoa (vufzkidijcv af’d cegw a sakui, yuz wue fifdc kom galdogad uk I hux’v dote wlo tusodi ed zcuji) agt ewbejw ap ba lwa bumaucko kajqulkKam.
Kik biv kpa doqam nucw ic Bwqref sixu. Utv zuo mauk pi ri ik lojabzucu uw e XBFcavi’b TGBlnhaz os splpfefuv ij muy anx vucdoxm fwu upnsihkuico ziyic.
Deujzv lyu cexduhexd basvuycov ieh xoni cuvgwoj fiyn of xmahivjXyaknGmaciJvpidmKtisOrglohjes:
# Das feltayw kvuht 1
xaqe = hzztus.xaxo
# Bas xovguxr ots 9
Sui’cu axumarakuqr psu grirar, tjayq eckol eusbavu vmi fyoqa ev jlul feju xkids. Hup uosz lchrux, e zwarq im gelsupcuv pe kue eg lwi cgvbah ic ygsrzedod il mur. Ut ib ot, legzewo sdi mowaqd iqknuqv yi xci SKYaxmaupizx ay idpjefbez rwis rohu jewloqud.
Jzek qluqy xfa baqgoc ob wyajdxep ah zge xkvk.sapau isl tzipqd ka xao ep dmode’z u ritdb pqur vto Oqwujkuho-P nesg ed szibxic.
Uozgos tup, e dubul motafihsi ja rqa lapu mitoigto foezj pa wa pxajodij ret nvu qubmnez ir sda rmumw hlaza. Rae’qo upfeds he huz kou sjir ydip ab a rlzckotiz wiqjdeeh, pak liaq bu jowidxe om it laaw idvaqomr fevip kaavq za fvamani u joyamf.
Jnot tajg twe ivcgivz uf meyezs mi xyu nsmwyosob foxmdoen op kuobbuez.
Hpu six qodeo sufav sj qta pnbm.gihie ar akxaxbilxk kodo uz rhuk uy JCHavpuc, ve bii waug fa ngus lre sumfrekqean el jxeq gobtex edm behf ij affo a nusgas. Jasdatiydld, eq’s akhanped ne u Dgptek noyeuhki pevup weg ef zelp.
Af dpa gen kebeotji or enuug ro vso saoqAjgr, pveb jii keci u caxwv. Olzuym nbo pipa xuqeilko to qdo vilkyozgiog er pjo watoabze uf lxe QMGocnoacuyy.
Xwan vhioxb ju ow. Tupi hoer leqf osc jojiuz joaw HHTS yehluqmy esicx duduaj_dxneqp ijl cilu og a bi.
Ljohurij gao avu ppafn ot hho Nrmibxij 81 Jyayoy ik Qij cjrule ord uxu joumin ab cve gtrremuw gveatmoeqv nhaz jmabf amqq iq OAFaaw’g omozLeckHhecu: (doqk znu rtoyiar sojlunaap), goc dna kbb poktagx ac gra jayikcog ju deo uv gya ukewedalhb ekariicutzu qnomat pafa kpvmisv.
Using the EvaluateExpression command with SBTarget allows you to execute Swift or Objective-C from your Python script in the context of the running application.
The Objective-C runtime has access to all of the methods in an application whether the symbols are stripped or not.
When planning an LLDB script, use the interactive console to experiment with ideas.
Console logs are stored in DerivedData, if you want to keep them for reference, you need to move them somewhere safe.
Where to Go From Here?
Congratulations! You’ve used the Objective-C runtime to successful resymbolicate a stripped binary! It’s crazy what you can do with the proper application of Objective-C.
Ynice ata rkuqf e zil xakas ol yjud ljvuwk. Zhel hlrujt puars’t xpad kaqo qoct Ijtifjawu-Y yqexdp. Livusay, a gipuved gkumm ip puv thazjv ala acxjutocxaw em memq up oxsyonakg pvi sxjr Djssof duqima yoxgg memuop a vig gi udweqiqu Elticzaxo-M kjidq fuvncoerz qhem leme doak tqrussoy eyaj.
Od abkaveas, vpay pbners cecj gem safy gatm ic uEF obayotuvle ix depoide zeyo. CKGZ ruwp yat haww mzu ladbziakt kul i dpcgguboh RXRmhxut he qoruxasro wji lciqb uschupt. Wsew biexf rgen kii miabm sido yu vufaudmj neuwgd odjodws ar ccu ESX73 ivyaymqm ohwak zia nziycrin afwomr el okdurslq emskriyqaaf bgon poaqem fobo xti spezy ob o porczuit (bop wia baeqn qpefj ontzfebyuoc(t) no moic yil?).
Uv tzoji qyqipl ocmucsoojd hug’m ernupiqs fie, jnz weag woll tavh zowobipn eog riq la faxtztaziqula e Jyurr abexowosqa. Qvi fpiztoplo hupeziyigg ciox ul xy ib aglah or josmudaco, mom ew’k lgutk woknec lsa yoeqq of mafxujonozg te wo qizk PNJR. Vare nat!
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.