吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8416|回复: 20
收起左侧

[MacOS逆向] 新版Mac wx双开的实现

[复制链接]
zwo 发表于 2020-1-19 19:22
本帖最后由 zwo 于 2020-1-19 19:27 编辑

新版Mac wx(2.4.0)带来了一波新功能,包括万众期待的小程序,然而在拥抱新功能的同时,多开插件失效了。

01.png

首先想到新版的小程序会不会也是一个小程序对应一个新开的进程?这样小程序挂了不会导致主程序也挂。开一个小程序验证如下
09.png
可以看到的确两个实例都是通过主程序启动的。


下面就通过IDA分析一下,把app拖进去,经过若干小时的等待后,IDA完成了分析。由于是复用同一个实例,很可能在程序的入口就做了分支。先看看入口函数的流程,不难看出程序里每个关键的地方几乎都有日志输出,大大方便了我们的分析。
03.png
04.png

在日志的加持下,重新梳理了一下启动流程如下:
05.png

可见如果满足了实例个数小于2就可以直接初始化一个新的微信实例。可以通过hook返回实例数组的方法runningApplicationsWithBundleIdentifier,不过为了避免副作用,还是直接改掉跳转指令吧,也就是把jb改成jmp
06.png

另外一个存在的问题是,如果这样改,会使小程序的正常打开受到影响。可以通过设置个标志来判断是否需要修改跳转指令。
完整代码如下:
[Objective-C] 纯文本查看 复制代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <objc/message.h>
#import <Cocoa/Cocoa.h>

#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <mach-o/dyld.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#include <stdio.h>
#include <sys/sysctl.h>
#include <mach/mach.h>
#include <unistd.h>

static void patch_mem(uintptr_t p,unsigned int data){
    int page = getpagesize();
    uintptr_t address = (uintptr_t)(p);
    uintptr_t base = address/page * page;
    mach_port_t self = mach_task_self();
    kern_return_t error;
    if((page - (uintptr_t)(p) - base)<12){
        page *= 2;
    }
    if((error = vm_protect(self,base,page,FALSE ,VM_PROT_READ|VM_PROT_WRITE|VM_PROT_COPY))){
        return;
    }
*(unsigned int *) p = data;
    if((error = vm_protect(self,base,page,FALSE,VM_PROT_READ|VM_PROT_EXECUTE))){
        return;
    }
}

@implementation NSObject (WeChatTweak)

static void __attribute__((constructor)) tweak(void) {

    class_addMethod(objc_getClass("AppDelegate"), @selector(applicationDockMenu:), method_getImplementation(class_getInstanceMethod(objc_getClass("AppDelegate"), @selector(tweak_applicationDockMenu:))), "@:@"); 

    [NSObject alwaysOpenNewWeChat];
}

- (void)alwaysOpenNewWeChat
{
        NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
        NSString *flag=[defaults objectForKey:@"com.wechattweak"];
        if (flag)
        {
                const struct mach_header *mhp = _dyld_get_image_header(0);  
            uintptr_t module_base_cursor = (uintptr_t)mhp;
            // 0F 82 9E 02 00 00 jb -> E9 9F 02 00 00 jmp
            uintptr_t targetCursor = module_base_cursor + 0xf5a94f;
            patch_mem(targetCursor,0x29fe9);
            [defaults setObject:nil forKey:@"com.wechattweak"];
            [defaults synchronize];
        }
}

- (NSMenu *)tweak_applicationDockMenu:(NSApplication *)sender {
    NSMenu *menu = [[NSMenu alloc] init];
    NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:@"登录新的微信账号" action:@selector(openNewWeChatInstace:) keyEquivalent:@""];
    [menu insertItem:menuItem atIndex:0];
    return menu;
}

- (void)openNewWeChatInstace:(id)sender {
    NSString *applicationPath = [[NSBundle mainBundle] bundlePath];
    NSTask *task = [[NSTask alloc] init];
    task.launchPath = @"/usr/bin/open";
    task.arguments = @[@"-n", applicationPath];
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
    [defaults setObject:@"flag" forKey:@"com.wechattweak"];
    [defaults synchronize];
    [task launch];
}

@end


有一点需要注意的是,如果把上面代码编译成动态库并通过环境变量DYLD_INSERT_LIBRARIES注入,由于NSTask会继承父程序的所有环境变量,建议通过绝对路径来指定,并放在app的沙盒可以访问的位置。适用于以下版本
07.png

P.S. 用之前post的app web view调试方法 https://www.52pojie.cn/thread-1068599-1-1.html ,可以看出小程序其实是个web容器,可以通过web调试器看到里面的布局。
08.png

可惜网络请求是通过底层的原生代码完成的,没办法直接调试,有时间我还会进一步研究。

免费评分

参与人数 8威望 +2 吾爱币 +14 热心值 +8 收起 理由
wzxc + 1 + 1 我很赞同!
6620 + 1 + 1 我很赞同!
董... + 1 + 1 我很赞同!
Mint_Grass + 1 + 1 我很赞同!
Hmily + 2 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
む人生似梦 + 1 + 1 我很赞同!
xr5101616 + 1 + 1 热心回复!
陈世界 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

shawhero928 发表于 2020-1-21 10:56
异界封侯 发表于 2020-1-20 13:35
微信双开?有这么费劲吗

我记得是cmd+N    难倒最新的10.15双开软件快捷键失效了么= =
kuruite 发表于 2020-1-19 22:30
yonghune 发表于 2020-1-19 22:48
学士天下 发表于 2020-1-20 08:28
感觉挺厉害的,给作者点赞!!!
洋辣子 发表于 2020-1-20 09:27
感谢分享
linguo2625469 发表于 2020-1-20 10:47
挺厉害的,学习一下
hu3167343 发表于 2020-1-20 11:17
Lz牛逼,学习了~
异界封侯 发表于 2020-1-20 13:35
微信双开?有这么费劲吗
搜索中文字符串 发表于 2020-1-20 14:56
膜拜大神深分析
riverwind 发表于 2020-1-20 14:57
技术贴,涨姿势,谢谢分享!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 21:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表