Skip to content

Commit 71ffc73

Browse files
committed
Provide a more friendly interface to Objective-C runtime
1 parent eaa7ef6 commit 71ffc73

File tree

5 files changed

+174
-214
lines changed

5 files changed

+174
-214
lines changed

README.md

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,34 +64,26 @@ Working with Objective-C.
6464
```python
6565
from chomper import Chomper
6666
from chomper.const import ARCH_ARM64, OS_IOS
67+
from chomper.objc import ObjC
6768

6869
emu = Chomper(
6970
arch=ARCH_ARM64,
7071
os_type=OS_IOS,
7172
rootfs_path="examples/ios/rootfs",
7273
)
7374

74-
emu.load_module("examples/ios/apps/cn.com.scal.sichuanair/zsch")
75-
76-
# The ObjC can only be used through c functions for now,
77-
# more friendly API will be probided in the future.
75+
objc = ObjC(emu)
7876

79-
# Get classes and selectors
80-
nsstring_cls = emu.call_symbol("_objc_getClass", emu.create_string("NSString"))
81-
string_with_utf8_string_sel = emu.call_symbol("_sel_registerName", emu.create_string("stringWithUTF8String:"))
82-
cstring_using_encoding_sel = emu.call_symbol("_sel_registerName", emu.create_string("cStringUsingEncoding:"))
83-
84-
zschrsa_cls = emu.call_symbol("_objc_getClass", emu.create_string("ZSCHRSA"))
85-
get_req_sign_sel = emu.call_symbol("_sel_registerName", emu.create_string("getReqSign:"))
77+
emu.load_module("examples/ios/apps/cn.com.scal.sichuanair/zsch")
8678

8779
# Construct NSString object
88-
a1 = emu.call_symbol("_objc_msgSend", nsstring_cls, string_with_utf8_string_sel, emu.create_string("test"))
80+
a1 = objc.msg_send("NSString", "stringWithUTF8String:", "test")
8981

9082
# Call ObjC method
91-
req_sign = emu.call_symbol("_objc_msgSend", zschrsa_cls, get_req_sign_sel, a1)
83+
req_sign = objc.msg_send("ZSCHRSA", "getReqSign:", a1)
9284

93-
# Convert NSString to C string
94-
result_ptr = emu.call_symbol("_objc_msgSend", req_sign, cstring_using_encoding_sel, 4)
85+
# Convert NSString object to C string
86+
result_ptr = objc.msg_send(req_sign, "cStringUsingEncoding:", 4)
9587
result = emu.read_string(result_ptr)
9688
```
9789

examples/example_ios_ali_vmp_sign.py

Lines changed: 51 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from chomper import Chomper
66
from chomper.const import ARCH_ARM64, OS_IOS
7+
from chomper.objc import ObjC
78

89
base_path = os.path.abspath(os.path.dirname(__file__))
910

@@ -16,44 +17,7 @@
1617
logger = logging.getLogger(__name__)
1718

1819

19-
def create_emulator():
20-
return Chomper(
21-
arch=ARCH_ARM64,
22-
os_type=OS_IOS,
23-
logger=logger,
24-
rootfs_path=os.path.join(base_path, "ios/rootfs"),
25-
enable_objc=True,
26-
enable_ui_kit=True,
27-
)
28-
29-
30-
def objc_get_class(emu, class_name):
31-
return emu.call_symbol("_objc_getClass", emu.create_string(class_name))
32-
33-
34-
def objc_sel_register_name(emu, sel_name):
35-
return emu.call_symbol("_sel_registerName", emu.create_string(sel_name))
36-
37-
38-
def objc_create_ns_string(emu, s):
39-
ns_string_class = objc_get_class(emu, "NSString")
40-
string_with_utf8_string_sel = objc_sel_register_name(emu, "stringWithUTF8String:")
41-
obj = emu.call_symbol(
42-
"_objc_msgSend",
43-
ns_string_class,
44-
string_with_utf8_string_sel,
45-
emu.create_string(s),
46-
)
47-
return obj
48-
49-
50-
def objc_read_ns_string(emu, obj):
51-
c_string_using_encoding_sel = objc_sel_register_name(emu, "cStringUsingEncoding:")
52-
ptr = emu.call_symbol("_objc_msgSend", obj, c_string_using_encoding_sel, 4)
53-
return emu.read_string(ptr)
54-
55-
56-
def hook_pass(uc, address, size, user_data):
20+
def hook_skip(uc, address, size, user_data):
5721
pass
5822

