企业微信签到反编译

公司最近要企业微信签到了 好麻烦 每次下班总是忘记所以做了这个东西

#关于企业微信的 LibFakeLocation

包名:com.tencent.ww
前面的 就是 脱壳 ida 分析等步骤就省略了

##1.修改定位
首先开始的时候,想从签到的界面入手,直接通过Reveal分析签到界面
WWKAttendanceCheckViewController
发现他代理CLLocationManagerDelegate 来获取地理位置

  • (void)locationManager:(id)arg1 didUpdateLocations:(id)arg2;
    本来准备在这边改写的,后来发现了看到了糖小虾的关于PokemonGo修改定位日志更好的方法
    直接Method Swizzling 苹果的CLLocation的 coordinate 的get 方法,每当调用来获取坐标位置时来返回我们给他设好的默认值。
    参见 点这里
    ##2.如何将默认值设成动态可调的
    单纯的写死一个值以后,以后遇到在外考勤相关的时候,并不能打卡因为定位都是在自己预设的默认值上面,所以需要一个配置入口,最开始的想法是通过给自己发送某个固定文本的消息格式来做文字识别,然后将获取的x,y值存下来,用户上面方法的返回,按照这个思路去分析的话,先通过Reveal和Cycript来找到目标的VC的位置WWKConversationViewController
    看了一下他的头文件,准备在接收时候截取:
  • (void)OnAddMessage:(const vector_b095e902 *)arg1 end:(_Bool)arg2 inConversation:(scoped_refptr_fd92d7bf)arg3;

发现参数是个 (const vector_b095e902 *)arg1 应该是个结构体, 感觉有点不好处理 ,之前没有做过类似的反编译,在ida分析的过程中发现了有调用WWKMessage 类中的

  • (scoped_refptr_c1fa851d)getModelMessage; 有点纠结,这条路就作罢。
    峰回路转:
    后来在研究对话界面的时候,居然发现了有个发送位置的功能,岂不是可以直接获取这个位置的信息并设为我们的默认值?
    赶紧回到WWKConversationViewController的头文件中,结果发现了这么一推函数:
- (void)sm_sendEmotionWithData:(id)arg1 height:(float)arg2 width:(float)arg3 isDynamic:(BOOL)arg4;
- (void)sm_sendImage:(id)arg1 isHD:(BOOL)arg2;
- (void)sm_sendImageWithData:(id)arg1 isHD:(BOOL)arg2;
- (void)sm_sendLocation:(id)arg1;
- (void)sm_sendMessage:(id)arg1;
- (void)sm_sendTextMessage:(id)arg1;
- (void)sm_sendVoiceMessage:(id)arg1 duration:(double)arg2;

显然我们的目标函数就是- (void)sm_sendLocation:(id)arg1; 赶紧的给他上断点,lldb跑一下 看下这个id参数到底是个啥
打印出来的日志一看:

Process 4122 stopped

  • thread #1: tid = 0x1fb91, 0x001fe200 wework___lldb_unnamed_function7527$$wework, name = 'WeWork_MainThread', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x001fe200 wework___lldb_unnamed_function7527$$wework
    wework`___lldb_unnamed_function7527$$wework:
    → 0x1fe200 <+0>: push {r4, r5, r6, r7, lr}
    0x1fe202 <+2>: add r7, sp, #0xc
    0x1fe204 <+4>: push.w {r8, r10, r11}
    0x1fe208 <+8>: sub.w r4, sp, #0x40
    (lldb) po $r2
    0xc07a1f0 address = 奥体 & detailAddressName = 江苏省南京市建邺区奥体 & coordinate.lat = 32.001842 & coordinate.lng = 118.738358 & zoom = 0.000000 remote_id = 2951973348021359636

果然看到了coordinate的两个参数 那不就妥了么?
在头文件里全局搜索了一下 detailAddressName这个参数 ,发现了 一个 WWKLocationItem

@interface WWKLocationItem : NSObject <NSCopying>
{
    NSString *_remoteID;
    NSString *_addressName;
    NSString *_detailAddressName;
    double _zoom;
    CDStruct_2c43369c _coordinate;
}

完全符合打印的日志

剩下来就是编写hook代码了 详情见github吧
当时卡主我比较久的是结构体的hook 因为CDStruct_2c43369c 这个东西就是CLLocationCoordinate2D的结构体
最后通过这个方法取出来了 ,不知道各位有没有更好的方法,各位可以分享一下。

Ivar nsCoordinateIvar = class_getInstanceVariable(objc_getClass("WWKLocationItem"), "_coordinate");
ptrdiff_t offset = ivar_getOffset(nsCoordinateIvar);
unsigned char *stuffBytes = (unsigned char *)(__bridge void *)arg1;
CLLocationCoordinate2D posLL = * ((CLLocationCoordinate2D *)(stuffBytes + offset));

详细代码见 GitHub
libFakeLocation

2 个赞