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

v1.12.5 #159

Merged
merged 2 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions src/init-agent-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -1006,25 +1006,18 @@ const recvMsgNativeCallback = (() => {
moduleBaseAddress.add(offset.hook_point),
{
onEnter() {
const addr = this.context.eax//0xc30-0x08
let addr
let msgType = 0
let isMyMsg = 0

let curTime = new Date()
try {
addr = this.context.eax//0xc30-0x08
msgType = addr.add(0x38).readU32()

} catch (err) {
console.error('line at msgType = addr.add(0x38).readU32():', err)
}

try {
isMyMsg = addr.add(0x3C).readU32()//add isMyMsg

} catch (err) {
console.error('line at isMyMsg = addr.add(0x3C).readU32():', err)
console.error(curTime,'recvMsgNativeCallback at onEnter err:', err)
}


if (msgType > 0) {

const talkerIdPtr = addr.add(0x48).readPointer()
Expand Down
107 changes: 31 additions & 76 deletions src/puppet-xp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ import {

import { WeChatSidecar } from './wechat-sidecar.js'
import { ImageDecrypt } from './pure-functions/image-decrypt.js'
import { XmlDecrypt } from './pure-functions/xml-msgpayload.js'
// import type { Contact } from 'wechaty'
import timersPromise from 'timers/promises'

// 定义一个延时方法
async function wait (ms:number) {
return new Promise(resolve => setTimeout(resolve, ms))
}

const userInfo = os.userInfo()
const rootPath = `${userInfo.homedir}\\Documents\\WeChat Files\\`
Expand Down Expand Up @@ -697,18 +702,15 @@ class PuppetXp extends PUPPET.Puppet {
messageId: string,
): Promise<string> {
log.verbose('PuppetXp', 'messageContact(%s)', messageId)
const parser = new xml2js.Parser(/* options */)
const messageJson = await parser.parseStringPromise(this.messageStore[messageId]?.text || '')

// log.info(JSON.stringify(messageJson))

return messageJson.msg['$'].username
const message = this.messageStore[messageId]
return await XmlDecrypt(message?.text || '', message?.type || PUPPET.types.Message.Unknown)
}

override async messageImage (
messageId: string,
imageType: PUPPET.types.Image,
): Promise<FileBoxInterface> {

log.info('PuppetXp', 'messageImage(%s, %s[%s])',
messageId,
imageType,
Expand All @@ -718,19 +720,21 @@ class PuppetXp extends PUPPET.Puppet {
const message = this.messageStore[messageId]
let base64 = ''
let fileName = ''
let imagePath = ''
let file:FileBoxInterface

try {
if (message?.text) {
const picData = JSON.parse(message.text)
const filePath = picData[imageType]
const dataPath = rootPath + filePath // 要解密的文件路径
log.info(dataPath, true)

// 如果请求的是大图等待2s
if (imageType === PUPPET.types.Image.HD) {
await timersPromise.setTimeout(1000)
if (fs.existsSync(dataPath)) {
log.info(dataPath, true)
} else {
await timersPromise.setTimeout(1000)
await wait(1500)
if (!fs.existsSync(dataPath)) {
await wait(1500)
}
}

Expand All @@ -742,11 +746,19 @@ class PuppetXp extends PUPPET.Puppet {
console.info(dataPath, imageInfo.fileName, imageInfo.extension)
base64 = imageInfo.base64
fileName = `message-${messageId}-url-${imageType}.${imageInfo.extension}`
file = FileBox.fromBase64(
base64,
fileName,
)
const paths = dataPath.split('\\')
paths[paths.length - 1] = fileName
imagePath = paths.join('\\')
// console.debug(imagePath)
await file.toFile(imagePath)
}
} catch (err) {
console.error(err)
}

return FileBox.fromBase64(
base64,
fileName,
Expand Down Expand Up @@ -827,77 +839,20 @@ class PuppetXp extends PUPPET.Puppet {

override async messageUrl (messageId: string): Promise<PUPPET.payloads.UrlLink> {
log.verbose('PuppetXp', 'messageUrl(%s)', messageId)
// const attachment = this.mocker.MockMessage.loadAttachment(messageId)
// if (attachment instanceof UrlLink) {
// return attachment.payload
// }

// log.info('PuppetXp', 'message(%s)',this.messageStore[messageId]?.text)

const parser = new xml2js.Parser(/* options */)
const messageJson = await parser.parseStringPromise(this.messageStore[messageId]?.text || '')

// log.info(JSON.stringify(messageJson))
const appmsg = messageJson.msg.appmsg[0]

const UrlLinkPayload: PUPPET.payloads.UrlLink = {
description: appmsg.des[0],
thumbnailUrl: appmsg.appattach[0].cdnthumburl,
title: appmsg.title[0],
url: appmsg.url[0],
}

return UrlLinkPayload

const message = this.messageStore[messageId]
return await XmlDecrypt(message?.text || '', message?.type || PUPPET.types.Message.Unknown)
}

override async messageMiniProgram (messageId: string): Promise<PUPPET.payloads.MiniProgram> {
log.verbose('PuppetXp', 'messageMiniProgram(%s)', messageId)
// const attachment = this.mocker.MockMessage.loadAttachment(messageId)
// if (attachment instanceof MiniProgram) {
// return attachment.payload
// }
// log.verbose('PuppetXp', 'message(%s)', this.messageStore[messageId]?.text)

const parser = new xml2js.Parser(/* options */)
const messageJson = await parser.parseStringPromise(this.messageStore[messageId]?.text || '')

// log.info(JSON.stringify(messageJson))

const appmsg = messageJson.msg.appmsg[0]

const MiniProgramPayload: PUPPET.payloads.MiniProgram = {
appid: appmsg.weappinfo[0].appid[0], // optional, appid, get from wechat (mp.weixin.qq.com)
description: appmsg.des[0], // optional, mini program title
iconUrl: appmsg.weappinfo[0].weappiconurl[0], // optional, mini program icon url
pagePath: appmsg.weappinfo[0].pagepath[0], // optional, mini program page path
shareId: appmsg.weappinfo[0].shareId[0], // optional, the unique userId for who share this mini program
thumbKey: appmsg.appattach[0].cdnthumbaeskey[0], // original, thumbnailurl and thumbkey will make the headphoto of mini-program better
thumbUrl: appmsg.appattach[0].cdnthumburl[0], // optional, default picture, convert to thumbnail
title: appmsg.title[0], // optional, mini program title
username: appmsg.weappinfo[0].username[0], // original ID, get from wechat (mp.weixin.qq.com)
}
return MiniProgramPayload
const message = this.messageStore[messageId]
return await XmlDecrypt(message?.text || '', message?.type || PUPPET.types.Message.Unknown)
}

override async messageLocation (messageId: string): Promise<PUPPET.payloads.Location> {
log.verbose('PuppetXp', 'messageLocation(%s)', messageId)
const parser = new xml2js.Parser(/* options */)
const messageJson = await parser.parseStringPromise(this.messageStore[messageId]?.text || '')

log.info(JSON.stringify(messageJson))

const location = messageJson.msg.location[0]['$']

const LocationPayload: PUPPET.payloads.Location = {
accuracy: location.scale, // Estimated horizontal accuracy of this location, radial, in meters. (same as Android & iOS API)
address: location.label, // "北京市北京市海淀区45 Chengfu Rd"
latitude: location.x, // 39.995120999999997
longitude: location.y, // 116.334154
name: location.poiname, // "东升乡人民政府(海淀区成府路45号)"
}

return LocationPayload
const message = this.messageStore[messageId]
return await XmlDecrypt(message?.text || '', message?.type || PUPPET.types.Message.Unknown)
}

override async messageRawPayloadParser (payload: PUPPET.payloads.Message) {
Expand Down
9 changes: 9 additions & 0 deletions src/pure-functions/xml-msgpayload.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env -S ts-node --project tsconfig.cjs.json

import { test } from 'tstest'

import { XmlDecrypt } from './xml-msgpayload.js'

test('CJS: codeRoot()', async t => {
t.ok(XmlDecrypt, 'should exist XmlDecrypt')
})
102 changes: 102 additions & 0 deletions src/pure-functions/xml-msgpayload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import xml2js from 'xml2js'
// import readXml from 'xmlreader'
import * as PUPPET from 'wechaty-puppet'
import { log } from 'wechaty-puppet'
// import type {
// FileBoxInterface,
// } from 'file-box'
// import {
// FileBox,
// FileBoxType,
// } from 'file-box'

async function XmlDecrypt (xml: string, msgType: PUPPET.types.Message): Promise<any> {
let res
log.verbose('PuppetXp', 'text xml:(%s)', xml)

const parser = new xml2js.Parser(/* options */)
const messageJson = await parser.parseStringPromise(xml || '')
// log.info(JSON.stringify(messageJson))

switch (msgType) {
case PUPPET.types.Message.Attachment:
break
case PUPPET.types.Message.Audio:
break
case PUPPET.types.Message.Contact: {
res = messageJson.msg['$'].username
break
}
case PUPPET.types.Message.ChatHistory:
break
case PUPPET.types.Message.Emoticon:
break
case PUPPET.types.Message.Image:
break
case PUPPET.types.Message.Text:
break
case PUPPET.types.Message.Location: {
const location:any = messageJson.msg.location[0]['$']
const LocationPayload: PUPPET.payloads.Location = {
accuracy: location.scale, // Estimated horizontal accuracy of this location, radial, in meters. (same as Android & iOS API)
address: location.label, // "北京市北京市海淀区45 Chengfu Rd"
latitude: location.x, // 39.995120999999997
longitude: location.y, // 116.334154
name: location.poiname, // "东升乡人民政府(海淀区成府路45号)"
}

res = LocationPayload
break
}
case PUPPET.types.Message.MiniProgram: {
const appmsg = messageJson.msg.appmsg[0]
const MiniProgramPayload: PUPPET.payloads.MiniProgram = {
appid: appmsg.weappinfo[0].appid[0], // optional, appid, get from wechat (mp.weixin.qq.com)
description: appmsg.des[0], // optional, mini program title
iconUrl: appmsg.weappinfo[0].weappiconurl[0], // optional, mini program icon url
pagePath: appmsg.weappinfo[0].pagepath[0], // optional, mini program page path
shareId: appmsg.weappinfo[0].shareId[0], // optional, the unique userId for who share this mini program
thumbKey: appmsg.appattach[0].cdnthumbaeskey[0], // original, thumbnailurl and thumbkey will make the headphoto of mini-program better
thumbUrl: appmsg.appattach[0].cdnthumburl[0], // optional, default picture, convert to thumbnail
title: appmsg.title[0], // optional, mini program title
username: appmsg.weappinfo[0].username[0], // original ID, get from wechat (mp.weixin.qq.com)
}
res = MiniProgramPayload
break
}
case PUPPET.types.Message.GroupNote:
break
case PUPPET.types.Message.Transfer:
break
case PUPPET.types.Message.RedEnvelope:
break
case PUPPET.types.Message.Recalled:
break
case PUPPET.types.Message.Url: {

// log.info(JSON.stringify(messageJson))
const appmsg = messageJson.msg.appmsg[0]

const UrlLinkPayload: PUPPET.payloads.UrlLink = {
description: appmsg.des[0],
thumbnailUrl: appmsg.appattach[0].cdnthumburl,
title: appmsg.title[0],
url: appmsg.url[0],
}

res = UrlLinkPayload
break
}
case PUPPET.types.Message.Video:
break
case PUPPET.types.Message.Post:
break
default:
res = {}

}
return res
}
export {
XmlDecrypt,
}