Open jwwang2003 opened 2 years ago
Would appreciate it if you can provide more information or a minimum code with reproducible steps.
The init-agent-script file
console.log('Hello from init-agent-script')
//3.3.0.115
const offset = {
node_offset: 0x1db9728,
handle_offset: 0xe4,
send_txt_call_offset: 0x3e3b80,
hook_point: 0x40d3b1,
chatroom_node_offset: 0xb08,
nickname_offset: 0x1ddf534,
wxid_offset: 0x1ddf4bc,
head_img_url_offset: 0x1ddf7fc,
is_logged_in_offset: 0x1DDF9D4,
hook_on_login_offset: 0x51B790,
hook_on_logout_offset: 0x51C2C0,
hook_get_login_qr_offset: 0x4B6020,
hook_check_login_qr_offset: 0x478B90,
hook_save_login_qr_info_offset: 0x3DB2E0,
get_login_wnd_offset: 0x1DB96A4,
get_qr_login_data_offset: 0x282160,
get_qr_login_call_offset: 0x286930,
send_picmsg_call_offset1: 0x5ccb50,
send_picmsg_call_offset2: 0x6f5c0,
send_picmsg_call_offset3: 0x3e3490,
send_attatch_call_offset1: 0x5ccb50,
send_attatch_call_offset2: 0x5ccb10,
send_attatch_call_offset3: 0x5ccb50,
send_attatch_call_offset4: 0x5ccb50,
send_attatch_call_offset5: 0x074c90,
send_attatch_call_offset6: 0x2e2720,
send_attatch_call_para: 0x19a7350,
chatroom_member_nick_call_offset1: 0x558cb0,
chatroom_member_nick_call_offset2: 0x3b0fe0,
chatroom_member_nick_call_offset3: 0x55f6e0,
chatroom_member_nick_call_offset4: 0x34cb10,
};
//3.3.0.115
/*------------------global-------------------------------------------*/
const availableVersion = 1661141107 ////3.3.0.115
const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll')
const moduleLoad = Module.load('WeChatWin.dll')
let currentVersion = 0
let nodeList = [] //for contact
let contactList = [] //for contact
let chatroomNodeList = [] //for chatroom
let chatroomMemberList = []//for chatroom
let loggedIn = false
const hookLogoutEventCallback = (() => {
const nativeCallback = new NativeCallback(() => { }, 'void', ['int32'])
const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32'])
Interceptor.attach(moduleBaseAddress.add(offset.hook_on_logout_offset), {
onEnter: function (args) {
const bySrv = args[0].toInt32()
console.log(bySrv)
return bySrv
setImmediate(() => nativeativeFunction(bySrv))
}
})
return nativeCallback
})()
const getMyselfInfoFunction = (() => {
let ptr = 0
let wx_code = ''
let wx_id = ''
let wx_name = ''
let head_img_url = ''
wx_id = readString(moduleBaseAddress.add(offset.wxid_offset))
wx_code = wx_id
wx_name = readString(moduleBaseAddress.add(offset.nickname_offset))
head_img_url = readString(moduleBaseAddress.add(offset.head_img_url_offset))
const myself = {
id: wx_id,
code: wx_code,
name: wx_name,
head_img_url: head_img_url,
};
return JSON.stringify(myself)
})
const callLoginQrcodeFunction = ((forceRefresh = false) => {
const json = getQrcodeLoginData()
console.log(json)
if (!forceRefresh && json.uuid) {
return
}
const callAsm = Memory.alloc(Process.pageSize)
const loginWnd = moduleBaseAddress.add(offset.get_login_wnd_offset).readPointer()
Memory.patchCode(callAsm, Process.pageSize, code => {
var cw = new X86Writer(code, { pc: callAsm })
cw.putPushfx();
cw.putPushax();
cw.putMovRegAddress('ecx', loginWnd)
cw.putCallAddress(moduleBaseAddress.add(offset.get_qr_login_call_offset))
cw.putPopax()
cw.putPopfx()
cw.putRet()
cw.flush()
})
const nativeativeFunction = new NativeFunction(ptr(callAsm), 'void', [])
nativeativeFunction()
})
const getQrcodeLoginData = () => {
const getQRCodeLoginMgr = new NativeFunction(moduleBaseAddress.add(offset.get_qr_login_data_offset), 'pointer', [])
const qlMgr = getQRCodeLoginMgr()
console.log(qlMgr)
const json = {
status: 0,
uuid: '',
wxid: '',
avatarUrl: '',
}
if (!qlMgr.isNull()) {
json.uuid = readString(qlMgr.add(8))
json.status = qlMgr.add(40).readUInt()
json.wxid = readString(qlMgr.add(44))
json.avatarUrl = readString(qlMgr.add(92))
}
return json
}
const readString = (address) => {
return readStringPtr(address).readUtf8String()
}
const readStringPtr = (address) => {
const addr = ptr(address)
const size = addr.add(16).readU32()
const capacity = addr.add(20).readU32()
addr.ptr = addr
addr.size = size
addr.capacity = capacity
if (capacity > 15 && !addr.readPointer().isNull()) {
addr.ptr = addr.readPointer()
}
addr.ptr._readCString = addr.ptr.readCString
addr.ptr._readAnsiString = addr.ptr.readAnsiString
addr.ptr._readUtf8String = addr.ptr.readUtf8String
addr.readCString = () => { return addr.size ? addr.ptr._readCString(addr.size) : '' }
addr.readAnsiString = () => { return addr.size ? addr.ptr._readAnsiString(addr.size) : '' }
addr.readUtf8String = () => { return addr.size ? addr.ptr._readUtf8String(addr.size) : '' }
// console.log('readStringPtr() address:',address,' -> str ptr:', addr.ptr, 'size:', addr.size, 'capacity:', addr.capacity)
// console.log('readStringPtr() str:' , addr.readUtf8String())
// console.log('readStringPtr() address:', addr,'dump:', addr.readByteArray(24))
return addr
}
The main index.ts file
import fs from 'fs'
import path from 'path'
import {
Sidecar,
SidecarBody,
Call,
Hook,
Ret,
RetType,
ParamType,
attach,
detach,
agentTarget
} from 'sidecar'
import { codeRoot } from '../commonjs/code-root'
const initAgentScript = fs.readFileSync(path.join(
codeRoot,
'src',
'init-agent-script.js',
), 'utf-8')
@Sidecar(
'WeChat.exe',
initAgentScript,
)
class ChatboxSidecar extends SidecarBody {
@Call(agentTarget('callLoginQrcodeFunction'))
callLoginQrcode (
forceRefresh: boolean,
):Promise<null> { return Ret(forceRefresh) }
@Call(agentTarget('getMyselfInfoFunction'))
getMyselfInfo ():Promise<string> { return Ret() }
@Hook(agentTarget('hookLogoutEventCallback'))
logoutEvent (
@ParamType('int32', 'U32') bySrv: number,
) { return Ret(bySrv) }
}
async function main () {
const sidecar = new ChatboxSidecar()
await attach(sidecar)
console.log(await sidecar.getMyselfInfo())
sidecar.on('hook', ({ method, args }) => {
console.log('method:', method)
console.log('args:', args)
})
process.on('SIGINT', () => detach(sidecar))
process.on('SIGTERM', () => detach(sidecar))
}
main().catch(console.error)
Some of this code was taken from wechaty-xp, just experimenting with sidecar because this is my first time. Will later use this with a newer version of WeChat. I am currently using the latest version of "sidecar": "^1.0.19".
Thanks for the new information.
I will take a look when I got time with a windows VPS . (Currently I have no windows dev machine)
Have you joined the XP WeChat room? If not, please feel free to san the below qrcode to join and ask your question over there, with other sidecar users.
Enable experimentalDecorators
and emitDecoratorMetadata
in tsconfig.json
Hi, anyone interested in Puppet XP will be welcome to join the Discord for future discussion. Invitation link: https://discord.gg/uE8Tb77VBm
Happy New Year 2024!
The
@ParamType
causes the following error:If I don't include
@ParamType
, the application works without any errors.