大神论坛

找回密码
快速注册
查看: 68 | 回复: 0

[macOS] AnyGo for mac破解教程 手机虚拟位置修改工具通杀 附源码

digest

主题

帖子

0

积分

初入江湖

UID
591
积分
0
精华
威望
0 点
违规
大神币
68 枚
注册时间
2023-09-16 15:09
发表于 2024-03-17 22:24
本帖最后由 zhangdexi 于 2024-03-17 22:24 编辑

关于

AnyGo for Mac是一款专门设计用于iOS设备的虚拟定位软件。
通过连接到Mac,用户可以轻松地修改iPhone或iPad上的GPS位置,无需越狱。

环境/软件

分析

打开软件后有一个检测是否国区, 如果是则直接退出

目录全局搜索,匹配到以下资源文件

"%@ is not served in current region." = "%@不在该地区服务";

之后在 hopper 中搜索 is not served in current region, 得到下图的引用;

0000000100088e18         db         "%@ is not served in current region.", 0

调用类objc_cls_ref_GlobalFunction的俩个方法 isForTest 与 isInChina , 来判断是否弹框, 然后退出;
这里我们不用管 isForTest, 大概率是软件作者测试用的, 由于是 isInChina objc 的原生方法, 可用 method_exchangeImplementations 来交换方法, 替换成我们自己的, 来达到 hook 的目的;

method_exchangeImplementations 是 Objective-C 中的一个函数,它允许你交换一个类中两个方法的实现。
这在方法混合(method swizzling)中非常有用,方法混合是一种在运行时对方法实现进行操作的技术,通常用于调试或在不使用子类化的情况下扩展现有类的功能。

+ (int)hk_isInChina {
NSLog(@">>>>>> Swizzled hk_isInChina method called");
NSLog(@">>>>>> self.className : %@", self.className);
return 0;
}

[MemoryUtils hookClassMethod:
objc_getClass("GlobalFunction")
originalSelector:NSSelectorFromString(@"isInChina")
swizzledClass:[self class]
swizzledSelector:@selector(hk_isInChina)
];

之后打补丁,dylib 注入,重启 APP;
此刻 APP 可以正常打开了, 然后我们尝试连接手机修改位置;提示要购买;

根据提示全局搜素资源文件, 匹配到以下资源文件

"You are using the trial version. Please buy the full version to remove the limitations." = "您正在使用试用版。请购买完整版本以解除限制。";

之后在 hopper 中搜索 buy the full version to remove the limitations;

定位到了函数 / home.php?mod=space&uid=341152 RegisterLimitWinCtr / -(void)awakeFromNib 之后, 便查不到引用了;

我们在函数 awakeFromNib 下一个断点; 然后重启 APP, 让程序断下来,之后查看 堆栈 (通常只看主程序领空下的);

将这几个程序领空的栈帧地址挨个在 hopper 中打开分析; 看到#8堆栈里有一个关键函数;

/* @class MapViewCtr */
-(int)setAllowOperation:(int)arg2 {
var_50 = arg0;
r13 = [arg2 retain];
rax = [RegisterManager shareManager];
rax = [rax retain];
r14 = [rax isRegistered];
[rax release];
rax = [r13 objectForKey:@"pathType"];
rax = [rax retain];
var_40 = [rax intValue];
[rax release];
var_48 = r13;
if (r14 != 0x0) {

}else {
// 弹框
}

r14 = [[RegisterManager shareManager]] isRegistered
这里我们只需要让 r14 也就是 isRegistered 返回 true 即可跳过弹框;
与前面一样, 由于是 objc 的原生方法, 直接用 method_exchangeImplementations 机制来 hook

- (BOOL)hk_isRegistered {
NSLog(@">>>>>> Swizzled hk_isRegistered method called");
return YES;
}

[MemoryUtils hookInstanceMethod:
objc_getClass("RegisterManager")
originalSelector:NSSelectorFromString(@"isRegistered")
swizzledClass:[self class]
swizzledSelector:@selector(hk_isRegistered)
];

之后打包,dylib 注入, 重启;
启动后,发现试用购买的提示已经没有了, 但是修改手机位置的时候还是报错;

全局扫描资源文件:

"You have exceeded the number of allowed installations." = "您已超出设备台数限制。";
000000010009a2a1 db "You have exceeded the number of allowed installations."

查看引用;发现有三个地方;把这三个地方全部下断点;然后连接手机修改位置

程序最终在这里断下来了;
麻烦来了, 这里的代码里也没有逻辑判断的地方,而且这个方法查不到引用的地方;
堆栈数据也分析不出来有用的信息;

由于我们上一步断点断在了 ConnectViewCtr, 所以我们直接点类一样的倒数第二个引用进去,切到假码;

r12 = [[RegisterManager shareManager] retain];
rax = [r13 device];
rax = [rax retain];
r15 = rax;
rax = [rax UDID];
rax = [rax retain];
var_29 = [r12 isOverDevicesLimit:rax];
[rax release];
[r15 release];
[r12 release];
[rbx release];
if (var_29 == 0x0) goto loc_10003a8f1;

看到这一句 r12 isOverDevicesLimit:rax], 顿时豁然开朗, 拉屎都通畅了,不多说,按照前面的姿势,直接 hook;

- (BOOL)hk_isOverDevicesLimit {
NSLog(@">>>>>> Swizzled hk_isOverDevicesLimit method called");
return NO;
}

[MemoryUtils hookInstanceMethod:
objc_getClass("RegisterManager")
originalSelector:NSSelectorFromString(@"isOverDevicesLimit:")
swizzledClass:[self class]
swizzledSelector:@selector(hk_isOverDevicesLimit)
];

最后打包,dylib 注入, 重启, 连接手机,改一个 南极洲 看看效果吧;


下方隐藏内容为本帖所有文件或源码下载链接:

游客你好,如果您要查看本帖隐藏链接需要登录才能查看, 请先登录

返回顶部