Theos Hook Objective-C classes / methods with Unicode Characters

于是今天看到有人在问使用 THEOS 来 hook 带有汉字的 Objective-C 的方法时会有类似如下的报错。

$ make
> Making all for tweak UnicodeHook…
==> Preprocessing Tweak.xm…
==> Compiling Tweak.xm (armv7)…
Tweak.xm:3:1: error: missing context for method declaration
- (id)中文方法名 {
^
1 error generated.
THEOS complaints about unicode characters
THEOS complaints about unicode characters

于是研究了 THEOS 的源代码,给出了一个简单的解决办法,不仅可以 Hook 带有汉字的方法,带有日文、阿拉伯文等等的方法 / Objective-C 类,只要这些 identifier 在 Objective-C 的语法规则中被认可,那就都可以被 Hook。而且在写 %group 的时候也可以使用除 ACSII 以外的文字了。

THEOS 的语法是 Logos,而 Logos 是用 Perl 写的,

Perl(ww
Perl(ww

那么直接看 Logos 处理 xm 过程吧,文件是 theos/bin/logos.pl。定位到第 324 行,这里就是处理 "- (id)中文方法名 {" 的地方。

......
} elsif($currentClass && $line =~ /\G([+-])\s*\(\s*(.*?)\s*\)(?=\s*[\$_\w])/gc && $directiveDepth < 1) {
# [+-] (<return>)<[X:]>, but only when we're in a %hook.
......

可以看到正则表达式只允许了'$', '_', 以及由 ASCII 可打印字符所组成的 words,于是这里要想让汉字和其他理论上可行的 Unicode 字符通过正则表达式就可以了。

鉴于不同语言的字符在不同区域,要精确控制并不方便,考虑到平时写 Hook 的时候也不会随意写上什么字符,于是我将这里的规则改为如下(注意下面绿色背景高亮的部分)

......
} elsif($currentClass && $line =~ /\G([+-])\s*\(\s*(.*?)\s*\)(?=\s*[^\s])/gc && $directiveDepth < 1) {
# [+-] (<return>)<[X:]>, but only when we're in a %hook.
......

在这上面还有其他的几个判断规则,从上到下分别是匹配

  • %hook <identifier>
  • %subclass <identifier> : <identifier> \<<protocols ...>\>
  • %group <identifier>
  • %class [+-]<identifier>
  • %c([+-]<identifier>)

于是把它们的匹配规则一并改了。

......
if($line =~ /\G%hook\s+([^\s]+)/gc) {
    # "%hook <identifier>"
......
} elsif($line =~ /\G%subclass\s+([^\s]+)\s*:\s*([^\s]+)\s*(\<\s*(.*?)\s*\>)?/gc) {
    # %subclass <identifier> : <identifier> \<<protocols ...>\>
......
} elsif($line =~ /\G%group\s+([^\s]+)/gc) {
    # %group <identifier>
......
} elsif($line =~ /\G%class\s+([+-])?([^\s]+)/gc) {
    # %class [+-]<identifier>
......
} elsif($line =~ /\G%c\(\s*([+-])?([^\s]+)\s*\)/gc) {
   # %c([+-]<identifier>)
......
}
......

这样调整之后,就可以在 %hook, %subclass, %group, %class 和 %c 的对应的地方使用 Unicode 字符了,使用效果如下

Compile successfully with unicode characters
Compile successfully with unicode characters

使用 Hopper 反编译对应的 dylib 也可以看到

Disassemble in Hopper
Disassemble in Hopper

于是你可以考虑自己手动改,也可以去 git clone 我的修改过的 theos,theos

Leave a Reply

Your email address will not be published. Required fields are marked *

four × one =