IT评测·应用市场-qidao123.com

标题: 通杀修改微信版本(过旧版微信)以及查找微信数据库密钥 [打印本页]

作者: 一给    时间: 2024-10-12 01:36
标题: 通杀修改微信版本(过旧版微信)以及查找微信数据库密钥
这段时间闲来无事,遂打算逆向pc微信,看了下三年前写的代码,发现微信以及提示旧版本登录不上去,那么就开始研究一下如何绕过吧。
代码是用python实现的,主要使用到的库有
  1. import frida
  2. import os
  3. import sys, segno
  4. import re, time
  5. from win32api import HIWORD, LOWORD, GetFileVersionInfo
  6. import binascii
  7. import struct
  8. from pymem import Pymem, pattern, process
复制代码
先说一下思绪,既然需要登录旧版的微信,那么需要知道微信是如何验证的,上网搜了一下,大多是用易语言实现的成品,起不到学习的作用,有一篇大佬写的文章,大家可以去看一下,微信过低版本限制逆向分析_微信逆向-CSDN博客 实在过这种微信版本检测,千变万化,很多种办法,我这里主要实现的逻辑是 获取当前微信的版本,再在内存里搜刮,然后修改成想要的版本,实现图片如下。



很多大佬实现的方式是特征码+dll模块基址偏移  +读取&修改内存实现目标,我的就比较简朴粗暴,使用搜刮内存的办法进行暴力搜刮。
还添加了一个功能,获取内存里的微信db数据库密钥。详细实现如下。

以及精确定位手机号的功能,可以精确定位得手机号,就可以实现很多功能, 这里用CE检察可以看到它是由基址+偏移实现的。


这个找手机号的代码我会贴在下面,有需要自取。
至于拿到的数据库暗码就可以解密本地的数据库文件,看看内里有什么内容。
关于Session内里会话的内容

关于关注的微信公众号数据

关于你所有的微信好友的信息

还有很多数据库存放不同范例的数据,这个是MicroMsg.db数据库,其他的玩法自己探索吧。
下面贴代码:
这是搜刮手机号的焦点代码;
  1. module = pymem.process.module_from_name(pm.process_handle, module_name)
  2.         base_address = module.lpBaseOfDll
  3.         module_size = module.SizeOfImage
  4.         print(f"{module_name} 基地址: 0x{base_address:x}")
  5.         print(f"{module_name} 大小: 0x{module_size:x}")
  6.         found_phone_numbers = []
  7.         # 遍历模块内存,搜索字符串
  8.         for address in range(base_address, base_address + module_size, 4096):
  9.             try:
  10.                 # 读取内存块
  11.                 data = pm.read_bytes(address, 4096)
  12.                 # 提取可打印的ASCII字符串
  13.                 printable_data = ''.join([chr(b) if 32 <= b < 127 else '\0' for b in data])
  14.                 # 使用正则表达式匹配手机号码
  15.                 phone_numbers = re.findall(r'\b1\d{10}\b', printable_data)
  16.                 for number in phone_numbers:
  17.                     # 添加找到的手机号码及其地址
  18.                     number_address = address + printable_data.index(number)
  19.                     found_phone_numbers.append((number_address, number))
  20.             except pymem.exception.MemoryReadError:
  21.                 pass
  22.         if not found_phone_numbers:
  23.             print("[!] 未找到符合条件的手机号码")
  24.         else:
  25.             for number_address, number in found_phone_numbers:
  26.                 print(f"找到手机号码 '{number}',地址: 0x{number_address:x}")
  27.                 # 在手机号附近遍历内存,搜索符合规则的字符串
  28.                 search_range = 200  # 设置搜索范围为手机号附近50字节
  29.                 try:
  30.                     data = pm.read_bytes(number_address - search_range, search_range * 2)
  31.                     # 提取可打印的ASCII字符串
  32.                     printable_data = ''.join([chr(b) if 32 <= b < 127 else '\0' for b in data])
  33.                     # 使用正则表达式匹配符合规则的字符串
  34.                     valid_strings = re.findall(r'\b[A-Za-z_][A-Za-z0-9_-]{5,19}\b', printable_data)
  35.                     for string in valid_strings:
  36.                         if string.lower() not in ["iphone", "android"]:
  37.                             string_address = number_address - search_range + printable_data.index(string)
  38.                             print(f"找到符合规则的字符串 '{string}',地址: 0x{string_address:x}")
  39.                 except (pymem.exception.MemoryReadError, UnicodeDecodeError):
  40.                     pass
复制代码

