diff --git a/README.md b/README.md index 66fdf73..00dff81 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,22 @@ Puppet|xp👍| 登录事件|✅ 依赖协议|Windows +## VERSION SUPPORT + +puppet-xp|wechat| +|:---|:---| +|1.11.14|[WeChat-v3.3.0.115](https://github.com/wechaty/wechaty-puppet-xp/releases/download/v0.5/WeChatSetup-v3.3.0.115.exe)| +|1.12.7|[WeChat-v3.6.0.18](https://github.com/tom-snow/wechat-windows-versions/releases/download/v3.6.0.18/WeChatSetup-3.6.0.18.exe)| +|1.3.x|[WeChat-v3.2.2.23](https://github.com/tom-snow/wechat-windows-versions/releases/download/v3.9.2.23/WeChatSetup-3.9.2.23.exe)| + ## HISTORY -### main v1.12.0 (November 22, 2022) +### next v1.13.0 (September 21, 2023) + +1. This version start to support WeChat v3.9.2.23,need to update WeChat on your pc to 3.9.2.23 +2. [WeChatSetup-v3.2.2.23.exe](https://github.com/tom-snow/wechat-windows-versions/releases/download/v3.9.2.23/WeChatSetup-3.9.2.23.exe) + +### main v1.12.7 (November 22, 2022) 1. This version start to support WeChat v3.6.0.18,need to update WeChat on your pc to 3.6.0.18 2. [WeChatSetup-v3.6.0.18.exe](https://github.com/tom-snow/wechat-windows-versions/releases/download/v3.6.0.18/WeChatSetup-3.6.0.18.exe) diff --git a/package.json b/package.json index 8e9f1dd..ffe22cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wechaty-puppet-xp", - "version": "1.12.7", + "version": "1.13.0", "description": "Puppet XP for Wechaty", "type": "module", "exports": { diff --git a/src/agents/agent-script-3.6.0.18.js b/src/agents/agent-script-3.6.0.18.js index b0dc6b1..6ae2c78 100644 --- a/src/agents/agent-script-3.6.0.18.js +++ b/src/agents/agent-script-3.6.0.18.js @@ -17,8 +17,8 @@ const offset = { /**---nick call */ - chatroom_member_nick_call_offset_v6:0x3E47B0,//3.6.0.18 - chatroom_member_nick_esi_offset_v6:0x22553D4, + chatroom_member_nick_call_offset_v6: 0x3E47B0,//3.6.0.18 + chatroom_member_nick_esi_offset_v6: 0x22553D4, /**-- nick call */ node_offset: 0x222f3bc,//0x1db9728 -- 3.3.0.155 handle_offset: 0x4c, @@ -38,13 +38,13 @@ const offset = { get_qr_login_data_offset: 0x282160, get_qr_login_call_offset: 0x286930, //-------3.6.0.18 send pic - send_picmsg_call_offset0:0x9A1C0,//assign value to ecx + send_picmsg_call_offset0: 0x9A1C0,//assign value to ecx send_picmsg_call_offset1: 0x4BE160,//0x5ccb50, - send_picmsg_call_ecx:0x222F0F0, + send_picmsg_call_ecx: 0x222F0F0, //-------3.6.0.18 send pic /*send_picmsg_call_offset2: 0x6f5c0, send_picmsg_call_offset3: 0x3e3490,*/ - send_attatch_ecx_offset:0x1D8FA8C, + send_attatch_ecx_offset: 0x1D8FA8C, send_attatch_call_offset0: 0x9A1C0, send_attatch_call_offset1: 0x701DC0,//0x701CD0,//701CD0 send_attatch_call_offset2: 0x4BA5F0,//4B A5F0 @@ -63,13 +63,13 @@ const offset = { /*------------------global-------------------------------------------*/ -const availableVersion = 1661337618////3.3.0.115 ==1661141107 +const availableVersion = 1661337618////3.3.0.115 ==1661141107 const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll') const moduleLoad = Module.load('WeChatWin.dll') //1575CF98 -const g_EDIPtr = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readPointer()// -const g_EDIU32 = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readU32() +const g_EDIPtr = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readPointer()// +const g_EDIU32 = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readU32() let currentVersion = 0 let nodeList = [] //for contact @@ -88,46 +88,46 @@ let loggedIn = false let g_initTestAsm = null let g_BufferEbp2C = null -let g_initECXU32 = null -let g_initECXPtr = null -let g_initEBXPtr = null -let g_initEBX = null +let g_initECXU32 = null +let g_initECXPtr = null +let g_initEBXPtr = null +let g_initEBX = null let g_attatchEBP210Buffer = null -let g_attatchPathPtr = null -let g_attatchPath = null -let g_attatchEBPAc = null -let g_attatchEBPAcBufPtr = null +let g_attatchPathPtr = null +let g_attatchPath = null +let g_attatchEBPAc = null +let g_attatchEBPAcBufPtr = null -let g_attatchContactIdPtr = null +let g_attatchContactIdPtr = null //let g_attatchECXBuffer = null -let g_attatchESIU32 = null +let g_attatchESIU32 = null -let g_initECXTempPtr = null -const initGlobal = ( (contactId,attatchFile)=> { +let g_initECXTempPtr = null +const initGlobal = ((contactId, attatchFile) => { //const base = moduleBaseAddress.add(0x222f38c).readPointer() //g_EDI = base.add(0xD70).readPointer()//0x438+0x938 - console.log('------------g_attatchEBPAc',g_attatchEBPAc) - console.log('------------g_EDIU32',g_EDIU32) + console.log('------------g_attatchEBPAc', g_attatchEBPAc) + console.log('------------g_EDIU32', g_EDIU32) g_initTestAsm = Memory.alloc(Process.pageSize) - console.log('------------address',g_initTestAsm) - + console.log('------------address', g_initTestAsm) + g_initECXPtr = g_EDIPtr.add(0xB80).readPointer().add(0x1640) g_initECXTempPtr = g_EDIPtr.add(0xB88).readPointer() g_initECXU32 = g_initECXPtr.toInt32() - g_attatchESIU32 = g_EDIU32 + g_attatchESIU32 = g_EDIU32 + + console.log('------------g_initECXU32', g_initECXU32) + console.log('------------g_initESIU32', g_attatchESIU32) - console.log('------------g_initECXU32',g_initECXU32) - console.log('------------g_initESIU32',g_attatchESIU32) - //console.log('==========g_initECXPtr',g_initECXPtr) //console.log('==========g_EDIU32',g_EDIU32) - + //g_attatchECXBuffer = Memory.alloc(0x1024) //Memory.copy(g_attatchECXBuffer, g_initECXPtr, 0x1024) - + g_BufferEbp2C = Memory.alloc(0x48) //g_initEBX = moduleBaseAddress.add(0x2251724).readPointer().readPointer() @@ -150,7 +150,7 @@ const initGlobal = ( (contactId,attatchFile)=> { g_attatchEBP210Buffer.add(0x2C).writeU32(moduleBaseAddress.add(0x2ECE87).toInt32()) //console.log('------------g_attatchEBP210Buffer',g_attatchEBP210Buffer) /*---------------------------------ebp-210----------------*/ - + //g_attatchContactIdPtr = Memory.alloc(0x4) //g_attatchContactIdPtr.writeUtf16String(contactId) //console.log('------------g_attatchEBP210Buffer',g_attatchEBP210Buffer) @@ -160,17 +160,17 @@ const initGlobal = ( (contactId,attatchFile)=> { //g_attatchEBPAc.add(0x4).writePointer(g_attatchEBPAcBufPtr) //g_attatchEBPAc.add(0x8).writePointer(g_attatchEBPAcBufPtr) g_attatchEBPAc.add(0x10).writeU32(g_EDIU32) - console.log('------------g_attatchEBPAc',g_attatchEBPAc) - + console.log('------------g_attatchEBPAc', g_attatchEBPAc) + /*g_attatchECXBuffer.add(0x18).writePointer(g_attatchContactIdPtr) g_attatchECXBuffer.add(0x1C).writeU32(contactId.length*2) .add(0x04).writeU32(contactId.length*2)*/ - + //g_attatchESIU32 = g_EDI.toInt32() - + //console.log('------------g_attatchESIU32',g_attatchESIU32) //console.log('==========g_attatchECXBuffer',g_attatchECXBuffer) @@ -188,7 +188,7 @@ const initGlobal = ( (contactId,attatchFile)=> { cw.putCallAddress(moduleBaseAddress.add(0x131bb0))*/ //cw.putMovRegOffsetPtrU32('ebp', -20, 0) - + /*cw.putPushU32(0) cw.putMovRegAddress('eax', g_attatchPathPtr) cw.putPushReg('eax') @@ -241,24 +241,24 @@ const initGlobal = ( (contactId,attatchFile)=> { }) -let g_personal_detail_ebx =null -let g_personal_detail_asm =null +let g_personal_detail_ebx = null +let g_personal_detail_asm = null let g_personal_wxid = null let g_personal_wxid_ptr = null -const getOldTest = ( (wxid) => {//personal detail +const getOldTest = ((wxid) => {//personal detail g_personal_detail_asm = Memory.alloc(Process.pageSize) g_personal_detail_ebx = moduleBaseAddress.add(0x222F38C).readPointer().add(0xFB8).toInt32() - - g_personal_wxid_ptr=Memory.alloc(wxid.length * 2 + 2) + + g_personal_wxid_ptr = Memory.alloc(wxid.length * 2 + 2) g_personal_wxid_ptr.writeUtf16String(wxid) - g_personal_wxid=Memory.alloc(0x14) + g_personal_wxid = Memory.alloc(0x14) g_personal_wxid.writePointer(ptr(g_personal_wxid_ptr)).add(0x04) - .writeU32(wxid.length*2).add(0x04) - .writeU32(wxid.length*2).add(0x08) + .writeU32(wxid.length * 2).add(0x04) + .writeU32(wxid.length * 2).add(0x08) - console.log('-----------address----------',g_personal_detail_asm) + console.log('-----------address----------', g_personal_detail_asm) Memory.patchCode(g_personal_detail_asm, Process.pageSize, code => { var cw = new X86Writer(code, { pc: g_personal_detail_asm }) @@ -269,14 +269,14 @@ const getOldTest = ( (wxid) => {//personal detail //78BA9ACE | E8 2D05D6FF | call wechatwin.7890A000 | cw.putMovRegU32('ebx', g_personal_detail_ebx) - cw.putMovRegReg('esi','eax') + cw.putMovRegReg('esi', 'eax') cw.putPushReg('ebx') - cw.putSubRegImm('esp',0x14) + cw.putSubRegImm('esp', 0x14) cw.putMovRegAddress('eax', g_personal_wxid) - cw.putMovRegReg('ecx','esp') + cw.putMovRegReg('ecx', 'esp') cw.putPushReg('eax') cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) - cw.putMovRegReg('ecx','esi') + cw.putMovRegReg('ecx', 'esi') cw.putCallAddress(moduleBaseAddress.add(0x4024A0)) cw.putPopax() @@ -313,33 +313,33 @@ const getOldTest = ( (wxid) => {//personal detail * test call */ let attatchTestAsm = null -let attatchTestEbp2C = null -let attatchGlobalEDI = null -let attatchGlobalEDIB88 = null +let attatchTestEbp2C = null +let attatchGlobalEDI = null +let attatchGlobalEDIB88 = null let attatchTestEBX = null let g_tempEcx = null let attatchFirstECX = null //let attatchFirstECX = null -let gattatchFilePtr=null +let gattatchFilePtr = null let gattatchFile = null -let gattatchReceiveIdPtr=null -let gattatchReceiveId=null -let attatchEAX3B0Buf=null +let gattatchReceiveIdPtr = null +let gattatchReceiveId = null +let attatchEAX3B0Buf = null -let attatchESIbuf = null -const getWxTest = ( (contactId,filePath)=>{ +let attatchESIbuf = null +const getWxTest = ((contactId, filePath) => { //const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) //nativeativeFunction() attatchTestAsm = Memory.alloc(Process.pageSize) - console.log('----------------address',attatchTestAsm) + console.log('----------------address', attatchTestAsm) attatchTestEbp2C = Memory.alloc(0xC) attatchGlobalEDI = moduleBaseAddress.add(0x222f38c).readPointer() - .add(0x938).add(0x438).readPointer() + .add(0x938).add(0x438).readPointer() attatchGlobalEDIB88 = attatchGlobalEDI.add(0xB88).readPointer() - attatchTestEBX = Memory.alloc(0x4) + attatchTestEBX = Memory.alloc(0x4) attatchTestEBX.writePointer(attatchGlobalEDI) - console.log('----------------attatchGlobalEDI',attatchGlobalEDI) - console.log('----------------attatchGlobalEDIB88',attatchGlobalEDIB88) + console.log('----------------attatchGlobalEDI', attatchGlobalEDI) + console.log('----------------attatchGlobalEDIB88', attatchGlobalEDIB88) attatchFirstECX = Memory.alloc(0x28) //const attatchSecondEcx = Memory.alloc(0x14) @@ -348,13 +348,13 @@ const getWxTest = ( (contactId,filePath)=>{ const contractIdActLength = contactId.length - gattatchReceiveIdPtr=Memory.alloc(contactId.length * 2 + 2) + gattatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) gattatchReceiveIdPtr.writeUtf16String(contactId) - gattatchReceiveId=Memory.alloc(0x14) + gattatchReceiveId = Memory.alloc(0x14) gattatchReceiveId.writePointer(ptr(gattatchReceiveIdPtr)).add(0x04) - .writeU32(contactId.length*2).add(0x04) - .writeU32(contactId.length*2).add(0x08) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x08) //console.log('----------------attatchGlobalEDIB88',attatchGlobalEDIB88) //return /*console.log(hexdump(attatchTestEBX, { @@ -365,56 +365,56 @@ const getWxTest = ( (contactId,filePath)=>{ })) return*/ - gattatchFilePtr=Memory.alloc(filePath.length * 2 + 2) + gattatchFilePtr = Memory.alloc(filePath.length * 2 + 2) gattatchFilePtr.writeUtf16String(filePath) - gattatchFile=Memory.alloc(0x14) + gattatchFile = Memory.alloc(0x14) gattatchFile.writePointer(ptr(gattatchFilePtr)).add(0x04) - .writeU32(filePath.length*2).add(0x04) - .writeU32(filePath.length*2).add(0x08) + .writeU32(filePath.length * 2).add(0x04) + .writeU32(filePath.length * 2).add(0x08) const attatchLastECX = moduleBaseAddress.add(0x222f170).toInt32() - attatchEAX3B0Buf = Memory.alloc(0x3B0) + attatchEAX3B0Buf = Memory.alloc(0x3B0) - g_tempEcx = Memory.alloc(0x4) + g_tempEcx = Memory.alloc(0x4) //g_tempEcx1 = Memory.alloc(0x4) attatchESIbuf = Memory.alloc(0x100) attatchESIbuf.add(0x0).writeU32(3) attatchESIbuf.add(0x4).writePointer(gattatchFilePtr) - attatchESIbuf.add(0x8).writeU32(filePath.length*2) - attatchESIbuf.add(0xc).writeU32(filePath.length*2) - + attatchESIbuf.add(0x8).writeU32(filePath.length * 2) + attatchESIbuf.add(0xc).writeU32(filePath.length * 2) + Memory.patchCode(attatchTestAsm, Process.pageSize, code => { var cw = new X86Writer(code, { pc: attatchTestAsm }) cw.putPushfx() cw.putPushax() //cw.putMovRegU32('edi',attatchGlobalEDI) - - cw.putMovRegAddress('esi',attatchESIbuf) - + + cw.putMovRegAddress('esi', attatchESIbuf) + cw.putMovRegAddress('ecx', attatchFirstECX.add(0x14)) cw.putMovRegAddress('eax', gattatchFile) cw.putPushReg('eax') cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) - + cw.putMovRegAddress('ecx', attatchFirstECX) cw.putMovRegU32('eax', contactIdLength) cw.putPushReg('eax') cw.putPushU32(0) cw.putCallAddress(moduleBaseAddress.add(0x1a11c83)) cw.putAddRegImm('esp', 0x8) - - cw.putMovRegReg('edx','eax') - cw.putMovNearPtrReg(attatchFirstECX,'edx') + + cw.putMovRegReg('edx', 'eax') + cw.putMovNearPtrReg(attatchFirstECX, 'edx') cw.putMovRegU32('edi', contactIdLength) cw.putPushReg('edi') cw.putMovRegAddress('eax', gattatchReceiveIdPtr)//ebp-58 cw.putPushReg('eax') - cw.putMovRegNearPtr('eax',attatchFirstECX) + cw.putMovRegNearPtr('eax', attatchFirstECX) cw.putPushReg('eax') cw.putCallAddress(moduleBaseAddress.add(0x1a1047a)) cw.putAddRegImm('esp', 0x0c) @@ -424,7 +424,7 @@ const getWxTest = ( (contactId,filePath)=>{ //cw.putMovRegU32('edx', 0) //cw.putMovRegRegPtr('eax', 'ecx') //cw.putMovNearPtrReg(attatchFirstECX.add(0x04),'edi') - cw.putMovRegU32('edi',contactId.length * 2) + cw.putMovRegU32('edi', contactId.length * 2) cw.putMovRegU32('ecx', attatchLastECX) cw.putMovRegAddress('eax', attatchEAX3B0Buf) cw.putPushReg('eax') @@ -451,8 +451,8 @@ const getTestInfoFunction = ((addr) => { nativeativeFunction() //00CFE484 - - + + /*MemoryAccessMonitor.enable({base:ptr(addr),size:0x01}, { onAccess(details){ console.log('============') @@ -492,7 +492,7 @@ const getHeaderNodeAddress = (() => { // 005 const getChatroomNodeAddress = (() => { - const baseAddress= moduleBaseAddress.add(0x222f3fc).readPointer() + const baseAddress = moduleBaseAddress.add(0x222f3fc).readPointer() if (baseAddress.isNull()) { return baseAddress } @@ -530,7 +530,7 @@ const getMyselfInfoFunction = (() => { const getMyselfIdFunction = (() => { let wx_id = readString(moduleBaseAddress.add(offset.wxid_offset)) - + return wx_id }) @@ -668,9 +668,9 @@ const recurseNew = ((node) => { //const gender = node.add(0x18C).readU32() const contactJson = { - id1:id, + id1: id, id: wxid, - name:name, + name: name, /*code: wx_code, name: name, alias: alias, @@ -812,7 +812,7 @@ if (!isSupported) { const getContactNativeFunction = (() => { const headerNodeAddress = getHeaderNodeAddress() //console.log('headerNodeAddress',headerNodeAddress) - + if (headerNodeAddress.isNull()) { return '[]' } const node = headerNodeAddress.add(0x0).readPointer() @@ -820,7 +820,7 @@ const getContactNativeFunction = (() => { //console.log(ret) - console.log('getContactNativeFunction:',ret.length) + // console.log('getContactNativeFunction:',ret.length) /*for (let item of ret){ console.log(JSON.stringify(item)) }*/ @@ -998,7 +998,7 @@ const getQrcodeLoginData = () => { // 019 const recvMsgNativeCallback = (() => { - + const nativeCallback = new NativeCallback(() => { }, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) @@ -1006,79 +1006,85 @@ const recvMsgNativeCallback = (() => { moduleBaseAddress.add(offset.hook_point), { onEnter() { - const addr = this.context.eax//0xc30-0x08 - const msgType = addr.add(0x38).readU32() - const isMyMsg = addr.add(0x3C).readU32()//add isMyMsg - - if (msgType > 0) { - - const talkerIdPtr = addr.add(0x48).readPointer() - //console.log('txt msg',talkerIdPtr.readUtf16String()) - const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 - - const myTalkerIdPtr = Memory.alloc(talkerIdLen) - Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) - - - let contentPtr = null - let contentLen = 0 - let myContentPtr = null - if (msgType == 3) {// pic path - let thumbPtr = addr.add(0x198).readPointer(); - let hdPtr = addr.add(0x1ac).readPointer(); - let thumbPath = thumbPtr.readUtf16String(); - let hdPath = hdPtr.readUtf16String(); - let picData = [ - thumbPath,// PUPPET.types.Image.Unknown - thumbPath,// PUPPET.types.Image.Thumbnail - hdPath,// PUPPET.types.Image.HD - hdPath// PUPPET.types.Image.Artwork - ] - let content = JSON.stringify(picData); - myContentPtr = Memory.allocUtf16String(content); - } else { - contentPtr = addr.add(0x70).readPointer() - contentLen = addr.add(0x70 + 0x04).readU32() * 2 + 2 - myContentPtr = Memory.alloc(contentLen) - Memory.copy(myContentPtr, contentPtr, contentLen) - } - - // console.log('----------------------------------------') - // console.log(msgType) - // console.log(contentPtr.readUtf16String()) - // console.log('----------------------------------------') - const groupMsgAddr = addr.add(0x170).readU32() //* 2 + 2 - let myGroupMsgSenderIdPtr = null - if (groupMsgAddr == 0) {//weChatPublic is zero,type is 49 - - myGroupMsgSenderIdPtr = Memory.alloc(0x10) - myGroupMsgSenderIdPtr.writeUtf16String("null") - - } else { - - const groupMsgSenderIdPtr = addr.add(0x170).readPointer() - const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 - myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) - Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) - - } - - const xmlNullPtr = addr.add(0x1ec).readU32() - let myXmlContentPtr = null - if (xmlNullPtr == 0) { - - myXmlContentPtr = Memory.alloc(0x10) - myXmlContentPtr.writeUtf16String("null") - - } else { - const xmlContentPtr = addr.add(0x1ec).readPointer() - - const xmlContentLen = addr.add(0x1ec + 0x04).readU32() * 2 + 2 - myXmlContentPtr = Memory.alloc(xmlContentLen) - Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) + let addr + let msgType = 0 + let isMyMsg = 0 + let curTime = new Date() + try { + addr = this.context.eax//0xc30-0x08 + msgType = addr.add(0x38).readU32() + isMyMsg = addr.add(0x3C).readU32()//add isMyMsg + if (msgType > 0) { + const talkerIdPtr = addr.add(0x48).readPointer() + //console.log('txt msg',talkerIdPtr.readUtf16String()) + const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 + + const myTalkerIdPtr = Memory.alloc(talkerIdLen) + Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) + + + let contentPtr = null + let contentLen = 0 + let myContentPtr = null + if (msgType == 3) {// pic path + let thumbPtr = addr.add(0x198).readPointer(); + let hdPtr = addr.add(0x1ac).readPointer(); + let thumbPath = thumbPtr.readUtf16String(); + let hdPath = hdPtr.readUtf16String(); + let picData = [ + thumbPath,// PUPPET.types.Image.Unknown + thumbPath,// PUPPET.types.Image.Thumbnail + hdPath,// PUPPET.types.Image.HD + hdPath// PUPPET.types.Image.Artwork + ] + let content = JSON.stringify(picData); + myContentPtr = Memory.allocUtf16String(content); + } else { + contentPtr = addr.add(0x70).readPointer() + contentLen = addr.add(0x70 + 0x04).readU32() * 2 + 2 + myContentPtr = Memory.alloc(contentLen) + Memory.copy(myContentPtr, contentPtr, contentLen) + } + + // console.log('----------------------------------------') + // console.log(msgType) + // console.log(contentPtr.readUtf16String()) + // console.log('----------------------------------------') + const groupMsgAddr = addr.add(0x170).readU32() //* 2 + 2 + let myGroupMsgSenderIdPtr = null + if (groupMsgAddr == 0) {//weChatPublic is zero,type is 49 + + myGroupMsgSenderIdPtr = Memory.alloc(0x10) + myGroupMsgSenderIdPtr.writeUtf16String("null") + + } else { + + const groupMsgSenderIdPtr = addr.add(0x170).readPointer() + const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 + myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) + Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) + + } + + const xmlNullPtr = addr.add(0x1ec).readU32() + let myXmlContentPtr = null + if (xmlNullPtr == 0) { + + myXmlContentPtr = Memory.alloc(0x10) + myXmlContentPtr.writeUtf16String("null") + + } else { + const xmlContentPtr = addr.add(0x1ec).readPointer() + + const xmlContentLen = addr.add(0x1ec + 0x04).readU32() * 2 + 2 + myXmlContentPtr = Memory.alloc(xmlContentLen) + Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) + } + + setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) } - - setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) + } catch (err) { + console.error(curTime,'recvMsgNativeCallback at onEnter err:', err) } } }) @@ -1182,17 +1188,17 @@ let nickMemberIdStructV6 = null let memberNickBuffAsmV6 = null let nickResultEdiV6 = null -const getChatroomMemberNickInfoV1Function=((memberId, roomId)=>{ +const getChatroomMemberNickInfoV1Function = ((memberId, roomId) => { nickRoomIdV6 = initidStruct(roomId) nullEdiWxidStructV6 = initNullIdStruct('') nickMemberIdStructV6 = initStruct(memberId) memberNickBuffAsmV6 = Memory.alloc(Process.pageSize) - console.log('-----',memberNickBuffAsmV6) + console.log('-----', memberNickBuffAsmV6) const tmp = (moduleBaseAddress.add( offset.chatroom_member_nick_esi_offset_v6 )).readU32() - console.log('=======tmp',tmp) + console.log('=======tmp', tmp) Memory.patchCode(memberNickBuffAsmV6, Process.pageSize, code => { var cw = new X86Writer(code, { pc: memberNickBuffAsmV6 }) cw.putPushfx(); @@ -1202,19 +1208,19 @@ const getChatroomMemberNickInfoV1Function=((memberId, roomId)=>{ cw.putMovRegAddress('eax', nickMemberIdStructV6) cw.putMovRegAddress('ebx', nickRoomIdV6) - + cw.putMovRegAddress('esi', ptr(tmp)) cw.putPushReg('edi') cw.putPushReg('eax') cw.putPushReg('ebx') - + cw.putMovRegAddress('ecx', ptr(tmp)) cw.putCallAddress(moduleBaseAddress.add( offset.chatroom_member_nick_call_offset_v6 )) - + //cw.putMovNearPtrReg(nickResultEdiV6, 'edi') cw.putPopax() cw.putPopfx() @@ -1226,7 +1232,7 @@ const getChatroomMemberNickInfoV1Function=((memberId, roomId)=>{ const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsmV6), 'void', []) nativeativeFunction() - console.log('---------nullEdiWxidStructV6',nullEdiWxidStructV6) + console.log('---------nullEdiWxidStructV6', nullEdiWxidStructV6) const nickha = readWideString(nullEdiWxidStructV6) console.log('-----------------') @@ -1297,7 +1303,7 @@ const getChatroomMemberNickInfoFunction = ((memberId, roomId) => { cw.putAddRegImm('esp', 0x04) //cw.putMovNearPtrReg(nickRetAddr, 'ebx') //lea eax, buf - + cw.putPopax() cw.putPopfx() cw.putRet() @@ -1324,7 +1330,7 @@ let attatchPathPtr = null let attatchAsm = null let attatchBuf = null -let attatchReceiveIdPtr=null +let attatchReceiveIdPtr = null let attatchReceiveId = null let attatchSendId = null @@ -1340,15 +1346,15 @@ let attatchEbp210 = null let attatchEbpAc = null*/ let attatchEbp11E8 = null -let attatchEbpCC = null -let attatchEbp368 = null -let attatchEAX = null +let attatchEbpCC = null +let attatchEbp368 = null +let attatchEAX = null let sFileName = null let fileNamePtr = null let attatchEbp84 = null -let attatchECX = null +let attatchECX = null /** @@ -1358,37 +1364,37 @@ param {78EDBC86 | 8B80 38040000 | mov eax,dword ptr ds:[eax+438] */ // 021 -const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) => { +const sendAttatchMsgNativeFunction = ((contactId, senderId, path, filename, size) => { attatchAsm = Memory.alloc(Process.pageSize) - console.log('--------------address',attatchAsm) + console.log('--------------address', attatchAsm) - fileNamePtr=Memory.alloc(filename.length * 2 + 2) + fileNamePtr = Memory.alloc(filename.length * 2 + 2) fileNamePtr.writeUtf16String(filename) - sFileName=Memory.alloc(0x14) + sFileName = Memory.alloc(0x14) sFileName.writePointer(ptr(fileNamePtr)).add(0x04) - .writeU32(fileNamePtr.length*2).add(0x04) - .writeU32(fileNamePtr.length*2).add(0x08) + .writeU32(fileNamePtr.length * 2).add(0x04) + .writeU32(fileNamePtr.length * 2).add(0x08) //const fileSize = size.toInt32() - attatchReceiveIdPtr=Memory.alloc(contactId.length * 2 + 2) + attatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) attatchReceiveIdPtr.writeUtf16String(contactId) - attatchReceiveId=Memory.alloc(0x14) + attatchReceiveId = Memory.alloc(0x14) attatchReceiveId.writePointer(ptr(attatchReceiveIdPtr)).add(0x04) - .writeU32(contactId.length*2).add(0x04) - .writeU32(contactId.length*2).add(0x08) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x08) - attatchSendIdPtr=Memory.alloc(senderId.length * 2 + 2) + attatchSendIdPtr = Memory.alloc(senderId.length * 2 + 2) attatchSendIdPtr.writeUtf16String(senderId) - attatchSendId=Memory.alloc(0x14) + attatchSendId = Memory.alloc(0x14) attatchSendId.writePointer(ptr(attatchSendIdPtr)).add(0x04) - .writeU32(senderId.length*2).add(0x04) - .writeU32(senderId.length*2).add(0x08) + .writeU32(senderId.length * 2).add(0x04) + .writeU32(senderId.length * 2).add(0x08) attatchPathPtr = Memory.alloc(path.length * 2 + 2) attatchPathPtr.writeUtf16String(path) @@ -1399,16 +1405,16 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) = .writeU32(path.length * 2).add(0x04) attatchEbp11E8 = Memory.alloc(0xBE4) - attatchEbpCC = Memory.alloc(0x14) + attatchEbpCC = Memory.alloc(0x14) attatchEbp368 = Memory.alloc(0x290) - attatchEbp84 = Memory.alloc(0x18) - attatchEAX = Memory.alloc(0x18) + attatchEbp84 = Memory.alloc(0x18) + attatchEAX = Memory.alloc(0x18) attatchECX = moduleBaseAddress.add(0x222f178).toInt32() //console.log('basename',path.basename(path)) //return - + /** * -------------buffer------------------------------- */ @@ -1425,23 +1431,23 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) = cw.putPushU32(moduleBaseAddress.add(0x1E1B3C0).toInt32()) cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x4))//11e4 cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid - // cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid - - /** - * 78482B8D | 6A FF | push FFFFFFFF | - 78482B8F | 68 B895E979 | push wechatwin.79E995B8 | 79E995B8:L"0" - 78482B94 | 8D8D 48EEFFFF | lea ecx,dword ptr ss:[ebp-11B8] | - 78482B9A | E8 71F83600 | call wechatwin.787F2410 | 此处继续写ebp-11b8 - */ + // cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid + + /** + * 78482B8D | 6A FF | push FFFFFFFF | + 78482B8F | 68 B895E979 | push wechatwin.79E995B8 | 79E995B8:L"0" + 78482B94 | 8D8D 48EEFFFF | lea ecx,dword ptr ss:[ebp-11B8] | + 78482B9A | E8 71F83600 | call wechatwin.787F2410 | 此处继续写ebp-11b8 + */ cw.putPushU32(-1) cw.putPushU32(moduleBaseAddress.add(0x1DA95B8).toInt32()) cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x30))//11B8 cw.putCallAddress(moduleBaseAddress.add(0x702410)) - cw.putMovRegU32('eax',0x6) - cw.putMovNearPtrReg(attatchEbp11E8.add(0x80), 'eax')//1168 - cw.putMovRegU32('eax',size)//file size - cw.putMovNearPtrReg(attatchEbp11E8.add(0x108), 'eax')//10e0 + cw.putMovRegU32('eax', 0x6) + cw.putMovNearPtrReg(attatchEbp11E8.add(0x80), 'eax')//1168 + cw.putMovRegU32('eax', size)//file size + cw.putMovNearPtrReg(attatchEbp11E8.add(0x108), 'eax')//10e0 cw.putMovRegAddress('eax', sFileName) @@ -1453,8 +1459,8 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) = cw.putPushReg('eax') cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x160))//1088=0x11e8-0x160 cw.putCallAddress(moduleBaseAddress.add(0x702980)) - - + + cw.putMovRegAddress('eax', attatchEbpCC) cw.putPushReg('eax') cw.putMovRegAddress('ecx', attatchEbp11E8) @@ -1475,10 +1481,10 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) = cw.putPushReg('ecx') cw.putPushReg('eax') - cw.putMovRegAddress('eax',attatchEbpCC) + cw.putMovRegAddress('eax', attatchEbpCC) cw.putPushReg('eax') - cw.putMovRegAddress('eax',attatchReceiveId) + cw.putMovRegAddress('eax', attatchReceiveId) cw.putPushReg('eax') cw.putMovRegAddress('ecx', attatchEbp368) @@ -1503,7 +1509,7 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) = //cw.putMovNearPtrReg(attatchEbpCC.add(0x64), 'eax')//ebp-68 //cw.putAddRegImm('ecx', 0x8) //cw.putMovRegAddress('eax', attatchEbp368.add(0x64))//ebp-68 - + //cw.putMovRegU32('ecx',attatchECX) //cw.putPushReg('eax') //cw.putMovRegAddress('eax', attatchEbpCC.add(0x40))//ebp-8c @@ -1518,8 +1524,8 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId,path,filename,size) = //cw.putMovRegAddress('ecx', attatchEbp368) //cw.putCallAddress(moduleBaseAddress.add(0x63B4F0)) - // 78F33099 | 8D8D 34FFFFFF | lea ecx,dword ptr ss:[ebp-CC] | -//78F3309F | E8 AC0FD0FF | call wechatwin.78C34050 | + // 78F33099 | 8D8D 34FFFFFF | lea ecx,dword ptr ss:[ebp-CC] | + //78F3309F | E8 AC0FD0FF | call wechatwin.78C34050 | //cw.putMovRegAddress('ecx',attatchEbpCC) //cw.putCallAddress(moduleBaseAddress.add(0x94050)) @@ -1607,7 +1613,7 @@ const sendPicMsgNativeFunction = ((contactId, path) => { offset.send_picmsg_call_offset0 )) cw.putMovRegReg('edx', 'eax')//缓存 - + cw.putSubRegImm('esp', 0x14) cw.putMovRegAddress('eax', buffwxid) cw.putMovRegReg('ecx', 'esp') @@ -1681,7 +1687,7 @@ const sendPicMsgNativeFunction = ((contactId, path) => { }) - console.log('----------picAsm',picAsm) + console.log('----------picAsm', picAsm) const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) nativeativeFunction() @@ -1950,18 +1956,18 @@ const agentReadyCallback = (() => { })() // 027 -const SendMiniProgramNativeFunction = ((bg_path_str,send_wxid_str,recv_wxid_str,xmlstr) => { +const SendMiniProgramNativeFunction = ((bg_path_str, send_wxid_str, recv_wxid_str, xmlstr) => { console.log("------------------------------------------------------"); - var asmCode=Memory.alloc(Process.pageSize); + var asmCode = Memory.alloc(Process.pageSize); - var ECX_buf=Memory.alloc(0x300); - var Buf_EAX=Memory.alloc(0x300); - var buf_1=Memory.alloc(0x300); - var ptr_to_buf_1=Memory.alloc(0x4).writePointer(buf_1); - var buf_2=Memory.alloc(0x300); + var ECX_buf = Memory.alloc(0x300); + var Buf_EAX = Memory.alloc(0x300); + var buf_1 = Memory.alloc(0x300); + var ptr_to_buf_1 = Memory.alloc(0x4).writePointer(buf_1); + var buf_2 = Memory.alloc(0x300); -// var bg_path_str="C:/aaaa.jpg"; - var bg_path_Ptr=Memory.alloc(bg_path_str.length * 2 + 1) + // var bg_path_str="C:/aaaa.jpg"; + var bg_path_Ptr = Memory.alloc(bg_path_str.length * 2 + 1) bg_path_Ptr.writeUtf16String(bg_path_str); var bg_path_Struct = Memory.alloc(0x14) // returns a NativePointer bg_path_Struct.writePointer(bg_path_Ptr).add(0x04) @@ -1970,8 +1976,8 @@ const SendMiniProgramNativeFunction = ((bg_path_str,send_wxid_str,recv_wxid_str, .writeU32(0).add(0x04) .writeU32(0); - // var send_wxid_str="wxid_4zr616ir6fi122"; - var send_wxid_Ptr=Memory.alloc(send_wxid_str.length * 2 + 1) + // var send_wxid_str="wxid_4zr616ir6fi122"; + var send_wxid_Ptr = Memory.alloc(send_wxid_str.length * 2 + 1) send_wxid_Ptr.writeUtf16String(send_wxid_str); var send_wxid_Struct = Memory.alloc(0x14) // returns a NativePointer send_wxid_Struct.writePointer(send_wxid_Ptr).add(0x04) @@ -1980,8 +1986,8 @@ const SendMiniProgramNativeFunction = ((bg_path_str,send_wxid_str,recv_wxid_str, .writeU32(0).add(0x04) .writeU32(0); - // var recv_wxid_str="filehelper"; - var recv_wxid_Ptr=Memory.alloc(recv_wxid_str.length * 2 + 1) + // var recv_wxid_str="filehelper"; + var recv_wxid_Ptr = Memory.alloc(recv_wxid_str.length * 2 + 1) recv_wxid_Ptr.writeUtf16String(recv_wxid_str); var recv_wxid_Struct = Memory.alloc(0x14) // returns a NativePointer recv_wxid_Struct.writePointer(recv_wxid_Ptr).add(0x04) @@ -1990,9 +1996,9 @@ const SendMiniProgramNativeFunction = ((bg_path_str,send_wxid_str,recv_wxid_str, .writeU32(0).add(0x04) .writeU32(0); - // vvar pXml=initidStruct('wxid_4zr616ir6fi1220腾讯出行服务|加油代驾公交view330https://mp.weixin.qq.com/mp/waerrpage?appid=wx65cc950f42e8fff1&amp;type=upgrade&amp;upgradetype=3#wechat_redirecthttp://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=200腾讯出行服务|加油代驾公交0gh_ad64296dc8bd@appwx65cc950f42e8fff11http://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=20002_wx65cc950f42e8fff1_875237370_1644979747_11Window wechat'); + // vvar pXml=initidStruct('wxid_4zr616ir6fi1220腾讯出行服务|加油代驾公交view330https://mp.weixin.qq.com/mp/waerrpage?appid=wx65cc950f42e8fff1&amp;type=upgrade&amp;upgradetype=3#wechat_redirecthttp://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=200腾讯出行服务|加油代驾公交0gh_ad64296dc8bd@appwx65cc950f42e8fff11http://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=20002_wx65cc950f42e8fff1_875237370_1644979747_11Window wechat'); - var pXml=initidStruct(xmlstr) + var pXml = initidStruct(xmlstr) console.log(send_wxid_Struct); console.log(recv_wxid_Struct); diff --git a/src/agents/agent-script-3.9.2.23-laozhang-raw.js b/src/agents/agent-script-3.9.2.23-laozhang-raw.js new file mode 100644 index 0000000..5d9cddc --- /dev/null +++ b/src/agents/agent-script-3.9.2.23-laozhang-raw.js @@ -0,0 +1,801 @@ +/** + * WeChat 3.2.1.121 + * > Special thanks to: @cixingguangming55555 老张学技术 + * + * Credit: https://github.com/cixingguangming55555/wechat-bot + * Source: https://pan.baidu.com/s/1OmX2lxNOYHyGsl_3ByhsoA + * 《源码3.2.1.121》提取码: 1rfa + * WeChat: https://pan.baidu.com/share/init?surl=IHRM2OMvrLyuCz5MRbigGg + * 微信:3.2.1.121 提取码: cscn + */ + +//https://blog.csdn.net/iloveitvm/article/details/109119687 frida学习 + +//const { isNullishCoalesce } = require("typescript") + +//3.9.2.23 + +const offset = { + + + hook_point: 0xd19a0b, //3.9.2.23 + + myselfinfo: { + offset: 0x2FFD484, //老版本微信号偏移,后面的地址,都要在这个偏移上增加 + //wxid_len:0x10, + head_img_url: 0x2D8, + head_img_url_len: 0x2E8, + wx_nick_name: 0x10C, + wxcode_new: 0x64, //新版本微信号 + //wxcode_len:0x74 + wxid_len_offset: 0x4D4 + }, + + contactInfo: { + nodeOffset: 0x2FFDD7C, + nodeRootOffset: 0x64 + }, + chatroomInfo: { + nodeOffset: 0x2FFDDC8, + nodeRootOffset: 0x8c8 + }, + sendTxtMsg: { + callOffset: 0xCE6C80 + }, + sendPicMsg: { + call1: 0x768140, + call2: 0xf59e40, + call3: 0xce6640 + } +}; + + + +/*------------------global-------------------------------------------*/ +const availableVersion = 1661534743 ////3.9.2.23 ==0x63090217 + +const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll') +const moduleLoad = Module.load('WeChatWin.dll') +//1575CF98 + + +/*---------------base -------------------------*/ + +let retidPtr=null +let retidStruct=null +const initidStruct = ((str) => { + + retidPtr = Memory.alloc(str.length * 2 + 1) + retidPtr.writeUtf16String(str) + + retidStruct = Memory.alloc(0x14) // returns a NativePointer + + retidStruct + .writePointer(retidPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return retidStruct +}) + +let retPtr = null +let retStruct = null +const initStruct = ((str) => { + + retPtr = Memory.alloc(str.length * 2 + 1) + retPtr.writeUtf16String(str) + + retStruct = Memory.alloc(0x14) // returns a NativePointer + + retStruct + .writePointer(retPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return retStruct +}) + +let msgstrPtr=null +let msgStruct=null +const initmsgStruct = ((str) => { + msgstrPtr = Memory.alloc(str.length * 2 + 1) + msgstrPtr.writeUtf16String(str) + + msgStruct = Memory.alloc(0x14) // returns a NativePointer + + msgStruct + .writePointer(msgstrPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return msgStruct +}) + +let atStruct = null +const initAtMsgStruct = ((wxidStruct) => { + + atStruct = Memory.alloc(0x10) + + atStruct.writePointer(wxidStruct).add(0x04) + .writeU32(wxidStruct.toInt32() + 0x14).add(0x04)//0x14 = sizeof(wxid structure) + .writeU32(wxidStruct.toInt32() + 0x14).add(0x04) + .writeU32(0) + return atStruct +}) +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 +} + +// std::wstring +// const wstr = readWStringPtr(ptr).readUtf16String() +const readWStringPtr = (address) => { + const addr = ptr(address) + const size = addr.add(4).readU32() + const capacity = addr.add(8).readU32() + addr.ptr = addr.readPointer() + addr.size = size + addr.capacity = capacity + addr.ptr._readUtf16String = addr.ptr.readUtf16String + addr.readUtf16String = () => { + return addr.size ? addr.ptr._readUtf16String(addr.size * 2) : '' + } + + // console.log('readWStringPtr() address:',address,' -> ptr:', addr.ptr, 'size:', addr.size, 'capacity:', addr.capacity) + // console.log('readWStringPtr() str:' , `"${addr.readUtf16String()}"`,'\n',addr.ptr.readByteArray(addr.size*2+2),'\n') + // console.log('readWStringPtr() address:', addr,'dump:', addr.readByteArray(16),'\n') + + return addr +} + +const readString = (address) => { + return readStringPtr(address).readUtf8String() +} + +const readWideString = (address) => { + return readWStringPtr(address).readUtf16String() +} + + +/*-----------------base-------------------------*/ + +let currentVersion = 0 + +let nodeList = [] //for contact +let contactList = [] //for contact + +let chatroomNodeList = [] //for chatroom +let chatroomMemberList = [] //for chatroom +let loggedIn = false + + + +const getWechatVersionFunction = (() => { + if (currentVersion) { + return currentVersion + } + const pattern = '55 8B ?? 83 ?? ?? A1 ?? ?? ?? ?? 83 ?? ?? 85 ?? 7F ?? 8D ?? ?? E8 ?? ?? ?? ?? 84 ?? 74 ?? 8B ?? ?? ?? 85 ?? 75 ?? E8 ?? ?? ?? ?? 0F ?? ?? 0D ?? ?? ?? ?? A3 ?? ?? ?? ?? A3 ?? ?? ?? ?? 8B ?? 5D C3' + const results = Memory.scanSync(moduleLoad.base, moduleLoad.size, pattern) + if (results.length == 0) { + return 0 + } + const addr = results[0].address + const ret = addr.add(0x07).readPointer() + const ver = ret.add(0x0).readU32() + currentVersion = ver + return ver +}) + +// 011 +const getWechatVersionStringFunction = ((ver = getWechatVersionFunction()) => { + if (!ver) { + return '0.0.0.0' + } + const vers = [] + vers.push((ver >> 24) & 255 - 0x60) + vers.push((ver >> 16) & 255) + vers.push((ver >> 8) & 255) + vers.push(ver & 255) + return vers.join('.') +}) + +const checkSupportedFunction = (() => { + const ver = getWechatVersionFunction() + return ver == availableVersion +}) + +// 019 +const recvMsgNativeCallback = (() => { + + + const nativeCallback = new NativeCallback(() => {}, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + + Interceptor.attach( + moduleBaseAddress.add(offset.hook_point), { + onEnter() { + const addr = this.context.ecx //0xc30-0x08 + const msgType = addr.add(0x38).readU32() + const isMyMsg = addr.add(0x3C).readU32() //add isMyMsg + + if (msgType > 0) { + + const talkerIdPtr = addr.add(0x48).readPointer() + //console.log('txt msg',talkerIdPtr.readUtf16String()) + const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 + + const myTalkerIdPtr = Memory.alloc(talkerIdLen) + Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) + + + let contentPtr = null + let contentLen = 0 + let myContentPtr = null + if (msgType == 3) { // pic path + let thumbPtr = addr.add(0x198).readPointer(); + let hdPtr = addr.add(0x1ac).readPointer(); + let thumbPath = thumbPtr.readUtf16String(); + let hdPath = hdPtr.readUtf16String(); + let picData = [ + thumbPath, // PUPPET.types.Image.Unknown + thumbPath, // PUPPET.types.Image.Thumbnail + hdPath, // PUPPET.types.Image.HD + hdPath // PUPPET.types.Image.Artwork + ] + let content = JSON.stringify(picData); + myContentPtr = Memory.allocUtf16String(content); + } else { + contentPtr = addr.add(0x70).readPointer() + contentLen = addr.add(0x70 + 0x04).readU32() * 2 + 2 + myContentPtr = Memory.alloc(contentLen) + Memory.copy(myContentPtr, contentPtr, contentLen) + } + + // console.log('----------------------------------------') + // console.log(msgType) + // console.log(contentPtr.readUtf16String()) + // console.log('----------------------------------------') + const groupMsgAddr = addr.add(0x170).readU32() //* 2 + 2 + let myGroupMsgSenderIdPtr = null + if (groupMsgAddr == 0) { //weChatPublic is zero,type is 49 + + myGroupMsgSenderIdPtr = Memory.alloc(0x10) + myGroupMsgSenderIdPtr.writeUtf16String("null") + + } else { + + const groupMsgSenderIdPtr = addr.add(0x170).readPointer() + const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 + myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) + Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) + + } + + const xmlNullPtr = addr.add(0x1f0).readU32() //3.9.2.23 + let myXmlContentPtr = null + if (xmlNullPtr == 0) { + + myXmlContentPtr = Memory.alloc(0x10) + myXmlContentPtr.writeUtf16String("null") + + } else { + const xmlContentPtr = addr.add(0x1f0).readPointer() //3.9.2.23 + + const xmlContentLen = addr.add(0x1f0 + 0x04).readU32() * 2 + 2 + myXmlContentPtr = Memory.alloc(xmlContentLen) + Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) + } + + setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) + } + } + }) + return nativeCallback +})() + + +const getBaseNodeAddress = (() => { + return moduleBaseAddress.add(offset.contactInfo.nodeOffset).readPointer() +}) + +// 004 +const getHeaderNodeAddress = (() => { + const baseAddress = getBaseNodeAddress() + //console.log('baseAddress',baseAddress) + if (baseAddress.isNull()) { + return baseAddress + } + + //console.log('HeaderNodeAddress',baseAddress.add(offset.handle_offset).readPointer()) + return baseAddress.add(offset.contactInfo.nodeRootOffset).readPointer() +}) + +const getMyselfInfoFunction = (() => { + + let ptr = 0 + let wx_code = '' + let wx_id = '' + let wx_name = '' + let head_img_url = '' + + const base = moduleBaseAddress.add(offset.myselfinfo.offset) + const wxid_len = base.add(offset.myselfinfo.wxid_len_offset).readU32() + + if (wxid_len === 0x13) { // 新版本微信 + wx_id = base.readPointer().readAnsiString(wxid_len) + wx_code = base.add(offset.myselfinfo.wxcode_new).readAnsiString() + } else { + wx_id = readString(base) + wx_code = wx_id + } + + + wx_name = readString(base.add(offset.myselfinfo.wx_nick_name)) + const img_addr = base.add(offset.myselfinfo.head_img_url).readPointer() + const img_len = base.add(offset.myselfinfo.head_img_url_len).readU32() + + head_img_url = img_addr.readAnsiString(img_len) + + const myself = { + id: wx_id, + code: wx_code, + name: wx_name, + head_img_url: head_img_url, + }; + + return JSON.stringify(myself) + +}) + + +const recurseNew = ((node) => { + const headerNodeAddress = getHeaderNodeAddress() + if (headerNodeAddress.isNull()) { + return + } + + if (node.equals(headerNodeAddress)) { + return + } + + for (const item in nodeList) { + if (node.equals(nodeList[item])) { + return + } + } + + + nodeList.push(node) + const id = readString(node.add(0x8)) + //wxid, format relates to registration method + const wxid = readWideString(node.add(0x30)) + //console.log('-----------',wxid) + + + //custom id, if not set return null, and use wxid which should be custom id + //const wx_code = readWideString(node.add(0x4c)) || readWideString(node.add(0x38)) + + //custom Nickname + const name = readWideString(node.add(0x8c)) + + //alias aka 'remark' in wechat + //const alias = readWideString(node.add(0x80)) + + //avatarUrl + //const avatar = readWideString(node.add(0x138)) + //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) + //contact gender + //const gender = node.add(0x18C).readU32() + + const contactJson = { + id1: id, + id: wxid, + name: name, + /*code: wx_code, + name: name, + alias: alias, + avatarUrl: avatar, + gender: gender,*/ + } + + contactList.push(contactJson) + + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + //const rightNode = node.add(0x08).readPointer() + + recurseNew(leftNode) + recurseNew(centerNode) + //recurse(rightNode) + + const allContactJson = contactList + return allContactJson + +}) + + +const getContactNativeFunction = (() => { + const headerNodeAddress = getHeaderNodeAddress() + //console.log('headerNodeAddress',headerNodeAddress) + + if (headerNodeAddress.isNull()) { + return '[]' + } + + const node = headerNodeAddress.add(0x0).readPointer() + const ret = recurseNew(node) + + //console.log(ret) + + console.log('getContactNativeFunction:', ret.length) + /*for (let item of ret){ + console.log(JSON.stringify(item)) + }*/ + //console.log(ret.contact) + const cloneRet = JSON.stringify(ret) + nodeList.length = 0 + contactList.length = 0 + + return cloneRet +}) + + +const getChatroomNodeAddress = (() => { + const baseAddress = moduleBaseAddress.add(offset.chatroomInfo.nodeOffset).readPointer() + if (baseAddress.isNull()) { + return baseAddress + } + return baseAddress.add(offset.chatroomInfo.nodeRootOffset).readPointer() +}) + +const chatroomRecurse = ((node) => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return + } + + if (node.equals(chatroomNodeAddress)) { + return + } + + for (const item in chatroomNodeList) { + if (node.equals(chatroomNodeList[item])) { + return + } + } + + chatroomNodeList.push(node) + const roomid = readWideString(node.add(0x10)) + + const len = node.add(0x54).readU32() // + //const memberJson={} + if (len > 4) { // + const memberStr = readString(node.add(0x44)) + if (memberStr.length > 0) { + const memberList = memberStr.split(/[\\^][G]/) + const memberJson = { + roomid: roomid, + roomMember: memberList + } + + chatroomMemberList.push(memberJson) + } + + } + + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + const rightNode = node.add(0x08).readPointer() + + chatroomRecurse(leftNode) + chatroomRecurse(centerNode) + chatroomRecurse(rightNode) + + const allChatroomMemberJson = chatroomMemberList + return allChatroomMemberJson +}) + +const getChatroomMemberInfoFunction = (() => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return '[]' + } + + const node = chatroomNodeAddress.add(0x0).readPointer() + const ret = chatroomRecurse(node) + + const cloneRet = JSON.stringify(ret) + chatroomNodeList.length = 0 //empty + chatroomMemberList.length = 0 //empty + return cloneRet +}) + + + +/** + * sendMsgNativeFunction + * send text message + * @param {string} talkerId = wxid or roomid + * @param {string} content + */ +const sendMsgNativeFunction = ((talkerId, content) => { + + const txtAsm = Memory.alloc(Process.pageSize) + //const buffwxid = Memory.alloc(0x20) + + + let wxidPtr = Memory.alloc(talkerId.length * 2 + 2) + wxidPtr.writeUtf16String(talkerId) + + let picWxid = Memory.alloc(0x0c) + picWxid.writePointer(ptr(wxidPtr)).add(0x04) + .writeU32(talkerId.length * 2).add(0x04) + .writeU32(talkerId.length * 2).add(0x04) + + let contentPtr = Memory.alloc(content.length * 2 + 2) + contentPtr.writeUtf16String(content) + + const sizeOfStringStruct = Process.pointerSize * 5 + let contentStruct = Memory.alloc(sizeOfStringStruct) + + contentStruct + .writePointer(contentPtr).add(0x4) + .writeU32(content.length).add(0x4) + .writeU32(content.length * 2) + + + const ecxBuffer = Memory.alloc(0x2d8) + + Memory.patchCode(txtAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: txtAsm + }) + cw.putPushfx() + cw.putPushax() + + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + cw.putPushU32(0x0) + + //cw.putMovRegReg + + cw.putMovRegAddress('eax', contentStruct) + cw.putPushReg('eax') + + cw.putMovRegAddress('edx', picWxid) //room_id + + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) + + cw.putAddRegImm('esp', 0x18) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + console.log('----------txtAsm', txtAsm) + const nativeativeFunction = new NativeFunction(ptr(txtAsm), 'void', []) + nativeativeFunction() + +}) + + +let asmAtMsg = null +let roomid_, msg_, wxid_, atid_ +let ecxBuffer +const sendAtMsgNativeFunction = ((roomId, text, contactId,nickname) => { + + asmAtMsg = Memory.alloc(Process.pageSize) + ecxBuffer = Memory.alloc(0x3b0) + + const atContent = '@'+nickname+' '+text + + roomid_ = initStruct(roomId) + wxid_ = initidStruct(contactId) + msg_ = initmsgStruct(atContent) + atid_ = initAtMsgStruct(wxid_) + + Memory.patchCode(asmAtMsg, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: asmAtMsg + }) + cw.putPushfx() + cw.putPushax() + + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + //cw.putPushU32(0x0) + cw.putMovRegAddress('eax', atid_) + cw.putPushReg('eax') + + //cw.putMovRegReg + + cw.putMovRegAddress('eax', msg_) + cw.putPushReg('eax') + + cw.putMovRegAddress('edx', roomid_) //room_id + + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) + + cw.putAddRegImm('esp', 0x18) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + //console.log('----------txtAsm', asmAtMsg) + const nativeativeFunction = new NativeFunction(ptr(asmAtMsg), 'void', []) + nativeativeFunction() + +}) + +/** + * + * @param {*} contactId + * @param {*} path + */ +const sendPicMsgNativeFunction = ((contactId, path) => { + + const picAsm = Memory.alloc(Process.pageSize) + const buffwxid = Memory.alloc(0x20) + const picbuff = Memory.alloc(0x2D8) + + let pathPtr = Memory.alloc(path.length * 2 + 1) + pathPtr.writeUtf16String(path) + + let imagefilepath = Memory.alloc(0x24) + imagefilepath.writePointer(pathPtr).add(0x04) + .writeU32(path.length * 2).add(0x04) + .writeU32(path.length * 2).add(0x04) + + let picWxidPtr = Memory.alloc(contactId.length * 2 + 1) + picWxidPtr.writeUtf16String(contactId) + + let picWxid = Memory.alloc(0x0c) + picWxid.writePointer(ptr(picWxidPtr)).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + + + //const test_offset1 = 0x701DC0; + Memory.patchCode(picAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: picAsm + }) + cw.putPushfx(); + cw.putPushax(); + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call1 + )) + cw.putMovRegReg('edx', 'eax') //缓存 + + cw.putSubRegImm('esp', 0x14) + cw.putMovRegAddress('eax', buffwxid) + cw.putMovRegReg('ecx', 'esp') + cw.putMovRegAddress('edi', imagefilepath) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call2 + )) + + cw.putMovRegReg('ecx', 'edx') + cw.putMovRegAddress('eax', picWxid) //=lea + cw.putMovRegAddress('edi', imagefilepath) + cw.putPushReg('edi') + cw.putPushReg('eax') + cw.putMovRegAddress('eax', picbuff) + cw.putPushReg('eax') + + cw.putMovRegAddress('edi', picWxid) //edi + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call3 + )) + + + + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + //console.log('----------picAsm',picAsm) + const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) + nativeativeFunction() + +}) + + + + +let memberNickBuffAsm = null +let nickRoomId = null +let nickMemberId = null +let nickBuff = null +const getChatroomMemberNickInfoFunction = ((memberId, roomId) => { + + nickBuff = Memory.alloc(0x7e4) + //const nickRetAddr = Memory.alloc(0x04) + memberNickBuffAsm = Memory.alloc(Process.pageSize) + //console.log('asm address----------',memberNickBuffAsm) + nickRoomId = initidStruct(roomId) + //console.log('nick room id',nickRoomId) + nickMemberId = initStruct(memberId) + + //console.log('nick nickMemberId id',nickMemberId) + //const nickStructPtr = initmsgStruct('') + + Memory.patchCode(memberNickBuffAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: memberNickBuffAsm + }) + cw.putPushfx() + cw.putPushax() + cw.putMovRegAddress('edi', nickRoomId) + cw.putMovRegAddress('eax', nickBuff) + cw.putMovRegReg('edx', 'edi') + cw.putPushReg('eax') + cw.putMovRegAddress('ecx', nickMemberId) + cw.putCallAddress(moduleBaseAddress.add(0xC06F10)) + cw.putAddRegImm('esp', 0x04) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsm), 'void', []) + nativeativeFunction() + + const nickname = readWideString(nickBuff) + console.log('----nickname', nickname) + return readWideString(nickBuff) +}) + + diff --git a/src/agents/agent-script-3.9.2.23.js b/src/agents/agent-script-3.9.2.23.js new file mode 100644 index 0000000..9c97f9a --- /dev/null +++ b/src/agents/agent-script-3.9.2.23.js @@ -0,0 +1,1899 @@ +/** + * > Special thanks to: @cixingguangming55555 老张学技术 + * + * Credit: https://github.com/cixingguangming55555/wechat-bot + */ + +//https://blog.csdn.net/iloveitvm/article/details/109119687 frida学习 + +//const { isNullishCoalesce } = require("typescript") + +// wechat:3.9.2.23 + +// 028 done +const offset = { + + + hook_point: 0xd19a0b, //3.9.2.23 + + myselfinfo: { + offset: 0x2FFD484, //老版本微信号偏移,后面的地址,都要在这个偏移上增加 + //wxid_len:0x10, + head_img_url: 0x2D8, + head_img_url_len: 0x2E8, + wx_nick_name: 0x10C, + wxcode_new: 0x64, //新版本微信号 + //wxcode_len:0x74 + wxid_len_offset: 0x4D4 + }, + + contactInfo: { + nodeOffset: 0x2FFDD7C, + nodeRootOffset: 0x64 + }, + chatroomInfo: { + nodeOffset: 0x2FFDDC8, + nodeRootOffset: 0x8c8 + }, + sendTxtMsg: { + callOffset: 0xCE6C80 + }, + sendPicMsg: { + call1: 0x768140, + call2: 0xf59e40, + call3: 0xce6640 + } +}; + +// 029 done +/*------------------global-------------------------------------------*/ +const availableVersion = 1661534743 ////3.9.2.23 ==0x63090217 + +const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll') +const moduleLoad = Module.load('WeChatWin.dll') +// tbd +const g_EDIPtr = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readPointer()// +const g_EDIU32 = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readU32() +/*------------------global-------------------------------------------*/ + +/*---------------base -------------------------*/ +// 030 done +let retidPtr=null +let retidStruct=null +const initidStruct = ((str) => { + + retidPtr = Memory.alloc(str.length * 2 + 1) + retidPtr.writeUtf16String(str) + + retidStruct = Memory.alloc(0x14) // returns a NativePointer + + retidStruct + .writePointer(retidPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return retidStruct +}) + +// 031 done +let retPtr = null +let retStruct = null +const initStruct = ((str) => { + + retPtr = Memory.alloc(str.length * 2 + 1) + retPtr.writeUtf16String(str) + + retStruct = Memory.alloc(0x14) // returns a NativePointer + + retStruct + .writePointer(retPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return retStruct +}) + +// 032 done +let msgstrPtr=null +let msgStruct=null +const initmsgStruct = ((str) => { + msgstrPtr = Memory.alloc(str.length * 2 + 1) + msgstrPtr.writeUtf16String(str) + + msgStruct = Memory.alloc(0x14) // returns a NativePointer + + msgStruct + .writePointer(msgstrPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return msgStruct +}) + +// 034 done +/** +* at msg structure +*/ +let atStruct = null +const initAtMsgStruct = ((wxidStruct) => { + + atStruct = Memory.alloc(0x10) + + atStruct.writePointer(wxidStruct).add(0x04) + .writeU32(wxidStruct.toInt32() + 0x14).add(0x04)//0x14 = sizeof(wxid structure) + .writeU32(wxidStruct.toInt32() + 0x14).add(0x04) + .writeU32(0) + return atStruct +}) + +// 033 tbd +let retidNullStruct = null +let retidNullPtr = null +const initNullIdStruct = ((str) => { + + retidNullPtr = Memory.alloc(str.length * 2 + 1) + retidNullPtr.writeUtf16String(str) + + retidNullStruct = Memory.alloc(0x14) // returns a NativePointer + + retidNullStruct + .writePointer(retidNullPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + + return retidNullStruct +}) + +// 035 done +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 +} + +// 036 done +const readString = (address) => { + return readStringPtr(address).readUtf8String() +} + +// 037 done +const readWideString = (address) => { + return readWStringPtr(address).readUtf16String() +} +/*-----------------base-------------------------*/ + +// 041 +// std::wstring +// const wstr = readWStringPtr(ptr).readUtf16String() +const readWStringPtr = (address) => { + const addr = ptr(address) + const size = addr.add(4).readU32() + const capacity = addr.add(8).readU32() + addr.ptr = addr.readPointer() + addr.size = size + addr.capacity = capacity + addr.ptr._readUtf16String = addr.ptr.readUtf16String + addr.readUtf16String = () => { + return addr.size ? addr.ptr._readUtf16String(addr.size * 2) : '' + } + + // console.log('readWStringPtr() address:',address,' -> ptr:', addr.ptr, 'size:', addr.size, 'capacity:', addr.capacity) + // console.log('readWStringPtr() str:' , `"${addr.readUtf16String()}"`,'\n',addr.ptr.readByteArray(addr.size*2+2),'\n') + // console.log('readWStringPtr() address:', addr,'dump:', addr.readByteArray(16),'\n') + + return addr +} + +/*-----------------base-------------------------*/ + +// 010 done +let currentVersion = 0 + +let nodeList = [] //for contact +let contactList = [] //for contact + +let chatroomNodeList = [] //for chatroom +let chatroomMemberList = [] //for chatroom +let loggedIn = false + + +const getWechatVersionFunction = (() => { + if (currentVersion) { + return currentVersion + } + const pattern = '55 8B ?? 83 ?? ?? A1 ?? ?? ?? ?? 83 ?? ?? 85 ?? 7F ?? 8D ?? ?? E8 ?? ?? ?? ?? 84 ?? 74 ?? 8B ?? ?? ?? 85 ?? 75 ?? E8 ?? ?? ?? ?? 0F ?? ?? 0D ?? ?? ?? ?? A3 ?? ?? ?? ?? A3 ?? ?? ?? ?? 8B ?? 5D C3' + const results = Memory.scanSync(moduleLoad.base, moduleLoad.size, pattern) + if (results.length == 0) { + return 0 + } + const addr = results[0].address + const ret = addr.add(0x07).readPointer() + const ver = ret.add(0x0).readU32() + currentVersion = ver + return ver +}) + +// 011 done +const getWechatVersionStringFunction = ((ver = getWechatVersionFunction()) => { + if (!ver) { + return '0.0.0.0' + } + const vers = [] + vers.push((ver >> 24) & 255 - 0x60) + vers.push((ver >> 16) & 255) + vers.push((ver >> 8) & 255) + vers.push(ver & 255) + return vers.join('.') +}) + +// 012 done +const checkSupportedFunction = (() => { + const ver = getWechatVersionFunction() + return ver == availableVersion +}) + +// 019 done +/** + * @Hook: recvMsg -> recvMsgNativeCallback + */ + const recvMsgNativeCallback = (() => { + + + const nativeCallback = new NativeCallback(() => {}, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + + Interceptor.attach( + moduleBaseAddress.add(offset.hook_point), { + onEnter() { + const addr = this.context.ecx //0xc30-0x08 + const msgType = addr.add(0x38).readU32() + const isMyMsg = addr.add(0x3C).readU32() //add isMyMsg + + if (msgType > 0) { + + const talkerIdPtr = addr.add(0x48).readPointer() + //console.log('txt msg',talkerIdPtr.readUtf16String()) + const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 + + const myTalkerIdPtr = Memory.alloc(talkerIdLen) + Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) + + + let contentPtr = null + let contentLen = 0 + let myContentPtr = null + if (msgType == 3) { // pic path + let thumbPtr = addr.add(0x198).readPointer(); + let hdPtr = addr.add(0x1ac).readPointer(); + let thumbPath = thumbPtr.readUtf16String(); + let hdPath = hdPtr.readUtf16String(); + let picData = [ + thumbPath, // PUPPET.types.Image.Unknown + thumbPath, // PUPPET.types.Image.Thumbnail + hdPath, // PUPPET.types.Image.HD + hdPath // PUPPET.types.Image.Artwork + ] + let content = JSON.stringify(picData); + myContentPtr = Memory.allocUtf16String(content); + } else { + contentPtr = addr.add(0x70).readPointer() + contentLen = addr.add(0x70 + 0x04).readU32() * 2 + 2 + myContentPtr = Memory.alloc(contentLen) + Memory.copy(myContentPtr, contentPtr, contentLen) + } + + // console.log('----------------------------------------') + // console.log(msgType) + // console.log(contentPtr.readUtf16String()) + // console.log('----------------------------------------') + const groupMsgAddr = addr.add(0x170).readU32() //* 2 + 2 + let myGroupMsgSenderIdPtr = null + if (groupMsgAddr == 0) { //weChatPublic is zero,type is 49 + + myGroupMsgSenderIdPtr = Memory.alloc(0x10) + myGroupMsgSenderIdPtr.writeUtf16String("null") + + } else { + + const groupMsgSenderIdPtr = addr.add(0x170).readPointer() + const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 + myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) + Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) + + } + + const xmlNullPtr = addr.add(0x1f0).readU32() //3.9.2.23 + let myXmlContentPtr = null + if (xmlNullPtr == 0) { + + myXmlContentPtr = Memory.alloc(0x10) + myXmlContentPtr.writeUtf16String("null") + + } else { + const xmlContentPtr = addr.add(0x1f0).readPointer() //3.9.2.23 + + const xmlContentLen = addr.add(0x1f0 + 0x04).readU32() * 2 + 2 + myXmlContentPtr = Memory.alloc(xmlContentLen) + Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) + } + + setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) + } + } + }) + return nativeCallback +})() + +// 003 done +const getBaseNodeAddress = (() => { + return moduleBaseAddress.add(offset.contactInfo.nodeOffset).readPointer() +}) + +// 004 done +const getHeaderNodeAddress = (() => { + const baseAddress = getBaseNodeAddress() + //console.log('baseAddress',baseAddress) + if (baseAddress.isNull()) { + return baseAddress + } + + //console.log('HeaderNodeAddress',baseAddress.add(offset.handle_offset).readPointer()) + return baseAddress.add(offset.contactInfo.nodeRootOffset).readPointer() +}) + +// 006 done +const getMyselfInfoFunction = (() => { + + let ptr = 0 + let wx_code = '' + let wx_id = '' + let wx_name = '' + let head_img_url = '' + + const base = moduleBaseAddress.add(offset.myselfinfo.offset) + const wxid_len = base.add(offset.myselfinfo.wxid_len_offset).readU32() + + if (wxid_len === 0x13) { // 新版本微信 + wx_id = base.readPointer().readAnsiString(wxid_len) + wx_code = base.add(offset.myselfinfo.wxcode_new).readAnsiString() + } else { + wx_id = readString(base) + wx_code = wx_id + } + + + wx_name = readString(base.add(offset.myselfinfo.wx_nick_name)) + const img_addr = base.add(offset.myselfinfo.head_img_url).readPointer() + const img_len = base.add(offset.myselfinfo.head_img_url_len).readU32() + + head_img_url = img_addr.readAnsiString(img_len) + + const myself = { + id: wx_id, + code: wx_code, + name: wx_name, + head_img_url: head_img_url, + }; + + return JSON.stringify(myself) + +}) + +// 043 done +const recurseNew = ((node) => { + const headerNodeAddress = getHeaderNodeAddress() + if (headerNodeAddress.isNull()) { + return + } + + if (node.equals(headerNodeAddress)) { + return + } + + for (const item in nodeList) { + if (node.equals(nodeList[item])) { + return + } + } + + + nodeList.push(node) + const id = readString(node.add(0x8)) + //wxid, format relates to registration method + const wxid = readWideString(node.add(0x30)) + //console.log('-----------',wxid) + + + //custom id, if not set return null, and use wxid which should be custom id + //const wx_code = readWideString(node.add(0x4c)) || readWideString(node.add(0x38)) + + //custom Nickname + const name = readWideString(node.add(0x8c)) + + //alias aka 'remark' in wechat + //const alias = readWideString(node.add(0x80)) + + //avatarUrl + //const avatar = readWideString(node.add(0x138)) + //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) + //contact gender + //const gender = node.add(0x18C).readU32() + + const contactJson = { + id1: id, + id: wxid, + name: name, + /*code: wx_code, + name: name, + alias: alias, + avatarUrl: avatar, + gender: gender,*/ + } + + contactList.push(contactJson) + + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + //const rightNode = node.add(0x08).readPointer() + + recurseNew(leftNode) + recurseNew(centerNode) + //recurse(rightNode) + + const allContactJson = contactList + return allContactJson + +}) + +// 044 done +const getContactNativeFunction = (() => { + const headerNodeAddress = getHeaderNodeAddress() + //console.log('headerNodeAddress',headerNodeAddress) + + if (headerNodeAddress.isNull()) { + return '[]' + } + + const node = headerNodeAddress.add(0x0).readPointer() + const ret = recurseNew(node) + + //console.log(ret) + + console.log('getContactNativeFunction:', ret.length) + /*for (let item of ret){ + console.log(JSON.stringify(item)) + }*/ + //console.log(ret.contact) + const cloneRet = JSON.stringify(ret) + nodeList.length = 0 + contactList.length = 0 + + return cloneRet +}) + +// 0xx done +const getChatroomNodeAddress = (() => { + const baseAddress = moduleBaseAddress.add(offset.chatroomInfo.nodeOffset).readPointer() + if (baseAddress.isNull()) { + return baseAddress + } + return baseAddress.add(offset.chatroomInfo.nodeRootOffset).readPointer() +}) + +// 008chatroom member done +const chatroomRecurse = ((node) => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return + } + + if (node.equals(chatroomNodeAddress)) { + return + } + + for (const item in chatroomNodeList) { + if (node.equals(chatroomNodeList[item])) { + return + } + } + + chatroomNodeList.push(node) + const roomid = readWideString(node.add(0x10)) + + const len = node.add(0x54).readU32() // + //const memberJson={} + if (len > 4) { // + const memberStr = readString(node.add(0x44)) + if (memberStr.length > 0) { + const memberList = memberStr.split(/[\\^][G]/) + const memberJson = { + roomid: roomid, + roomMember: memberList + } + + chatroomMemberList.push(memberJson) + } + + } + + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + const rightNode = node.add(0x08).readPointer() + + chatroomRecurse(leftNode) + chatroomRecurse(centerNode) + chatroomRecurse(rightNode) + + const allChatroomMemberJson = chatroomMemberList + return allChatroomMemberJson +}) + +// 009 done +const getChatroomMemberInfoFunction = (() => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return '[]' + } + + const node = chatroomNodeAddress.add(0x0).readPointer() + const ret = chatroomRecurse(node) + + const cloneRet = JSON.stringify(ret) + chatroomNodeList.length = 0 //empty + chatroomMemberList.length = 0 //empty + return cloneRet +}) + +// 024 done +/** + * sendMsgNativeFunction + * send text message + * @param {string} talkerId = wxid or roomid + * @param {string} content + */ + const sendMsgNativeFunction = ((talkerId, content) => { + + const txtAsm = Memory.alloc(Process.pageSize) + //const buffwxid = Memory.alloc(0x20) + + + let wxidPtr = Memory.alloc(talkerId.length * 2 + 2) + wxidPtr.writeUtf16String(talkerId) + + let picWxid = Memory.alloc(0x0c) + picWxid.writePointer(ptr(wxidPtr)).add(0x04) + .writeU32(talkerId.length * 2).add(0x04) + .writeU32(talkerId.length * 2).add(0x04) + + let contentPtr = Memory.alloc(content.length * 2 + 2) + contentPtr.writeUtf16String(content) + + const sizeOfStringStruct = Process.pointerSize * 5 + let contentStruct = Memory.alloc(sizeOfStringStruct) + + contentStruct + .writePointer(contentPtr).add(0x4) + .writeU32(content.length).add(0x4) + .writeU32(content.length * 2) + + + const ecxBuffer = Memory.alloc(0x2d8) + + Memory.patchCode(txtAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: txtAsm + }) + cw.putPushfx() + cw.putPushax() + + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + cw.putPushU32(0x0) + + //cw.putMovRegReg + + cw.putMovRegAddress('eax', contentStruct) + cw.putPushReg('eax') + + cw.putMovRegAddress('edx', picWxid) //room_id + + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) + + cw.putAddRegImm('esp', 0x18) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + console.log('----------txtAsm', txtAsm) + const nativeativeFunction = new NativeFunction(ptr(txtAsm), 'void', []) + nativeativeFunction() + +}) + +// 023 done +/** +* send at msg +*/ +let asmAtMsg = null +let roomid_, msg_, wxid_, atid_ +let ecxBuffer +const sendAtMsgNativeFunction = ((roomId, text, contactId,nickname) => { + + asmAtMsg = Memory.alloc(Process.pageSize) + ecxBuffer = Memory.alloc(0x3b0) + + const atContent = '@'+nickname+' '+text + + roomid_ = initStruct(roomId) + wxid_ = initidStruct(contactId) + msg_ = initmsgStruct(atContent) + atid_ = initAtMsgStruct(wxid_) + + Memory.patchCode(asmAtMsg, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: asmAtMsg + }) + cw.putPushfx() + cw.putPushax() + + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + //cw.putPushU32(0x0) + cw.putMovRegAddress('eax', atid_) + cw.putPushReg('eax') + + //cw.putMovRegReg + + cw.putMovRegAddress('eax', msg_) + cw.putPushReg('eax') + + cw.putMovRegAddress('edx', roomid_) //room_id + + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) + + cw.putAddRegImm('esp', 0x18) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + //console.log('----------txtAsm', asmAtMsg) + const nativeativeFunction = new NativeFunction(ptr(asmAtMsg), 'void', []) + nativeativeFunction() + +}) + +// 022 done +/** + * + * @param {*} contactId + * @param {*} path + */ + const sendPicMsgNativeFunction = ((contactId, path) => { + + const picAsm = Memory.alloc(Process.pageSize) + const buffwxid = Memory.alloc(0x20) + const picbuff = Memory.alloc(0x2D8) + + let pathPtr = Memory.alloc(path.length * 2 + 1) + pathPtr.writeUtf16String(path) + + let imagefilepath = Memory.alloc(0x24) + imagefilepath.writePointer(pathPtr).add(0x04) + .writeU32(path.length * 2).add(0x04) + .writeU32(path.length * 2).add(0x04) + + let picWxidPtr = Memory.alloc(contactId.length * 2 + 1) + picWxidPtr.writeUtf16String(contactId) + + let picWxid = Memory.alloc(0x0c) + picWxid.writePointer(ptr(picWxidPtr)).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + + + //const test_offset1 = 0x701DC0; + Memory.patchCode(picAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: picAsm + }) + cw.putPushfx(); + cw.putPushax(); + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call1 + )) + cw.putMovRegReg('edx', 'eax') //缓存 + + cw.putSubRegImm('esp', 0x14) + cw.putMovRegAddress('eax', buffwxid) + cw.putMovRegReg('ecx', 'esp') + cw.putMovRegAddress('edi', imagefilepath) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call2 + )) + + cw.putMovRegReg('ecx', 'edx') + cw.putMovRegAddress('eax', picWxid) //=lea + cw.putMovRegAddress('edi', imagefilepath) + cw.putPushReg('edi') + cw.putPushReg('eax') + cw.putMovRegAddress('eax', picbuff) + cw.putPushReg('eax') + + cw.putMovRegAddress('edi', picWxid) //edi + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call3 + )) + + + + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + //console.log('----------picAsm',picAsm) + const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) + nativeativeFunction() + +}) + +// 020 done +let memberNickBuffAsm = null +let nickRoomId = null +let nickMemberId = null +let nickBuff = null +const getChatroomMemberNickInfoFunction = ((memberId, roomId) => { + + nickBuff = Memory.alloc(0x7e4) + //const nickRetAddr = Memory.alloc(0x04) + memberNickBuffAsm = Memory.alloc(Process.pageSize) + //console.log('asm address----------',memberNickBuffAsm) + nickRoomId = initidStruct(roomId) + //console.log('nick room id',nickRoomId) + nickMemberId = initStruct(memberId) + + //console.log('nick nickMemberId id',nickMemberId) + //const nickStructPtr = initmsgStruct('') + + Memory.patchCode(memberNickBuffAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: memberNickBuffAsm + }) + cw.putPushfx() + cw.putPushax() + cw.putMovRegAddress('edi', nickRoomId) + cw.putMovRegAddress('eax', nickBuff) + cw.putMovRegReg('edx', 'edi') + cw.putPushReg('eax') + cw.putMovRegAddress('ecx', nickMemberId) + cw.putCallAddress(moduleBaseAddress.add(0xC06F10)) + cw.putAddRegImm('esp', 0x04) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsm), 'void', []) + nativeativeFunction() + + const nickname = readWideString(nickBuff) + console.log('----nickname', nickname) + return readWideString(nickBuff) +}) + +/* 由此之后是3.9.2.23中缺失的未实现方法 */ + +// 038 初始化全局变量 tbd +let g_initTestAsm = null +let g_BufferEbp2C = null +let g_initECXU32 = null +let g_initECXPtr = null +let g_initEBXPtr = null +let g_initEBX = null + +let g_attatchEBP210Buffer = null +let g_attatchPathPtr = null +let g_attatchPath = null +let g_attatchEBPAc = null +let g_attatchEBPAcBufPtr = null + +let g_attatchContactIdPtr = null +//let g_attatchECXBuffer = null +let g_attatchESIU32 = null + +let g_initECXTempPtr = null +const initGlobal = ((contactId, attatchFile) => { + + //const base = moduleBaseAddress.add(0x222f38c).readPointer() + //g_EDI = base.add(0xD70).readPointer()//0x438+0x938 + console.log('------------g_attatchEBPAc', g_attatchEBPAc) + console.log('------------g_EDIU32', g_EDIU32) + g_initTestAsm = Memory.alloc(Process.pageSize) + console.log('------------address', g_initTestAsm) + + g_initECXPtr = g_EDIPtr.add(0xB80).readPointer().add(0x1640) + g_initECXTempPtr = g_EDIPtr.add(0xB88).readPointer() + g_initECXU32 = g_initECXPtr.toInt32() + g_attatchESIU32 = g_EDIU32 + + console.log('------------g_initECXU32', g_initECXU32) + console.log('------------g_initESIU32', g_attatchESIU32) + + + //console.log('==========g_initECXPtr',g_initECXPtr) + //console.log('==========g_EDIU32',g_EDIU32) + + //g_attatchECXBuffer = Memory.alloc(0x1024) + //Memory.copy(g_attatchECXBuffer, g_initECXPtr, 0x1024) + + g_BufferEbp2C = Memory.alloc(0x48) + + //g_initEBX = moduleBaseAddress.add(0x2251724).readPointer().readPointer() + //g_initEBXPtr = Memory.alloc(0x14).writePointer(g_initEBX) + //g_initEBXPtr.add(0x08).writePointer(g_BufferEbp2C) + + g_attatchPathPtr = Memory.alloc(attatchFile.length * 2 + 2) + g_attatchPathPtr.writeUtf16String(attatchFile) + + g_attatchPath = Memory.alloc(0x28) + g_attatchPath.writePointer(g_attatchPathPtr).add(0x04) + .writeU32(attatchFile.length * 2).add(0x04) + .writeU32(attatchFile.length * 2).add(0x04) + /*---------------------------------ebp-210----------------*/ + g_attatchEBP210Buffer = Memory.alloc(0x48) + g_attatchEBP210Buffer.writeU32(0x3) + g_attatchEBP210Buffer.add(0x4).writePointer(g_attatchPathPtr) + g_attatchEBP210Buffer.add(0x8).writeU32(attatchFile.length * 2) + g_attatchEBP210Buffer.add(0xC).writeU32(attatchFile.length * 2) + g_attatchEBP210Buffer.add(0x2C).writeU32(moduleBaseAddress.add(0x2ECE87).toInt32()) + //console.log('------------g_attatchEBP210Buffer',g_attatchEBP210Buffer) + /*---------------------------------ebp-210----------------*/ + + //g_attatchContactIdPtr = Memory.alloc(0x4) + //g_attatchContactIdPtr.writeUtf16String(contactId) + //console.log('------------g_attatchEBP210Buffer',g_attatchEBP210Buffer) + g_attatchEBPAc = Memory.alloc(0x140) + //g_attatchEBPAcBufPtr = Memory.alloc(0x100) + //g_attatchEBPAc.writePointer(g_attatchEBP210Buffer) + //g_attatchEBPAc.add(0x4).writePointer(g_attatchEBPAcBufPtr) + //g_attatchEBPAc.add(0x8).writePointer(g_attatchEBPAcBufPtr) + g_attatchEBPAc.add(0x10).writeU32(g_EDIU32) + console.log('------------g_attatchEBPAc', g_attatchEBPAc) + + /*g_attatchECXBuffer.add(0x18).writePointer(g_attatchContactIdPtr) + g_attatchECXBuffer.add(0x1C).writeU32(contactId.length*2) + .add(0x04).writeU32(contactId.length*2)*/ + + + + //g_attatchESIU32 = g_EDI.toInt32() + + + //console.log('------------g_attatchESIU32',g_attatchESIU32) + //console.log('==========g_attatchECXBuffer',g_attatchECXBuffer) + + Memory.patchCode(g_initTestAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: g_initTestAsm }) + cw.putPushfx() + cw.putPushax() + //cw.putMovRegAddress('eax', g_attatchEBP210Buffer) + + /*cw.putMovRegAddress('edi',g_EDIPtr) + cw.putMovRegReg('esi','edi') + cw.putMovRegAddress('eax',g_BufferEbp2C) + cw.putMovRegAddress('ecx',g_initECXTempPtr) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x131bb0))*/ + + //cw.putMovRegOffsetPtrU32('ebp', -20, 0) + + /*cw.putPushU32(0) + cw.putMovRegAddress('eax', g_attatchPathPtr) + cw.putPushReg('eax') + cw.putPushU32(3) + cw.putMovRegAddress('ecx', g_attatchEBP210Buffer) + cw.putCallAddress(moduleBaseAddress.add(0x130220))*/ + + + /*cw.putMovRegAddress('edi', g_attatchEBPAc)//后面要用的的ebp-2c + cw.putMovRegAddress('ecx', g_attatchEBP210Buffer) + cw.putPushReg('ecx') + cw.putMovRegU32('eax',0) + cw.putPushReg('eax')//push eax + cw.putMovRegReg('ecx', 'edi') + cw.putMovRegAddress('esi',g_attatchPathPtr) + cw.putCallAddress(moduleBaseAddress.add(0x138880))*/ + + + /*cw.putSubRegImm('esp',0x14) + cw.putMovRegU32('ecx',g_initECXU32) + cw.putMovRegU32('esi',g_attatchESIU32) + cw.putMovRegAddress('eax', g_attatchEBPAc) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x173620))*/ + //cw.putCallAddress(moduleBaseAddress.add(0x522590)) + + /** g_attatchEBPAc*/ + //cw.putMovRegNearPtr('eax', g_attatchEBPAc) + //cw.putMovNearPtrReg(g_attatchEBPAc.add(0xc), 'eax') + /** g_attatchEBPAc*/ + + + //cw.putMovRegAddress('ebx', g_initEBXPtr) + //cw.putMovRegU32('edi', g_EDI.toInt32()) + //cw.putMovRegU32('esi', g_EDI.toInt32()) + /*cw.putMovRegU32('ecx', g_initECX) + cw.putMovRegAddress('eax', g_BufferEbp2C) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x131BB0))*/ + + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(g_initTestAsm), 'void', []) + nativeativeFunction() +}) + +// 039 +let g_personal_detail_ebx = null +let g_personal_detail_asm = null +let g_personal_wxid = null +let g_personal_wxid_ptr = null +const getOldTest = ((wxid) => {//personal detail + + g_personal_detail_asm = Memory.alloc(Process.pageSize) + g_personal_detail_ebx = moduleBaseAddress.add(0x222F38C).readPointer().add(0xFB8).toInt32() + + g_personal_wxid_ptr = Memory.alloc(wxid.length * 2 + 2) + g_personal_wxid_ptr.writeUtf16String(wxid) + + g_personal_wxid = Memory.alloc(0x14) + g_personal_wxid.writePointer(ptr(g_personal_wxid_ptr)).add(0x04) + .writeU32(wxid.length * 2).add(0x04) + .writeU32(wxid.length * 2).add(0x08) + + console.log('-----------address----------', g_personal_detail_asm) + + Memory.patchCode(g_personal_detail_asm, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: g_personal_detail_asm }) + cw.putPushfx() + cw.putPushax() + + cw.putCallAddress(moduleBaseAddress.add(0x9A000)) + + //78BA9ACE | E8 2D05D6FF | call wechatwin.7890A000 | + cw.putMovRegU32('ebx', g_personal_detail_ebx) + cw.putMovRegReg('esi', 'eax') + cw.putPushReg('ebx') + cw.putSubRegImm('esp', 0x14) + cw.putMovRegAddress('eax', g_personal_wxid) + cw.putMovRegReg('ecx', 'esp') + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) + cw.putMovRegReg('ecx', 'esi') + cw.putCallAddress(moduleBaseAddress.add(0x4024A0)) + + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(g_personal_detail_asm), 'void', []) + nativeativeFunction() + + +}) + +// const writeLogNativeCallback = (() => { +// const nativeCallback = new NativeCallback(() => { }, 'void', []) +// const nativeCallFunction = new NativeFunction(nativeCallback, 'void', []) + +// Interceptor.attach( +// moduleBaseAddress.add(0x7008A4), +// { +// onEnter() { +// const addr = this.context.eax//.sub(0x114)//0xc30-0x08 +// if(addr >0){ +// const log = ptr(addr).readAnsiString() +// } +// } +// }) +// return nativeCallback +// })() + +// 040 +/** + * test call + */ +let attatchTestAsm = null +let attatchTestEbp2C = null +let attatchGlobalEDI = null +let attatchGlobalEDIB88 = null +let attatchTestEBX = null +let g_tempEcx = null +let attatchFirstECX = null +//let attatchFirstECX = null +let gattatchFilePtr = null +let gattatchFile = null +let gattatchReceiveIdPtr = null +let gattatchReceiveId = null +let attatchEAX3B0Buf = null + +let attatchESIbuf = null +const getWxTest = ((contactId, filePath) => { + //const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) + //nativeativeFunction() + attatchTestAsm = Memory.alloc(Process.pageSize) + console.log('----------------address', attatchTestAsm) + attatchTestEbp2C = Memory.alloc(0xC) + attatchGlobalEDI = moduleBaseAddress.add(0x222f38c).readPointer() + .add(0x938).add(0x438).readPointer() + attatchGlobalEDIB88 = attatchGlobalEDI.add(0xB88).readPointer() + attatchTestEBX = Memory.alloc(0x4) + attatchTestEBX.writePointer(attatchGlobalEDI) + console.log('----------------attatchGlobalEDI', attatchGlobalEDI) + console.log('----------------attatchGlobalEDIB88', attatchGlobalEDIB88) + + attatchFirstECX = Memory.alloc(0x28) + //const attatchSecondEcx = Memory.alloc(0x14) + + const contactIdLength = contactId.length * 2 + 2//edx + const contractIdActLength = contactId.length + + + gattatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) + gattatchReceiveIdPtr.writeUtf16String(contactId) + + gattatchReceiveId = Memory.alloc(0x14) + gattatchReceiveId.writePointer(ptr(gattatchReceiveIdPtr)).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x08) + //console.log('----------------attatchGlobalEDIB88',attatchGlobalEDIB88) + //return + /*console.log(hexdump(attatchTestEBX, { + offset: 0, + length: 0x40, + header: true, + ansi: true + })) + return*/ + + gattatchFilePtr = Memory.alloc(filePath.length * 2 + 2) + gattatchFilePtr.writeUtf16String(filePath) + + gattatchFile = Memory.alloc(0x14) + gattatchFile.writePointer(ptr(gattatchFilePtr)).add(0x04) + .writeU32(filePath.length * 2).add(0x04) + .writeU32(filePath.length * 2).add(0x08) + + const attatchLastECX = moduleBaseAddress.add(0x222f170).toInt32() + + attatchEAX3B0Buf = Memory.alloc(0x3B0) + + g_tempEcx = Memory.alloc(0x4) + //g_tempEcx1 = Memory.alloc(0x4) + + attatchESIbuf = Memory.alloc(0x100) + attatchESIbuf.add(0x0).writeU32(3) + attatchESIbuf.add(0x4).writePointer(gattatchFilePtr) + attatchESIbuf.add(0x8).writeU32(filePath.length * 2) + attatchESIbuf.add(0xc).writeU32(filePath.length * 2) + + Memory.patchCode(attatchTestAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: attatchTestAsm }) + cw.putPushfx() + cw.putPushax() + //cw.putMovRegU32('edi',attatchGlobalEDI) + + + cw.putMovRegAddress('esi', attatchESIbuf) + + cw.putMovRegAddress('ecx', attatchFirstECX.add(0x14)) + cw.putMovRegAddress('eax', gattatchFile) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) + + + cw.putMovRegAddress('ecx', attatchFirstECX) + cw.putMovRegU32('eax', contactIdLength) + cw.putPushReg('eax') + cw.putPushU32(0) + cw.putCallAddress(moduleBaseAddress.add(0x1a11c83)) + cw.putAddRegImm('esp', 0x8) + + cw.putMovRegReg('edx', 'eax') + cw.putMovNearPtrReg(attatchFirstECX, 'edx') + cw.putMovRegU32('edi', contactIdLength) + cw.putPushReg('edi') + cw.putMovRegAddress('eax', gattatchReceiveIdPtr)//ebp-58 + cw.putPushReg('eax') + cw.putMovRegNearPtr('eax', attatchFirstECX) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x1a1047a)) + cw.putAddRegImm('esp', 0x0c) + + //cw.putMovRegNearPtr('ecx',attatchFirstECX) + //cw.putAddRegImm('esp', 0x0c) + //cw.putMovRegU32('edx', 0) + //cw.putMovRegRegPtr('eax', 'ecx') + //cw.putMovNearPtrReg(attatchFirstECX.add(0x04),'edi') + cw.putMovRegU32('edi', contactId.length * 2) + cw.putMovRegU32('ecx', attatchLastECX) + cw.putMovRegAddress('eax', attatchEAX3B0Buf) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x392260)) + + cw.putMovRegAddress('ecx', attatchEAX3B0Buf) + cw.putCallAddress(moduleBaseAddress.add(0x94200)) + + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(attatchTestAsm), 'void', []) + nativeativeFunction() + + +}) + +// 001 +const getTestInfoFunction = ((addr) => { + const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) + nativeativeFunction() + + //00CFE484 + + + /*MemoryAccessMonitor.enable({base:ptr(addr),size:0x01}, { + onAccess(details){ + console.log('============') + console.log(details.operation) + console.log(details.from) + console.log(details.address) + console.log('============') + } + })*/ + +}) + +// 002 +const isLoggedInFunction = (() => { + loggedIn = moduleBaseAddress.add(offset.is_logged_in_offset).readU32() + return !!loggedIn +}) + +// 007 获得当前账号信息 +const getMyselfIdFunction = (() => { + + let wx_id = readString(moduleBaseAddress.add(offset.wxid_offset)) + + return wx_id + +}) + +//contact +// 042 +const recurse = ((node) => { + const headerNodeAddress = getHeaderNodeAddress() + if (headerNodeAddress.isNull()) { return } + + if (node.equals(headerNodeAddress)) { return } + + for (const item in nodeList) { + if (node.equals(nodeList[item])) { + return + } + } + + + nodeList.push(node) + //wxid, format relates to registration method + const wxid = readWideString(node.add(0x38)) + + //custom id, if not set return null, and use wxid which should be custom id + const wx_code = readWideString(node.add(0x4c)) || readWideString(node.add(0x38)) + + //custom Nickname + const name = readWideString(node.add(0x94)) + + //alias aka 'remark' in wechat + const alias = readWideString(node.add(0x80)) + + //avatarUrl + const avatar = readWideString(node.add(0x138)) + //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) + //contact gender + const gender = node.add(0x18C).readU32() + + const contactJson = { + id: wxid, + code: wx_code, + name: name, + alias: alias, + avatarUrl: avatar, + gender: gender, + } + + contactList.push(contactJson) + + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + const rightNode = node.add(0x08).readPointer() + + recurse(leftNode) + recurse(centerNode) + recurse(rightNode) + + const allContactJson = contactList + return allContactJson + +}) + +// 013 +const isSupported = checkSupportedFunction() + +if (!isSupported) { + throw new Error(`Wechat version not supported. \nWechat version: ${getWechatVersionStringFunction()}, supported version: ${getWechatVersionStringFunction(availableVersion)}`) +} + +// 015 +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() + setImmediate(() => nativeativeFunction(bySrv)) + } + }) + return nativeCallback +})() + +// 016 +const hookLoginEventCallback = (() => { + const nativeCallback = new NativeCallback(() => { }, 'void', []) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', []) + Interceptor.attach(moduleBaseAddress.add(offset.hook_on_login_offset), { + onLeave: function (retval) { + isLoggedInFunction() + setImmediate(() => nativeativeFunction()) + return retval + } + }) + + setTimeout(() => { + if (isLoggedInFunction()) { + setImmediate(() => nativeativeFunction()) + } + }, 500); + + return nativeCallback +})() + +// 017 +const checkQRLoginNativeCallback = (() => { + + const nativeCallback = new NativeCallback(() => { }, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'int32', 'pointer']) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'int32', 'pointer']) + // const json = { + // status, + // uuid, + // wxid, + // avatarUrl, + // nickname, + // phoneType, + // phoneClientVer, + // pairWaitTip, + // } + + const callback = { + onLeave: function (retval) { + const json = getQrcodeLoginData() + if (json.status == 0) { + // 当状态为 0 时,即未扫码。而其他状态会触发另一个方法,拥有更多数据。 + ret(json) + } + return retval + }, + } + + const ret = (json) => { + const arr = [ + json.status || 0, + Memory.allocUtf8String(json.uuid ? `http://weixin.qq.com/x/${json.uuid}` : ''), + Memory.allocUtf8String(json.wxid || ''), + Memory.allocUtf8String(json.avatarUrl || ''), + Memory.allocUtf8String(json.nickname || ''), + Memory.allocUtf8String(json.phoneType || ''), + json.phoneClientVer || 0, + Memory.allocUtf8String(json.pairWaitTip || ''), + ] + setImmediate(() => nativeativeFunction(...arr)) + } + + Interceptor.attach(moduleBaseAddress.add(offset.hook_get_login_qr_offset), callback) + Interceptor.attach(moduleBaseAddress.add(offset.hook_check_login_qr_offset), callback) + Interceptor.attach(moduleBaseAddress.add(offset.hook_save_login_qr_info_offset), { + onEnter: function () { + const qrNotify = this.context['ebp'].sub(72) + const uuid = readString(qrNotify.add(4).readPointer()) + const wxid = readString(qrNotify.add(8).readPointer()) + const status = qrNotify.add(16).readUInt() + const avatarUrl = readString(qrNotify.add(24).readPointer()) + const nickname = readString(qrNotify.add(28).readPointer()) + const pairWaitTip = readString(qrNotify.add(32).readPointer()) + const phoneClientVer = qrNotify.add(40).readUInt() + const phoneType = readString(qrNotify.add(44).readPointer()) + + const json = { + status, + uuid, + wxid, + avatarUrl, + nickname, + phoneType, + phoneClientVer, + pairWaitTip, + } + ret(json) + }, + onLeave: function (retval) { + return retval + }, + }) + + if (!isLoggedInFunction()) { + setTimeout(() => { + const json = getQrcodeLoginData() + ret(json) + }, 100); + } + + return nativeCallback +})() + +// 018 +const getQrcodeLoginData = () => { + const getQRCodeLoginMgr = new NativeFunction(moduleBaseAddress.add(offset.get_qr_login_data_offset), 'pointer', []) + const qlMgr = getQRCodeLoginMgr() + + 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 +} + +// 045 +/** + * 20220504 writelog + * 7A566D72 | FFB5 ECFEFFFF | push dword ptr ss:[ebp-114] | 【3.6.0.18】写日志,这个里面就是日志内容 + 7A566D78 | FFB5 E8FEFFFF | push dword ptr ss:[ebp-118] | + */ +const writeLogNativeCallback = (() => { + const nativeCallback = new NativeCallback(() => { }, 'void', []) + const nativeCallFunction = new NativeFunction(nativeCallback, 'void', []) + + Interceptor.attach( + moduleBaseAddress.add(0x1576D7E), + { + onEnter() { + const addr = this.context.ebp.sub(0x114)//0xc30-0x08 + console.log('-------',addr) + + } + }) + return nativeCallback +})() + +// 046 +let nickRoomIdV6 = null +let nullEdiWxidStructV6 = null +let nickMemberIdStructV6 = null +let memberNickBuffAsmV6 = null +let nickResultEdiV6 = null + +const getChatroomMemberNickInfoV1Function = ((memberId, roomId) => { + nickRoomIdV6 = initidStruct(roomId) + nullEdiWxidStructV6 = initNullIdStruct('') + nickMemberIdStructV6 = initStruct(memberId) + memberNickBuffAsmV6 = Memory.alloc(Process.pageSize) + console.log('-----', memberNickBuffAsmV6) + + const tmp = (moduleBaseAddress.add( + offset.chatroom_member_nick_esi_offset_v6 + )).readU32() + console.log('=======tmp', tmp) + Memory.patchCode(memberNickBuffAsmV6, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: memberNickBuffAsmV6 }) + cw.putPushfx(); + cw.putPushax(); + + cw.putMovRegAddress('edi', nullEdiWxidStructV6) + cw.putMovRegAddress('eax', nickMemberIdStructV6) + cw.putMovRegAddress('ebx', nickRoomIdV6) + + + cw.putMovRegAddress('esi', ptr(tmp)) + cw.putPushReg('edi') + cw.putPushReg('eax') + cw.putPushReg('ebx') + + cw.putMovRegAddress('ecx', ptr(tmp)) + + cw.putCallAddress(moduleBaseAddress.add( + offset.chatroom_member_nick_call_offset_v6 + )) + + + //cw.putMovNearPtrReg(nickResultEdiV6, 'edi') + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsmV6), 'void', []) + nativeativeFunction() + + console.log('---------nullEdiWxidStructV6', nullEdiWxidStructV6) + const nickha = readWideString(nullEdiWxidStructV6) + + console.log('-----------------') + console.log(nickha) + console.log('-----------------') + return readWideString(nullEdiWxidStructV6) +}) + +// 021 +/** +* send attatch +*/ +let attatchWxid = null +let attatchPath = null +let attatchPathPtr = null +let attatchAsm = null +let attatchBuf = null + +let attatchReceiveIdPtr = null +let attatchReceiveId = null + +let attatchSendId = null +let attatchSendIdPtr = null + +/* +let attatchEbp2C = null +let attatchEDIPtr = null +let attatchEDIU32 = null +let attatchECX = null + +let attatchEbp210 = null +let attatchEbpAc = null*/ + +let attatchEbp11E8 = null +let attatchEbpCC = null +let attatchEbp368 = null +let attatchEAX = null + +let sFileName = null +let fileNamePtr = null + +let attatchEbp84 = null +let attatchECX = null + + +/** + * +param {78EDBC86 | 8B80 38040000 | mov eax,dword ptr ds:[eax+438] | +78EDBC8C | 8BB0 800B0000 | mov esi,dword ptr ds:[eax+B80] |} sendWxid +*/ +const sendAttatchMsgNativeFunction = ((contactId, senderId, path, filename, size) => { + + attatchAsm = Memory.alloc(Process.pageSize) + console.log('--------------address', attatchAsm) + + fileNamePtr = Memory.alloc(filename.length * 2 + 2) + fileNamePtr.writeUtf16String(filename) + + sFileName = Memory.alloc(0x14) + sFileName.writePointer(ptr(fileNamePtr)).add(0x04) + .writeU32(fileNamePtr.length * 2).add(0x04) + .writeU32(fileNamePtr.length * 2).add(0x08) + + //const fileSize = size.toInt32() + + + attatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) + attatchReceiveIdPtr.writeUtf16String(contactId) + + attatchReceiveId = Memory.alloc(0x14) + attatchReceiveId.writePointer(ptr(attatchReceiveIdPtr)).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x08) + + attatchSendIdPtr = Memory.alloc(senderId.length * 2 + 2) + attatchSendIdPtr.writeUtf16String(senderId) + + attatchSendId = Memory.alloc(0x14) + attatchSendId.writePointer(ptr(attatchSendIdPtr)).add(0x04) + .writeU32(senderId.length * 2).add(0x04) + .writeU32(senderId.length * 2).add(0x08) + + attatchPathPtr = Memory.alloc(path.length * 2 + 2) + attatchPathPtr.writeUtf16String(path) + + attatchPath = Memory.alloc(0x28) + attatchPath.writePointer(attatchPathPtr).add(0x04) + .writeU32(path.length * 2).add(0x04) + .writeU32(path.length * 2).add(0x04) + + attatchEbp11E8 = Memory.alloc(0xBE4) + attatchEbpCC = Memory.alloc(0x14) + attatchEbp368 = Memory.alloc(0x290) + attatchEbp84 = Memory.alloc(0x18) + attatchEAX = Memory.alloc(0x18) + + attatchECX = moduleBaseAddress.add(0x222f178).toInt32() + + //console.log('basename',path.basename(path)) + //return + + /** + * -------------buffer------------------------------- + */ + + Memory.patchCode(attatchAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: attatchAsm }) + cw.putPushfx() + cw.putPushax() + + cw.putMovRegAddress('ecx', attatchEbp11E8) + cw.putCallAddress(moduleBaseAddress.add(0xE1590)) + + cw.putPushU32(-1) + cw.putPushU32(moduleBaseAddress.add(0x1E1B3C0).toInt32()) + cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x4))//11e4 + cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid + // cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid + + /** + * 78482B8D | 6A FF | push FFFFFFFF | + 78482B8F | 68 B895E979 | push wechatwin.79E995B8 | 79E995B8:L"0" + 78482B94 | 8D8D 48EEFFFF | lea ecx,dword ptr ss:[ebp-11B8] | + 78482B9A | E8 71F83600 | call wechatwin.787F2410 | 此处继续写ebp-11b8 + */ + cw.putPushU32(-1) + cw.putPushU32(moduleBaseAddress.add(0x1DA95B8).toInt32()) + cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x30))//11B8 + cw.putCallAddress(moduleBaseAddress.add(0x702410)) + + cw.putMovRegU32('eax', 0x6) + cw.putMovNearPtrReg(attatchEbp11E8.add(0x80), 'eax')//1168 + cw.putMovRegU32('eax', size)//file size + cw.putMovNearPtrReg(attatchEbp11E8.add(0x108), 'eax')//10e0 + + + cw.putMovRegAddress('eax', sFileName) + cw.putPushReg('eax') + cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x44))//11a4=0x11e8-0x160 + cw.putCallAddress(moduleBaseAddress.add(0x702980))//write filename + + cw.putMovRegAddress('eax', attatchSendId) + cw.putPushReg('eax') + cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x160))//1088=0x11e8-0x160 + cw.putCallAddress(moduleBaseAddress.add(0x702980)) + + + cw.putMovRegAddress('eax', attatchEbpCC) + cw.putPushReg('eax') + cw.putMovRegAddress('ecx', attatchEbp11E8) + cw.putCallAddress(moduleBaseAddress.add(0x617C30)) + + cw.putMovRegAddress('ecx', attatchEbp368) + cw.putCallAddress(moduleBaseAddress.add(0x954F0)) + + cw.putPushU32(-1) + cw.putPushU32((moduleBaseAddress.add(0x1D8F248)).toInt32()) + cw.putMovRegAddress('ecx', attatchEbp84) + cw.putCallAddress(moduleBaseAddress.add(0x701CD0)) + + cw.putMovRegAddress('ecx', attatchPath) + cw.putPushU32(0x6) + cw.putMovRegAddress('edx', attatchEbp11E8.add(0x160))//1088 + //cw.putMovRegAddress('eax',attatchEAX) + cw.putPushReg('ecx') + cw.putPushReg('eax') + + cw.putMovRegAddress('eax', attatchEbpCC) + cw.putPushReg('eax') + + cw.putMovRegAddress('eax', attatchReceiveId) + cw.putPushReg('eax') + + cw.putMovRegAddress('ecx', attatchEbp368) + cw.putCallAddress(moduleBaseAddress.add(0x391F80)) + cw.putAddRegImm('esp', 0x14) + + + cw.putPushU32(moduleBaseAddress.add(0x223EC34).toInt32()) + cw.putPushU32(moduleBaseAddress.add(0x223EC34).toInt32()) + //cw.putMovRegU32('edx',0xAD0001) 两行代码都可以 + cw.putAddRegImm('edx', 0x1) + cw.putMovRegAddress('ecx', attatchEbp368) + cw.putCallAddress(moduleBaseAddress.add(0x392150)) + cw.putAddRegImm('esp', 0x8) + + + + //cw.putMovRegAddress('ecx', attatchEbp368) + //cw.putCallAddress(moduleBaseAddress.add(0x63B4F0)) + // 7B53F178 + //cw.putMovRegU32('ecx', attatchEbpCC.add(0x3c).toInt32())//ebp-90 + //cw.putMovNearPtrReg(attatchEbpCC.add(0x64), 'eax')//ebp-68 + //cw.putAddRegImm('ecx', 0x8) + //cw.putMovRegAddress('eax', attatchEbp368.add(0x64))//ebp-68 + + //cw.putMovRegU32('ecx',attatchECX) + //cw.putPushReg('eax') + //cw.putMovRegAddress('eax', attatchEbpCC.add(0x40))//ebp-8c + //cw.putPushReg('eax') + //cw.putCallAddress(moduleBaseAddress.add(0xC9D30)) + //cw.putCallAddress(moduleBaseAddress.add(0x522590)) + //78483063 | E8 28F51800 | call wechatwin.78612590 | + + + //78483039 | 8D8D 98FCFFFF | lea ecx,dword ptr ss:[ebp-368] | + //7848303F | E8 AC842A00 | call wechatwin.7872B4F0 | + //cw.putMovRegAddress('ecx', attatchEbp368) + //cw.putCallAddress(moduleBaseAddress.add(0x63B4F0)) + + // 78F33099 | 8D8D 34FFFFFF | lea ecx,dword ptr ss:[ebp-CC] | + //78F3309F | E8 AC0FD0FF | call wechatwin.78C34050 | + + //cw.putMovRegAddress('ecx',attatchEbpCC) + //cw.putCallAddress(moduleBaseAddress.add(0x94050)) + + /** + * 78F3307F | 8B4D AC | mov ecx,dword ptr ss:[ebp-54] | + 78F33082 | 8D85 98FCFFFF | lea eax,dword ptr ss:[ebp-368] | + 78F33088 | 50 | push eax | + 78F33089 | E8 82DACFFF | call wechatwin.78C30B10 | + + cw.putMovRegAddress('ecx', attatchEbp54) + cw.putMovRegAddress('eax', attatchEbp368) + cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x90B10))*/ + + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() + + }) + + const nativeativeFunction = new NativeFunction(ptr(attatchAsm), 'void', []) + nativeativeFunction() + /*console.log(hexdump(attatchEbp11E8.add(0x80), { + offset: 0, + length: 0x40, + header: true, + ansi: true + }))*/ + //console.log('') + /*console.log(hexdump(attatchEbpCC.add(0x160), { + offset: 0, + length: 0x64, + header: true, + ansi: true + }))*/ + //console.log('-------',attatchEbp1C.readPointer()) + //console.log('-------',attatchEbp1C.add(0x4).readPointer()) + //console.log('-------',attatchEbp1C.add(0x8).readPointer()) +}) + +// 025 +const callLoginQrcodeFunction = ((forceRefresh = false) => { + const json = getQrcodeLoginData() + 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() +}) + + +// 026 +const agentReadyCallback = (() => { + const nativeCallback = new NativeCallback(() => { }, 'void', []) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', []) + + setTimeout(() => { + nativeativeFunction() + }, 500); + return nativeCallback +})() + +// 027 +const SendMiniProgramNativeFunction = ((bg_path_str, send_wxid_str, recv_wxid_str, xmlstr) => { + console.log("------------------------------------------------------"); + var asmCode = Memory.alloc(Process.pageSize); + + var ECX_buf = Memory.alloc(0x300); + var Buf_EAX = Memory.alloc(0x300); + var buf_1 = Memory.alloc(0x300); + var ptr_to_buf_1 = Memory.alloc(0x4).writePointer(buf_1); + var buf_2 = Memory.alloc(0x300); + + // var bg_path_str="C:/aaaa.jpg"; + var bg_path_Ptr = Memory.alloc(bg_path_str.length * 2 + 1) + bg_path_Ptr.writeUtf16String(bg_path_str); + var bg_path_Struct = Memory.alloc(0x14) // returns a NativePointer + bg_path_Struct.writePointer(bg_path_Ptr).add(0x04) + .writeU32(bg_path_str.length * 2).add(0x04) + .writeU32(bg_path_str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0); + + // var send_wxid_str="wxid_4zr616ir6fi122"; + var send_wxid_Ptr = Memory.alloc(send_wxid_str.length * 2 + 1) + send_wxid_Ptr.writeUtf16String(send_wxid_str); + var send_wxid_Struct = Memory.alloc(0x14) // returns a NativePointer + send_wxid_Struct.writePointer(send_wxid_Ptr).add(0x04) + .writeU32(send_wxid_str.length * 2).add(0x04) + .writeU32(send_wxid_str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0); + + // var recv_wxid_str="filehelper"; + var recv_wxid_Ptr = Memory.alloc(recv_wxid_str.length * 2 + 1) + recv_wxid_Ptr.writeUtf16String(recv_wxid_str); + var recv_wxid_Struct = Memory.alloc(0x14) // returns a NativePointer + recv_wxid_Struct.writePointer(recv_wxid_Ptr).add(0x04) + .writeU32(recv_wxid_str.length * 2).add(0x04) + .writeU32(recv_wxid_str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0); + + // vvar pXml=initidStruct('wxid_4zr616ir6fi1220腾讯出行服务|加油代驾公交view330https://mp.weixin.qq.com/mp/waerrpage?appid=wx65cc950f42e8fff1&amp;type=upgrade&amp;upgradetype=3#wechat_redirecthttp://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=200腾讯出行服务|加油代驾公交0gh_ad64296dc8bd@appwx65cc950f42e8fff11http://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=20002_wx65cc950f42e8fff1_875237370_1644979747_11Window wechat'); + + var pXml = initidStruct(xmlstr) + + console.log(send_wxid_Struct); + console.log(recv_wxid_Struct); + console.log(pXml); + console.log("okkk"); + + console.log("------------------------------------------------------"); + + Memory.patchCode(asmCode, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: asmCode }) + cw.putPushfx(); + cw.putPushax(); + cw.putMovRegReg('ecx', 'ecx'); + cw.putMovRegAddress('ecx', ECX_buf); + cw.putCallAddress(moduleBaseAddress.add(0x69BB0)); //init ecx + + cw.putPushU32(0x21); + + + cw.putPushNearPtr(ptr_to_buf_1); //ptr + cw.putPushU32(bg_path_Struct.toInt32()); + cw.putPushU32(pXml.toInt32()); + cw.putPushU32(recv_wxid_Struct.toInt32()); + + cw.putMovRegAddress('edx', send_wxid_Struct); + cw.putMovRegAddress('ecx', ECX_buf); + cw.putCallAddress(moduleBaseAddress.add(0x2E2420)); + cw.putAddRegImm('esp', 0x14) + + cw.putPushU32(Buf_EAX.toInt32()); + cw.putMovRegAddress('ecx', ECX_buf); + cw.putCallAddress(moduleBaseAddress.add(0x94C10)); + + cw.putPushU32(moduleBaseAddress.add(0x1DCB46C).toInt32()); + cw.putPushU32(moduleBaseAddress.add(0x1DCB46C).toInt32()); + cw.putMovRegAddress('ecx', ECX_buf); + cw.putCallAddress(moduleBaseAddress.add(0x2E2630)); + cw.putAddRegImm('esp', 0x8) + + cw.putPopax(); + cw.putPopfx(); + cw.putRet(); + cw.flush(); + }) + + const nativeativeFunction = new NativeFunction(ptr(asmCode), 'void', []) + nativeativeFunction() + + +}) \ No newline at end of file diff --git a/src/init-agent-script.js b/src/init-agent-script.js index 6ae2c78..802ce45 100644 --- a/src/init-agent-script.js +++ b/src/init-agent-script.js @@ -13,469 +13,320 @@ //const { isNullishCoalesce } = require("typescript") -//3.6.0.18 +//3.9.2.23 const offset = { - /**---nick call */ - chatroom_member_nick_call_offset_v6: 0x3E47B0,//3.6.0.18 - chatroom_member_nick_esi_offset_v6: 0x22553D4, - /**-- nick call */ - node_offset: 0x222f3bc,//0x1db9728 -- 3.3.0.155 - handle_offset: 0x4c, - send_txt_call_offset: 0x4BE7B0,//0x3e3b80 - hook_point: 0x4E94F2,//0x4E9464,//3.3.0.115 = 0x40d3b1 - chatroom_node_offset: 0xad8, - nickname_offset: 0x222EBB4, - wxid_offset: 0x222F020, - head_img_url_offset: 0x222EE94, - 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, - //-------3.6.0.18 send pic - send_picmsg_call_offset0: 0x9A1C0,//assign value to ecx - send_picmsg_call_offset1: 0x4BE160,//0x5ccb50, - send_picmsg_call_ecx: 0x222F0F0, - //-------3.6.0.18 send pic - /*send_picmsg_call_offset2: 0x6f5c0, - send_picmsg_call_offset3: 0x3e3490,*/ - send_attatch_ecx_offset: 0x1D8FA8C, - send_attatch_call_offset0: 0x9A1C0, - send_attatch_call_offset1: 0x701DC0,//0x701CD0,//701CD0 - send_attatch_call_offset2: 0x4BA5F0,//4B A5F0 - send_attatch_call_offset3: 0xC95A0, - send_attatch_call_offset4: 0x94200, - send_attatch_call_offset5: 0x3C4950, - send_attatch_call_offset6: 0x63B4F0, - send_attatch_call_para1: 0x1D8F248, - send_attatch_call_para2: 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, + + + hook_point: 0xd19a0b, //3.9.2.23 + + myselfinfo: { + offset: 0x2FFD484, //老版本微信号偏移,后面的地址,都要在这个偏移上增加 + //wxid_len:0x10, + head_img_url: 0x2D8, + head_img_url_len: 0x2E8, + wx_nick_name: 0x10C, + wxcode_new: 0x64, //新版本微信号 + //wxcode_len:0x74 + wxid_len_offset: 0x4D4 + }, + + contactInfo: { + nodeOffset: 0x2FFDD7C, + nodeRootOffset: 0x64 + }, + chatroomInfo: { + nodeOffset: 0x2FFDDC8, + nodeRootOffset: 0x8c8 + }, + sendTxtMsg: { + callOffset: 0xCE6C80 + }, + sendPicMsg: { + call1: 0x768140, + call2: 0xf59e40, + call3: 0xce6640 + } }; -//3.3.0.115 + /*------------------global-------------------------------------------*/ -const availableVersion = 1661337618////3.3.0.115 ==1661141107 +const availableVersion = 1661534743 ////3.9.2.23 ==0x63090217 const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll') const moduleLoad = Module.load('WeChatWin.dll') //1575CF98 -const g_EDIPtr = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readPointer()// -const g_EDIU32 = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readU32() -let currentVersion = 0 - -let nodeList = [] //for contact -let contactList = [] //for contact - -let chatroomNodeList = [] //for chatroom -let chatroomMemberList = []//for chatroom -let loggedIn = false - -/*------------------global-------------------------------------------*/ -//开启日志 3.6.0.18 -// //[0x221c330+wechatwin.dll]+0xf8 -// 20220504 +/*---------------base -------------------------*/ -let g_initTestAsm = null -let g_BufferEbp2C = null -let g_initECXU32 = null -let g_initECXPtr = null -let g_initEBXPtr = null -let g_initEBX = null - -let g_attatchEBP210Buffer = null -let g_attatchPathPtr = null -let g_attatchPath = null -let g_attatchEBPAc = null -let g_attatchEBPAcBufPtr = null - -let g_attatchContactIdPtr = null -//let g_attatchECXBuffer = null -let g_attatchESIU32 = null - -let g_initECXTempPtr = null -const initGlobal = ((contactId, attatchFile) => { +let retidPtr=null +let retidStruct=null +const initidStruct = ((str) => { - //const base = moduleBaseAddress.add(0x222f38c).readPointer() - //g_EDI = base.add(0xD70).readPointer()//0x438+0x938 - console.log('------------g_attatchEBPAc', g_attatchEBPAc) - console.log('------------g_EDIU32', g_EDIU32) - g_initTestAsm = Memory.alloc(Process.pageSize) - console.log('------------address', g_initTestAsm) + retidPtr = Memory.alloc(str.length * 2 + 1) + retidPtr.writeUtf16String(str) - g_initECXPtr = g_EDIPtr.add(0xB80).readPointer().add(0x1640) - g_initECXTempPtr = g_EDIPtr.add(0xB88).readPointer() - g_initECXU32 = g_initECXPtr.toInt32() - g_attatchESIU32 = g_EDIU32 + retidStruct = Memory.alloc(0x14) // returns a NativePointer - console.log('------------g_initECXU32', g_initECXU32) - console.log('------------g_initESIU32', g_attatchESIU32) + retidStruct + .writePointer(retidPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + return retidStruct +}) - //console.log('==========g_initECXPtr',g_initECXPtr) - //console.log('==========g_EDIU32',g_EDIU32) +let retPtr = null +let retStruct = null +const initStruct = ((str) => { - //g_attatchECXBuffer = Memory.alloc(0x1024) - //Memory.copy(g_attatchECXBuffer, g_initECXPtr, 0x1024) + retPtr = Memory.alloc(str.length * 2 + 1) + retPtr.writeUtf16String(str) - g_BufferEbp2C = Memory.alloc(0x48) + retStruct = Memory.alloc(0x14) // returns a NativePointer - //g_initEBX = moduleBaseAddress.add(0x2251724).readPointer().readPointer() - //g_initEBXPtr = Memory.alloc(0x14).writePointer(g_initEBX) - //g_initEBXPtr.add(0x08).writePointer(g_BufferEbp2C) + retStruct + .writePointer(retPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) - g_attatchPathPtr = Memory.alloc(attatchFile.length * 2 + 2) - g_attatchPathPtr.writeUtf16String(attatchFile) + return retStruct +}) - g_attatchPath = Memory.alloc(0x28) - g_attatchPath.writePointer(g_attatchPathPtr).add(0x04) - .writeU32(attatchFile.length * 2).add(0x04) - .writeU32(attatchFile.length * 2).add(0x04) - /*---------------------------------ebp-210----------------*/ - g_attatchEBP210Buffer = Memory.alloc(0x48) - g_attatchEBP210Buffer.writeU32(0x3) - g_attatchEBP210Buffer.add(0x4).writePointer(g_attatchPathPtr) - g_attatchEBP210Buffer.add(0x8).writeU32(attatchFile.length * 2) - g_attatchEBP210Buffer.add(0xC).writeU32(attatchFile.length * 2) - g_attatchEBP210Buffer.add(0x2C).writeU32(moduleBaseAddress.add(0x2ECE87).toInt32()) - //console.log('------------g_attatchEBP210Buffer',g_attatchEBP210Buffer) - /*---------------------------------ebp-210----------------*/ +let msgstrPtr=null +let msgStruct=null +const initmsgStruct = ((str) => { + msgstrPtr = Memory.alloc(str.length * 2 + 1) + msgstrPtr.writeUtf16String(str) - //g_attatchContactIdPtr = Memory.alloc(0x4) - //g_attatchContactIdPtr.writeUtf16String(contactId) - //console.log('------------g_attatchEBP210Buffer',g_attatchEBP210Buffer) - g_attatchEBPAc = Memory.alloc(0x140) - //g_attatchEBPAcBufPtr = Memory.alloc(0x100) - //g_attatchEBPAc.writePointer(g_attatchEBP210Buffer) - //g_attatchEBPAc.add(0x4).writePointer(g_attatchEBPAcBufPtr) - //g_attatchEBPAc.add(0x8).writePointer(g_attatchEBPAcBufPtr) - g_attatchEBPAc.add(0x10).writeU32(g_EDIU32) - console.log('------------g_attatchEBPAc', g_attatchEBPAc) + msgStruct = Memory.alloc(0x14) // returns a NativePointer - /*g_attatchECXBuffer.add(0x18).writePointer(g_attatchContactIdPtr) - g_attatchECXBuffer.add(0x1C).writeU32(contactId.length*2) - .add(0x04).writeU32(contactId.length*2)*/ + msgStruct + .writePointer(msgstrPtr).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(str.length * 2).add(0x04) + .writeU32(0).add(0x04) + .writeU32(0) + return msgStruct +}) +let atStruct = null +const initAtMsgStruct = ((wxidStruct) => { - //g_attatchESIU32 = g_EDI.toInt32() + atStruct = Memory.alloc(0x10) + atStruct.writePointer(wxidStruct).add(0x04) + .writeU32(wxidStruct.toInt32() + 0x14).add(0x04)//0x14 = sizeof(wxid structure) + .writeU32(wxidStruct.toInt32() + 0x14).add(0x04) + .writeU32(0) + return atStruct +}) +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('------------g_attatchESIU32',g_attatchESIU32) - //console.log('==========g_attatchECXBuffer',g_attatchECXBuffer) + // 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)) - Memory.patchCode(g_initTestAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: g_initTestAsm }) - cw.putPushfx() - cw.putPushax() - //cw.putMovRegAddress('eax', g_attatchEBP210Buffer) + return addr +} - /*cw.putMovRegAddress('edi',g_EDIPtr) - cw.putMovRegReg('esi','edi') - cw.putMovRegAddress('eax',g_BufferEbp2C) - cw.putMovRegAddress('ecx',g_initECXTempPtr) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x131bb0))*/ +// std::wstring +// const wstr = readWStringPtr(ptr).readUtf16String() +const readWStringPtr = (address) => { + const addr = ptr(address) + const size = addr.add(4).readU32() + const capacity = addr.add(8).readU32() + addr.ptr = addr.readPointer() + addr.size = size + addr.capacity = capacity + addr.ptr._readUtf16String = addr.ptr.readUtf16String + addr.readUtf16String = () => { + return addr.size ? addr.ptr._readUtf16String(addr.size * 2) : '' + } - //cw.putMovRegOffsetPtrU32('ebp', -20, 0) + // console.log('readWStringPtr() address:',address,' -> ptr:', addr.ptr, 'size:', addr.size, 'capacity:', addr.capacity) + // console.log('readWStringPtr() str:' , `"${addr.readUtf16String()}"`,'\n',addr.ptr.readByteArray(addr.size*2+2),'\n') + // console.log('readWStringPtr() address:', addr,'dump:', addr.readByteArray(16),'\n') - /*cw.putPushU32(0) - cw.putMovRegAddress('eax', g_attatchPathPtr) - cw.putPushReg('eax') - cw.putPushU32(3) - cw.putMovRegAddress('ecx', g_attatchEBP210Buffer) - cw.putCallAddress(moduleBaseAddress.add(0x130220))*/ + return addr +} +const readString = (address) => { + return readStringPtr(address).readUtf8String() +} - /*cw.putMovRegAddress('edi', g_attatchEBPAc)//后面要用的的ebp-2c - cw.putMovRegAddress('ecx', g_attatchEBP210Buffer) - cw.putPushReg('ecx') - cw.putMovRegU32('eax',0) - cw.putPushReg('eax')//push eax - cw.putMovRegReg('ecx', 'edi') - cw.putMovRegAddress('esi',g_attatchPathPtr) - cw.putCallAddress(moduleBaseAddress.add(0x138880))*/ +const readWideString = (address) => { + return readWStringPtr(address).readUtf16String() +} - /*cw.putSubRegImm('esp',0x14) - cw.putMovRegU32('ecx',g_initECXU32) - cw.putMovRegU32('esi',g_attatchESIU32) - cw.putMovRegAddress('eax', g_attatchEBPAc) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x173620))*/ - //cw.putCallAddress(moduleBaseAddress.add(0x522590)) +/*-----------------base-------------------------*/ - /** g_attatchEBPAc*/ - //cw.putMovRegNearPtr('eax', g_attatchEBPAc) - //cw.putMovNearPtrReg(g_attatchEBPAc.add(0xc), 'eax') - /** g_attatchEBPAc*/ +let currentVersion = 0 +let nodeList = [] //for contact +let contactList = [] //for contact - //cw.putMovRegAddress('ebx', g_initEBXPtr) - //cw.putMovRegU32('edi', g_EDI.toInt32()) - //cw.putMovRegU32('esi', g_EDI.toInt32()) - /*cw.putMovRegU32('ecx', g_initECX) - cw.putMovRegAddress('eax', g_BufferEbp2C) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x131BB0))*/ +let chatroomNodeList = [] //for chatroom +let chatroomMemberList = [] //for chatroom +let loggedIn = false - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - }) - const nativeativeFunction = new NativeFunction(ptr(g_initTestAsm), 'void', []) - nativeativeFunction() +const getWechatVersionFunction = (() => { + if (currentVersion) { + return currentVersion + } + const pattern = '55 8B ?? 83 ?? ?? A1 ?? ?? ?? ?? 83 ?? ?? 85 ?? 7F ?? 8D ?? ?? E8 ?? ?? ?? ?? 84 ?? 74 ?? 8B ?? ?? ?? 85 ?? 75 ?? E8 ?? ?? ?? ?? 0F ?? ?? 0D ?? ?? ?? ?? A3 ?? ?? ?? ?? A3 ?? ?? ?? ?? 8B ?? 5D C3' + const results = Memory.scanSync(moduleLoad.base, moduleLoad.size, pattern) + if (results.length == 0) { + return 0 + } + const addr = results[0].address + const ret = addr.add(0x07).readPointer() + const ver = ret.add(0x0).readU32() + currentVersion = ver + return ver }) - -let g_personal_detail_ebx = null -let g_personal_detail_asm = null -let g_personal_wxid = null -let g_personal_wxid_ptr = null -const getOldTest = ((wxid) => {//personal detail - - g_personal_detail_asm = Memory.alloc(Process.pageSize) - g_personal_detail_ebx = moduleBaseAddress.add(0x222F38C).readPointer().add(0xFB8).toInt32() - - g_personal_wxid_ptr = Memory.alloc(wxid.length * 2 + 2) - g_personal_wxid_ptr.writeUtf16String(wxid) - - g_personal_wxid = Memory.alloc(0x14) - g_personal_wxid.writePointer(ptr(g_personal_wxid_ptr)).add(0x04) - .writeU32(wxid.length * 2).add(0x04) - .writeU32(wxid.length * 2).add(0x08) - - console.log('-----------address----------', g_personal_detail_asm) - - Memory.patchCode(g_personal_detail_asm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: g_personal_detail_asm }) - cw.putPushfx() - cw.putPushax() - - cw.putCallAddress(moduleBaseAddress.add(0x9A000)) - - //78BA9ACE | E8 2D05D6FF | call wechatwin.7890A000 | - cw.putMovRegU32('ebx', g_personal_detail_ebx) - cw.putMovRegReg('esi', 'eax') - cw.putPushReg('ebx') - cw.putSubRegImm('esp', 0x14) - cw.putMovRegAddress('eax', g_personal_wxid) - cw.putMovRegReg('ecx', 'esp') - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) - cw.putMovRegReg('ecx', 'esi') - cw.putCallAddress(moduleBaseAddress.add(0x4024A0)) - - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - - }) - - const nativeativeFunction = new NativeFunction(ptr(g_personal_detail_asm), 'void', []) - nativeativeFunction() - - +// 011 +const getWechatVersionStringFunction = ((ver = getWechatVersionFunction()) => { + if (!ver) { + return '0.0.0.0' + } + const vers = [] + vers.push((ver >> 24) & 255 - 0x60) + vers.push((ver >> 16) & 255) + vers.push((ver >> 8) & 255) + vers.push(ver & 255) + return vers.join('.') }) -// const writeLogNativeCallback = (() => { -// const nativeCallback = new NativeCallback(() => { }, 'void', []) -// const nativeCallFunction = new NativeFunction(nativeCallback, 'void', []) - -// Interceptor.attach( -// moduleBaseAddress.add(0x7008A4), -// { -// onEnter() { -// const addr = this.context.eax//.sub(0x114)//0xc30-0x08 -// if(addr >0){ -// const log = ptr(addr).readAnsiString() -// } -// } -// }) -// return nativeCallback -// })() - -/** - * test call - */ -let attatchTestAsm = null -let attatchTestEbp2C = null -let attatchGlobalEDI = null -let attatchGlobalEDIB88 = null -let attatchTestEBX = null -let g_tempEcx = null -let attatchFirstECX = null -//let attatchFirstECX = null -let gattatchFilePtr = null -let gattatchFile = null -let gattatchReceiveIdPtr = null -let gattatchReceiveId = null -let attatchEAX3B0Buf = null - -let attatchESIbuf = null -const getWxTest = ((contactId, filePath) => { - //const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) - //nativeativeFunction() - attatchTestAsm = Memory.alloc(Process.pageSize) - console.log('----------------address', attatchTestAsm) - attatchTestEbp2C = Memory.alloc(0xC) - attatchGlobalEDI = moduleBaseAddress.add(0x222f38c).readPointer() - .add(0x938).add(0x438).readPointer() - attatchGlobalEDIB88 = attatchGlobalEDI.add(0xB88).readPointer() - attatchTestEBX = Memory.alloc(0x4) - attatchTestEBX.writePointer(attatchGlobalEDI) - console.log('----------------attatchGlobalEDI', attatchGlobalEDI) - console.log('----------------attatchGlobalEDIB88', attatchGlobalEDIB88) - - attatchFirstECX = Memory.alloc(0x28) - //const attatchSecondEcx = Memory.alloc(0x14) - - const contactIdLength = contactId.length * 2 + 2//edx - const contractIdActLength = contactId.length - - - gattatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) - gattatchReceiveIdPtr.writeUtf16String(contactId) - - gattatchReceiveId = Memory.alloc(0x14) - gattatchReceiveId.writePointer(ptr(gattatchReceiveIdPtr)).add(0x04) - .writeU32(contactId.length * 2).add(0x04) - .writeU32(contactId.length * 2).add(0x08) - //console.log('----------------attatchGlobalEDIB88',attatchGlobalEDIB88) - //return - /*console.log(hexdump(attatchTestEBX, { - offset: 0, - length: 0x40, - header: true, - ansi: true - })) - return*/ - - gattatchFilePtr = Memory.alloc(filePath.length * 2 + 2) - gattatchFilePtr.writeUtf16String(filePath) - - gattatchFile = Memory.alloc(0x14) - gattatchFile.writePointer(ptr(gattatchFilePtr)).add(0x04) - .writeU32(filePath.length * 2).add(0x04) - .writeU32(filePath.length * 2).add(0x08) - - const attatchLastECX = moduleBaseAddress.add(0x222f170).toInt32() - - attatchEAX3B0Buf = Memory.alloc(0x3B0) - - g_tempEcx = Memory.alloc(0x4) - //g_tempEcx1 = Memory.alloc(0x4) - - attatchESIbuf = Memory.alloc(0x100) - attatchESIbuf.add(0x0).writeU32(3) - attatchESIbuf.add(0x4).writePointer(gattatchFilePtr) - attatchESIbuf.add(0x8).writeU32(filePath.length * 2) - attatchESIbuf.add(0xc).writeU32(filePath.length * 2) - - Memory.patchCode(attatchTestAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: attatchTestAsm }) - cw.putPushfx() - cw.putPushax() - //cw.putMovRegU32('edi',attatchGlobalEDI) - - - cw.putMovRegAddress('esi', attatchESIbuf) - - cw.putMovRegAddress('ecx', attatchFirstECX.add(0x14)) - cw.putMovRegAddress('eax', gattatchFile) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) - +const checkSupportedFunction = (() => { + const ver = getWechatVersionFunction() + return ver == availableVersion +}) - cw.putMovRegAddress('ecx', attatchFirstECX) - cw.putMovRegU32('eax', contactIdLength) - cw.putPushReg('eax') - cw.putPushU32(0) - cw.putCallAddress(moduleBaseAddress.add(0x1a11c83)) - cw.putAddRegImm('esp', 0x8) +// 019 +const recvMsgNativeCallback = (() => { - cw.putMovRegReg('edx', 'eax') - cw.putMovNearPtrReg(attatchFirstECX, 'edx') - cw.putMovRegU32('edi', contactIdLength) - cw.putPushReg('edi') - cw.putMovRegAddress('eax', gattatchReceiveIdPtr)//ebp-58 - cw.putPushReg('eax') - cw.putMovRegNearPtr('eax', attatchFirstECX) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x1a1047a)) - cw.putAddRegImm('esp', 0x0c) - - //cw.putMovRegNearPtr('ecx',attatchFirstECX) - //cw.putAddRegImm('esp', 0x0c) - //cw.putMovRegU32('edx', 0) - //cw.putMovRegRegPtr('eax', 'ecx') - //cw.putMovNearPtrReg(attatchFirstECX.add(0x04),'edi') - cw.putMovRegU32('edi', contactId.length * 2) - cw.putMovRegU32('ecx', attatchLastECX) - cw.putMovRegAddress('eax', attatchEAX3B0Buf) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x392260)) - cw.putMovRegAddress('ecx', attatchEAX3B0Buf) - cw.putCallAddress(moduleBaseAddress.add(0x94200)) + const nativeCallback = new NativeCallback(() => {}, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() + Interceptor.attach( + moduleBaseAddress.add(offset.hook_point), { + onEnter() { + const addr = this.context.ecx //0xc30-0x08 + const msgType = addr.add(0x38).readU32() + const isMyMsg = addr.add(0x3C).readU32() //add isMyMsg + + if (msgType > 0) { + + const talkerIdPtr = addr.add(0x48).readPointer() + //console.log('txt msg',talkerIdPtr.readUtf16String()) + const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 + + const myTalkerIdPtr = Memory.alloc(talkerIdLen) + Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) + + + let contentPtr = null + let contentLen = 0 + let myContentPtr = null + if (msgType == 3) { // pic path + let thumbPtr = addr.add(0x198).readPointer(); + let hdPtr = addr.add(0x1ac).readPointer(); + let thumbPath = thumbPtr.readUtf16String(); + let hdPath = hdPtr.readUtf16String(); + let picData = [ + thumbPath, // PUPPET.types.Image.Unknown + thumbPath, // PUPPET.types.Image.Thumbnail + hdPath, // PUPPET.types.Image.HD + hdPath // PUPPET.types.Image.Artwork + ] + let content = JSON.stringify(picData); + myContentPtr = Memory.allocUtf16String(content); + } else { + contentPtr = addr.add(0x70).readPointer() + contentLen = addr.add(0x70 + 0x04).readU32() * 2 + 2 + myContentPtr = Memory.alloc(contentLen) + Memory.copy(myContentPtr, contentPtr, contentLen) + } - }) + // console.log('----------------------------------------') + // console.log(msgType) + // console.log(contentPtr.readUtf16String()) + // console.log('----------------------------------------') + const groupMsgAddr = addr.add(0x170).readU32() //* 2 + 2 + let myGroupMsgSenderIdPtr = null + if (groupMsgAddr == 0) { //weChatPublic is zero,type is 49 - const nativeativeFunction = new NativeFunction(ptr(attatchTestAsm), 'void', []) - nativeativeFunction() + myGroupMsgSenderIdPtr = Memory.alloc(0x10) + myGroupMsgSenderIdPtr.writeUtf16String("null") + } else { -}) -// 001 -const getTestInfoFunction = ((addr) => { - const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) - nativeativeFunction() + const groupMsgSenderIdPtr = addr.add(0x170).readPointer() + const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 + myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) + Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) - //00CFE484 + } + const xmlNullPtr = addr.add(0x1f0).readU32() //3.9.2.23 + let myXmlContentPtr = null + if (xmlNullPtr == 0) { - /*MemoryAccessMonitor.enable({base:ptr(addr),size:0x01}, { - onAccess(details){ - console.log('============') - console.log(details.operation) - console.log(details.from) - console.log(details.address) - console.log('============') - } - })*/ + myXmlContentPtr = Memory.alloc(0x10) + myXmlContentPtr.writeUtf16String("null") -}) + } else { + const xmlContentPtr = addr.add(0x1f0).readPointer() //3.9.2.23 -// 002get global data + const xmlContentLen = addr.add(0x1f0 + 0x04).readU32() * 2 + 2 + myXmlContentPtr = Memory.alloc(xmlContentLen) + Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) + } -const isLoggedInFunction = (() => { - loggedIn = moduleBaseAddress.add(offset.is_logged_in_offset).readU32() - return !!loggedIn -}) + setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) + } + } + }) + return nativeCallback +})() -// 003get myself info const getBaseNodeAddress = (() => { - return moduleBaseAddress.add(offset.node_offset).readPointer() + return moduleBaseAddress.add(offset.contactInfo.nodeOffset).readPointer() }) // 004 @@ -487,19 +338,9 @@ const getHeaderNodeAddress = (() => { } //console.log('HeaderNodeAddress',baseAddress.add(offset.handle_offset).readPointer()) - return baseAddress.add(offset.handle_offset).readPointer() -}) - -// 005 -const getChatroomNodeAddress = (() => { - const baseAddress = moduleBaseAddress.add(0x222f3fc).readPointer() - if (baseAddress.isNull()) { - return baseAddress - } - return baseAddress.add(offset.chatroom_node_offset).readPointer() + return baseAddress.add(offset.contactInfo.nodeRootOffset).readPointer() }) -// 006 const getMyselfInfoFunction = (() => { let ptr = 0 @@ -508,12 +349,23 @@ const getMyselfInfoFunction = (() => { let wx_name = '' let head_img_url = '' - wx_id = readString(moduleBaseAddress.add(offset.wxid_offset)) - wx_code = wx_id + const base = moduleBaseAddress.add(offset.myselfinfo.offset) + const wxid_len = base.add(offset.myselfinfo.wxid_len_offset).readU32() + + if (wxid_len === 0x13) { // 新版本微信 + wx_id = base.readPointer().readAnsiString(wxid_len) + wx_code = base.add(offset.myselfinfo.wxcode_new).readAnsiString() + } else { + wx_id = readString(base) + wx_code = wx_id + } + - wx_name = readString(moduleBaseAddress.add(offset.nickname_offset)) - head_img_url = readString(moduleBaseAddress.add(offset.head_img_url_offset)) + wx_name = readString(base.add(offset.myselfinfo.wx_nick_name)) + const img_addr = base.add(offset.myselfinfo.head_img_url).readPointer() + const img_len = base.add(offset.myselfinfo.head_img_url_len).readU32() + head_img_url = img_addr.readAnsiString(img_len) const myself = { id: wx_id, @@ -526,130 +378,29 @@ const getMyselfInfoFunction = (() => { }) -// 007 缺失,请标注已废弃或者其他原因 -const getMyselfIdFunction = (() => { - let wx_id = readString(moduleBaseAddress.add(offset.wxid_offset)) - - return wx_id - -}) - -// 008chatroom member -const chatroomRecurse = ((node) => { - const chatroomNodeAddress = getChatroomNodeAddress() - if (chatroomNodeAddress.isNull()) { return } +const recurseNew = ((node) => { + const headerNodeAddress = getHeaderNodeAddress() + if (headerNodeAddress.isNull()) { + return + } - if (node.equals(chatroomNodeAddress)) { return } + if (node.equals(headerNodeAddress)) { + return + } - for (const item in chatroomNodeList) { - if (node.equals(chatroomNodeList[item])) { + for (const item in nodeList) { + if (node.equals(nodeList[item])) { return } } - chatroomNodeList.push(node) - const roomid = readWideString(node.add(0x10)) - const len = node.add(0x50).readU32() // - //const memberJson={} - if (len > 4) {// - const memberStr = readString(node.add(0x40)) - if (memberStr.length > 0) { - const memberList = memberStr.split(/[\\^][G]/) - const memberJson = { - roomid: roomid, - roomMember: memberList - } - - chatroomMemberList.push(memberJson) - } - - } - - const leftNode = node.add(0x0).readPointer() - const centerNode = node.add(0x04).readPointer() - const rightNode = node.add(0x08).readPointer() - - chatroomRecurse(leftNode) - chatroomRecurse(centerNode) - chatroomRecurse(rightNode) - - const allChatroomMemberJson = chatroomMemberList - return allChatroomMemberJson -}) - -// std::string -// const str = readStringPtr(ptr).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 -} - -// std::wstring -// const wstr = readWStringPtr(ptr).readUtf16String() -const readWStringPtr = (address) => { - const addr = ptr(address) - const size = addr.add(4).readU32() - const capacity = addr.add(8).readU32() - addr.ptr = addr.readPointer() - addr.size = size - addr.capacity = capacity - addr.ptr._readUtf16String = addr.ptr.readUtf16String - addr.readUtf16String = () => { return addr.size ? addr.ptr._readUtf16String(addr.size * 2) : '' } - - // console.log('readWStringPtr() address:',address,' -> ptr:', addr.ptr, 'size:', addr.size, 'capacity:', addr.capacity) - // console.log('readWStringPtr() str:' , `"${addr.readUtf16String()}"`,'\n',addr.ptr.readByteArray(addr.size*2+2),'\n') - // console.log('readWStringPtr() address:', addr,'dump:', addr.readByteArray(16),'\n') - - return addr -} - -const readString = (address) => { - return readStringPtr(address).readUtf8String() -} - -const readWideString = (address) => { - return readWStringPtr(address).readUtf16String() -} - -const recurseNew = ((node) => { - const headerNodeAddress = getHeaderNodeAddress() - if (headerNodeAddress.isNull()) { return } - - if (node.equals(headerNodeAddress)) { return } - - for (const item in nodeList) { - if (node.equals(nodeList[item])) { - return - } - } - - - nodeList.push(node) - const id = readString(node.add(0x8)) - //wxid, format relates to registration method - const wxid = readWideString(node.add(0x30)) - //console.log('-----------',wxid) + nodeList.push(node) + const id = readString(node.add(0x8)) + //wxid, format relates to registration method + const wxid = readWideString(node.add(0x30)) + //console.log('-----------',wxid) //custom id, if not set return null, and use wxid which should be custom id @@ -694,133 +445,20 @@ const recurseNew = ((node) => { }) -//contact -const recurse = ((node) => { - const headerNodeAddress = getHeaderNodeAddress() - if (headerNodeAddress.isNull()) { return } - - if (node.equals(headerNodeAddress)) { return } - - for (const item in nodeList) { - if (node.equals(nodeList[item])) { - return - } - } - - - nodeList.push(node) - //wxid, format relates to registration method - const wxid = readWideString(node.add(0x38)) - - //custom id, if not set return null, and use wxid which should be custom id - const wx_code = readWideString(node.add(0x4c)) || readWideString(node.add(0x38)) - - //custom Nickname - const name = readWideString(node.add(0x94)) - - //alias aka 'remark' in wechat - const alias = readWideString(node.add(0x80)) - - //avatarUrl - const avatar = readWideString(node.add(0x138)) - //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) - //contact gender - const gender = node.add(0x18C).readU32() - - const contactJson = { - id: wxid, - code: wx_code, - name: name, - alias: alias, - avatarUrl: avatar, - gender: gender, - } - - contactList.push(contactJson) - - const leftNode = node.add(0x0).readPointer() - const centerNode = node.add(0x04).readPointer() - const rightNode = node.add(0x08).readPointer() - - recurse(leftNode) - recurse(centerNode) - recurse(rightNode) - - const allContactJson = contactList - return allContactJson - -}) - -// 009 -const getChatroomMemberInfoFunction = (() => { - const chatroomNodeAddress = getChatroomNodeAddress() - if (chatroomNodeAddress.isNull()) { return '[]' } - - const node = chatroomNodeAddress.add(0x0).readPointer() - const ret = chatroomRecurse(node) - - const cloneRet = JSON.stringify(ret) - chatroomNodeList.length = 0//empty - chatroomMemberList.length = 0 //empty - return cloneRet -}) - -// 010 -const getWechatVersionFunction = (() => { - if (currentVersion) { - return currentVersion - } - const pattern = '55 8B ?? 83 ?? ?? A1 ?? ?? ?? ?? 83 ?? ?? 85 ?? 7F ?? 8D ?? ?? E8 ?? ?? ?? ?? 84 ?? 74 ?? 8B ?? ?? ?? 85 ?? 75 ?? E8 ?? ?? ?? ?? 0F ?? ?? 0D ?? ?? ?? ?? A3 ?? ?? ?? ?? A3 ?? ?? ?? ?? 8B ?? 5D C3' - const results = Memory.scanSync(moduleLoad.base, moduleLoad.size, pattern) - if (results.length == 0) { - return 0 - } - const addr = results[0].address - const ret = addr.add(0x07).readPointer() - const ver = ret.add(0x0).readU32() - currentVersion = ver - return ver -}) - -// 011 -const getWechatVersionStringFunction = ((ver = getWechatVersionFunction()) => { - if (!ver) { - return '0.0.0.0' - } - const vers = [] - vers.push((ver >> 24) & 255 - 0x60) - vers.push((ver >> 16) & 255) - vers.push((ver >> 8) & 255) - vers.push(ver & 255) - return vers.join('.') -}) - -// 012 -const checkSupportedFunction = (() => { - const ver = getWechatVersionFunction() - return ver == availableVersion -}) - -// 013 -const isSupported = checkSupportedFunction() - -if (!isSupported) { - throw new Error(`Wechat version not supported. \nWechat version: ${getWechatVersionStringFunction()}, supported version: ${getWechatVersionStringFunction(availableVersion)}`) -} - -// 014 const getContactNativeFunction = (() => { const headerNodeAddress = getHeaderNodeAddress() //console.log('headerNodeAddress',headerNodeAddress) - if (headerNodeAddress.isNull()) { return '[]' } + if (headerNodeAddress.isNull()) { + return '[]' + } const node = headerNodeAddress.add(0x0).readPointer() const ret = recurseNew(node) //console.log(ret) - // console.log('getContactNativeFunction:',ret.length) + console.log('getContactNativeFunction:', ret.length) /*for (let item of ret){ console.log(JSON.stringify(item)) }*/ @@ -832,715 +470,139 @@ const getContactNativeFunction = (() => { return cloneRet }) -// 015 -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() - setImmediate(() => nativeativeFunction(bySrv)) - } - }) - return nativeCallback -})() -// 016 -const hookLoginEventCallback = (() => { - const nativeCallback = new NativeCallback(() => { }, 'void', []) - const nativeativeFunction = new NativeFunction(nativeCallback, 'void', []) - Interceptor.attach(moduleBaseAddress.add(offset.hook_on_login_offset), { - onLeave: function (retval) { - isLoggedInFunction() - setImmediate(() => nativeativeFunction()) - return retval - } - }) - - setTimeout(() => { - if (isLoggedInFunction()) { - setImmediate(() => nativeativeFunction()) - } - }, 500); - - return nativeCallback -})() - -// 017 -const checkQRLoginNativeCallback = (() => { - - const nativeCallback = new NativeCallback(() => { }, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'int32', 'pointer']) - const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'pointer', 'int32', 'pointer']) - // const json = { - // status, - // uuid, - // wxid, - // avatarUrl, - // nickname, - // phoneType, - // phoneClientVer, - // pairWaitTip, - // } - - const callback = { - onLeave: function (retval) { - const json = getQrcodeLoginData() - if (json.status == 0) { - // 当状态为 0 时,即未扫码。而其他状态会触发另一个方法,拥有更多数据。 - ret(json) - } - return retval - }, - } - - const ret = (json) => { - const arr = [ - json.status || 0, - Memory.allocUtf8String(json.uuid ? `http://weixin.qq.com/x/${json.uuid}` : ''), - Memory.allocUtf8String(json.wxid || ''), - Memory.allocUtf8String(json.avatarUrl || ''), - Memory.allocUtf8String(json.nickname || ''), - Memory.allocUtf8String(json.phoneType || ''), - json.phoneClientVer || 0, - Memory.allocUtf8String(json.pairWaitTip || ''), - ] - setImmediate(() => nativeativeFunction(...arr)) +const getChatroomNodeAddress = (() => { + const baseAddress = moduleBaseAddress.add(offset.chatroomInfo.nodeOffset).readPointer() + if (baseAddress.isNull()) { + return baseAddress } + return baseAddress.add(offset.chatroomInfo.nodeRootOffset).readPointer() +}) - Interceptor.attach(moduleBaseAddress.add(offset.hook_get_login_qr_offset), callback) - Interceptor.attach(moduleBaseAddress.add(offset.hook_check_login_qr_offset), callback) - Interceptor.attach(moduleBaseAddress.add(offset.hook_save_login_qr_info_offset), { - onEnter: function () { - const qrNotify = this.context['ebp'].sub(72) - const uuid = readString(qrNotify.add(4).readPointer()) - const wxid = readString(qrNotify.add(8).readPointer()) - const status = qrNotify.add(16).readUInt() - const avatarUrl = readString(qrNotify.add(24).readPointer()) - const nickname = readString(qrNotify.add(28).readPointer()) - const pairWaitTip = readString(qrNotify.add(32).readPointer()) - const phoneClientVer = qrNotify.add(40).readUInt() - const phoneType = readString(qrNotify.add(44).readPointer()) - - const json = { - status, - uuid, - wxid, - avatarUrl, - nickname, - phoneType, - phoneClientVer, - pairWaitTip, - } - ret(json) - }, - onLeave: function (retval) { - return retval - }, - }) - - if (!isLoggedInFunction()) { - setTimeout(() => { - const json = getQrcodeLoginData() - ret(json) - }, 100); +const chatroomRecurse = ((node) => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return } - return nativeCallback -})() - -// 018 -const getQrcodeLoginData = () => { - const getQRCodeLoginMgr = new NativeFunction(moduleBaseAddress.add(offset.get_qr_login_data_offset), 'pointer', []) - const qlMgr = getQRCodeLoginMgr() - - const json = { - status: 0, - uuid: '', - wxid: '', - avatarUrl: '', + if (node.equals(chatroomNodeAddress)) { + return } - 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)) + for (const item in chatroomNodeList) { + if (node.equals(chatroomNodeList[item])) { + return + } } - return json -} - - -/** - * 20220504 writelog - * 7A566D72 | FFB5 ECFEFFFF | push dword ptr ss:[ebp-114] | 【3.6.0.18】写日志,这个里面就是日志内容 - 7A566D78 | FFB5 E8FEFFFF | push dword ptr ss:[ebp-118] | - */ -/*const writeLogNativeCallback = (() => { - const nativeCallback = new NativeCallback(() => { }, 'void', []) - const nativeCallFunction = new NativeFunction(nativeCallback, 'void', []) - - Interceptor.attach( - moduleBaseAddress.add(0x1576D7E), - { - onEnter() { - const addr = this.context.ebp.sub(0x114)//0xc30-0x08 - console.log('-------',addr) - - } - }) - return nativeCallback -})()*/ - -/** - * @Hook: recvMsg -> recvMsgNativeCallback - */ - -// 019 -const recvMsgNativeCallback = (() => { - - - const nativeCallback = new NativeCallback(() => { }, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) - const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) - - Interceptor.attach( - moduleBaseAddress.add(offset.hook_point), - { - onEnter() { - let addr - let msgType = 0 - let isMyMsg = 0 - let curTime = new Date() - try { - addr = this.context.eax//0xc30-0x08 - msgType = addr.add(0x38).readU32() - isMyMsg = addr.add(0x3C).readU32()//add isMyMsg - if (msgType > 0) { - const talkerIdPtr = addr.add(0x48).readPointer() - //console.log('txt msg',talkerIdPtr.readUtf16String()) - const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 - - const myTalkerIdPtr = Memory.alloc(talkerIdLen) - Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) - - - let contentPtr = null - let contentLen = 0 - let myContentPtr = null - if (msgType == 3) {// pic path - let thumbPtr = addr.add(0x198).readPointer(); - let hdPtr = addr.add(0x1ac).readPointer(); - let thumbPath = thumbPtr.readUtf16String(); - let hdPath = hdPtr.readUtf16String(); - let picData = [ - thumbPath,// PUPPET.types.Image.Unknown - thumbPath,// PUPPET.types.Image.Thumbnail - hdPath,// PUPPET.types.Image.HD - hdPath// PUPPET.types.Image.Artwork - ] - let content = JSON.stringify(picData); - myContentPtr = Memory.allocUtf16String(content); - } else { - contentPtr = addr.add(0x70).readPointer() - contentLen = addr.add(0x70 + 0x04).readU32() * 2 + 2 - myContentPtr = Memory.alloc(contentLen) - Memory.copy(myContentPtr, contentPtr, contentLen) - } - - // console.log('----------------------------------------') - // console.log(msgType) - // console.log(contentPtr.readUtf16String()) - // console.log('----------------------------------------') - const groupMsgAddr = addr.add(0x170).readU32() //* 2 + 2 - let myGroupMsgSenderIdPtr = null - if (groupMsgAddr == 0) {//weChatPublic is zero,type is 49 - - myGroupMsgSenderIdPtr = Memory.alloc(0x10) - myGroupMsgSenderIdPtr.writeUtf16String("null") - - } else { - - const groupMsgSenderIdPtr = addr.add(0x170).readPointer() - const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 - myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) - Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) - - } - - const xmlNullPtr = addr.add(0x1ec).readU32() - let myXmlContentPtr = null - if (xmlNullPtr == 0) { - - myXmlContentPtr = Memory.alloc(0x10) - myXmlContentPtr.writeUtf16String("null") - - } else { - const xmlContentPtr = addr.add(0x1ec).readPointer() - - const xmlContentLen = addr.add(0x1ec + 0x04).readU32() * 2 + 2 - myXmlContentPtr = Memory.alloc(xmlContentLen) - Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) - } - - setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) - } - } catch (err) { - console.error(curTime,'recvMsgNativeCallback at onEnter err:', err) - } - } - }) - return nativeCallback -})() - - -let msgStruct = null -let msgstrPtr = null -const initmsgStruct = ((str) => { - msgstrPtr = Memory.alloc(str.length * 2 + 1) - msgstrPtr.writeUtf16String(str) - - msgStruct = Memory.alloc(0x14) // returns a NativePointer - - msgStruct - .writePointer(msgstrPtr).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0) - - return msgStruct -}) - -let retidNullStruct = null -let retidNullPtr = null -const initNullIdStruct = ((str) => { - - retidNullPtr = Memory.alloc(str.length * 2 + 1) - retidNullPtr.writeUtf16String(str) - - retidNullStruct = Memory.alloc(0x14) // returns a NativePointer - - retidNullStruct - .writePointer(retidNullPtr).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0) - - return retidNullStruct -}) - -let retidStruct = null -let retidPtr = null -const initidStruct = ((str) => { - - retidPtr = Memory.alloc(str.length * 2 + 1) - retidPtr.writeUtf16String(str) - - retidStruct = Memory.alloc(0x14) // returns a NativePointer - - retidStruct - .writePointer(retidPtr).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0) - - return retidStruct -}) - -let retPtr = null -let retStruct = null -const initStruct = ((str) => { - - retPtr = Memory.alloc(str.length * 2 + 1) - retPtr.writeUtf16String(str) - - retStruct = Memory.alloc(0x14) // returns a NativePointer - retStruct - .writePointer(retPtr).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0) - - return retStruct -}) - -/** -* at msg structure -*/ -let atStruct = null -const initAtMsgStruct = ((wxidStruct) => { - - atStruct = Memory.alloc(0x10) - - atStruct.writePointer(wxidStruct).add(0x04) - .writeU32(wxidStruct.toInt32() + 0x14).add(0x04)//0x14 = sizeof(wxid structure) - .writeU32(wxidStruct.toInt32() + 0x14).add(0x04) - .writeU32(0) - return atStruct -}) - -let nickRoomIdV6 = null -let nullEdiWxidStructV6 = null -let nickMemberIdStructV6 = null -let memberNickBuffAsmV6 = null -let nickResultEdiV6 = null - -const getChatroomMemberNickInfoV1Function = ((memberId, roomId) => { - nickRoomIdV6 = initidStruct(roomId) - nullEdiWxidStructV6 = initNullIdStruct('') - nickMemberIdStructV6 = initStruct(memberId) - memberNickBuffAsmV6 = Memory.alloc(Process.pageSize) - console.log('-----', memberNickBuffAsmV6) - - const tmp = (moduleBaseAddress.add( - offset.chatroom_member_nick_esi_offset_v6 - )).readU32() - console.log('=======tmp', tmp) - Memory.patchCode(memberNickBuffAsmV6, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: memberNickBuffAsmV6 }) - cw.putPushfx(); - cw.putPushax(); - - cw.putMovRegAddress('edi', nullEdiWxidStructV6) - cw.putMovRegAddress('eax', nickMemberIdStructV6) - cw.putMovRegAddress('ebx', nickRoomIdV6) - - - cw.putMovRegAddress('esi', ptr(tmp)) - cw.putPushReg('edi') - cw.putPushReg('eax') - cw.putPushReg('ebx') - - cw.putMovRegAddress('ecx', ptr(tmp)) - - cw.putCallAddress(moduleBaseAddress.add( - offset.chatroom_member_nick_call_offset_v6 - )) - - - //cw.putMovNearPtrReg(nickResultEdiV6, 'edi') - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - - }) - - const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsmV6), 'void', []) - nativeativeFunction() - - console.log('---------nullEdiWxidStructV6', nullEdiWxidStructV6) - const nickha = readWideString(nullEdiWxidStructV6) - - console.log('-----------------') - console.log(nickha) - console.log('-----------------') - return readWideString(nullEdiWxidStructV6) -}) - -//get nick from chatroom -let nickRoomId = null -let nickMemberId = null -let nickStructPtr = null -let nickBuff = null -let memberNickBuffAsm = null -let nickRetAddr = null - -// 020 -const getChatroomMemberNickInfoFunction = ((memberId, roomId) => { - - nickBuff = Memory.alloc(0x7e4) - nickRetAddr = Memory.alloc(0x04) - memberNickBuffAsm = Memory.alloc(Process.pageSize) - nickRoomId = initidStruct(roomId) - nickMemberId = initStruct(memberId) - nickStructPtr = initmsgStruct('') - - Memory.patchCode(memberNickBuffAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: memberNickBuffAsm }) - cw.putPushfx(); - cw.putPushax(); - - /*cw.putMovRegAddress('ebx', nickStructPtr) - cw.putMovRegAddress('esi', nickMemberId) - cw.putMovRegAddress('edi', nickRoomId) - - cw.putMovRegAddress('ecx', nickBuff) - cw.putCallAddress(moduleBaseAddress.add( - offset.chatroom_member_nick_call_offset1 - )) - - cw.putMovRegAddress('eax', nickBuff) - cw.putPushReg('eax') - cw.putPushReg('esi') - cw.putCallAddress(moduleBaseAddress.add( - offset.chatroom_member_nick_call_offset2 - )) - - cw.putMovRegReg('ecx', 'eax') - cw.putCallAddress(moduleBaseAddress.add( - offset.chatroom_member_nick_call_offset3 - )) - - cw.putPushU32(1) - cw.putPushReg('ebx') - cw.putMovRegReg('edx', 'edi') - cw.putMovRegAddress('ecx', nickBuff) - cw.putCallAddress(moduleBaseAddress.add( - offset.chatroom_member_nick_call_offset4 - )) - cw.putAddRegImm('esp', 0x08) - cw.putMovNearPtrReg(nickRetAddr, 'ebx')*/ - cw.putMovRegAddress('edi', nickRoomId) - cw.putMovRegAddress('eax', nickBuff) - cw.putMovRegReg('edx', 'edi') - cw.putPushReg('eax') - cw.putMovRegAddress('ecx', nickMemberId) - cw.putCallAddress(moduleBaseAddress.add(0x404500)) - cw.putAddRegImm('esp', 0x04) - //cw.putMovNearPtrReg(nickRetAddr, 'ebx') - //lea eax, buf - - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - - }) - - const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsm), 'void', []) - nativeativeFunction() - - const nickname = readWideString(nickBuff); - // console.log('--------nickname',nickname) - return readWideString(nickBuff); - //return readWideString(nickRetAddr.readPointer()) - -}) - -/** -* send attatch -*/ -let attatchWxid = null -let attatchPath = null -let attatchPathPtr = null -let attatchAsm = null -let attatchBuf = null - -let attatchReceiveIdPtr = null -let attatchReceiveId = null - -let attatchSendId = null -let attatchSendIdPtr = null - -/* -let attatchEbp2C = null -let attatchEDIPtr = null -let attatchEDIU32 = null -let attatchECX = null - -let attatchEbp210 = null -let attatchEbpAc = null*/ + chatroomNodeList.push(node) + const roomid = readWideString(node.add(0x10)) -let attatchEbp11E8 = null -let attatchEbpCC = null -let attatchEbp368 = null -let attatchEAX = null + const len = node.add(0x54).readU32() // + //const memberJson={} + if (len > 4) { // + const memberStr = readString(node.add(0x44)) + if (memberStr.length > 0) { + const memberList = memberStr.split(/[\\^][G]/) + const memberJson = { + roomid: roomid, + roomMember: memberList + } -let sFileName = null -let fileNamePtr = null + chatroomMemberList.push(memberJson) + } -let attatchEbp84 = null -let attatchECX = null + } + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + const rightNode = node.add(0x08).readPointer() -/** - * -param {78EDBC86 | 8B80 38040000 | mov eax,dword ptr ds:[eax+438] | -78EDBC8C | 8BB0 800B0000 | mov esi,dword ptr ds:[eax+B80] |} sendWxid -*/ + chatroomRecurse(leftNode) + chatroomRecurse(centerNode) + chatroomRecurse(rightNode) -// 021 -const sendAttatchMsgNativeFunction = ((contactId, senderId, path, filename, size) => { + const allChatroomMemberJson = chatroomMemberList + return allChatroomMemberJson +}) - attatchAsm = Memory.alloc(Process.pageSize) - console.log('--------------address', attatchAsm) +const getChatroomMemberInfoFunction = (() => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return '[]' + } - fileNamePtr = Memory.alloc(filename.length * 2 + 2) - fileNamePtr.writeUtf16String(filename) + const node = chatroomNodeAddress.add(0x0).readPointer() + const ret = chatroomRecurse(node) - sFileName = Memory.alloc(0x14) - sFileName.writePointer(ptr(fileNamePtr)).add(0x04) - .writeU32(fileNamePtr.length * 2).add(0x04) - .writeU32(fileNamePtr.length * 2).add(0x08) + const cloneRet = JSON.stringify(ret) + chatroomNodeList.length = 0 //empty + chatroomMemberList.length = 0 //empty + return cloneRet +}) - //const fileSize = size.toInt32() - attatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) - attatchReceiveIdPtr.writeUtf16String(contactId) +/** + * sendMsgNativeFunction + * send text message + * @param {string} talkerId = wxid or roomid + * @param {string} content + */ +const sendMsgNativeFunction = ((talkerId, content) => { - attatchReceiveId = Memory.alloc(0x14) - attatchReceiveId.writePointer(ptr(attatchReceiveIdPtr)).add(0x04) - .writeU32(contactId.length * 2).add(0x04) - .writeU32(contactId.length * 2).add(0x08) + const txtAsm = Memory.alloc(Process.pageSize) + //const buffwxid = Memory.alloc(0x20) - attatchSendIdPtr = Memory.alloc(senderId.length * 2 + 2) - attatchSendIdPtr.writeUtf16String(senderId) - attatchSendId = Memory.alloc(0x14) - attatchSendId.writePointer(ptr(attatchSendIdPtr)).add(0x04) - .writeU32(senderId.length * 2).add(0x04) - .writeU32(senderId.length * 2).add(0x08) + let wxidPtr = Memory.alloc(talkerId.length * 2 + 2) + wxidPtr.writeUtf16String(talkerId) - attatchPathPtr = Memory.alloc(path.length * 2 + 2) - attatchPathPtr.writeUtf16String(path) + let picWxid = Memory.alloc(0x0c) + picWxid.writePointer(ptr(wxidPtr)).add(0x04) + .writeU32(talkerId.length * 2).add(0x04) + .writeU32(talkerId.length * 2).add(0x04) - attatchPath = Memory.alloc(0x28) - attatchPath.writePointer(attatchPathPtr).add(0x04) - .writeU32(path.length * 2).add(0x04) - .writeU32(path.length * 2).add(0x04) + let contentPtr = Memory.alloc(content.length * 2 + 2) + contentPtr.writeUtf16String(content) - attatchEbp11E8 = Memory.alloc(0xBE4) - attatchEbpCC = Memory.alloc(0x14) - attatchEbp368 = Memory.alloc(0x290) - attatchEbp84 = Memory.alloc(0x18) - attatchEAX = Memory.alloc(0x18) + const sizeOfStringStruct = Process.pointerSize * 5 + let contentStruct = Memory.alloc(sizeOfStringStruct) - attatchECX = moduleBaseAddress.add(0x222f178).toInt32() + contentStruct + .writePointer(contentPtr).add(0x4) + .writeU32(content.length).add(0x4) + .writeU32(content.length * 2) - //console.log('basename',path.basename(path)) - //return - /** - * -------------buffer------------------------------- - */ + const ecxBuffer = Memory.alloc(0x2d8) - Memory.patchCode(attatchAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: attatchAsm }) + Memory.patchCode(txtAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: txtAsm + }) cw.putPushfx() cw.putPushax() - cw.putMovRegAddress('ecx', attatchEbp11E8) - cw.putCallAddress(moduleBaseAddress.add(0xE1590)) - - cw.putPushU32(-1) - cw.putPushU32(moduleBaseAddress.add(0x1E1B3C0).toInt32()) - cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x4))//11e4 - cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid - // cw.putCallAddress(moduleBaseAddress.add(0x702410))//write appid - - /** - * 78482B8D | 6A FF | push FFFFFFFF | - 78482B8F | 68 B895E979 | push wechatwin.79E995B8 | 79E995B8:L"0" - 78482B94 | 8D8D 48EEFFFF | lea ecx,dword ptr ss:[ebp-11B8] | - 78482B9A | E8 71F83600 | call wechatwin.787F2410 | 此处继续写ebp-11b8 - */ - cw.putPushU32(-1) - cw.putPushU32(moduleBaseAddress.add(0x1DA95B8).toInt32()) - cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x30))//11B8 - cw.putCallAddress(moduleBaseAddress.add(0x702410)) - - cw.putMovRegU32('eax', 0x6) - cw.putMovNearPtrReg(attatchEbp11E8.add(0x80), 'eax')//1168 - cw.putMovRegU32('eax', size)//file size - cw.putMovNearPtrReg(attatchEbp11E8.add(0x108), 'eax')//10e0 - - - cw.putMovRegAddress('eax', sFileName) - cw.putPushReg('eax') - cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x44))//11a4=0x11e8-0x160 - cw.putCallAddress(moduleBaseAddress.add(0x702980))//write filename - - cw.putMovRegAddress('eax', attatchSendId) - cw.putPushReg('eax') - cw.putMovRegAddress('ecx', attatchEbp11E8.add(0x160))//1088=0x11e8-0x160 - cw.putCallAddress(moduleBaseAddress.add(0x702980)) - + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + cw.putPushU32(0x0) - cw.putMovRegAddress('eax', attatchEbpCC) - cw.putPushReg('eax') - cw.putMovRegAddress('ecx', attatchEbp11E8) - cw.putCallAddress(moduleBaseAddress.add(0x617C30)) - - cw.putMovRegAddress('ecx', attatchEbp368) - cw.putCallAddress(moduleBaseAddress.add(0x954F0)) - - cw.putPushU32(-1) - cw.putPushU32((moduleBaseAddress.add(0x1D8F248)).toInt32()) - cw.putMovRegAddress('ecx', attatchEbp84) - cw.putCallAddress(moduleBaseAddress.add(0x701CD0)) - - cw.putMovRegAddress('ecx', attatchPath) - cw.putPushU32(0x6) - cw.putMovRegAddress('edx', attatchEbp11E8.add(0x160))//1088 - //cw.putMovRegAddress('eax',attatchEAX) - cw.putPushReg('ecx') - cw.putPushReg('eax') - - cw.putMovRegAddress('eax', attatchEbpCC) - cw.putPushReg('eax') + //cw.putMovRegReg - cw.putMovRegAddress('eax', attatchReceiveId) + cw.putMovRegAddress('eax', contentStruct) cw.putPushReg('eax') - cw.putMovRegAddress('ecx', attatchEbp368) - cw.putCallAddress(moduleBaseAddress.add(0x391F80)) - cw.putAddRegImm('esp', 0x14) - - - cw.putPushU32(moduleBaseAddress.add(0x223EC34).toInt32()) - cw.putPushU32(moduleBaseAddress.add(0x223EC34).toInt32()) - //cw.putMovRegU32('edx',0xAD0001) 两行代码都可以 - cw.putAddRegImm('edx', 0x1) - cw.putMovRegAddress('ecx', attatchEbp368) - cw.putCallAddress(moduleBaseAddress.add(0x392150)) - cw.putAddRegImm('esp', 0x8) - - - - //cw.putMovRegAddress('ecx', attatchEbp368) - //cw.putCallAddress(moduleBaseAddress.add(0x63B4F0)) - // 7B53F178 - //cw.putMovRegU32('ecx', attatchEbpCC.add(0x3c).toInt32())//ebp-90 - //cw.putMovNearPtrReg(attatchEbpCC.add(0x64), 'eax')//ebp-68 - //cw.putAddRegImm('ecx', 0x8) - //cw.putMovRegAddress('eax', attatchEbp368.add(0x64))//ebp-68 - - //cw.putMovRegU32('ecx',attatchECX) - //cw.putPushReg('eax') - //cw.putMovRegAddress('eax', attatchEbpCC.add(0x40))//ebp-8c - //cw.putPushReg('eax') - //cw.putCallAddress(moduleBaseAddress.add(0xC9D30)) - //cw.putCallAddress(moduleBaseAddress.add(0x522590)) - //78483063 | E8 28F51800 | call wechatwin.78612590 | - - - //78483039 | 8D8D 98FCFFFF | lea ecx,dword ptr ss:[ebp-368] | - //7848303F | E8 AC842A00 | call wechatwin.7872B4F0 | - //cw.putMovRegAddress('ecx', attatchEbp368) - //cw.putCallAddress(moduleBaseAddress.add(0x63B4F0)) + cw.putMovRegAddress('edx', picWxid) //room_id - // 78F33099 | 8D8D 34FFFFFF | lea ecx,dword ptr ss:[ebp-CC] | - //78F3309F | E8 AC0FD0FF | call wechatwin.78C34050 | - - //cw.putMovRegAddress('ecx',attatchEbpCC) - //cw.putCallAddress(moduleBaseAddress.add(0x94050)) - - /** - * 78F3307F | 8B4D AC | mov ecx,dword ptr ss:[ebp-54] | - 78F33082 | 8D85 98FCFFFF | lea eax,dword ptr ss:[ebp-368] | - 78F33088 | 50 | push eax | - 78F33089 | E8 82DACFFF | call wechatwin.78C30B10 | - - cw.putMovRegAddress('ecx', attatchEbp54) - cw.putMovRegAddress('eax', attatchEbp368) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add(0x90B10))*/ + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) + cw.putAddRegImm('esp', 0x18) cw.putPopax() cw.putPopfx() cw.putRet() @@ -1548,138 +610,56 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId, path, filename, size }) - const nativeativeFunction = new NativeFunction(ptr(attatchAsm), 'void', []) + console.log('----------txtAsm', txtAsm) + const nativeativeFunction = new NativeFunction(ptr(txtAsm), 'void', []) nativeativeFunction() - /*console.log(hexdump(attatchEbp11E8.add(0x80), { - offset: 0, - length: 0x40, - header: true, - ansi: true - }))*/ - //console.log('') - /*console.log(hexdump(attatchEbpCC.add(0x160), { - offset: 0, - length: 0x64, - header: true, - ansi: true - }))*/ - //console.log('-------',attatchEbp1C.readPointer()) - //console.log('-------',attatchEbp1C.add(0x4).readPointer()) - //console.log('-------',attatchEbp1C.add(0x8).readPointer()) -}) -/*-----------------send pic 3.6.0.18----------------*/ -/*------------------send pic --------------------------*/ -let buffwxid = null -let imagefilepath = null -let pathPtr = null -let picWxid = null -let picWxidPtr = null -let picAsm = null -let picbuff = null - -// 022 -const sendPicMsgNativeFunction = ((contactId, path) => { - - picAsm = Memory.alloc(Process.pageSize) - buffwxid = Memory.alloc(0x20) - picbuff = Memory.alloc(0x3B0) - pathPtr = Memory.alloc(path.length * 2 + 1) - pathPtr.writeUtf16String(path) - - imagefilepath = Memory.alloc(0x24) - imagefilepath.writePointer(pathPtr).add(0x04) - .writeU32(path.length * 2).add(0x04) - .writeU32(path.length * 2).add(0x04) +}) - picWxidPtr = Memory.alloc(contactId.length * 2 + 1) - picWxidPtr.writeUtf16String(contactId) - picWxid = Memory.alloc(0x0c) - picWxid.writePointer(ptr(picWxidPtr)).add(0x04) - .writeU32(contactId.length * 2).add(0x04) - .writeU32(contactId.length * 2).add(0x04) +let asmAtMsg = null +let roomid_, msg_, wxid_, atid_ +let ecxBuffer +const sendAtMsgNativeFunction = ((roomId, text, contactId,nickname) => { - /*const ecxValue = (moduleBaseAddress.add( - offset.send_picmsg_call_offset0 - )).toInt32() -*/ - const test_offset1 = 0x701DC0; - Memory.patchCode(picAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: picAsm }) - cw.putPushfx(); - cw.putPushax(); - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset0 - )) - cw.putMovRegReg('edx', 'eax')//缓存 + asmAtMsg = Memory.alloc(Process.pageSize) + ecxBuffer = Memory.alloc(0x3b0) - cw.putSubRegImm('esp', 0x14) - cw.putMovRegAddress('eax', buffwxid) - cw.putMovRegReg('ecx', 'esp') - cw.putMovRegAddress('edi', imagefilepath) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add( - test_offset1 - )) + const atContent = '@'+nickname+' '+text - cw.putMovRegReg('ecx', 'edx') - cw.putMovRegAddress('eax', picWxid) //=lea - cw.putMovRegAddress('edi', imagefilepath) - cw.putPushReg('edi') - cw.putPushReg('eax') - cw.putMovRegAddress('eax', picbuff) - cw.putPushReg('eax') + roomid_ = initStruct(roomId) + wxid_ = initidStruct(contactId) + msg_ = initmsgStruct(atContent) + atid_ = initAtMsgStruct(wxid_) - cw.putMovRegAddress('edi', picWxid)//edi - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset1 - )) + Memory.patchCode(asmAtMsg, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: asmAtMsg + }) + cw.putPushfx() + cw.putPushax() - /*cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset0 - )) - cw.putMovRegReg('ecx', 'eax') - cw.putMovRegAddress('eax', picWxid) - cw.putMovRegAddress('edi', imagefilepath) - cw.putPushReg('edi') - cw.putPushReg('eax') - cw.putMovRegAddress('eax', picbuff) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + //cw.putPushU32(0x0) + cw.putMovRegAddress('eax', atid_) cw.putPushReg('eax') - cw.putMovRegAddress('edi', picWxid)//edi - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset1 - ))-------ok but exception*/ - - /*3.3.0.115 - cw.putSubRegImm('esp', 0x14) - cw.putMovRegAddress('eax', buffwxid) - - cw.putMovRegReg('ecx', 'esp') + //cw.putMovRegReg + cw.putMovRegAddress('eax', msg_) cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset1 - )) - - cw.putMovRegAddress('ebx', imagefilepath) - cw.putPushReg('ebx') - cw.putMovRegAddress('eax', picWxid) - cw.putPushReg('eax') + cw.putMovRegAddress('edx', roomid_) //room_id - cw.putMovRegAddress('eax', picbuff) - cw.putPushReg('eax') + cw.putMovRegAddress('ecx', ecxBuffer) cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset2 + offset.sendTxtMsg.callOffset )) - cw.putMovRegReg('ecx', 'eax') - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset3 - ))*/ - + cw.putAddRegImm('esp', 0x18) cw.putPopax() cw.putPopfx() cw.putRet() @@ -1687,365 +667,139 @@ const sendPicMsgNativeFunction = ((contactId, path) => { }) - console.log('----------picAsm', picAsm) - const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) + //console.log('----------txtAsm', asmAtMsg) + const nativeativeFunction = new NativeFunction(ptr(asmAtMsg), 'void', []) nativeativeFunction() }) -/*------------------send pic -------------------------- -let buffwxid = null -let imagefilepath = null -let pathPtr = null -let picWxid = null -let picWxidPtr = null -let picAsm = null -let picbuff = null + +/** + * + * @param {*} contactId + * @param {*} path + */ const sendPicMsgNativeFunction = ((contactId, path) => { - picAsm = Memory.alloc(Process.pageSize) - buffwxid = Memory.alloc(0x20) - picbuff = Memory.alloc(0x378) + const picAsm = Memory.alloc(Process.pageSize) + const buffwxid = Memory.alloc(0x20) + const picbuff = Memory.alloc(0x2D8) - pathPtr = Memory.alloc(path.length * 2 + 1) + let pathPtr = Memory.alloc(path.length * 2 + 1) pathPtr.writeUtf16String(path) - imagefilepath = Memory.alloc(0x24) + let imagefilepath = Memory.alloc(0x24) imagefilepath.writePointer(pathPtr).add(0x04) .writeU32(path.length * 2).add(0x04) .writeU32(path.length * 2).add(0x04) - picWxidPtr = Memory.alloc(contactId.length * 2 + 1) + let picWxidPtr = Memory.alloc(contactId.length * 2 + 1) picWxidPtr.writeUtf16String(contactId) - picWxid = Memory.alloc(0x0c) + let picWxid = Memory.alloc(0x0c) picWxid.writePointer(ptr(picWxidPtr)).add(0x04) .writeU32(contactId.length * 2).add(0x04) .writeU32(contactId.length * 2).add(0x04) + + //const test_offset1 = 0x701DC0; Memory.patchCode(picAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: picAsm }) + var cw = new X86Writer(code, { + pc: picAsm + }) cw.putPushfx(); cw.putPushax(); + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call1 + )) + cw.putMovRegReg('edx', 'eax') //缓存 cw.putSubRegImm('esp', 0x14) cw.putMovRegAddress('eax', buffwxid) - cw.putMovRegReg('ecx', 'esp') - + cw.putMovRegAddress('edi', imagefilepath) cw.putPushReg('eax') cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset1 + offset.sendPicMsg.call2 )) - cw.putMovRegAddress('ebx', imagefilepath) - cw.putPushReg('ebx') - - cw.putMovRegAddress('eax', picWxid) + cw.putMovRegReg('ecx', 'edx') + cw.putMovRegAddress('eax', picWxid) //=lea + cw.putMovRegAddress('edi', imagefilepath) + cw.putPushReg('edi') cw.putPushReg('eax') - cw.putMovRegAddress('eax', picbuff) cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset2 - )) - cw.putMovRegReg('ecx', 'eax') + cw.putMovRegAddress('edi', picWxid) //edi cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset3 + offset.sendPicMsg.call3 )) - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - - }) - - const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) - nativeativeFunction() - -})*/ -/** -* send at msg -*/ -let asmAtMsg = null -let roomid_, msg_, wxid_, atid_ -let ecxBuffer - -// 023 -const sendAtMsgNativeFunction = ((roomId, text, contactId) => { - asmAtMsg = Memory.alloc(Process.pageSize) - ecxBuffer = Memory.alloc(0x3b0) - - - roomid_ = initStruct(roomId) - wxid_ = initidStruct(contactId) - msg_ = initmsgStruct(text) - atid_ = initAtMsgStruct(wxid_) - - Memory.patchCode(asmAtMsg, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: asmAtMsg }) - //cw.putMovRegAddress('eax',roomid) - - cw.putPushfx(); - cw.putPushax(); - - cw.putPushU32(1) // push - - cw.putMovRegAddress('edi', atid_) - cw.putMovRegAddress('ebx', msg_)//msg_ - - cw.putPushReg('edi') - cw.putPushReg('ebx') - //cw.putMovRegRegOffsetPtr('edx', 'ebp', 0x10)//at wxid - cw.putMovRegAddress('edx', roomid_)//room_id - cw.putMovRegAddress('ecx', ecxBuffer) - - cw.putCallAddress(moduleBaseAddress.add( - offset.send_txt_call_offset - )) - cw.putAddRegImm('esp', 0xc) cw.putPopax() cw.putPopfx() cw.putRet() cw.flush() - }) - - const atMsgNativeFunction = new NativeFunction(ptr(asmAtMsg), 'void', []) - atMsgNativeFunction() -}) - -/** -* @Call: sendMsg -> agentSendMsg -*/ - -// 024 -const sendMsgNativeFunction = (() => { - //const asmBuffer = Memory.alloc(/*0x5a8*/0x5f0) // magic number from wechat-bot (laozhang) - const asmBuffer = Memory.alloc(0x5f0) - const asmSendMsg = Memory.alloc(Process.pageSize) - Memory.patchCode(asmSendMsg, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: asmSendMsg }) - - cw.putPushReg('ebp') - cw.putMovRegReg('ebp', 'esp') - cw.putPushax() - cw.putPushfx() - - cw.putPushU32(1) // push - cw.putPushU32(0) // push - - cw.putMovRegRegOffsetPtr('ebx', 'ebp', 0xc) // arg 1 - cw.putPushReg('ebx') // push - - cw.putMovRegRegOffsetPtr('edx', 'ebp', 0x8) // arg 0 - cw.putMovRegAddress('ecx', asmBuffer) - - //0x3b56a0 3.2.1.121 - cw.putCallAddress(moduleBaseAddress.add( - offset.send_txt_call_offset - )) - cw.putAddRegImm('esp', 0xc) - - cw.putPopfx() - cw.putPopax() - cw.putMovRegRegPtr('esp', 'ebp') // Huan(202107): why use RegRegPtr? (RegRet will fail) - cw.putPopReg('ebp') - cw.putRet() - cw.flush() }) - /*let ins = Instruction.parse(asmSendMsg) - for (let i=0; i<20; i++) { - console.log(ins.address, '\t', ins.mnemonic, '\t', ins.opStr) - ins = Instruction.parse(ins.next) - }*/ - - const asmNativeFunction = new NativeFunction(asmSendMsg, 'void', ['pointer', 'pointer']) - - const sendMsg = ( - talkerId, - content, - ) => { - const talkerIdPtr = Memory.alloc(talkerId.length * 2 + 1) - const contentPtr = Memory.alloc(content.length * 2 + 1) - - talkerIdPtr.writeUtf16String(talkerId) - contentPtr.writeUtf16String(content) - - const sizeOfStringStruct = Process.pointerSize * 5 // + 0xd - - // allocate space for the struct - const talkerIdStruct = Memory.alloc(sizeOfStringStruct) // returns a NativePointer - const contentStruct = Memory.alloc(sizeOfStringStruct) // returns a NativePointer - - talkerIdStruct - .writePointer(talkerIdPtr).add(0x4) - .writeU32(talkerId.length).add(0x4) - .writeU32(talkerId.length * 2) - - contentStruct - .writePointer(contentPtr).add(0x4) - .writeU32(content.length).add(0x4) - .writeU32(content.length * 2) + //console.log('----------picAsm',picAsm) + const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) + nativeativeFunction() - asmNativeFunction(talkerIdStruct, contentStruct) - } +}) - /** - * Best Practices - * https://frida.re/docs/best-practices/ - * - * There is however a pitfall: the value returned by Memory.allocUtf8String() must be kept alive - * – it gets freed as soon as the JavaScript value gets garbage-collected. - * - * This means it needs to be kept alive for at least the duration of the function-call, - * and in some cases even longer; the exact semantics depend on how the API was designed. - */ - const refHolder = { - asmBuffer, - asmSendMsg, - asmNativeFunction, - sendMsg, - } - return (...args) => refHolder.sendMsg(...args) -})() -// 025 -const callLoginQrcodeFunction = ((forceRefresh = false) => { - const json = getQrcodeLoginData() - if (!forceRefresh && json.uuid) { - return - } - const callAsm = Memory.alloc(Process.pageSize) - const loginWnd = moduleBaseAddress.add(offset.get_login_wnd_offset).readPointer() +let memberNickBuffAsm = null +let nickRoomId = null +let nickMemberId = null +let nickBuff = null +const getChatroomMemberNickInfoFunction = ((memberId, roomId) => { - Memory.patchCode(callAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: callAsm }) - cw.putPushfx(); - cw.putPushax(); + nickBuff = Memory.alloc(0x7e4) + //const nickRetAddr = Memory.alloc(0x04) + memberNickBuffAsm = Memory.alloc(Process.pageSize) + //console.log('asm address----------',memberNickBuffAsm) + nickRoomId = initidStruct(roomId) + //console.log('nick room id',nickRoomId) + nickMemberId = initStruct(memberId) - cw.putMovRegAddress('ecx', loginWnd) - cw.putCallAddress(moduleBaseAddress.add(offset.get_qr_login_call_offset)) + //console.log('nick nickMemberId id',nickMemberId) + //const nickStructPtr = initmsgStruct('') + Memory.patchCode(memberNickBuffAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: memberNickBuffAsm + }) + cw.putPushfx() + cw.putPushax() + cw.putMovRegAddress('edi', nickRoomId) + cw.putMovRegAddress('eax', nickBuff) + cw.putMovRegReg('edx', 'edi') + cw.putPushReg('eax') + cw.putMovRegAddress('ecx', nickMemberId) + cw.putCallAddress(moduleBaseAddress.add(0xC06F10)) + cw.putAddRegImm('esp', 0x04) cw.putPopax() cw.putPopfx() cw.putRet() cw.flush() - }) - - const nativeativeFunction = new NativeFunction(ptr(callAsm), 'void', []) - nativeativeFunction() -}) - - -// 026 -const agentReadyCallback = (() => { - const nativeCallback = new NativeCallback(() => { }, 'void', []) - const nativeativeFunction = new NativeFunction(nativeCallback, 'void', []) - - setTimeout(() => { - nativeativeFunction() - }, 500); - return nativeCallback -})() - -// 027 -const SendMiniProgramNativeFunction = ((bg_path_str, send_wxid_str, recv_wxid_str, xmlstr) => { - console.log("------------------------------------------------------"); - var asmCode = Memory.alloc(Process.pageSize); - - var ECX_buf = Memory.alloc(0x300); - var Buf_EAX = Memory.alloc(0x300); - var buf_1 = Memory.alloc(0x300); - var ptr_to_buf_1 = Memory.alloc(0x4).writePointer(buf_1); - var buf_2 = Memory.alloc(0x300); - - // var bg_path_str="C:/aaaa.jpg"; - var bg_path_Ptr = Memory.alloc(bg_path_str.length * 2 + 1) - bg_path_Ptr.writeUtf16String(bg_path_str); - var bg_path_Struct = Memory.alloc(0x14) // returns a NativePointer - bg_path_Struct.writePointer(bg_path_Ptr).add(0x04) - .writeU32(bg_path_str.length * 2).add(0x04) - .writeU32(bg_path_str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0); - - // var send_wxid_str="wxid_4zr616ir6fi122"; - var send_wxid_Ptr = Memory.alloc(send_wxid_str.length * 2 + 1) - send_wxid_Ptr.writeUtf16String(send_wxid_str); - var send_wxid_Struct = Memory.alloc(0x14) // returns a NativePointer - send_wxid_Struct.writePointer(send_wxid_Ptr).add(0x04) - .writeU32(send_wxid_str.length * 2).add(0x04) - .writeU32(send_wxid_str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0); - - // var recv_wxid_str="filehelper"; - var recv_wxid_Ptr = Memory.alloc(recv_wxid_str.length * 2 + 1) - recv_wxid_Ptr.writeUtf16String(recv_wxid_str); - var recv_wxid_Struct = Memory.alloc(0x14) // returns a NativePointer - recv_wxid_Struct.writePointer(recv_wxid_Ptr).add(0x04) - .writeU32(recv_wxid_str.length * 2).add(0x04) - .writeU32(recv_wxid_str.length * 2).add(0x04) - .writeU32(0).add(0x04) - .writeU32(0); - // vvar pXml=initidStruct('wxid_4zr616ir6fi1220腾讯出行服务|加油代驾公交view330https://mp.weixin.qq.com/mp/waerrpage?appid=wx65cc950f42e8fff1&amp;type=upgrade&amp;upgradetype=3#wechat_redirecthttp://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=200腾讯出行服务|加油代驾公交0gh_ad64296dc8bd@appwx65cc950f42e8fff11http://mmbiz.qpic.cn/mmbiz_png/NM1fK7leWGPaFnMAe95jbg4sZAI3fkEZWHq69CIk6zA00SGARbmsGTbgLnZUXFoRwjROelKicbSp9K34MaZBuuA/640?wx_fmt=png&wxfrom=20002_wx65cc950f42e8fff1_875237370_1644979747_11Window wechat'); - - var pXml = initidStruct(xmlstr) - - console.log(send_wxid_Struct); - console.log(recv_wxid_Struct); - console.log(pXml); - console.log("okkk"); - - console.log("------------------------------------------------------"); - - Memory.patchCode(asmCode, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: asmCode }) - cw.putPushfx(); - cw.putPushax(); - cw.putMovRegReg('ecx', 'ecx'); - cw.putMovRegAddress('ecx', ECX_buf); - cw.putCallAddress(moduleBaseAddress.add(0x69BB0)); //init ecx - - cw.putPushU32(0x21); - - - cw.putPushNearPtr(ptr_to_buf_1); //ptr - cw.putPushU32(bg_path_Struct.toInt32()); - cw.putPushU32(pXml.toInt32()); - cw.putPushU32(recv_wxid_Struct.toInt32()); - - cw.putMovRegAddress('edx', send_wxid_Struct); - cw.putMovRegAddress('ecx', ECX_buf); - cw.putCallAddress(moduleBaseAddress.add(0x2E2420)); - cw.putAddRegImm('esp', 0x14) - - cw.putPushU32(Buf_EAX.toInt32()); - cw.putMovRegAddress('ecx', ECX_buf); - cw.putCallAddress(moduleBaseAddress.add(0x94C10)); - - cw.putPushU32(moduleBaseAddress.add(0x1DCB46C).toInt32()); - cw.putPushU32(moduleBaseAddress.add(0x1DCB46C).toInt32()); - cw.putMovRegAddress('ecx', ECX_buf); - cw.putCallAddress(moduleBaseAddress.add(0x2E2630)); - cw.putAddRegImm('esp', 0x8) - - cw.putPopax(); - cw.putPopfx(); - cw.putRet(); - cw.flush(); }) - const nativeativeFunction = new NativeFunction(ptr(asmCode), 'void', []) + const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsm), 'void', []) nativeativeFunction() + const nickname = readWideString(nickBuff) + console.log('----nickname', nickname) + return readWideString(nickBuff) +}) +const isLoggedInFunction = (() => { + // loggedIn = moduleBaseAddress.add(offset.is_logged_in_offset).readU32() + // return !!loggedIn + return true }) \ No newline at end of file diff --git a/src/puppet-xp.ts b/src/puppet-xp.ts index 446ffae..ce4278f 100644 --- a/src/puppet-xp.ts +++ b/src/puppet-xp.ts @@ -108,6 +108,7 @@ class PuppetXp extends PUPPET.Puppet { this.#sidecar = new WeChatSidecar() await attach(this.sidecar) + void this.onLogin() this.sidecar.on('hook', ({ method, args }) => { log.verbose('PuppetXp', 'onHook(%s, %s)', method, JSON.stringify(args)) @@ -141,15 +142,16 @@ class PuppetXp extends PUPPET.Puppet { private async onAgentReady () { log.verbose('PuppetXp', 'onAgentReady()') - const isLoggedIn = await this.sidecar.isLoggedIn() - if (!isLoggedIn) { - await this.sidecar.callLoginQrcode(false) - } + // const isLoggedIn = await this.sidecar.isLoggedIn() + // if (!isLoggedIn) { + // await this.sidecar.callLoginQrcode(false) + // } } private async onLogin () { const selfInfoRaw = JSON.parse(await this.sidecar.getMyselfInfo()) + // console.debug('selfInfoRaw:\n\n\n', selfInfoRaw) const selfInfo: PUPPET.payloads.Contact = { alias: '', avatar: selfInfoRaw.head_img_url, @@ -567,7 +569,7 @@ class PuppetXp extends PUPPET.Puppet { id: roomId, memberIdList: roomMember, ownerId: '', - topic: topic, + topic, } this.roomStore[roomId] = room delete this.contactStore[roomId] @@ -834,7 +836,7 @@ class PuppetXp extends PUPPET.Puppet { } } - if ([PUPPET.types.Message.Video, PUPPET.types.Message.Audio].includes(message?.type || PUPPET.types.Message.Unknown)) { + if ([ PUPPET.types.Message.Video, PUPPET.types.Message.Audio ].includes(message?.type || PUPPET.types.Message.Unknown)) { this.notSupported('Video/`Audio') } return FileBox.fromFile( diff --git a/src/wechat-sidecar.ts b/src/wechat-sidecar.ts index 8e73d49..ab02a70 100644 --- a/src/wechat-sidecar.ts +++ b/src/wechat-sidecar.ts @@ -37,6 +37,7 @@ import { codeRoot } from './cjs.js' const supportedVersions = { v330115:'3.3.0.115', v360000:'3.6.0.18', + v39223:'3.9.2.23', } // let initAgentScript = fs.readFileSync(path.join( @@ -46,7 +47,11 @@ const supportedVersions = { // 'agent-script-3.3.0.115.js', // ), 'utf-8') -let initAgentScript = '' +let initAgentScript = fs.readFileSync(path.join( + codeRoot, + 'src', + 'init-agent-script.js', +), 'utf-8') try { // const wechatVersion = new WeChatVersion() @@ -58,7 +63,7 @@ try { // await detach(wechatVersion) - const currentVersion = '3.6.0.18' + const currentVersion = '3.9.2.23' switch (currentVersion) { case supportedVersions.v330115: @@ -82,6 +87,19 @@ try { 'init-agent-script.js', ), 'utf-8') break + case supportedVersions.v39223: + // initAgentScript = fs.readFileSync(path.join( + // codeRoot, + // 'src', + // 'agents', + // 'agent-script-3.6.0.18.js', + // ), 'utf-8') + initAgentScript = fs.readFileSync(path.join( + codeRoot, + 'src', + 'init-agent-script.js', + ), 'utf-8') + break default: throw new Error(`Wechat version not supported. \nWechat version: ${currentVersion}, supported version: ${JSON.stringify(supportedVersions)}`) } @@ -90,8 +108,8 @@ try { @Sidecar('WeChat.exe', initAgentScript) class WeChatSidecar extends SidecarBody { - @Call(agentTarget('getTestInfoFunction')) - getTestInfo ():Promise { return Ret() } + // @Call(agentTarget('getTestInfoFunction')) + // getTestInfo ():Promise { return Ret() } @Call(agentTarget('getChatroomMemberNickInfoFunction')) getChatroomMemberNickInfo ( @@ -117,10 +135,10 @@ class WeChatSidecar extends SidecarBody { @Call(agentTarget('checkSupportedFunction')) checkSupported ():Promise { return Ret() } - @Call(agentTarget('callLoginQrcodeFunction')) - callLoginQrcode ( - forceRefresh: boolean, - ):Promise { return Ret(forceRefresh) } + // @Call(agentTarget('callLoginQrcodeFunction')) + // callLoginQrcode ( + // forceRefresh: boolean, + // ):Promise { return Ret(forceRefresh) } @Call(agentTarget('getContactNativeFunction')) getContact ():Promise { return Ret() } @@ -167,30 +185,30 @@ class WeChatSidecar extends SidecarBody { @ParamType('int32', 'U32') isMyMsg: number, // add isMyMsg type ) { return Ret(msgType, contactId, text, groupMsgSenderId, xmlContent, isMyMsg) } - @Hook(agentTarget('checkQRLoginNativeCallback')) - checkQRLogin ( - @ParamType('int32', 'U32') status: number, - @ParamType('pointer', 'Utf8String') qrcodeUrl: string, - @ParamType('pointer', 'Utf8String') wxid: string, - @ParamType('pointer', 'Utf8String') avatarUrl: string, - @ParamType('pointer', 'Utf8String') nickname: string, - @ParamType('pointer', 'Utf8String') phoneType: string, - @ParamType('int32', 'U32') phoneClientVer: number, - @ParamType('pointer', 'Utf8String') pairWaitTip: string, - ) { return Ret(status, qrcodeUrl, wxid, avatarUrl, nickname, phoneType, phoneClientVer, pairWaitTip) } - - @Hook(agentTarget('hookLogoutEventCallback')) - logoutEvent ( - @ParamType('int32', 'U32') bySrv: number, - ) { return Ret(bySrv) } - - @Hook(agentTarget('hookLoginEventCallback')) - loginEvent ( - ) { return Ret() } - - @Hook(agentTarget('agentReadyCallback')) - agentReady ( - ) { return Ret() } + // @Hook(agentTarget('checkQRLoginNativeCallback')) + // checkQRLogin ( + // @ParamType('int32', 'U32') status: number, + // @ParamType('pointer', 'Utf8String') qrcodeUrl: string, + // @ParamType('pointer', 'Utf8String') wxid: string, + // @ParamType('pointer', 'Utf8String') avatarUrl: string, + // @ParamType('pointer', 'Utf8String') nickname: string, + // @ParamType('pointer', 'Utf8String') phoneType: string, + // @ParamType('int32', 'U32') phoneClientVer: number, + // @ParamType('pointer', 'Utf8String') pairWaitTip: string, + // ) { return Ret(status, qrcodeUrl, wxid, avatarUrl, nickname, phoneType, phoneClientVer, pairWaitTip) } + + // @Hook(agentTarget('hookLogoutEventCallback')) + // logoutEvent ( + // @ParamType('int32', 'U32') bySrv: number, + // ) { return Ret(bySrv) } + + // @Hook(agentTarget('hookLoginEventCallback')) + // loginEvent ( + // ) { return Ret() } + + // @Hook(agentTarget('agentReadyCallback')) + // agentReady ( + // ) { return Ret() } }