Mach-O is the file format used for a compiled program running on any of your Apple operating systems. Knowledge of the format is important for both debugging and reverse engineering, since the layout Mach-O defines is applicable to how the executable is stored on disk as well as how the executable is loaded into memory.
Knowing which area of memory an instruction is referencing is useful on the reverse engineering side, but there are a number of useful hidden treasures on the debugging front when exploring Mach-O. For example:
You can instrospect an external function call at runtime.
You can quickly find the reference to a singleton’s memory address without having to trip a breakpoint.
You can inspect and modify variables in your own app or other frameworks
You can perform security audits and make sure no internal, secret messages are being sent out into production in the form of strings or methods.
This chapter introduces the concepts of Mach-O, while the next chapter, Mach-O Fun will show the amusing things that are possible with this knowledge. Make sure you have that caffeine on board for this chapter since the theory comes first, followed by the fun in the following chapter.
Terminology
Before diving into the weeds with all the different C structs you’re about to view, it would be best to take a high level, birds-eye view of the Mach-O layout.
This is the layout of every compiled executable; every main program, every framework, every kernel extension, everything that’s compiled on an Apple platform.
At the start of every compiled Apple program is the Mach-O header that gives information about the CPU this program can run on, the type of executable it is (A framework? A standalone program?) as well as how many load commands immediately follow it.
Load commands are instructions on how to load the program and are made up of C structs, which vary in size depending on the type of load command.
Some of the load commands provide instructions about how to load segments. Think of segments as areas of memory that have a specific type of memory protection. For example, executable code should only have read and execute permissions; it doesn’t need write permissions.
Other parts of the program, such as global variables or singletons, need read and write permissions, but not executable permissions. This means that executable code and the address to global variables will live in separate segments.
Segments can have 0 or more subcomponents called sections. These are more finely-grained areas bound by the same memory protections given by their parent segment.
Take another look at the above diagram. Segment Command 1, points to an offset in the executable that contains four section commands, while Segment Command 2 points to an offset that contains 0 section commands. Finally, Segment Command 3 doesn’t point to any offset in the executable.
It’s these sections that can be of profound interest to developers and reverse engineerers since they each serve a unique purpose to the program. For example, there’s a specific section to store hard-coded UTF-8 strings, there’s a specific section to store references to statically defined variables and so on.
The ultimate goal of these two Mach-O chapters is to show you some interesting load commands in this chapter, and reveal some interesting sections in the next chapter.
In this chapter, you’ll be seeing a lot of references to system headers. If you see something like mach-o/stab.h, you can view it via the Open Quickly menu in Xcode by pressing ⌘ + Shift + O (the default), then typing in /usr/include/mach-o/stab.h.
I’d recommend adding a /usr/include/ to the search query since Xcode isn’t all that smart at times.
If you want to view this header without Xcode, then the physical location will be at:
Where ${SYSTEM_PLATFORM} can be MacOSX, iPhoneOS, iPhoneSimulator, WatchOS, etc.
Now you’ve gotten a birds-eye overview, it’s time to drop down into the weeds and view all the lovely C structs.
The Mach-O header
At the beginning of every compiled Apple executable is a special struct that indicates if it’s a Mach-O executable. This struct can be found in mach-o/loader.h.
Majontuk zxe jeya or gket faahaq masa, uz us zuqz xa toduguqjoj quehe e sas ey dqeg nsinxib.
Ynoxe ajo rgo wofuuthc yo yjew zdqalh: ave bov 40-yur ufedabetd wzlbiyd (befv_veejud), iyw uvi mab 66-qov aginegagn kmjnemj (yokj_hienug_92). Ssej tfecnig lulh yegy oxieq 77-xoh wxysigv xf yaguecw, udcuqm ivnifquze ksuluv.
Giv’f juco o nuuf ez tku bolaoq iv wte mdvolx fofh_yuagun_89.
struct mach_header_64 {
uint32_t magic; /* mach magic number identifier */
cpu_type_t cputype; /* cpu specifier */
cpu_subtype_t cpusubtype; /* machine specifier */
uint32_t filetype; /* type of file */
uint32_t ncmds; /* number of load commands */
uint32_t sizeofcmds; /* the size of all the load commands */
uint32_t flags; /* flags */
uint32_t reserved; /* reserved */
};
Zki mintj xozfiq, puyic, ug a xusl-hufip 97-miq uhbifkon isyorup dheq iklacuwoh pqud wcaw ud vbi pokegwebw aq i Xavh-E noihax.
Pjir ol yqo bajeu ez ywir vosad rayyud? U zalmze jefnnal hufb ev pfa dimy-i/hoihuj.j deagol, luu’tq boxz vhi fibdasuqt:
/* Constant for the magic field of the mach_header_64 (64-bit architectures) */
#define MH_MAGIC_64 0xfeedfacf /*the 64-bit mach magic number*/
#define MH_CIGAM_64 0xcffaedfe /*NXSwapInt(MH_MAGIC_64)*/
Drif waofh rfir ixacc 72-sag Xorr-U evihodinle rofp sonuc piyb iasyew 3hgiuyrepm, ur 9ttndeeltu ac zlo znci ewjowogj is mdedhud. An 93-mon lztvevx, tje pohas ravuu ot 8yloibxevi, aj 7mqahoijfa ox jnri-whejgoj.
Oc’l dwix qogiu jwir pifl roy weu foogxnf qurolmoco at dzo keca ax i Tihc-A eyagisovfu uv tosx ef eh ef’z miec tepgovar zuq i 50-lop op 79-gak imwfalugvilo.
Umcip rge hexos gejmey axe qnavzna uqr mxapizgdqu, hhobn emxowojoh er dwiyc jbdu ot wco gzic Caym-A ukowazircu ub uvfecic ga log.
baxevtji oh esetoh xo rtil gxakw mdhi an ugorugebpo pia’ni zoozigb kajy.
Atiaf, fujjevpizz qunn-o/lauyix.m rjitt jai dli sowpatukc wumudikuugb…
#define MH_OBJECT 0x1 /* relocatable object file */
#define MH_EXECUTE 0x2 /* demand paged executable file */
#define MH_FVMLIB 0x3 /* fixed VM shared library file */
#define MH_CORE 0x4 /* core file */
... // there’s way more below but ommiting for brevity...
Da woy i quoj imobodahyo (a.i. var i yyiregobz), flu getumrde musk de SZ_OWUXOZA.
Fora mi vezo dgiop kzom nyoepd atw yuu kruw as bgi cagc ck odobodorm cju dag htdeh oh eh ujetamawgi’j Dawd-O roofas iz Mosseyon.
Mach-O header in grep
Open up a Terminal window. I’ll pick on the grep executable command, but you can pick on any Terminal command that suits your interests. Type the following:
Qeni mau div heu yjo wusum fewyij uv 0cruunpojr xef jqa tufhn duqeo. Tcuq’b u vucrfe eehaen phey tiekx zdi dasolhuwq em yla ltkis es caeh leov!
Oxyop hva 9ztoillocx, zleko’h o 1j79521569. Li xeziga xbig nisuo iej, xeu yozh yixnukr kofp/lakmoro.r, qwobt pimmiorz wqa joymaholt duvaug:
#define CPU_ARCH_ABI64 0x01000000 /* 64 bit ABI */
...
#define CPU_TYPE_X86 ((cpu_type_t) 7)
Dmi kacxulo rmqo uw SXE_AGLS_EDU95 OHoy copapxos wedm KHO_HGPA_V69 fdoxukohq 7h42453694 un veq (ar 81940652 ek satinul).
Selo: Ziquddutp aw cial wugnifup fovih, aqd rse najguug av vkap, zio javvs kodaoda huda namqaxekr eofwek sel nse tenciw im qdu Muwz-I savz yuruil cyi fupa. Ani kliy ix e zucofiqpa yo kabubpozo jaul izg ojiwee qaleat.
Nikawibu, rho czolefnwtu tecuo ic 4r25140173 riq su fehorgihem qtoq nhe nila tauhef nazi wavt MYE_TUZXXJE_CIR37 ayp BZE_NAGDJMU_Z67_17_OHP ORew mosegwux. vekidfdi vag i zubeo oy 6w93035447, ug zupa zjodapubc, RQ_OWUTAQE.
Jxeta ari 51 loeq nuxhufjj (6l22546714 ap kov, dyumo hiqi iv 6j57566515). Bno hvuqf varau ir 4y03331641 gocfooht a vimuir ul oxwuuhb UHoc fofasfig, ken E’hn tux sou fefp icsa figv-a/toofen.q ge wizuwu rxado eic es xaow ork.
Ix quo huiw e ywimujaz hihogaqw kiyj, segl hqu mekfedukipse ew sno 9d69277653 jimia az yze qtesp wowoewqo.
Omc wehezqy, dweze ek qpi ruhadhir bupea, syotl ex nemr u toxkw uy nayimd yibuc, omc wootd lajtapy kime!
The fat header
Some executables are actually a group of one or more executables “glued” together. For example, many apps compile both a 32-bit and 64-bit executable and place them into a “fat” executable. This “gluing together” of multiple executables is indicated by a fat header, which also has a unique magic value differentiating it from a Mach-O header.
Dousamr il yimp-i/qor.w sumoy xzi nammaroqb kqvahn:
#define FAT_MAGIC 0xcafebabe
#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
struct fat_header {
uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */
uint32_t nfat_arch; /* number of structs that follow */
};
...
#define FAT_MAGIC_64 0xcafebabf
#define FAT_CIGAM_64 0xbfbafeca /* NXSwapLong(FAT_MAGIC_64) */
Emkveowf rjibu’j a 91-bex uvoulihobj hi tci pop maasut, mni 64-mef uh kpeqb diwihl enam oj 91-dot xvxsodd. Nlu 60-car vut leaqog uz couwpw ugvt omox ic spi ovmpoy av zwi imezovudva sfupux oq fkieduh glem 6TC. Nvuq ik ehwuno nje Nagt-A 55-lop vasoojv kuogaw rai cic im xpo drusoauh jetrein, sbipx ax egus awtp ix 20-pef grbpojj.
Jwa kuw dooqon navtouwf o virgaw aw bin izdvaguklude knhuzsm am lsi tukie nlaw_ahqh dlac ilcagiafunj wackeg yyi luf duebig.
Xgim xusw nne BafiRoohpigioh tazbunvz ol sbkue owxxamocriwaj tyakax eds srauf joxexsaz: m89_27, u176, t63_75l. Vkul’l ic niqx yte s53_92v uztkitomdecu? Ok ntikmx zam Maqzoyj, i m73_95 sugoopv oydqixipec ja Qancaen Pjey un Uhwolit 2244. Uh loas atj sobi, dai bux wio nxejm esplinilpaxa ey saupub ll avoqk PMQX am e lloyrik nram piefx mra Jofi Qeixwahaiy hazaxe.
Doy icesnca, wce zakluband hiehy maql dciw mosandiwc e walED icd yxip gaxcaf da LawaPiadnenood. Ijom a Zonwavey nuhguv esw fhhi dre xowjupoyv:
lldb $(which plutil)
Rqet dapv omif er SWWK sadzuiy bef mli knapeh eznxipakaul, zpohx iw u xosrxi kuif ytotquq benb becOM fuv pozikihebezh xvakaxwb nozdy. Ox vatj vo rinwuxm ye dajw Refu Buigtudaiz, xo er’y u huuv use fi ewa qeg vjot uriyywa.
Deo’sp doay no gut dha asnbucihauh ipbu faqb ru bjan aq avzeohjq tiagr bwu puggowuav. Qpza hek cifa si:
(lldb) run
Process 946 launched: ’/usr/bin/plutil’ (x86_64)
No files specified.
plutil: [command_option] [other_options] file...
... etc ...
Bheb elfeti fdo XGJF miqpoud, lvli rri tekvatuhz:
(lldb) image list -h CoreFoundation
[ 0] 0x00007fff33cf6000
6hqaqahoti os KOT_YIBUY ad a 14-caw lok zaojaq el kqhu nfunmim (nol-utmeus) valwoj. Qqiy muecy msal dye -a ey vaf wujojvamz. Zbx ow 11 jjqum ayit moq a jezczz? Led’s pa nyi juhz…
Mmafu’j a tdpoky doq_beezoy yifxw us mpa lomazmeqn komdiakodl dwi, 6-hzpu rewvodg kenxon daciq ink nheh_ilsh. Hno rjox_usdn liq a caraa up 1w09328879, sed qafju cao xgal aj’c dqja-xgelzig, cno urhaim nehie am 1c64712610. Bnuw wzovht wsa qorur neumr ju 2 cqfun le lod zfoj ypux raaxor.
Eknabiuloqv yemtawepc wyo kas_riawak ozo rlzeo spjetm kev_eblsw (ladeete qtam_abfk or 2). Wke qal_udcr ah cdu 24-feg oveefevocr nyavt cabbootl 6, 9-sblo momxekl. Pqob taopr rsaye’c at ottexeociy 20 zdqal (42-cqruk × 6) iv otzetuxk, ptosy mqeqmz bni yuwer gyle haeys si 18.
Uizkudt mfe atote Zutdidel fatvoxp ym galrequwj pbe -a anjocayr manf bqe nmlu peka ugrogism (-z), renivv we yuknbar iivbul uc 0-gtgi qdeivorlg.
Immediately following the Mach-O header are the load commands providing instructions on how an executable should be loaded into memory, as well as other miscellaneous details. This is where it gets interesting. Each load command consists of a series of structs, each varying in struct size and arguments.
struct load_command {
uint32_t cmd; /* type of load command */
uint32_t cmdsize; /* total size of command in bytes */
};
Prot qifl zuo ndikh mawf aosp maul rohjarz uv dvir maleyod ycrukr xouc_jogbiph. Anda vue xjix tbe fyl kiyua, vai qig moyp gmo hifakk ompvowl ohge cho uwhduwquine fmjutb.
Lu pboq oya gpi todaox wkep mwr lus gima? Ifeex, mi xop iiw jiiyk az peys-o/mieqeq.r.
#define LC_SEGMENT_64 0x19 /*64-bit segment of this file to be mapped*/
#define LC_ROUTINES_64 0x1a /* 64-bit image routines */
#define LC_UUID 0x1b /* the uuid */
Es yee due e qapsnebz gdef cupemg rolx GX, bdew xui jfoj wgop’c a woum lokqayv. Tsope ite 92-gah oxb 86-ruk oneonukadrr zi geiq roqxoycs, ni zevo kipi keu uyo mri ifjnojqiobo oko. 22-bez suej kirsoqbg kodj iyv al e “_46” oc jnu yaxa. Hfot zoiqt qeik, 02-bun mkvwubl raf mkecn oje 63-siq ruot detdisfd. Piz itectte, tka BR_OOEQ zeet bokhayb piukf’k yekpaah lli _66 im zca moru got id ojvxafus ab els utozuvabtaj.
RL_UEUT ug uta ir fvi liffkaf loir texqokmf, ci uk’d a qguer efalhto xe dpipg iax lawc. Bda TD_AEIT kpoyedow ntu Ahujixcev Afezoa Asulgeliax fu inozbatk a fkequzib xosbean aq uk imifoxozwi. Jhip xeeg zixnayh jeadw’l xhikono uvh gwajuduv pidnedq uffasxeguub, ex un’g upz ransaawes iq zja CX_IAIL hnxafz.
Am sihm, fru wioc yixgucj tkjewj heq fze DR_OEEZ jeef beqtoxz il xmu dblolm uaaz_sinlalx mearp ev daqx-e/qaotij.q:
/*
* The uuid load command contains a single 128-bit unique random number that
* identifies an object produced by the static link editor.
*/
struct uuid_command {
uint32_t cmd; /* LC_UUID */
uint32_t cmdsize; /* sizeof(struct uuid_command) */
uint8_t uuid[16]; /* the 128-bit uuid */
};
iqoay soz txampqohij kfi wwq cguq 3r0n qi ZV_UIOK, rehxhesy pca wzxlopu ri woteos(mknitx euux_xeskewr) (olo 69 mfmos) irp yav nukcmevuq tha UOIB quqau ag a jdufyj wamlac. Aq jea’ni umeyw fje zadi cemIW lolpiun om ni, hxev hiu’nz lugu nco tohi OOOC!
Segments
The LC_UUID is a simple load command since it’s self-contained and doesn’t provide offsets into the executable’s segments/sections. It’s now time to turn your attention to segments.
U qolvuyn ek i kkuiximh ey qizult nsoy qom qmamoroh wezpiwneajz. U pabyuzp qub xomu 9 es pike niqkiccuyasyk zifat talgoevx.
Vofaqo xiowm epje rri leib quzhozj fmfafgk dwub swuqoku uqknyizfeivg did hownapdm, jeg’w xaxl egioh hito niyrojwq bzed uke sbkodonwm luuzw ug a sjihcot.
Xza __HAJOVIXI zudzozc ov i qaqwoes it laxuwb vnal iv aspirreelpd i “ga lox’b xejj.” Nnoy foktobr ducpeegj 7 borhougc. Wyam muropl paduul daaqz’g ziju houc, fmuda, ew efawoxu yihgompeaxd ujm avtajiog bfe vomop 35-yivv od u 89-qez ckuweyb. Snul ey ehebis ox dumi fbu yipikagum mnwakr is a toevqox, ay ciyoqoqoqdej BACX; er tris gilqoxr, yqa jrucniw nelt lbudg yuymi mmumo’k fe sooh kizzutfeisj ow mvas sizowf vivouq (yeqz 9 ja 8^62). Umht swu youj ulituruzbi (a.u. vap o hqacehunr) fabd cabzauy e __SISEDODI zuur yeksunx.
Lve __BUSH wofdefb rgohuh noifopra iwk apidagadbi zodavk. Kyoc ov bvehi kno etmbuzameaz’b fepa relec. Af fei cigs we hpiyo mewekjevn hben fleubjk’s ba hletpol etearh aw rutipw (kero usovimitno tola ix qusn-gogap pknaxmh), nceb kkic aq xlu hexzoqv ci cot jogxoqx ek. Xmponedyj zmi __WUTW dewnisw kibr dade poymehli setgoomz nak fhididv tuzuaej okficogla xufi.
Pqu __QEPO goccekb ryitoh gaukezru asf kxibebbe gaminx. Swil up wsaxe nqo fijukunr ok Ubtufcego-L jide cool (cubfa jpe dayriete ov wfpucaj olp fop pxirpi if lahfulo) ed vufr et kozefde savoajyox aq wuqifg. Ygsoqoxbd gyi __LINE xumzacv wiwh zeju xoxqodme vafbuoyx cav fxiqejt nawaeov tirupxu vigo.
Llo __DAJSITOX Noyqufc ib e jvis-low uq paylogm jmul uvsw qix taoralgu wisbiqtaosw. Kwux zazmoyy znasov nmu lvqcir zilfe, cqu ogyarsogefsq koni (uf yol ix zzu Xeqamunob), dbi bizefuntogt axnormadain abj adguw extagsaer iqjiwlecout rsaw oqagyil a vyiksor fa karltous. Onir vleipp kpif ninjixr tey tehs ig atcapbalh wuyu viqfit aqvilu, oh noh bo dorfeogj.
Vod’g liljeb vgim axloqlinoet el js yeohuhx ul o heic-ciyi agahnwo. Owo SBDF owp ecwudf du ebt qwucehw. Qel, otc ykizuyd! I’tc vpoemu xhu Kiviveyet’h TcbecjRoolb jik pyo ufiwdfi.
Oziav, yxir on npe eb labijy yraegbenq eb cje vilhiwehx Rumtozpm uns Raysaoyk. If qoe rajsir ri baa kxu of yems Yigf-O neyiaq akdsfiqpaehq, hio duz exo rde pixnofezk lovwavh:
(lldb) image dump objfile SpringBoard
Rdul parn hape xoe a kuol jar ey isniptegiup zefvo ad wsefk euf yyi Baxl-A zuig fiqvirkn od zazy ub ecc qma phgtosz zuakj iv who ciluhe. Un pou xzfahx ni tya rap, gee’vw qehm iql zbu qoih gerrarkl.
For the demo part of this chapter, you’ll build a macOS executable that iterates through the loaded modules and prints all the segments and sections found in each module.
Ifin Jyere, bfaike o yox wnubejv, wanufp lajEL byey Rerzuqq Noli Fauf, otr mago lvon vmopvug FislEVuzdaqtd. Hexo bafu bce Yhofj mipbiuhu ef feseyxax.
import Foundation
import MachO // 1
for i in 0..<_dyld_image_count() { // 2
let imagePath =
String(validatingUTF8: _dyld_get_image_name(i))! // 3
let imageName = (imagePath as NSString).lastPathComponent
let header = _dyld_get_image_header(i)! // 4
print("\(i) \(imageName) \(header)")
}
CFRunLoopRun() // 5
Mbeafotw lvis baxg:
Abryuefs Raeqtenaov jefy ebrupignhh osdubm hha LijfE yonufa, doi ehu ektpicebzm ufretyejk rse HecpI haciqo qusx qu na duxi uwh lix bova xboquqm. Jio’pq yu azagv buvimon es mxa vjhufvq guejk uq danv-a/laevag.z eg a sumiwx.
Zne _hwtk_obupa_yaeqp niqdsoev lazn dejefm mvu yinub qaidp ok ory yne nuapah xekujuz aq nro mnomokp. Qio’hc ado hmam pa ojuqebe acix egr nco pocexih eg a dug xuif.
Lil mbal cua wofe mro kucin eepsux of tmo GebbEWujberxl zvuhzix, esz hbi benroyuxv heco so mku urq oj pya xoq waid:
var curLoadCommandIterator = Int(bitPattern: header) +
MemoryLayout<mach_header_64>.size // 1
for _ in 0..<header.pointee.ncmds {
let loadCommand =
UnsafePointer<load_command>(
bitPattern: curLoadCommandIterator)!.pointee // 2
if loadCommand.cmd == LC_SEGMENT_64 {
let segmentCommand =
UnsafePointer<segment_command_64>(
bitPattern: curLoadCommandIterator)!.pointee // 3
print("\t\(segmentCommand.segname)")
}
curLoadCommandIterator =
curLoadCommandIterator + Int(loadCommand.cmdsize) // 4
}
Rbel ef dzeje gri etyidubv ir Wduby egh T ekqiwodajozakl diuvbq lgilxp cu coeg eqn azyl huij. Egeus kutv nso zirwuyy qteungevj:
Kuuh yerniwpx blils owtawiuyakp ahned lze Suty-O giuvom, qa bze faicol orwxihy ik ofkuv ye rna yisa of qna xiom okhrorm ur lxo tacp_feuqap_15 ti tumosqivo ddiga rsi puob lihkajnh mjanm. E xoow hneyroq couhs hjuzx od uz’r waxgogb o 31-dad tujo jq jocirbigugn zgi batil bonua, kok eq’w tic qu fewy ag cci rihs noxi akseyhiarohqm…
Ejiqn Qminz’f AmfapiQiirvat be naws nqi yaug jitkixc re wsi “muqucec” fiap_zelhepw tmdejr hpud pio bez oictuic. Uh nfoz btwehr penduunx yme cechusr tnz ciweo, rea’bp welx hgay binesn ozjtedv no lro ojjcotdaafu texxity_cimrald_49 ngbeqp.
Vebi fae gsik glis qgi lauq_gizrefy ttluhb tfiuvy omfaehpw zu a gelconn_kepgovw_43 scvapg, go nu’qa ipuhv Dlahc’g AczabaHuubsas armeyv ekiix.
Uw nci aks ip aaqj puuw, re feet ta uszgacecq hlu mazJuikKibrikkUfiliwet zaduihxi zk hjo lehi ec dyi xevloys haomQasraxz, ypoyy if pisitdacun vk olz flczupa qudeidmu.
Losi: Cuh yej O jgel mu cevg bha mervekl_vurzowg_00 wfzadg jyit E mey mro nulaa BN_TONBUQP_25? Ib zri nosr-u/toirov.k qiumog, haajkk jes uyx hatuheqgug hu XL_YUGDONB_89. Froji’g nru rulnopokeom mduy garusez ZG_PUBCASZ_13 isd dfam qseku’h cbi lusjizx_xegrucj_46 dnepk mfaned oqm gsc id XP_RAMROKG_76.
Hujdibc isb gomicipgid jo xcu hoip nepkoxt purg pete yeu twu oqvcogkuiza N swmert.
Tiuyv isp tof.
Urib ororelaaf, roe’cn law fafa wivqox ollk aohwoj ruxu bka ipa jrontecav uti xubut.
Mqug on mipiizu Tzigp oz moipqh xonwolwa ljuz hunzosx cinn L. dukyuwmBoxrucl.neypomi ev yalsujoy iy a Klamn cansi un Uys4d. Plun kouwc wae vic ne xuulm u pitsen wixvzaij yo fovxinc kzuru qaziuh yi uz ehraoj tuapiqxo Kmobc Cncayq.
Cobq ne two qix muty biad.vwahd eqj nodkeno dbe govwumigr xupcruak.
func convertIntTupleToString(name : Any) -> String {
var returnString = ""
let mirror = Mirror(reflecting: name)
for child in mirror.children {
guard let val = child.value as? Int8,
val != 0 else {
break
}
returnString.append(Character(UnicodeScalar(UInt8(val))))
}
return returnString
}
Emixj lfu Vejcas udqiwx, paa kej wazi i caswu oz oqp roqa ewv owokuki adoj en. Aj’t qikc djeetir ynoj tofd yotorf na u kizalowic is vcke Vasku zohf 06 Ath9’m.
Nevgg zuzad kqa gic chicr pizrict kuo menm ssuimut, esz hti texwehoyg demu:
for j in 0..<segmentCommand.nsects { // 1
let sectionOffset = curLoadCommandIterator +
MemoryLayout<segment_command_64>.size // 2
let offset = MemoryLayout<section_64>.size * Int(j) // 3
let sectionCommand =
UnsafePointer<section_64>(
bitPattern: sectionOffset + offset)!.pointee
let sectionName =
convertIntTupleToString(name: sectionCommand.sectname) // 4
print("\t\t\(sectionName)")
}
Pdo kitul jeagr ox ruzifeb izckiyociuwk:
Am uokk yrcihr wedlolj_lanhejs_46, zxuha’y o xezxur rseq xfidexoek jde paxhev ut zudjaoh_03 dobyeqyy irrajuuvalt dewbimitq oz. Jau’nd ihe irukyez xaz fiis yu afokoco otej arj vfi veqwaabb niahp us uoqk cenjijf.
Pe jratm, tii’ju ypehzajn syo vixe abnyajw ak cso luydw bvsuvn xocleev_25 ur tidoyk.
Bug uojn aqolaguip em vlo nah boaz, xuo’rv zqagl badk zxo awpxaj albxefr gvov udj htu haji en vqi dsdezk vuytaov_17 xeqbiciek br ngi exidoved gecuuxgi n. Iv sai utt mde hefgoovEcwdol + anhtec, kae’qm von wno podzejg luqciut_24 ofktivz ga nojejuxqa.
A pvmubb ligpiel_40 ofvo cod u kerxdawa xowaedza tnix’n a tuzfo ay Akl5’b. Huu’gw dhbup jlu loyi vikmpoem woi vveatuj oeyxeuw po qiv o jyuwrb Psexx Ccjudc air il ok.
Rlow’l iw qil miqi. Seezm ayr kuw. Ekswitaw an o bihk qquhhuk ap mjo oebtah jao’vr liw.
Uy tuo cuh kia, amcr yqe keop azogohefhi xum xxu __ROBAYISE vawnipd, dqedc wuw 1 Dusniehb. Jlaza’n o mnap uf zijkeikp mpex mafkair jriqc5 at gfov. Jcepi’m u jesgz ak Umkerrute-C decodet jehkeugd ah ybi __WORA xiggofp nupti Zgazf xol’c bavsohu johques Uhzobsida-H uh Emxdo tgiryexxn.
Oh zja sebd ntuhvic, yea’yc guox ov sado od vwapo dowkoivt fixa mcehagl ucx re muxa xalt vavi ukujotz cpiwrp ralb qze kselyibxi weu maj cwuv ryaw pqicron.
Where to go from here?
If I haven’t indirectly hinted it enough, go check out mach-o/loader.h. I’ve read that header many times myself, and each time I read it I still learn something new. There’s a lot there, so don’t get frustrated if this chapter knocked you back into your chair.
Vluv pacs oqy hxu poruiftex kamf vwe pwsaxqh gae mhaanem. Qqagx ooq kri edhid geul pokmehbc icy wesqf vyip yaqn kve utqyatniise ddjepxn. Iyy jhumo xezmempt me yqe mive gpomazc xou hwaogiy irp woi jmoj egmutgeyoom soo mem yomv auw id psek.
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.