Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于遍历找key (def get_key(pid, db_path, addr_len):) #102

Closed
TaihouKai opened this issue Jun 13, 2024 · 5 comments
Closed

关于遍历找key (def get_key(pid, db_path, addr_len):) #102

TaihouKai opened this issue Jun 13, 2024 · 5 comments

Comments

@TaihouKai
Copy link

TaihouKai commented Jun 13, 2024

我自己手动写代码测试了这个遍历找key的get_key function:

void_p = ctypes.c_void_p
addr_len = 64
pid = 9092
pm = pymem.Pymem(pid)
module_name = "WeChatWin.dll"
MicroMsg_path = "MicroMsg.db"
MicroMsg_path = os.path.join("C:\\Users\\<USERNAME>\\Documents\\WeChat Files\\wxid_<ID>\\", "MSG", "MicroMsg.db")
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory

def read_key_bytes(h_process, address, address_len=8):
  # ... copy-paste

def verify_key(key, wx_db_path):
  # ... copy-paste

phone_type1 = "iphone\x00"
phone_type2 = "android\x00"
phone_type3 = "ipad\x00"

type1_addrs = pm.pattern_scan_module(phone_type1.encode(), module_name, return_multiple=True)
type2_addrs = pm.pattern_scan_module(phone_type2.encode(), module_name, return_multiple=True)
type3_addrs = pm.pattern_scan_module(phone_type3.encode(), module_name, return_multiple=True)
if type1_addrs == None or type2_addrs == None or type3_addrs == None:
    print("Error: pattern_scan_module failed")
    exit()

print(type1_addrs, type2_addrs, type3_addrs)

type_addrs = []
if len(type1_addrs) >= 2: type_addrs += type1_addrs
if len(type2_addrs) >= 2: type_addrs += type2_addrs
if len(type3_addrs) >= 2: type_addrs += type3_addrs
if len(type_addrs) == 0:
    print("Error: type_addrs is empty")
    exit()

type_addrs.sort()
print(type_addrs)

for i in type_addrs[::-1]:
    for j in range(i, i - 2000, -addr_len):
        key_bytes = read_key_bytes(pm.process_handle, j, addr_len)
        if key_bytes == "None":
            continue
        # print(key_bytes.hex())
        if verify_key(key_bytes, MicroMsg_path):
            key = key_bytes.hex()

print(key)

我发现addr_len=64的情况下找不到key,只有在addr_len=16或者8的情况下可以。
(我试过get_exe_bit,确实返回的是64)
请问这是为什么?

@simoole
Copy link

simoole commented Jun 13, 2024

因为key是个32位的字节串

@TaihouKai
Copy link
Author

TaihouKai commented Jun 13, 2024

因为key是个32位的字节串

感谢回复。如果按照代码里的话,get_exe_bit会返回64吧?(因为是64位的exe)
那样的话addr_len就得是64了……?

(get_wx_info.py)

addrLen = get_exe_bit(process.exe())
...
...
if rd['filePath'] != "None" and rd['key'] == "None" and not isKey:
    rd['key'] = get_key(rd['pid'], rd['filePath'], addrLen) 

@xaoyaoo
Copy link
Owner

xaoyaoo commented Jun 13, 2024

这个和系统位数以及内存读写方式有关。
32位系统和64位系统,对内存读写单元大小不同。

@TaihouKai
Copy link
Author

TaihouKai commented Jun 14, 2024

这个和系统位数以及内存读写方式有关。
32位系统和64位系统,对内存读写单元大小不同。

感谢回复。
这样的话,如果我要手动复现遍历,请问这个地方的for j in range(i, i - 2000, -addr_len):是不是该改成-int(addr_len/8),以匹配读写单元的大小(4/8 bytes)?我试了下,不改成/8的话在我的电脑上遍历不着key

for i in type_addrs[::-1]:
    for j in range(i, i - 2000, -addr_len):
        key_bytes = read_key_bytes(pm.process_handle, j, addr_len)
        if key_bytes == "None":
            continue
        # print(key_bytes.hex())
        if verify_key(key_bytes, MicroMsg_path):
            key = key_bytes.hex()

@xaoyaoo
Copy link
Owner

xaoyaoo commented Jun 14, 2024

@TaihouKai
所以你已经有了结论。

@xaoyaoo xaoyaoo closed this as completed Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants