From a9405957015b3ce77f76f8bdb2ed9a8c8c0ad355 Mon Sep 17 00:00:00 2001 From: choogoo <104893934+choogoo@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:22:08 +0800 Subject: [PATCH] 3.9.2.23 init (#182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 3.9.2.23 initt * Update init-agent-script.js * 3.9.2.23 adapter * 适配3.9.2.23 * Delete agent-script-3.9.2.23-new.js --- ...9.2.23-new.js => agent-script-3.9.2.23.js} | 1845 ++++++++--------- 1 file changed, 890 insertions(+), 955 deletions(-) rename src/agents/{agent-script-3.9.2.23-new.js => agent-script-3.9.2.23.js} (95%) diff --git a/src/agents/agent-script-3.9.2.23-new.js b/src/agents/agent-script-3.9.2.23.js similarity index 95% rename from src/agents/agent-script-3.9.2.23-new.js rename to src/agents/agent-script-3.9.2.23.js index f706c38..9c97f9a 100644 --- a/src/agents/agent-script-3.9.2.23-new.js +++ b/src/agents/agent-script-3.9.2.23.js @@ -8,11 +8,14 @@ //const { isNullishCoalesce } = require("typescript") -//3.9.2.23 +// wechat:3.9.2.23 -// 偏移地址集合 done +// 028 done const offset = { + + hook_point: 0xd19a0b, //3.9.2.23 + myselfinfo: { offset: 0x2FFD484, //老版本微信号偏移,后面的地址,都要在这个偏移上增加 //wxid_len:0x10, @@ -23,6 +26,7 @@ const offset = { //wxcode_len:0x74 wxid_len_offset: 0x4D4 }, + contactInfo: { nodeOffset: 0x2FFDD7C, nodeRootOffset: 0x64 @@ -40,25 +44,20 @@ const offset = { call3: 0xce6640 } }; -//3.9.2.23 -// 全局配置 done +// 029 done /*------------------global-------------------------------------------*/ const availableVersion = 1661534743 ////3.9.2.23 ==0x63090217 const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll') const moduleLoad = Module.load('WeChatWin.dll') -//1575CF98 - -// 全局变量 tbd +// tbd const g_EDIPtr = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readPointer()// const g_EDIU32 = moduleBaseAddress.add(0x222f38c).readPointer().add(0xD70).readU32() - /*------------------global-------------------------------------------*/ /*---------------base -------------------------*/ - -// done +// 030 done let retidPtr=null let retidStruct=null const initidStruct = ((str) => { @@ -78,7 +77,7 @@ const initidStruct = ((str) => { return retidStruct }) -// done +// 031 done let retPtr = null let retStruct = null const initStruct = ((str) => { @@ -98,7 +97,7 @@ const initStruct = ((str) => { return retStruct }) -// done +// 032 done let msgstrPtr=null let msgStruct=null const initmsgStruct = ((str) => { @@ -117,7 +116,23 @@ const initmsgStruct = ((str) => { return msgStruct }) -// tbd +// 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) => { @@ -137,25 +152,7 @@ const initNullIdStruct = ((str) => { return retidNullStruct }) -// 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 -}) - -// done -// std::string -// const str = readStringPtr(ptr).readUtf8String() +// 035 done const readStringPtr = (address) => { const addr = ptr(address) const size = addr.add(16).readU32() @@ -169,9 +166,15 @@ const readStringPtr = (address) => { 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) : '' } + 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()) @@ -180,913 +183,853 @@ const readStringPtr = (address) => { return addr } -// done +// 036 done const readString = (address) => { return readStringPtr(address).readUtf8String() } -// done +// 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 nodeList = [] //for contact let contactList = [] //for contact let chatroomNodeList = [] //for chatroom -let chatroomMemberList = []//for chatroom +let chatroomMemberList = [] //for chatroom let loggedIn = false -//开启日志 3.6.0.18 -// //[0x221c330+wechatwin.dll]+0xf8 -// 20220504 +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_initTestAsm = null -let g_BufferEbp2C = null -let g_initECXU32 = null -let g_initECXPtr = null -let g_initEBXPtr = null -let g_initEBX = null +// 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('.') +}) -let g_attatchEBP210Buffer = null -let g_attatchPathPtr = null -let g_attatchPath = null -let g_attatchEBPAc = null -let g_attatchEBPAcBufPtr = null +// 012 done +const checkSupportedFunction = (() => { + const ver = getWechatVersionFunction() + return ver == availableVersion +}) -let g_attatchContactIdPtr = null -//let g_attatchECXBuffer = null -let g_attatchESIU32 = null +// 019 done +/** + * @Hook: recvMsg -> recvMsgNativeCallback + */ + const recvMsgNativeCallback = (() => { -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) + const nativeCallback = new NativeCallback(() => {}, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) - 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 + 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 - console.log('------------g_initECXU32', g_initECXU32) - console.log('------------g_initESIU32', g_attatchESIU32) + if (msgType > 0) { + const talkerIdPtr = addr.add(0x48).readPointer() + //console.log('txt msg',talkerIdPtr.readUtf16String()) + const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 - //console.log('==========g_initECXPtr',g_initECXPtr) - //console.log('==========g_EDIU32',g_EDIU32) + const myTalkerIdPtr = Memory.alloc(talkerIdLen) + Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) - //g_attatchECXBuffer = Memory.alloc(0x1024) - //Memory.copy(g_attatchECXBuffer, g_initECXPtr, 0x1024) - g_BufferEbp2C = Memory.alloc(0x48) + 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) + } - //g_initEBX = moduleBaseAddress.add(0x2251724).readPointer().readPointer() - //g_initEBXPtr = Memory.alloc(0x14).writePointer(g_initEBX) - //g_initEBXPtr.add(0x08).writePointer(g_BufferEbp2C) + // 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 - g_attatchPathPtr = Memory.alloc(attatchFile.length * 2 + 2) - g_attatchPathPtr.writeUtf16String(attatchFile) + myGroupMsgSenderIdPtr = Memory.alloc(0x10) + myGroupMsgSenderIdPtr.writeUtf16String("null") - 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----------------*/ + } else { - //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) + const groupMsgSenderIdPtr = addr.add(0x170).readPointer() + const groupMsgSenderIdLen = addr.add(0x170 + 0x04).readU32() * 2 + 2 + myGroupMsgSenderIdPtr = Memory.alloc(groupMsgSenderIdLen) + Memory.copy(myGroupMsgSenderIdPtr, groupMsgSenderIdPtr, groupMsgSenderIdLen) - /*g_attatchECXBuffer.add(0x18).writePointer(g_attatchContactIdPtr) - g_attatchECXBuffer.add(0x1C).writeU32(contactId.length*2) - .add(0x04).writeU32(contactId.length*2)*/ + } + const xmlNullPtr = addr.add(0x1f0).readU32() //3.9.2.23 + let myXmlContentPtr = null + if (xmlNullPtr == 0) { + myXmlContentPtr = Memory.alloc(0x10) + myXmlContentPtr.writeUtf16String("null") - //g_attatchESIU32 = g_EDI.toInt32() + } 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) + } - //console.log('------------g_attatchESIU32',g_attatchESIU32) - //console.log('==========g_attatchECXBuffer',g_attatchECXBuffer) + setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) + } + } + }) + return nativeCallback +})() - Memory.patchCode(g_initTestAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: g_initTestAsm }) - cw.putPushfx() - cw.putPushax() - //cw.putMovRegAddress('eax', g_attatchEBP210Buffer) +// 003 done +const getBaseNodeAddress = (() => { + return moduleBaseAddress.add(offset.contactInfo.nodeOffset).readPointer() +}) - /*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))*/ +// 004 done +const getHeaderNodeAddress = (() => { + const baseAddress = getBaseNodeAddress() + //console.log('baseAddress',baseAddress) + if (baseAddress.isNull()) { + return baseAddress + } - //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))*/ + //console.log('HeaderNodeAddress',baseAddress.add(offset.handle_offset).readPointer()) + return baseAddress.add(offset.contactInfo.nodeRootOffset).readPointer() +}) +// 006 done +const getMyselfInfoFunction = (() => { - /*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))*/ + 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() - /*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)) + 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 + } - /** g_attatchEBPAc*/ - //cw.putMovRegNearPtr('eax', g_attatchEBPAc) - //cw.putMovNearPtrReg(g_attatchEBPAc.add(0xc), 'eax') - /** g_attatchEBPAc*/ + 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() - //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))*/ + head_img_url = img_addr.readAnsiString(img_len) - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() + const myself = { + id: wx_id, + code: wx_code, + name: wx_name, + head_img_url: head_img_url, + }; - }) + return JSON.stringify(myself) - const nativeativeFunction = new NativeFunction(ptr(g_initTestAsm), 'void', []) - nativeativeFunction() }) +// 043 done +const recurseNew = ((node) => { + const headerNodeAddress = getHeaderNodeAddress() + if (headerNodeAddress.isNull()) { + return + } -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 + if (node.equals(headerNodeAddress)) { + return + } - g_personal_detail_asm = Memory.alloc(Process.pageSize) - g_personal_detail_ebx = moduleBaseAddress.add(0x222F38C).readPointer().add(0xFB8).toInt32() + for (const item in nodeList) { + if (node.equals(nodeList[item])) { + return + } + } - 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) + nodeList.push(node) + const id = readString(node.add(0x8)) + //wxid, format relates to registration method + const wxid = readWideString(node.add(0x30)) + //console.log('-----------',wxid) - 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() + //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)) - cw.putCallAddress(moduleBaseAddress.add(0x9A000)) + //custom Nickname + const name = readWideString(node.add(0x8c)) - //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)) + //alias aka 'remark' in wechat + //const alias = readWideString(node.add(0x80)) - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() + //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,*/ + } - const nativeativeFunction = new NativeFunction(ptr(g_personal_detail_asm), 'void', []) - nativeativeFunction() + 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 writeLogNativeCallback = (() => { -// const nativeCallback = new NativeCallback(() => { }, 'void', []) -// const nativeCallFunction = new NativeFunction(nativeCallback, 'void', []) + const allContactJson = contactList + return allContactJson -// 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 +// 044 done +const getContactNativeFunction = (() => { + const headerNodeAddress = getHeaderNodeAddress() + //console.log('headerNodeAddress',headerNodeAddress) -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) + if (headerNodeAddress.isNull()) { + return '[]' + } - attatchFirstECX = Memory.alloc(0x28) - //const attatchSecondEcx = Memory.alloc(0x14) + const node = headerNodeAddress.add(0x0).readPointer() + const ret = recurseNew(node) - const contactIdLength = contactId.length * 2 + 2//edx - const contractIdActLength = contactId.length + //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 - gattatchReceiveIdPtr = Memory.alloc(contactId.length * 2 + 2) - gattatchReceiveIdPtr.writeUtf16String(contactId) + return cloneRet +}) - 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*/ +// 0xx done +const getChatroomNodeAddress = (() => { + const baseAddress = moduleBaseAddress.add(offset.chatroomInfo.nodeOffset).readPointer() + if (baseAddress.isNull()) { + return baseAddress + } + return baseAddress.add(offset.chatroomInfo.nodeRootOffset).readPointer() +}) - 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() +// 008chatroom member done +const chatroomRecurse = ((node) => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return + } + if (node.equals(chatroomNodeAddress)) { + return + } -}) -// 001 -const getTestInfoFunction = ((addr) => { - const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) - nativeativeFunction() + for (const item in chatroomNodeList) { + if (node.equals(chatroomNodeList[item])) { + return + } + } - //00CFE484 + 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 + } - /*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('============') + chatroomMemberList.push(memberJson) } - })*/ -}) + } -// 002get global data + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + const rightNode = node.add(0x08).readPointer() -const isLoggedInFunction = (() => { - loggedIn = moduleBaseAddress.add(offset.is_logged_in_offset).readU32() - return !!loggedIn -}) + chatroomRecurse(leftNode) + chatroomRecurse(centerNode) + chatroomRecurse(rightNode) -// 007 缺失,请标注已废弃或者其他原因 -const getMyselfIdFunction = (() => { + const allChatroomMemberJson = chatroomMemberList + return allChatroomMemberJson +}) - let wx_id = readString(moduleBaseAddress.add(offset.wxid_offset)) +// 009 done +const getChatroomMemberInfoFunction = (() => { + const chatroomNodeAddress = getChatroomNodeAddress() + if (chatroomNodeAddress.isNull()) { + return '[]' + } - return wx_id + 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 }) -// 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') +// 024 done +/** + * sendMsgNativeFunction + * send text message + * @param {string} talkerId = wxid or roomid + * @param {string} content + */ + const sendMsgNativeFunction = ((talkerId, content) => { - return addr -} + const txtAsm = Memory.alloc(Process.pageSize) + //const buffwxid = Memory.alloc(0x20) -//contact -const recurse = ((node) => { - const headerNodeAddress = getHeaderNodeAddress() - if (headerNodeAddress.isNull()) { return } - if (node.equals(headerNodeAddress)) { return } + let wxidPtr = Memory.alloc(talkerId.length * 2 + 2) + wxidPtr.writeUtf16String(talkerId) - for (const item in nodeList) { - if (node.equals(nodeList[item])) { - return - } - } + 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) - nodeList.push(node) - //wxid, format relates to registration method - const wxid = readWideString(node.add(0x38)) + const sizeOfStringStruct = Process.pointerSize * 5 + let contentStruct = Memory.alloc(sizeOfStringStruct) - //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)) + contentStruct + .writePointer(contentPtr).add(0x4) + .writeU32(content.length).add(0x4) + .writeU32(content.length * 2) - //custom Nickname - const name = readWideString(node.add(0x94)) - //alias aka 'remark' in wechat - const alias = readWideString(node.add(0x80)) + const ecxBuffer = Memory.alloc(0x2d8) - //avatarUrl - const avatar = readWideString(node.add(0x138)) - //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) - //contact gender - const gender = node.add(0x18C).readU32() + Memory.patchCode(txtAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: txtAsm + }) + cw.putPushfx() + cw.putPushax() - const contactJson = { - id: wxid, - code: wx_code, - name: name, - alias: alias, - avatarUrl: avatar, - gender: gender, - } + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + cw.putPushU32(0x0) - contactList.push(contactJson) + //cw.putMovRegReg - const leftNode = node.add(0x0).readPointer() - const centerNode = node.add(0x04).readPointer() - const rightNode = node.add(0x08).readPointer() + cw.putMovRegAddress('eax', contentStruct) + cw.putPushReg('eax') - recurse(leftNode) - recurse(centerNode) - recurse(rightNode) + cw.putMovRegAddress('edx', picWxid) //room_id - const allContactJson = contactList - return allContactJson + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) -}) + cw.putAddRegImm('esp', 0x18) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() -// 010 done -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('.') -}) + console.log('----------txtAsm', txtAsm) + const nativeativeFunction = new NativeFunction(ptr(txtAsm), 'void', []) + nativeativeFunction() -// 012 done -const checkSupportedFunction = (() => { - const ver = getWechatVersionFunction() - return ver == availableVersion }) +// 023 done /** - * @Hook: recvMsg -> recvMsgNativeCallback - */ +* send at msg +*/ +let asmAtMsg = null +let roomid_, msg_, wxid_, atid_ +let ecxBuffer +const sendAtMsgNativeFunction = ((roomId, text, contactId,nickname) => { -// 019 done -const recvMsgNativeCallback = (() => { + asmAtMsg = Memory.alloc(Process.pageSize) + ecxBuffer = Memory.alloc(0x3b0) + const atContent = '@'+nickname+' '+text - const nativeCallback = new NativeCallback(() => {}, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) - const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32', 'pointer', 'pointer', 'pointer', 'pointer', 'int32']) + roomid_ = initStruct(roomId) + wxid_ = initidStruct(contactId) + msg_ = initmsgStruct(atContent) + atid_ = initAtMsgStruct(wxid_) - 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 + Memory.patchCode(asmAtMsg, Process.pageSize, code => { + var cw = new X86Writer(code, { + pc: asmAtMsg + }) + cw.putPushfx() + cw.putPushax() - if (msgType > 0) { + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x0) + cw.putPushU32(0x1) + //cw.putPushU32(0x0) + cw.putMovRegAddress('eax', atid_) + cw.putPushReg('eax') - const talkerIdPtr = addr.add(0x48).readPointer() - //console.log('txt msg',talkerIdPtr.readUtf16String()) - const talkerIdLen = addr.add(0x48 + 0x04).readU32() * 2 + 2 + //cw.putMovRegReg - const myTalkerIdPtr = Memory.alloc(talkerIdLen) - Memory.copy(myTalkerIdPtr, talkerIdPtr, talkerIdLen) + cw.putMovRegAddress('eax', msg_) + cw.putPushReg('eax') + cw.putMovRegAddress('edx', roomid_) //room_id - 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) - } + cw.putMovRegAddress('ecx', ecxBuffer) + cw.putCallAddress(moduleBaseAddress.add( + offset.sendTxtMsg.callOffset + )) - // 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 + cw.putAddRegImm('esp', 0x18) + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() - myGroupMsgSenderIdPtr = Memory.alloc(0x10) - myGroupMsgSenderIdPtr.writeUtf16String("null") + }) - } else { + //console.log('----------txtAsm', asmAtMsg) + const nativeativeFunction = new NativeFunction(ptr(asmAtMsg), '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) +}) - } +// 022 done +/** + * + * @param {*} contactId + * @param {*} path + */ + const sendPicMsgNativeFunction = ((contactId, path) => { - const xmlNullPtr = addr.add(0x1f0).readU32() //3.9.2.23 - let myXmlContentPtr = null - if (xmlNullPtr == 0) { + const picAsm = Memory.alloc(Process.pageSize) + const buffwxid = Memory.alloc(0x20) + const picbuff = Memory.alloc(0x2D8) - myXmlContentPtr = Memory.alloc(0x10) - myXmlContentPtr.writeUtf16String("null") + let pathPtr = Memory.alloc(path.length * 2 + 1) + pathPtr.writeUtf16String(path) - } else { - const xmlContentPtr = addr.add(0x1f0).readPointer() //3.9.2.23 + let imagefilepath = Memory.alloc(0x24) + imagefilepath.writePointer(pathPtr).add(0x04) + .writeU32(path.length * 2).add(0x04) + .writeU32(path.length * 2).add(0x04) - const xmlContentLen = addr.add(0x1f0 + 0x04).readU32() * 2 + 2 - myXmlContentPtr = Memory.alloc(xmlContentLen) - Memory.copy(myXmlContentPtr, xmlContentPtr, xmlContentLen) - } + let picWxidPtr = Memory.alloc(contactId.length * 2 + 1) + picWxidPtr.writeUtf16String(contactId) - setImmediate(() => nativeativeFunction(msgType, myTalkerIdPtr, myContentPtr, myGroupMsgSenderIdPtr, myXmlContentPtr, isMyMsg)) - } - } - }) - return nativeCallback -})() + let picWxid = Memory.alloc(0x0c) + picWxid.writePointer(ptr(picWxidPtr)).add(0x04) + .writeU32(contactId.length * 2).add(0x04) + .writeU32(contactId.length * 2).add(0x04) -// 003get myself info 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 - } + //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') //缓存 - //console.log('HeaderNodeAddress',baseAddress.add(offset.handle_offset).readPointer()) - return baseAddress.add(offset.contactInfo.nodeRootOffset).readPointer() -}) + 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 + )) -// 006 done -const getMyselfInfoFunction = (() => { + 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') - let ptr = 0 - let wx_code = '' - let wx_id = '' - let wx_name = '' - let head_img_url = '' + cw.putMovRegAddress('edi', picWxid) //edi + cw.putCallAddress(moduleBaseAddress.add( + offset.sendPicMsg.call3 + )) - 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 - } + cw.putPopax() + cw.putPopfx() + cw.putRet() + cw.flush() - 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) + //console.log('----------picAsm',picAsm) + const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) + nativeativeFunction() - const myself = { - id: wx_id, - code: wx_code, - name: wx_name, - head_img_url: head_img_url, - }; +}) - return JSON.stringify(myself) +// 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) -// done -const recurseNew = ((node) => { - const headerNodeAddress = getHeaderNodeAddress() - if (headerNodeAddress.isNull()) { - return - } + //console.log('nick nickMemberId id',nickMemberId) + //const nickStructPtr = initmsgStruct('') - if (node.equals(headerNodeAddress)) { - return - } + 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() - for (const item in nodeList) { - if (node.equals(nodeList[item])) { - return - } - } + }) + const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsm), 'void', []) + nativeativeFunction() - nodeList.push(node) - const id = readString(node.add(0x8)) - //wxid, format relates to registration method - const wxid = readWideString(node.add(0x30)) - //console.log('-----------',wxid) + const nickname = readWideString(nickBuff) + console.log('----nickname', nickname) + return readWideString(nickBuff) +}) +/* 由此之后是3.9.2.23中缺失的未实现方法 */ - //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)) +// 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 - //custom Nickname - const name = readWideString(node.add(0x8c)) +let g_attatchEBP210Buffer = null +let g_attatchPathPtr = null +let g_attatchPath = null +let g_attatchEBPAc = null +let g_attatchEBPAcBufPtr = null - //alias aka 'remark' in wechat - //const alias = readWideString(node.add(0x80)) +let g_attatchContactIdPtr = null +//let g_attatchECXBuffer = null +let g_attatchESIU32 = null - //avatarUrl - //const avatar = readWideString(node.add(0x138)) - //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) - //contact gender - //const gender = node.add(0x18C).readU32() +let g_initECXTempPtr = null +const initGlobal = ((contactId, attatchFile) => { - const contactJson = { - id1: id, - id: wxid, - name: name, - /*code: wx_code, - name: name, - alias: alias, - avatarUrl: avatar, - gender: gender,*/ - } + //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) - contactList.push(contactJson) + 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 - const leftNode = node.add(0x0).readPointer() - const centerNode = node.add(0x04).readPointer() - //const rightNode = node.add(0x08).readPointer() + console.log('------------g_initECXU32', g_initECXU32) + console.log('------------g_initESIU32', g_attatchESIU32) - recurseNew(leftNode) - recurseNew(centerNode) - //recurse(rightNode) - const allContactJson = contactList - return allContactJson + //console.log('==========g_initECXPtr',g_initECXPtr) + //console.log('==========g_EDIU32',g_EDIU32) -}) + //g_attatchECXBuffer = Memory.alloc(0x1024) + //Memory.copy(g_attatchECXBuffer, g_initECXPtr, 0x1024) -// done ? -const getContactNativeFunction = (() => { - const headerNodeAddress = getHeaderNodeAddress() - //console.log('headerNodeAddress',headerNodeAddress) + g_BufferEbp2C = Memory.alloc(0x48) - if (headerNodeAddress.isNull()) { - return '[]' - } + //g_initEBX = moduleBaseAddress.add(0x2251724).readPointer().readPointer() + //g_initEBXPtr = Memory.alloc(0x14).writePointer(g_initEBX) + //g_initEBXPtr.add(0x08).writePointer(g_BufferEbp2C) - const node = headerNodeAddress.add(0x0).readPointer() - const ret = recurseNew(node) + g_attatchPathPtr = Memory.alloc(attatchFile.length * 2 + 2) + g_attatchPathPtr.writeUtf16String(attatchFile) - //console.log(ret) + 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----------------*/ - 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 + //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) - return cloneRet -}) + /*g_attatchECXBuffer.add(0x18).writePointer(g_attatchContactIdPtr) + g_attatchECXBuffer.add(0x1C).writeU32(contactId.length*2) + .add(0x04).writeU32(contactId.length*2)*/ -// 005 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 - } + //g_attatchESIU32 = g_EDI.toInt32() - for (const item in chatroomNodeList) { - if (node.equals(chatroomNodeList[item])) { - return - } - } - chatroomNodeList.push(node) - const roomid = readWideString(node.add(0x10)) + //console.log('------------g_attatchESIU32',g_attatchESIU32) + //console.log('==========g_attatchECXBuffer',g_attatchECXBuffer) - 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 - } + Memory.patchCode(g_initTestAsm, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: g_initTestAsm }) + cw.putPushfx() + cw.putPushax() + //cw.putMovRegAddress('eax', g_attatchEBP210Buffer) - chatroomMemberList.push(memberJson) - } + /*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) - const leftNode = node.add(0x0).readPointer() - const centerNode = node.add(0x04).readPointer() - const rightNode = node.add(0x08).readPointer() + /*cw.putPushU32(0) + cw.putMovRegAddress('eax', g_attatchPathPtr) + cw.putPushReg('eax') + cw.putPushU32(3) + cw.putMovRegAddress('ecx', g_attatchEBP210Buffer) + cw.putCallAddress(moduleBaseAddress.add(0x130220))*/ - chatroomRecurse(leftNode) - chatroomRecurse(centerNode) - chatroomRecurse(rightNode) - const allChatroomMemberJson = chatroomMemberList - return allChatroomMemberJson -}) + /*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))*/ -// 009 done -const getChatroomMemberInfoFunction = (() => { - const chatroomNodeAddress = getChatroomNodeAddress() - if (chatroomNodeAddress.isNull()) { - return '[]' - } - const node = chatroomNodeAddress.add(0x0).readPointer() - const ret = chatroomRecurse(node) + /*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)) - const cloneRet = JSON.stringify(ret) - chatroomNodeList.length = 0 //empty - chatroomMemberList.length = 0 //empty - return cloneRet -}) + /** g_attatchEBPAc*/ + //cw.putMovRegNearPtr('eax', g_attatchEBPAc) + //cw.putMovNearPtrReg(g_attatchEBPAc.add(0xc), 'eax') + /** g_attatchEBPAc*/ -// 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) + //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() - 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) + const nativeativeFunction = new NativeFunction(ptr(g_initTestAsm), 'void', []) + nativeativeFunction() +}) - let contentPtr = Memory.alloc(content.length * 2 + 2) - contentPtr.writeUtf16String(content) +// 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 - const sizeOfStringStruct = Process.pointerSize * 5 - let contentStruct = Memory.alloc(sizeOfStringStruct) + g_personal_detail_asm = Memory.alloc(Process.pageSize) + g_personal_detail_ebx = moduleBaseAddress.add(0x222F38C).readPointer().add(0xFB8).toInt32() - contentStruct - .writePointer(contentPtr).add(0x4) - .writeU32(content.length).add(0x4) - .writeU32(content.length * 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.writePointer(ptr(g_personal_wxid_ptr)).add(0x04) + .writeU32(wxid.length * 2).add(0x04) + .writeU32(wxid.length * 2).add(0x08) - const ecxBuffer = Memory.alloc(0x2d8) + console.log('-----------address----------', g_personal_detail_asm) - Memory.patchCode(txtAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { - pc: txtAsm - }) + Memory.patchCode(g_personal_detail_asm, Process.pageSize, code => { + var cw = new X86Writer(code, { pc: g_personal_detail_asm }) cw.putPushfx() cw.putPushax() - cw.putPushU32(0x0) - cw.putPushU32(0x0) - cw.putPushU32(0x0) - cw.putPushU32(0x1) - cw.putPushU32(0x0) - - //cw.putMovRegReg + cw.putCallAddress(moduleBaseAddress.add(0x9A000)) - cw.putMovRegAddress('eax', contentStruct) + //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.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() @@ -1094,59 +1037,154 @@ const getChatroomMemberInfoFunction = (() => { }) - console.log('----------txtAsm', txtAsm) - const nativeativeFunction = new NativeFunction(ptr(txtAsm), 'void', []) + const nativeativeFunction = new NativeFunction(ptr(g_personal_detail_asm), 'void', []) nativeativeFunction() + }) -// 023 done +// 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 /** -* send at msg -*/ -let asmAtMsg = null -let roomid_, msg_, wxid_, atid_ -let ecxBuffer -const sendAtMsgNativeFunction = ((roomId, text, contactId,nickname) => { + * 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 - asmAtMsg = Memory.alloc(Process.pageSize) - ecxBuffer = Memory.alloc(0x3b0) +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) - const atContent = '@'+nickname+' '+text + attatchFirstECX = Memory.alloc(0x28) + //const attatchSecondEcx = Memory.alloc(0x14) - roomid_ = initStruct(roomId) - wxid_ = initidStruct(contactId) - msg_ = initmsgStruct(atContent) - atid_ = initAtMsgStruct(wxid_) + const contactIdLength = contactId.length * 2 + 2//edx + const contractIdActLength = contactId.length - Memory.patchCode(asmAtMsg, Process.pageSize, code => { - var cw = new X86Writer(code, { - pc: asmAtMsg - }) + + 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.putPushU32(0x0) - cw.putPushU32(0x0) - cw.putPushU32(0x0) - cw.putPushU32(0x1) - //cw.putPushU32(0x0) - cw.putMovRegAddress('eax', atid_) + + cw.putMovRegAddress('esi', attatchESIbuf) + + cw.putMovRegAddress('ecx', attatchFirstECX.add(0x14)) + cw.putMovRegAddress('eax', gattatchFile) cw.putPushReg('eax') + cw.putCallAddress(moduleBaseAddress.add(0x701DC0)) - //cw.putMovRegReg - cw.putMovRegAddress('eax', msg_) + cw.putMovRegAddress('ecx', attatchFirstECX) + cw.putMovRegU32('eax', contactIdLength) cw.putPushReg('eax') + cw.putPushU32(0) + cw.putCallAddress(moduleBaseAddress.add(0x1a11c83)) + cw.putAddRegImm('esp', 0x8) - cw.putMovRegAddress('edx', roomid_) //room_id + 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.putMovRegAddress('ecx', ecxBuffer) - cw.putCallAddress(moduleBaseAddress.add( - offset.sendTxtMsg.callOffset - )) + //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.putAddRegImm('esp', 0x18) cw.putPopax() cw.putPopfx() cw.putRet() @@ -1154,134 +1192,103 @@ const sendAtMsgNativeFunction = ((roomId, text, contactId,nickname) => { }) - //console.log('----------txtAsm', asmAtMsg) - const nativeativeFunction = new NativeFunction(ptr(asmAtMsg), 'void', []) + const nativeativeFunction = new NativeFunction(ptr(attatchTestAsm), 'void', []) nativeativeFunction() + }) -// 022 done -/** - * - * @param {*} contactId - * @param {*} path - */ - const sendPicMsgNativeFunction = ((contactId, path) => { +// 001 +const getTestInfoFunction = ((addr) => { + const nativeativeFunction = new NativeFunction(ptr(addr), 'void', []) + nativeativeFunction() - const picAsm = Memory.alloc(Process.pageSize) - const buffwxid = Memory.alloc(0x20) - const picbuff = Memory.alloc(0x2D8) + //00CFE484 - 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) + /*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('============') + } + })*/ - 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) +// 002 +const isLoggedInFunction = (() => { + loggedIn = moduleBaseAddress.add(offset.is_logged_in_offset).readU32() + return !!loggedIn +}) +// 007 获得当前账号信息 +const getMyselfIdFunction = (() => { - //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') //缓存 + let wx_id = readString(moduleBaseAddress.add(offset.wxid_offset)) - 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 - )) + return wx_id - 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 - )) +//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 + } + } - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - }) + nodeList.push(node) + //wxid, format relates to registration method + const wxid = readWideString(node.add(0x38)) - //console.log('----------picAsm',picAsm) - const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) - nativeativeFunction() + //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)) -// 020 done -let memberNickBuffAsm = null -let nickRoomId = null -let nickMemberId = null -let nickBuff = null -const getChatroomMemberNickInfoFunction = ((memberId, roomId) => { + //alias aka 'remark' in wechat + const alias = readWideString(node.add(0x80)) - 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) + //avatarUrl + const avatar = readWideString(node.add(0x138)) + //const avatar = Memory.readUtf16String(node.add(0x138).readPointer()) + //contact gender + const gender = node.add(0x18C).readU32() - //console.log('nick nickMemberId id',nickMemberId) - //const nickStructPtr = initmsgStruct('') + const contactJson = { + id: wxid, + code: wx_code, + name: name, + alias: alias, + avatarUrl: avatar, + gender: gender, + } - 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() + contactList.push(contactJson) - }) + const leftNode = node.add(0x0).readPointer() + const centerNode = node.add(0x04).readPointer() + const rightNode = node.add(0x08).readPointer() - const nativeativeFunction = new NativeFunction(ptr(memberNickBuffAsm), 'void', []) - nativeativeFunction() + recurse(leftNode) + recurse(centerNode) + recurse(rightNode) + + const allContactJson = contactList + return allContactJson - const nickname = readWideString(nickBuff) - console.log('----nickname', nickname) - return readWideString(nickBuff) }) // 013 @@ -1428,13 +1435,13 @@ const getQrcodeLoginData = () => { 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 writeLogNativeCallback = (() => { const nativeCallback = new NativeCallback(() => { }, 'void', []) const nativeCallFunction = new NativeFunction(nativeCallback, 'void', []) @@ -1448,8 +1455,9 @@ const getQrcodeLoginData = () => { } }) return nativeCallback -})()*/ +})() +// 046 let nickRoomIdV6 = null let nullEdiWxidStructV6 = null let nickMemberIdStructV6 = null @@ -1509,6 +1517,7 @@ const getChatroomMemberNickInfoV1Function = ((memberId, roomId) => { return readWideString(nullEdiWxidStructV6) }) +// 021 /** * send attatch */ @@ -1550,8 +1559,6 @@ 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 */ - -// 021 const sendAttatchMsgNativeFunction = ((contactId, senderId, path, filename, size) => { attatchAsm = Memory.alloc(Process.pageSize) @@ -1755,78 +1762,6 @@ const sendAttatchMsgNativeFunction = ((contactId, senderId, path, filename, size //console.log('-------',attatchEbp1C.add(0x4).readPointer()) //console.log('-------',attatchEbp1C.add(0x8).readPointer()) }) -/*------------------send pic -------------------------- -let buffwxid = null -let imagefilepath = null -let pathPtr = null -let picWxid = null -let picWxidPtr = null -let picAsm = null -let picbuff = null -const sendPicMsgNativeFunction = ((contactId, path) => { - - picAsm = Memory.alloc(Process.pageSize) - buffwxid = Memory.alloc(0x20) - picbuff = Memory.alloc(0x378) - - 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) - - Memory.patchCode(picAsm, Process.pageSize, code => { - var cw = new X86Writer(code, { pc: picAsm }) - cw.putPushfx(); - cw.putPushax(); - - cw.putSubRegImm('esp', 0x14) - cw.putMovRegAddress('eax', buffwxid) - - cw.putMovRegReg('ecx', 'esp') - - 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('eax', picbuff) - cw.putPushReg('eax') - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset2 - )) - - cw.putMovRegReg('ecx', 'eax') - cw.putCallAddress(moduleBaseAddress.add( - offset.send_picmsg_call_offset3 - )) - cw.putPopax() - cw.putPopfx() - cw.putRet() - cw.flush() - - }) - - const nativeativeFunction = new NativeFunction(ptr(picAsm), 'void', []) - nativeativeFunction() - -})*/ // 025 const callLoginQrcodeFunction = ((forceRefresh = false) => {