Swift Reversing

Post on 13-Feb-2017

243 views 0 download

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• ryan@trailofbits.com

49