├── .gitignore ├── README.md ├── LICENSE ├── hook.py └── old └── hook.js /.gitignore: -------------------------------------------------------------------------------- 1 | /output -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # frida-wechat-sticker 2 | 3 | 提取 PC 微信加密的表情包 (V1MMWX) 4 | 5 | 仅在 3.6.0.18 经过测试 6 | 7 | 8 | 9 | ## usage 10 | 11 | ```bash 12 | pip install frida-tools 13 | # open wechat 14 | hook.py 15 | # hook.py [output dir] 16 | ``` 17 | 18 | 19 | 20 | ## Credits 21 | 22 | 23 | 24 | [牛掰!把微信表情包导出GIF文件](https://jishuin.proginn.com/p/763bfbd35068) 25 | 26 | [获取、导出微信所有表情](https://blog.csdn.net/qq_43572067/article/details/100062493) 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 K265 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /hook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from __future__ import print_function 5 | 6 | import hashlib 7 | import os 8 | import sys 9 | import time 10 | 11 | import frida 12 | 13 | output_dir = './output' 14 | 15 | 16 | def on_message(message, data): 17 | if message['payload'] == 'image': 18 | filename = hashlib.sha1(data).hexdigest() + '.gif' 19 | output = os.path.join(output_dir, filename) 20 | if os.path.exists(output): 21 | return 22 | 23 | with open(output, 'wb') as f: 24 | f.write(data) 25 | print(f"wrote {output}") 26 | else: 27 | print("[%s] => %s" % (message, data)) 28 | 29 | 30 | def main(): 31 | session = frida.attach('WeChat.exe') 32 | 33 | script = session.create_script(""" 34 | 35 | var baseAddr = Module.findBaseAddress("VoipEngine.dll"); 36 | console.log("VoipEngine.dll baseAddr: " + baseAddr); 37 | 38 | if (baseAddr) { 39 | // isWxGF 函数偏移地址, 从 DLL 中查看 40 | var isWxGF = baseAddr.add(0x2fd760); 41 | console.log("isWxGF 函数地址: " + isWxGF); 42 | 43 | // hook 函数, 监听参数 44 | Interceptor.attach(isWxGF, { 45 | onEnter: function (args) { 46 | var gif = Memory.readByteArray(args[0], args[1].toInt32()); 47 | send('image', gif); 48 | }, 49 | }); 50 | } else { 51 | console.log("VoipEngine.dll 模块未加载"); 52 | } 53 | """) 54 | script.on('message', on_message) 55 | script.load() 56 | print("[!] Ctrl+D on UNIX, Ctrl+Z on Windows/cmd.exe to detach from instrumented program.\n\n") 57 | sys.stdin.read() 58 | session.detach() 59 | 60 | 61 | if __name__ == '__main__': 62 | if len(sys.argv) >= 2: 63 | output_dir = sys.argv[1] 64 | if not os.path.exists(output_dir): 65 | os.makedirs(output_dir) 66 | main() 67 | -------------------------------------------------------------------------------- /old/hook.js: -------------------------------------------------------------------------------- 1 | var baseAddr = Module.findBaseAddress("VoipEngine.dll"); 2 | console.log("VoipEngine.dll baseAddr: " + baseAddr); 3 | 4 | if (baseAddr) { 5 | // isWxGF 函数偏移地址, 从 DLL 中查看 6 | var isWxGF = baseAddr.add(0x2fd760); 7 | console.log("isWxGF 函数地址: " + isWxGF); 8 | 9 | // hook 函数, 监听参数 10 | Interceptor.attach(isWxGF, { 11 | onEnter: function (args) { 12 | var gif = Memory.readByteArray(args[0], args[1].toInt32()); 13 | var filename = "r:/" + new Date().getTime() + ".gif"; 14 | var f = new File(filename, "wb"); 15 | f.write(gif); 16 | f.flush(); 17 | f.close(); 18 | }, 19 | }); 20 | } else { 21 | console.log("VoipEngine.dll 模块未加载"); 22 | } 23 | 24 | // /* 25 | // * @name 微信小程序PC版 wxapkg提取 26 | // * @author kksanyu 27 | // * @url https://github.com/kksanyu/frida_with_wechat_applet 28 | // */ 29 | 30 | // var baseAddr = Module.findBaseAddress('WeChatAppHost.dll'); 31 | // console.log('WeChatAppHost.dll baseAddr: ' + baseAddr); 32 | 33 | // if (baseAddr) { 34 | 35 | // // EncryptBufToFile函数偏移地址, 从DLL中查看 36 | // var EncryptBufToFile = baseAddr.add(0x1800F); 37 | // console.log('EncryptBufToFile 函数地址: ' + EncryptBufToFile); 38 | 39 | // // HOOK函数, 监听参数 40 | // Interceptor.attach(EncryptBufToFile, { 41 | // onEnter: function (args) { 42 | // // 微信小程序AppId 43 | // this.appId = ptr(args[0]).readPointer().readAnsiString(); 44 | // // 微信小程序本地缓存文件路径 45 | // this.apkgFilePath = ptr(args[1]).readPointer().readAnsiString(); 46 | // // 小程序代码原始内容(未加密) 47 | // this.originalData = Memory.readByteArray(args[2], args[3].toInt32()); 48 | // }, 49 | // onLeave: function (retval) { 50 | // console.log('文件解密成功', this.apkgFilePath); 51 | 52 | // // 将文件替换为未加密的wxapkg包 53 | // var f = new File(this.apkgFilePath, 'wb'); 54 | // f.write(this.originalData); 55 | // f.flush(); 56 | // f.close(); 57 | 58 | // // 释放内存 59 | // delete this.appId; 60 | // delete this.apkgFilePath; 61 | // delete this.originalData; 62 | // } 63 | // }); 64 | 65 | // } else { 66 | // console.log('WeChatAppHost.dll 模块未加载, 请先打开界面中的小程序面板'); 67 | // } 68 | --------------------------------------------------------------------------------