5923

@@ -64,90 +28,90 @@ def decorator(uc, address, size, user_data):
6428
return decorator
6529

6630

67-
def hook_ns_bundle(emu):
68-
ns_mutable_dictionary_cls = objc_get_class(emu, "NSMutableDictionary")
69-
dictionary_with_object_for_key_sel = objc_sel_register_name(emu, "dictionaryWithObject:forKey:")
70-
add_object_for_key_sel = objc_sel_register_name(emu, "addObject:forKey:")
31+
def hook_ns_bundle(emu, objc):
32+
bundle_identifier = objc.msg_send("NSString", "stringWithUTF8String:", "com.ceair.b2m")
7133

72-
bundle_identifier = objc_create_ns_string(emu, "com.ceair.b2m")
73-
executable_path = objc_create_ns_string(emu, f"/var/containers/Bundle/Application"
74-
f"/{uuid.uuid4()}/com.ceair.b2m/ceair_iOS_branch")
34+
executable_path = objc.msg_send(
35+
"NSString",
36+
"stringWithUTF8String:",
37+
f"/var/containers/Bundle/Application/{uuid.uuid4()}/com.ceair.b2m/ceair_iOS_branch",
38+
)
7539

76-
bundle_info_directory = emu.call_symbol(
77-
"_objc_msgSend",
78-
ns_mutable_dictionary_cls,
79-
dictionary_with_object_for_key_sel,
80-
objc_create_ns_string(emu, "9.4.7"),
81-
objc_create_ns_string(emu, "CFBundleShortVersionString"),
40+
bundle_info_directory = objc.msg_send(
41+
"NSMutableDictionary",
42+
"dictionaryWithObject:forKey:",
43+
objc.msg_send("NSString", "stringWithUTF8String:", "9.4.7"),
44+
objc.msg_send("NSString", "stringWithUTF8String:", "CFBundleShortVersionString"),
8245
)
8346

84-
emu.call_symbol(
85-
"_objc_msgSend",
47+
objc.msg_send(
8648
bundle_info_directory,
87-
add_object_for_key_sel,
49+
"addObject:forKey:",
8850
executable_path,
89-
objc_create_ns_string(emu, "CFBundleExecutable"),
51+
objc.msg_send("NSString", "stringWithUTF8String:", "CFBundleExecutable"),
9052
)
9153

92-
emu.add_interceptor("-[NSBundle initWithPath:]", hook_pass)
54+
emu.add_interceptor("-[NSBundle initWithPath:]", hook_skip)
9355
emu.add_interceptor("-[NSBundle bundleIdentifier]", hook_retval(bundle_identifier))
9456
emu.add_interceptor("-[NSBundle executablePath]", hook_retval(executable_path))
9557
emu.add_interceptor("-[NSBundle infoDictionary]", hook_retval(bundle_info_directory))
9658

9759

98-
def hook_ns_locale(emu):
99-
ns_array_cls = objc_get_class(emu, "NSArray")
100-
array_with_object_sel = objc_sel_register_name(emu, "arrayWithObject:")
101-
102-
preferred_languages = emu.call_symbol(
103-
"_objc_msgSend",
104-
ns_array_cls,
105-
array_with_object_sel,
106-
objc_create_ns_string(emu, "zh-cn"),
60+
def hook_ns_locale(emu, objc):
61+
preferred_languages = objc.msg_send(
62+
"NSArray",
63+
"arrayWithObject:",
64+
objc.msg_send("NSString", "stringWithUTF8String:", "zh-cn")
10765
)
10866

10967
emu.add_interceptor("+[NSLocale preferredLanguages]", hook_retval(preferred_languages))
11068

11169

112-
def hook_ui_device(emu):
113-
system_version = objc_create_ns_string(emu, "14.4.0")
114-
device_name = objc_create_ns_string(emu, "iPhone")
115-
device_model = objc_create_ns_string(emu, "iPhone13,1")
70+
def hook_ui_device(emu, objc):
71+
system_version = objc.msg_send("NSString", "stringWithUTF8String:", "14.4.0")
72+
device_name = objc.msg_send("NSString", "stringWithUTF8String:", "iPhone")
73+
device_model = objc.msg_send("NSString", "stringWithUTF8String:", "iPhone13,1")
11674

11775
emu.add_interceptor("-[UIDevice systemVersion]", hook_retval(system_version))
11876
emu.add_interceptor("-[UIDevice name]", hook_retval(device_name))
11977
emu.add_interceptor("-[UIDevice model]", hook_retval(device_model))
12078

12179

12280
def main():
123-
emu = create_emulator()
81+
emu = Chomper(
82+
arch=ARCH_ARM64,
83+
os_type=OS_IOS,
84+
logger=logger,
85+
rootfs_path=os.path.join(base_path, "ios/rootfs"),
86+
enable_ui_kit=True,
87+
)
88+
89+
objc = ObjC(emu)
12490

125-
hook_ns_bundle(emu)
126-
hook_ns_locale(emu)
127-
hook_ui_device(emu)
91+
hook_ns_bundle(emu, objc)
92+
hook_ns_locale(emu, objc)
93+
hook_ui_device(emu, objc)
12894

95+
# Skip a file operation
12996
emu.add_interceptor("_fopen", hook_retval(0))
13097

13198
emu.load_module(os.path.join(base_path, "ios/apps/com.csair.MBP/CSMBP-AppStore-Package"))
13299

133-
ali_tiger_tally_class = objc_get_class(emu, "AliTigerTally")
100+
ali_tiger_tally_instance = objc.msg_send("AliTigerTally", "sharedInstance")
134101

135-
shared_instance_sel = objc_sel_register_name(emu, "sharedInstance")
136-
initialize_sel = objc_sel_register_name(emu, "initialize:")
137-
vmp_sign_sel = objc_sel_register_name(emu, "vmpSign:")
138-
data_using_encoding_sel = objc_sel_register_name(emu, "dataUsingEncoding:")
139-
140-
ali_tiger_tally_instance = emu.call_symbol("_objc_msgSend", ali_tiger_tally_class, shared_instance_sel)
141-
142-
app_key = objc_create_ns_string(emu, "xPEj7uv0KuziQnXUyPIBNUjnDvvHuW09VOYFuLYBcY-jV6fgqmfy5B1y75_iSuRM5U2zNq7MRoR9N1F-UthTEgv-QBWk68gr95BrAySzWuDzt08FrkeBZWQCGyZ0iAybalYLOJEF7nkKBtmDGLewcw==", )
143-
emu.call_symbol("_objc_msgSend", ali_tiger_tally_instance, initialize_sel, app_key)
102+
app_key = objc.msg_send(
103+
"NSString",
104+
"stringWithUTF8String:",
105+
"xPEj7uv0KuziQnXUyPIBNUjnDvvHuW09VOYFuLYBcY-jV6fgqmfy5B1y75_iSuRM5U2zNq7MRoR9N1F-UthTEgv-QBWk68gr95BrAySzWuDzt08FrkeBZWQCGyZ0iAybalYLOJEF7nkKBtmDGLewcw==",
106+
)
144107

145-
encrypt_str = objc_create_ns_string(emu, '{"biClassId":["2","3","4"]}')
146-
encrypt_bytes = emu.call_symbol("_objc_msgSend", encrypt_str, data_using_encoding_sel, 1)
108+
objc.msg_send(ali_tiger_tally_instance, "initialize:", app_key)
147109

148-
vmp_sign = emu.call_symbol("_objc_msgSend", ali_tiger_tally_instance, vmp_sign_sel, encrypt_bytes)
110+
encrypt_str = objc.msg_send("NSString", "stringWithUTF8String:", '{"biClassId":["2","3","4"]}')
111+
encrypt_bytes = objc.msg_send(encrypt_str, "dataUsingEncoding:", 1)
149112

150-
logger.info("vmp sign: %s", objc_read_ns_string(emu, vmp_sign))
113+
vmp_sign = objc.msg_send(ali_tiger_tally_instance, "vmpSign:", encrypt_bytes)
114+
logger.info("vmp sign: %s", emu.read_string(objc.msg_send(vmp_sign, "cStringUsingEncoding:", 4)))
151115

152116

153117
if __name__ == "__main__":

0 commit comments

Comments
 (0)