Swift is Apple's newest programming language, which, according to many people, is used to "replace" objective-c. But there is no clear evidence. I spent some time in reverse engineering for Swift's binary and operational environments, and then I had some minor discoveries about Swift. So far, the conclusion is that Swift is a objective-c without a message mechanism.
Object
Believe it or not, the object in Swift is the object of Objective-c. In the Mach-o binary, __objc_classlist contains the data for the class in each binary file. The structure looks like the following:
Copy Code code as follows:
struct Objc_class {
Uint64_t Isa;
uint64_t superclass;
uint64_t Cache;
uint64_t vtable;
uint64_t data;
};
(Note: All structures are from 64-bit versions)
Note The data record, which points to a structure in the class that lists the contents of the method, instance variables, and protocols. Typically, data is 8-byte aligned, but for the Swift class, the last digit of data is only 1 bytes.
class
The real structure of the Swift class is a bit odd. The Swift class has no Objective-c method. We will implement it in the future. The variables of the Swift class are stored as instance variables. What the swift getter and setter method really modifies is the value of the instance variable. The strange thing is that the instance variable of the Swift class has no type encoding. A pointer to a type encoding should normally be null. This is probably due to the fact that the OBJECTIVE-C runtime does not support handling the SWIFT variable itself.
Inherited
The succession of Swift is what you expect. In Swift, Square is a subclass of shape and a subclass of Objective-c class shape. However, there are no super classes in the Swift class?
For example
Copy Code code as follows:
In this example, the shape class is a subclass of the swiftobject. Swiftobject is a root objective-c class, similar to NSObject. It does not have a superclass, meaning that Isa points to itself. Its purpose is to use swift run-time methods such as allocation and deallocation instead of standard objective-c run-time methods. For example, (void) retain does not call Objc_retain, but it invokes Swift_retain.
Class method
As I mentioned earlier, there is no method for the class of the Swift object, which replaces functions like C + +, name adaptations, and everything. This may be why swift claims to be faster than objective-c. You no longer need to find and Invoke method implementations for Objc_msgsend.
In Objective-c, the method is implemented like this:
Copy Code code as follows:
Type method (id self, SEL _cmd, id arg1, id arg2, ...)
The Swift method is very similar, but with a slight use of different parameter configurations, self is passed as the last parameter and there is no selector.
Copy Code code as follows:
Type method (ID arg1, id arg2, ..., id self)
Virtual Table
Like C + +, the Swift class also has a virtual table that lists the methods in the class. It is placed directly after the class data in the binary file, and looks like this:
Copy Code code as follows:
struct Swift_vtable_header {
uint32_t vtable_size;
uint32_t unknown_000;
uint32_t unknown_001;
uint32_t unknown_002;
void* Nominaltypedescriptor;
vtable pointers
}
As far as I know, virtual tables in the Swift class are used only when they are visible during compilation. Otherwise, it will look like a bunch of messy symbols.
Name reorganization
Swift keeps the metadata of functions in their respective symbols, which is called the name reorganization. Metadata Treasure House The name of the Austrian function (obvious), attributes, module name, parameter type, return value type, and more data, such as this example
Copy Code code as follows:
Class shape{
Func numberofsides ()-> Int {
Return 5
}
}
The reorganization of the Simpledescription method is named:
_tfc9swifttest5shape17simpledescriptionfs0_ft_si. Here is a detailed description:
_t-The prefix of all swift symbols, each of which begins with the _t.
F-function
C-Class function (method)
9swifttest-module name with length prefix
5Shape-the class that the function belongs to, with the length prefix
17simpleDescription-the name of the function
F-Function Properties. In this case it is F, which is a normal function.
S0_ft-I'm not particularly sure what that means, but it's a marker that starts with a parameter and return type
' _ '-this underline divides the type of the parameter and the return value. Because the function has no parameters, it's directly behind the s0_ft.
S-Returns the start of the value. ' S ' on behalf of Swift; The return type is the built-in type of swift, and the next character determines the type
I-this is the built-in type of Swift. A lowercase "I" represents an int.
Function Properties
Character type
F normal function
S setter
G Getter
D destructor
D-Release device
C Constructor
C Distributor
Swift internal functions
Character type
Array A
B-Boolean
C Character Constants Quantity
D double-precision floating-point number
F single-precision floating-point
I integral type
U UINT Type
Q-Implicit optional
S-String
In addition to the functions, there are many named conversion mechanisms, here I only give a brief overview.
hook function
Fed up with this part of semantics, let's touch something interesting! Let's say we have a class like this:
Copy Code code as follows:
Class Shape {
var numberofsides:int;
Init () {
Numberofsides = 5;
}
}
For example, we want to change the value of Numberofsides to 4, there are many ways to do it. We can use MobileSubstrate to hang into the getter method and then change the return value, just like this:
Copy Code code as follows:
Int (*numberofsides) (id self);
Mshook (int, numberofsides, id self) {
return 4;
}
%ctor{
Numberofsides = (int (*) (ID self)) dlsym (Rtld_default, "_tfc9swifttest5shapeg13numberofsidessi");
Mshookfunction (Numberofsides, Mshake (numberofsides));
}
If we create an instance of a shape and print out the Numberofsides value, we get 4! Looks good, doesn't it? Now, I know you're probably thinking, shouldn't we be returning an object with a very amount of 4?
Well, in Swift, many of the built-in types are written in volume. An int, for example, is like the int in the C language (although it can be a long shape--Don't let me run into this). A little hint, string type is a bit old, this is a low priority UTF-16 string, so no C literal is available.
Let's do the same thing, but this time, we're not on the picker, we set the hook on the picker.
Copy Code code as follows:
void (*setnumberofsides) (int newnumber, id self);
Mshook (void, setnumberofsides, int newnumber, id self) {
_setnumberofsides (4, self);
}
%ctor {
Setnumberofsides = (void (*) (int newnumber, id self) dlsym (Rtld_default, "_tfc9swifttest5shapes13numberofsidessi");
Mshookfunction (Setnumberofsides, Mshake (setnumberofsides));
}
Try again, and then ... It's still 5. What's going on, you ask? Well, in some parts of swift, functions are inline. The Class Builder is one of the places. It directly sets Numberofsides to Ivar, and the device is invoked only when the value is set again by the top-level code. Called in that, you know, we got 4.
Finally, let's modify the Numberofsides by setting the value of the instance variable directly.
Copy Code code as follows:
void (*setnumberofsides) (int newnumber, id self);
Mshook (void, setnumberofsides, int newnumber, id self) {
Mshookivar<int> (self, "numberofsides") = 4;
}
%ctor {
Setnumberofsides = (void (*) (int newnumber, id self) dlsym (Rtld_default, "_tfc9swifttest5shapes13numberofsidessi");
Mshookfunction (Setnumberofsides, Mshake (setnumberofsides));
}
This function can be implemented, although it is not recommended, but it does have an effect.
This is what I want to write at the moment. Of course, there are many other things I am looking at, including the witness table, because I do not know much, so here I can not write a summary. A lot of the content is changed in this article, and they are just what I get from running and viewing the binary files compiled in swift language for reverse engineering.
What I have found should be very good, which means that mobilesubstrate will not perish with objective-c, and that fine-tuning can still be done! I would like to know what will happen in the future of the application store in the jailbreak scene ... Can logos be updated to automatically destroy names? Even the common type of Swift library ...
If you find out more about how Swift works, don't hesitate, please let me know!