这是通过静态找数据库密钥的代码:
  1. import pefile
  2. import re
  3. import capstone
  4. import struct
  5. pe = pefile.PE("D:\\Wechat\\[3.9.10.19]\\WeChatWin.dll")
  6. target_bytes = b"\x4F\x6E\x20\x53\x65\x74\x20\x49\x6E\x66\x6F\x20\x69\x6E\x66\x6F\x20\x6D\x64\x35"
  7. def find_byte_sequence(data, pattern):
  8.     return [m.start() for m in re.finditer(re.escape(pattern), data)]
  9. rdata_sections = [section for section in pe.sections if b'.rdata' in section.Name]
  10. data_offset = 0
  11. for section in rdata_sections:
  12.     section_data = section.get_data()
  13.     start_address = section.VirtualAddress
  14.     matches = find_byte_sequence(section_data, target_bytes)
  15.     if matches:
  16.         for offset in matches:
  17.             data_offset = offset + section.VirtualAddress
  18.             # print(f"{data_offset:04x}")
  19. target_bytes = b"\x48\x8D\x05"
  20. code_sections = [section for section in pe.sections if b'.text' in section.Name]
  21. for section in code_sections:
  22.     section_data = section.get_data()
  23.     start_address = section.VirtualAddress
  24.     cs = capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_64)
  25.     matches = find_byte_sequence(section_data, target_bytes)
  26.     if matches:
  27.         for offset in matches:
  28.             inst = list(cs.disasm(section_data[offset:offset + 7], offset + start_address))[0]
  29.             unpacked_value = struct.unpack("<I", inst.bytes[3:])[0]
  30.             if inst.address + inst.size + unpacked_value == data_offset:
  31.                 instructions = list(
  32.                     cs.disasm(section_data[inst.address - start_address:inst.address - start_address + 256],
  33.                               inst.address))
  34.                 call = 0
  35.                 for inst in instructions:
  36.                     if inst.mnemonic == "call":
  37.                         call = call + 1
  38.                         if call == 2:
  39.                             addr = int(inst.op_str, 16)
  40.                             instructions = list(
  41.                                 cs.disasm(section_data[addr - start_address:addr - start_address + 256], addr))
  42.                             for inst in instructions:
  43.                                 # print(f"{inst.address:04x}: {inst.mnemonic} {inst.op_str}")
  44.                                 opcode = inst.bytes
  45.                                 if len(opcode) == 1 and opcode[0] == 0xC3:
  46.                                     break
  47.                                 if len(opcode) > 3:
  48.                                     if opcode[0] == 0x48 and opcode[1] == 0x8D and opcode[2] == 0x05:
  49.                                         unpacked_value = struct.unpack("<I", opcode[3:])[0]
  50.                                         as_addr = inst.address + inst.size + unpacked_value
  51.                                         dbkey_offset = 1760
  52.                                         print("final AccoutService addr:", as_addr, hex(as_addr))
  53.                                         print("final DBkey addr:", as_addr + dbkey_offset, hex(as_addr + dbkey_offset))
  54.                 break
复制代码
 这是通过Frida 搜刮wechatwin.dll模块的内存达到修改微信版本号的焦点js代码
  1. frida_script = """
  2.     const moduleName = 'WeChatWin.dll';
  3.     const targetValue = {target_value};
  4.     const newValue = {new_value};
  5.     function intToBytesLE(value) {{
  6.         let bytes = [];
  7.         for (let i = 0; i < 4; i++) {{
  8.             bytes.push(value & 0xFF);
  9.             value = value >> 8;
  10.         }}
  11.         return bytes;
  12.     }}
  13.     function bytesToHex(bytes) {{
  14.         return bytes.map(byte => ('0' + (byte & 0xFF).toString(16)).slice(-2)).join('');
  15.     }}
  16.     const targetBytes = intToBytesLE(targetValue);
  17.     const targetPattern = bytesToHex(targetBytes);
  18.     function searchAndModifyMemory() {{
  19.         var module = Process.findModuleByName(moduleName);
  20.         if (!module) {{
  21.             console.log(moduleName + ' 模块未找到');
  22.             send(null);
  23.             return;
  24.         }}
  25.         var baseAddress = module.base;
  26.         var moduleSize = module.size;
  27.         console.log(moduleName + ' 基地址: ' + baseAddress);
  28.         console.log(moduleName + ' 大小: ' + moduleSize);
  29.         var modifiedAddresses = [];
  30.         Memory.scan(baseAddress, moduleSize, targetPattern, {{
  31.             onMatch: function(address, size) {{
  32.                 console.log('找到目标数值 0x' + targetValue.toString(16) + ' 在地址: ' + address);
  33.                 Memory.writeUInt(address, newValue);
  34.                 modifiedAddresses.push(address.toString());
  35.             }},
  36.             onComplete: function() {{
  37.                 if (modifiedAddresses.length === 0) {{
  38.                     console.log('未在内存中搜索到目标数值');
  39.                     send(null);
  40.                 }} else {{
  41.                     console.log('数值修改完成');
  42.                     send(modifiedAddresses);
  43.                 }}
  44.             }}
  45.         }});
  46.     }}
  47.     searchAndModifyMemory();
  48.     """.format(target_value=target_value, new_value=new_value)
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4