记一次钉钉自动签到
声明:只是为了学习追求技术的提升,如有侵权,请告知删除
使用条件
钉钉课程打卡
版本
钉钉5.0.12
钉钉5.0.15
其他版本敬请摸索
工具
xposed,Android Studio
开发基础
xposed.rimet
这个项目原是skywei的钉钉助手开源项目,我拿来重复造轮子,如有侵权,敬请告知。
注意!以下内容必须是有钉钉源码才能看得懂
ddms查看堆栈
本步略过。懒得截图了
追溯调用
可以找到 Interative_helper,这个类(是混淆过的,需要寻找代码)找到了ctw$a 这个instance。发现几乎所有的call都是这个instance,于是用xposedHelper得到这个instance
代码如下
Class InterativeCardInternal= findClass(M.classz.class_defpackage_Interative_helper);
Object InterativeCardInstance= XposedHelpers.getStaticObjectField(InterativeCardInternal,"a");
除此之外,还有一个cardInstanceId十分关键,直接通过message类调用它的子类实现getCardId。
Object messageContent = XposedHelpers.callMethod(message, getXString(M.method.method_wukong_im_message_MessageImpl_messageContent)); long cardId=(long)XposedHelpers.callMethod(messageContent,"getCardId");
获得的信息类似于下图args:
还需要进行下一步转换,由于该项目没有JSON,于是直接饮用alibaba的fastjson
Class ClassJSON=findClass(M.classz.class_com_alibaba_fastjson_JSON);
Object Jobject= XposedHelpers.callStaticMethod(ClassJSON,"parseObject","{\"actionData\":{\"bizType\":\"1\"},\"actionId\":\"\",\"actionType\":\"0\",\"cardInstanceId\":\""+cardId+"\"}");
直接调用a方法,实现按钮点击
XposedHelpers.callMethod(InterativeCardInstance,"a",cardId,Jobject);
这一步实现了但是还没有结束,因为服务器是接收到了签到信息,事实上也是签到完成了,但是客户端没有及时处理这个消息。所以我们需要更新一下数据库,这里直接copy反撤回代码。
Method methodMessageUpdate = findMatcherMethod( M.classz.class_defpackage_MessageDs, M.method.method_defpackage_MessageDs_update, String.class, String.class, List.class); Class classIMDatabase = findClass(M.classz.class_wukong_im_base_IMDatabase); String dbName = (String) XposedHelpers.callStaticMethod(classIMDatabase, getXString(M.method.method_wukong_im_base_IMDatabase_getWritableDatabase)); methodMessageUpdate.invoke(null, dbName, cid, Collections.singletonList(message));
完整代码
private void handlerLessonMessage(String cid, Object message){ if (!mEnableLesson)return; // 直接根据消息类型来处理 Object messageContent = XposedHelpers.callMethod(message, getXString(M.method.method_wukong_im_message_MessageImpl_messageContent)); long cardId=(long)XposedHelpers.callMethod(messageContent,"getCardId"); try { Class InterativeCardInternal= findClass(M.classz.class_defpackage_Interative_helper); Object InterativeCardInstance= XposedHelpers.getStaticObjectField(InterativeCardInternal,"a"); Class ClassJSON=findClass(M.classz.class_com_alibaba_fastjson_JSON); Object Jobject= XposedHelpers.callStaticMethod(ClassJSON,"parseObject","{\"actionData\":{\"bizType\":\"1\"},\"actionId\":\"\",\"actionType\":\"0\",\"cardInstanceId\":\""+cardId+"\"}"); //Log.d("sky","InterativeCardGot"); Log.d(TAG, "handlerLessonMessage: "+InterativeCardInstance.getClass().getName()); XposedHelpers.callMethod(InterativeCardInstance,"a",cardId,Jobject); Method methodMessageUpdate = findMatcherMethod( M.classz.class_defpackage_MessageDs, M.method.method_defpackage_MessageDs_update, String.class, String.class, List.class); Class classIMDatabase = findClass(M.classz.class_wukong_im_base_IMDatabase); String dbName = (String) XposedHelpers.callStaticMethod(classIMDatabase, getXString(M.method.method_wukong_im_base_IMDatabase_getWritableDatabase)); methodMessageUpdate.invoke(null, dbName, cid, Collections.singletonList(message)); } catch (Exception e) { e.printStackTrace(); } }
这个handleLesson类似于skywei项目的
handlerLuckyMessage等函数,我只是加入了一个cid参数,这个在上一层可以获取。
最后
特别感谢skywei的钉钉助手项目,这个项目在我的github上有,有兴趣的朋友右上角fork me 进入我的github可以查看