Swift Reversing
Transcript of Swift Reversing
SwiftReversing
RyanStortzInfiltrate2016
PresentationOverview
Part1SwiftIntroduction
Part2Methodology
Part3SwiftRE
2
SwiftIntroduction
3
4
SwiftLanguage
• Safe,fast,andexpressive• Closuresandfirst-classfunctions• Tuplesandmultiplereturnvalues• Generics• Fastandconciseiterationoverarangeorcollection• Structs thatsupportmethods,extensions,andprotocols• Functionalprogrammingpatterns,e.g.,mapandfilter• Powerfulerrorhandlingbuilt-in• Advancedcontrolflowwith do, guard, defer,and repeat keywords
5
CompilerArchitecture
6
7
8
9
10
11
12
13
Methodology
14
Motivation
• ApplicationPenetrationTesting• ExploitDevelopment• Re-implementation• Interoperability• BuildCharacter
15
InitialQuestions
• Toolchain• Whattoolsareavailablenow?
• LanguageCore• IsitmessagebasedlikeObjective-CordoesitlookmorelikeC/C++?• IsitlazylikeHaskell?• Whatnativetypesareavailable?• Whichstoragebackswhichtypesofvariables?• Whatdoesclassinstantiationlooklike?• HowareOptionals unwrapped?
• ABI• HowdoesSwiftbridgeintoObjective-C?• Howdoesitrepresentvirtualmethodcallsunderthehood?• Howareclassesandstructureslaidoutinmemory?• WhatistheSwiftcallingconvention?
16
Methodology:Examples
17
18
19
SwiftRE:Toolchain
20
21
Toolchain
• swiftc• Thecompiler
• swift• ThecompilerREPL
• swift-demangle• Anamedemangler
22
23
swift-demangle
$ echo '__TFeRq_Ss14CollectionTypezqq_S_9GeneratorGVSs17IndexingGeneratorq__zqq_Ss9Indexable8_Elementqqq_S_9GeneratorSs13GeneratorType7Element_SsS_8generateuRq_S_zqq_S_9GeneratorGS0_q__zqq_S1_8_Elementqqq_S_9GeneratorS2_7Element_fq_FT_GS0_q__' | xcrun swift-demangle_ext.Swift.Swift.CollectionType<A where A: Swift.CollectionType, A.Generator == Swift.IndexingGenerator<A>, A._Element == A.Generator.Element>.generate <A where A: Swift.CollectionType, A.Generator == Swift.IndexingGenerator<A>, A._Element == A.Generator.Element> (A)() -> Swift.IndexingGenerator<A>
$ echo ‘_TTSf4n_d___TTSg5C11CommandLine6Option___TZFSa28_allocateBufferUninitializedurfMGSaq__FSiGVSs12_ArrayBufferq__' | xcrun swift-demanglefunction signature specialization <Arg[1] = Dead> of generic specialization <CommandLine.Option> of static Swift.Array._allocateBufferUninitialized <A> ([A].Type)(Swift.Int) -> Swift._ArrayBuffer<A>
24
$ echo '__TFeRq_Ss14CollectionTypezqq_S_9GeneratorGVSs17IndexingGeneratorq__zqq_Ss9Indexable8_Elementqqq_S_9GeneratorSs13GeneratorType7Element_SsS_8generateuRq_S_zqq_S_9GeneratorGS0_q__zqq_S1_8_Elementqqq_S_9GeneratorS2_7Element_fq_FT_GS0_q__' | xcrunswift-demangle –expand
_Demangling for _TFeRq_Ss14CollectionTypezqq_S_9GeneratorGVSs17IndexingGeneratorq__zqq_Ss9Indexable8_Elementqqq_S_9GeneratorSs13GeneratorType7Element_SsS_8generateuRq_S_zqq_S_9GeneratorGS0_q__zqq_S1_8_Elementqqq_S_9GeneratorS2_7Element_fq_FT_GS0_q__
kind=Globalkind=Function
kind=Extensionkind=Module, text="Swift"kind=Protocolkind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=DependentGenericSignaturekind=DependentGenericParamCount, index=1kind=DependentGenericConformanceRequirementkind=Type
kind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=DependentGenericSameTypeRequirementkind=Type
kind=DependentMemberType, text="Generator"kind=Typekind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=Typekind=BoundGenericStructurekind=Typekind=Structurekind=Module, text="Swift"kind=Identifier, text="IndexingGenerator"
kind=TypeListkind=Typekind=DependentGenericParamType, text="A"
kind=Index, index=0kind=Index, index=0
kind=DependentGenericSameTypeRequirementkind=Type
kind=DependentMemberType, text="_Element"
kind=Typekind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="Indexable"
kind=Typekind=DependentMemberType, text="Element"kind=Typekind=DependentMemberType, text="Generator"kind=Type
kind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="GeneratorType"
kind=Identifier, text="generate"kind=Typekind=DependentGenericTypekind=DependentGenericSignaturekind=DependentGenericParamCount, index=1kind=DependentGenericConformanceRequirement
kind=Typekind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=DependentGenericSameTypeRequirementkind=Typekind=DependentMemberType, text="Generator"kind=Typekind=DependentGenericParamType, text="A"
kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocol
kind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=Typekind=BoundGenericStructurekind=Typekind=Structure
kind=Module, text="Swift"kind=Identifier, text="IndexingGenerator"
kind=TypeListkind=Type
kind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=DependentGenericSameTypeRequirement
kind=Typekind=DependentMemberType, text="_Element"kind=Typekind=DependentGenericParamType, text="A"
kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocol
kind=Module, text="Swift"kind=Identifier, text="Indexable"
kind=Typekind=DependentMemberType, text="Element"kind=Typekind=DependentMemberType, text="Generator"
kind=Typekind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=Typekind=Protocolkind=Module, text="Swift"kind=Identifier, text="CollectionType"
kind=Typekind=Protocol
kind=Module, text="Swift"kind=Identifier, text="GeneratorType"
kind=Typekind=UncurriedFunctionType
kind=ArgumentTuplekind=Typekind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
kind=ReturnTypekind=Typekind=FunctionTypekind=ArgumentTuple
kind=Typekind=NonVariadicTuple
kind=ReturnTypekind=Typekind=BoundGenericStructurekind=Typekind=Structure
kind=Module, text="Swift"kind=Identifier, text="IndexingGenerator"
kind=TypeListkind=Type
kind=DependentGenericParamType, text="A"kind=Index, index=0kind=Index, index=0
ext.Swift.Swift.CollectionType<A where A: Swift.CollectionType, A.Generator == Swift.IndexingGenerator<A>, A._Element == A.Generator.Element>.generate <A where A: Swift.CollectionType, A.Generator == Swift.IndexingGenerator<A>, A._Element == A.Generator.Element> (A)() -> Swift.IndexingGenerator<A>25
InitialQuestions:Revisited(Toolchain)
• Toolchain• Whattoolsareavailablenow?
26
swift-demangle
SwiftRE:LanguageCore
27
LanguageCore
• Nativetypes• String,Bool,Int,Int8,Int16,Int32,Int64,UInt,UInt8,UInt16,UInt32,UInt64,Float,Float80,Double• NotaggedpointersinSwift(butwillbeintheObjc bridges)
• ControlFlow• Optionals• ClassInstantiation
28
Messages?Laziness?
29
Optionals
• Swifthasoptionals whichalleviatesalotofnull/nilpointerproblems.
30
00000000`00000002 00 00000000`00000000 01[ Value = 2 ] [Op] [ Value = nil ] [Op](lldb) list
50 => case .Some(2):51 let train = Train()52 train.makeNoise()53 case .Some(3):54 let car = Car()55 print(car.description)56 default:57 print("Invalid choice!")5859 }
(lldb) reg readGeneral Purpose Registers:
rax = 0x0000000000000002rbx = 0x0000000000000000rcx = 0x0000000000000002rdx = 0x0000000000000002rdi = 0x0000000100702b80rsi = 0x000000000000000arbp = 0x00007fff5fbff9b0rsp = 0x00007fff5fbff840r8 = 0x0000000000000000r9 = 0x0000000000000000
r10 = 0x00000001002ad201r11 = 0x00000001000dfcc0r12 = 0x0000000000000000r13 = 0x0000000000000000r14 = 0x0000000000000000r15 = 0x0000000000000000rip = 0x000000010000148e classes`classes.main () -> () + 446 at
classes.swift:50rflags = 0x0000000000000297
cs = 0x000000000000002bfs = 0x0000000000000000gs = 0x0000000000000000
(lldb) x/8i $pc-> 0x10000148e: 48 39 d1 cmpq %rdx, %rcx
0x100001491: 75 40 jne 0x1000014d3 0x100001493: e8 e8 02 00 00 callq 0x100001780 0x100001498: 48 89 c7 movq %rax, %rdi0x10000149b: e8 b0 fb ff ff callq 0x1000010500x1000014a0: 48 89 45 b0 movq %rax, -0x50(%rbp)0x1000014a4: 48 8b 38 movq (%rax), %rdi0x1000014a7: 48 89 bd 20 ff ff ff movq %rdi, -0xe0(%rbp)
(lldb) x/40xg $rbp-0x280x7fff5fbff988: 0x0000000000000002 0x0000000000000300
31
32
DynamicAllocationandClassInstantiation
RefCounted *swift_allocObject(Metadata *type, size_t size, size_t alignMask);
33
34
35
InitialQuestions:Revisited(LanguageCore)
• LanguageCore• IsitmessagebasedlikeObjective-CordoesitlookmorelikeC/C++?• IsitlazylikeHaskell?• Whatnativetypesareavailable?• Whichstoragebackswhichtypesofvariables?• Whatdoesclassinstantiationlooklike?• HowareOptionals unwrapped?
36
C++
No,thankGod
Stack,Heap,dependsonlifetime
SlightlydifferentthanC++
WithabitwiseAND
Theusuals
SwiftRE:ABI
37
ABI
• Objective-CBridging• Virtualfunctioncalls• Ownershiprules• Callingconvention
38
Objective-CBridging
39
40
VirtualFunctionCalls
41
OwnershipandOwnershipRules
• SwiftisfullARC• AutomaticReferenceCounting• Everythingisderivedfromafewbasetypes,whichincludethereferencecounts.
• Functionsunderstandtheirargumentownershiprules• Dead• Guaranteed• Exploded• GuaranteedandExploded
42
CallingConvention
• Swift’sapproach:• YOLO• ExternalcallsareRAX:RDX:RCX:R8
• __swiftcall isnotsupportedinHexRays
• Scatteredreturnvalues• Hexrays hasalotoftroublewiththem:(
43
44
__swiftcall
Swift::String __usercall __spoils<rax,rdx,rcx,r8> func@<0:rdx, 8:rax, 16:rcx>(void *a1, void *a2)
Swift::String *__cdecl func(Swift::String *__return_ptr__struct_ptr retstr, void *a1, void *a2);
45
InitialQuestions:Revisited(ABI)
• ABI• HowdoesSwiftbridgeintoObjective-C?• Howdoesitrepresentvirtualmethodcallsunderthehood?• Howareclassesandstructureslaidoutinmemory?• WhatistheSwiftcallingconvention?
46
Seamlessly
SimilartoC++
ExactlylikeObjective-c
Yolo
Tools
47
swift.py
• IDAandHexRays plugin• RewritesHex-Raysoutputtodemangle names• AnnotatesIDAwithdemangled names• Classbodyrecovery• Typepropagation(ComingSoon)• Witnesstablerecovery(Comingsoon– Hopefully)
Demo
48
Questions?
RyanStortz• PrincipalSecurityResearcheratTrailofBits• PreviouslyatRaytheonSIGOVS
ContactInformation:• @withzombies• [email protected]
49