|
[原创] Thunder.app 2.x 逆向分析,实现免登录 + 会员加速
#!/usr/bin/env python3 # requires XCode import subprocess, sys, os, hashlib, plistlib package = '/Applications/Thunder.app/Contents' executable = os.path.join(package, 'MacOS/Thunder') plugins_dir = os.path.join(package, 'BrowserPlugins') def backup(): from shutil import copyfile backup = executable + '.bak' if os.path.isfile(backup): print('Backup found, maybe the file has already been patched.') sys.exit(-1) copyfile(executable, backup) def patch_exec(): try: output = subprocess.check_output(['nm', executable]) except: print('Failed to execute nm, please install XCode.') sys.exit(-1) ret_1 = b'\x48\xc7\xc0\x01\x00\x00\x00\xc3' ret_0 = b'\x48\x31\xc0\xc3' ret = b'\xc3' patches = { ret_1: [ '-[LocalTask isValidLixianTask]', '-[UserController isVip]', '-[UserController isPlatinum]', '-[UserController isDiamond]', '-[UserController isLogined]' ], ret_0: [ '-[AutoLiveUpdateController _shouldCheckUpdate:]', ], ret: [ '-[MainWndCtrl checkUpdate:]' ] } lookup = {} for code, symbols in patches.items(): for symbol in symbols: lookup[symbol] = code base = None output = output.decode('utf8') with open(executable, 'r+b') as f: for line in output.splitlines(): if '__mh_execute_header' in line: base, *_ = line.split() base = int(base, 16) if not base: print('Failed to retrive base address') sys.exit(-1) for line in output.splitlines(): if not len(lookup): break for symbol, code in lookup.items(): if symbol in line: addr, *_ = line.split() addr = int(addr, 16) offset = addr - base f.seek(offset, 0) f.write(code) # patch function print('%s has been patched.' % symbol) lookup.pop(symbol) break print('remove signature') args = ['codesign', executable, '--remove-signature'] try: subprocess.check_output(args) except: print('failed to remove signature, try run following command manually:') print(' '.join(args)) print('Successfully patched %s' % executable) def patch_self_check(): m = hashlib.md5() with open(executable, 'rb+') as f: while True: buf = f.read(1) if not buf: break m.update(buf) f.seek(1023, 1) digest = m.digest() lookup = (15, 4, 6, 3, 1, 0, 7, 8, 2, 11, 10, 13, 12, 14, 9, 5) hexdigest = ''.join(['%0.2X' % digest[index] for index in lookup]) dirname = os.path.join(plugins_dir, hexdigest) if not os.path.isdir(dirname): os.mkdir(dirname) def clear_quit_flag(): plist_path = os.path.join(os.environ.get( 'HOME'), 'Library/Preferences/com.xunlei.Thunder.plist') with open(plist_path, 'rb+') as f: pref = plistlib.load(f) force_quit = pref.get('ForceQuit') if force_quit: pref.update({'ForceQuit': True}) plistlib.dump(pref, f) print('Clear quit flag') if __name__ == '__main__': backup() patch_exec() patch_self_check() clear_quit_flag() 顺带去除检查更新。解析符号和偏移使用了 nm,需要安装 Xcode |
|
|
|
[讨论]看雪的登录验证码有意思吗
一行js自动填写验证码 |
|
|
|
[分享]逆向整理包编译通过版鬼影3.0代码~
前来膜拜V大~~~ |
|
|
|
[原创]丢几个好东西,完整可编译的ie2、ie5.5源码,嘿嘿
机器翻译的吧……“请在24小时之内删除”翻译成“请在24小时之后删除” |
|
|
|
|
|
|
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值