-
-
未解决 [求助]电脑端企业微信剪切板WeWork Message格式数据序列化和反序列化算法 3000雪币
-
发表于: 2025-12-9 12:16 761
-
自己分析了一个星期了也没有进展,普通的短的文字的还是可以拼凑出来的,但是超过一定长度或者是换了格式,拼凑出来的数据就不对了,有能分析的大佬帮忙看看是怎么处理的这个数据,感激不尽
为了方便测试,用AI写了个提取和写入的脚本,通过企业微信复制了内容之后,可以提取到“WeWork Message”格式的数据,以16进制的方式显示在软件上,下边是可以将16进制的内容写回剪切板,但是不知道他是通过什么方式转成16进制数据进行存储的,希望有大佬能帮忙把这个序列化和反序列化的方法通过python实现,这样就可以将我想要写入的内容直接写到剪切板了(不同的消息类型可能不一样,比如文字的、图片的、视频、视频号、卡片消息、消息记录等等)
import tkinter as tk
from tkinter import ttk
import win32clipboard as wcb
import win32con
import binascii
# 格式字典,用于将格式ID转换为可读名称
format_names = {
win32con.CF_TEXT: 'CF_TEXT',
win32con.CF_UNICODETEXT: 'CF_UNICODETEXT',
win32con.CF_BITMAP: 'CF_BITMAP',
win32con.CF_DIB: 'CF_DIB',
win32con.CF_DIBV5: 'CF_DIBV5',
win32con.CF_ENHMETAFILE: 'CF_ENHMETAFILE',
win32con.CF_METAFILEPICT: 'CF_METAFILEPICT',
win32con.CF_SYLK: 'CF_SYLK',
win32con.CF_DIF: 'CF_DIF',
win32con.CF_TIFF: 'CF_TIFF',
win32con.CF_OEMTEXT: 'CF_OEMTEXT',
win32con.CF_DIB: 'CF_DIB',
win32con.CF_PALETTE: 'CF_PALETTE',
win32con.CF_PENDATA: 'CF_PENDATA',
win32con.CF_RIFF: 'CF_RIFF',
win32con.CF_WAVE: 'CF_WAVE',
win32con.CF_UNICODETEXT: 'CF_UNICODETEXT',
win32con.CF_HDROP: 'CF_HDROP', # 文件拖放格式
win32con.CF_LOCALE: 'CF_LOCALE',
win32con.CF_DIBV5: 'CF_DIBV5',
win32con.CF_OWNERDISPLAY: 'CF_OWNERDISPLAY',
win32con.CF_DSPTEXT: 'CF_DSPTEXT',
win32con.CF_DSPBITMAP: 'CF_DSPBITMAP',
win32con.CF_DSPMETAFILEPICT: 'CF_DSPMETAFILEPICT',
win32con.CF_DSPENHMETAFILE: 'CF_DSPENHMETAFILE',
}
class WeWorkClipboardApp:
def __init__(self, root):
self.root = root
self.root.title("WeWork剪贴板同步工具")
self.root.geometry("600x500")
# 创建主框架
self.main_frame = ttk.Frame(self.root, padding="20")
self.main_frame.pack(fill=tk.BOTH, expand=True)
# 标题
self.title_label = ttk.Label(self.main_frame, text="WeWork Message 剪贴板工具", font=('Arial', 14, 'bold'))
self.title_label.pack(pady=10)
# 格式名称输入区域
self.format_frame = ttk.Frame(self.main_frame)
self.format_frame.pack(fill=tk.X, pady=10)
self.format_label = ttk.Label(self.format_frame, text="格式名称:")
self.format_label.pack(side=tk.LEFT, padx=5)
self.format_entry = ttk.Entry(self.format_frame, width=40)
self.format_entry.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
self.format_entry.insert(0, "WeWork Message") # 默认格式名称
# 提取数据按钮
self.extract_btn = ttk.Button(self.main_frame, text="提取数据", command=self.extract_wework_data)
self.extract_btn.pack(pady=10)
# 第一个输入框(显示提取的数据)
self.extract_label = ttk.Label(self.main_frame, text="提取的数据(十六进制):")
self.extract_label.pack(anchor=tk.W, pady=5)
self.extract_text = tk.Text(self.main_frame, height=8, width=60)
self.extract_text.pack(fill=tk.BOTH, expand=True, pady=5)
# 写入数据按钮
self.write_btn = ttk.Button(self.main_frame, text="写入数据", command=self.write_wework_data)
self.write_btn.pack(pady=10)
# 第二个输入框(输入要写入的数据)
self.write_label = ttk.Label(self.main_frame, text="要写入的数据(十六进制):")
self.write_label.pack(anchor=tk.W, pady=5)
self.write_text = tk.Text(self.main_frame, height=8, width=60)
self.write_text.pack(fill=tk.BOTH, expand=True, pady=5)
def extract_wework_data(self):
"""从剪贴板提取指定格式名称的数据,以十六进制形式显示"""
try:
# 获取用户输入的格式名称
target_format_name = self.format_entry.get().strip()
if not target_format_name:
self.extract_text.delete(1.0, tk.END)
self.extract_text.insert(1.0, "请输入格式名称,不输入则在日志中显示全部格式,并将最后一个格式输出在输入框内")
# return
wcb.OpenClipboard()
# 查找匹配的格式
target_format_id = None
found_data = None
# 获取第一个格式
format_id = wcb.EnumClipboardFormats(0)
formats_found = 0
while format_id:
formats_found += 1
# 尝试获取格式名称
current_format_name = ""
try:
current_format_name = wcb.GetClipboardFormatName(format_id)
except:
# 如果无法获取名称,使用预定义的格式名称或ID
current_format_name = format_names.get(format_id, f'自定义格式 (ID: {format_id})')
# 检查是否匹配目标格式名称
if current_format_name == target_format_name or target_format_name == '':
target_format_id = format_id
print(f"\n\n找到匹配的格式【{formats_found}】: {current_format_name} (ID: {format_id})")
# 尝试读取数据
try:
data = wcb.GetClipboardData(format_id)
if isinstance(data, bytes):
found_data = data
print(f" 数据大小: {len(data)} 字节")
# 打印前32字节的十六进制表示
print(f" 数据预览 : {data.hex()}")
# 增强的字符串转换尝试,使用多种编码
print(f" 文本转换尝试:")
try:
# 过滤掉控制字符和空白字符,只保留有效的文本部分
clean_data = ''.join(char for char in found_data.decode('utf-8', errors='replace') if ord(char) >= 32 or char in '\t\n\r')
if clean_data.strip():
print(f" [utf-8]: {clean_data}")
except Exception as enc_e:
print(f" [utf-8]: 解码失败 - {enc_e}")
elif isinstance(data, str):
found_data = data.encode('utf-8') # 转换为bytes
else:
# 其他类型转换为bytes
found_data = str(data).encode('utf-8')
if target_format_name != '':
break
except Exception as e:
print(f"读取数据时出错: {e}")
# 获取下一个格式
format_id = wcb.EnumClipboardFormats(format_id)
# 清空并显示提取的数据
self.extract_text.delete(1.0, tk.END)
if found_data:
self.extract_text.insert(1.0, found_data.hex())
else:
self.extract_text.insert(1.0, f"未找到格式为 '{target_format_name}' 的数据")
except Exception as e:
self.extract_text.delete(1.0, tk.END)
self.extract_text.insert(1.0, f"提取失败:{str(e)}")
finally:
try:
wcb.CloseClipboard()
except:
pass
def write_wework_data(self):
"""将十六进制数据转换为原始数据,按照指定格式名称写入剪贴板"""
try:
# 获取用户输入的格式名称
target_format_name = self.format_entry.get().strip()
if not target_format_name:
self.show_message("请输入格式名称")
return
# 获取输入框中的十六进制数据
hex_input = self.write_text.get(1.0, tk.END).strip()
if not hex_input:
self.show_message("请输入要写入的十六进制数据")
return
# 移除可能的空格和换行符
hex_input = ''.join(hex_input.split())
# 验证十六进制格式
if len(hex_input) % 2 != 0:
self.show_message("十六进制数据长度必须为偶数")
return
# 将十六进制字符串转换为二进制数据
raw_data = binascii.unhexlify(hex_input)
# 注册或获取目标格式ID
format_id = wcb.RegisterClipboardFormat(target_format_name)
print(f"注册/获取格式ID: {format_id} 用于格式名称: {target_format_name}")
wcb.OpenClipboard()
wcb.EmptyClipboard()
# 写入指定格式的数据
try:
wcb.SetClipboardData(format_id, raw_data)
print(f"成功写入数据到格式: {target_format_name} (ID: {format_id})")
except Exception as e:
print(f"写入指定格式数据失败: {e}")
# 尝试写入其他兼容格式
try:
# 写入CF_UNICODETEXT格式(如果数据是有效的Unicode)
unicode_text = raw_data.decode('utf-16-le')
wcb.SetClipboardData(win32con.CF_UNICODETEXT, unicode_text)
print("成功写入CF_UNICODETEXT格式")
except:
pass
wcb.CloseClipboard()
self.show_message(f"数据已成功写入剪贴板,格式名称: {target_format_name}")
except binascii.Error:
self.show_message("无效的十六进制数据,请检查输入格式")
except Exception as e:
self.show_message(f"写入失败:{str(e)}")
finally:
try:
if wcb.IsClipboardFormatAvailable(win32con.CF_UNICODETEXT):
wcb.CloseClipboard()
except:
pass
def show_message(self, message):
"""显示消息提示"""
# 创建临时提示窗口
msg_window = tk.Toplevel(self.root)
msg_window.title("提示")
msg_window.geometry("300x100")
msg_window.transient(self.root)
label = ttk.Label(msg_window, text=message)
label.pack(pady=20)
btn = ttk.Button(msg_window, text="确定", command=msg_window.destroy)
btn.pack()
if __name__ == "__main__":
root = tk.Tk()
app = WeWorkClipboardApp(root)
root.mainloop()
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
赞赏
赞赏
雪币:
留言: