sidecar icon indicating copy to clipboard operation
sidecar copied to clipboard

designParamTypeList in @ParamType is undefined?

Open jwwang2003 opened this issue 3 years ago • 5 comments

@Hook(agentTarget('hookLogoutEventCallback'))
  logoutEvent (
    @ParamType('int32', 'U32') bySrv: number,
  ) { return Ret(bySrv) }

The @ParamType causes the following error:

D:\编程\github\wechat-hook\node_modules\sidecar\src\decorators\param-type\guard-param-type.ts:26
  const designParamType = designParamTypeList[parameterIndex] 
                                             ^
TypeError: Cannot read properties of undefined (reading '0')
    at guardParamType (D:\编程\github\wechat-hook\node_modules\sidecar\src\decorators\param-type\guard-param-type.ts:26:46) 
    at paramTypeDecorator (D:\编程\github\wechat-hook\node_modules\sidecar\src\decorators\param-type\param-type.ts:48:19)   
    at D:\编程\github\wechat-hook\src\index.ts:9:37
    at DecorateProperty (D:\编程\github\wechat-hook\node_modules\reflect-metadata\Reflect.js:553:33)
    at Reflect.decorate (D:\编程\github\wechat-hook\node_modules\reflect-metadata\Reflect.js:123:24)
    at __decorate (D:\编程\github\wechat-hook\src\index.ts:4:92)
    at Object.<anonymous> (D:\编程\github\wechat-hook\src\index.ts:38:3)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Module.m._compile (D:\编程\github\wechat-hook\node_modules\ts-node\src\index.ts:1475:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1155:10)
[nodemon] app crashed - waiting for file changes before starting...

If I don't include @ParamType , the application works without any errors.

jwwang2003 avatar Mar 06 '22 06:03 jwwang2003

Would appreciate it if you can provide more information or a minimum code with reproducible steps.

huan avatar Mar 06 '22 12:03 huan

The init-agent-script file

console.log('Hello from init-agent-script')

//3.3.0.115
const offset = {
  node_offset: 0x1db9728,
  handle_offset: 0xe4,
  send_txt_call_offset: 0x3e3b80,
  hook_point: 0x40d3b1,
  chatroom_node_offset: 0xb08,
  nickname_offset: 0x1ddf534,
  wxid_offset: 0x1ddf4bc,
  head_img_url_offset: 0x1ddf7fc,
  is_logged_in_offset: 0x1DDF9D4,
  hook_on_login_offset: 0x51B790,
  hook_on_logout_offset: 0x51C2C0,
  hook_get_login_qr_offset: 0x4B6020,
  hook_check_login_qr_offset: 0x478B90,
  hook_save_login_qr_info_offset: 0x3DB2E0,
  get_login_wnd_offset: 0x1DB96A4,
  get_qr_login_data_offset: 0x282160,
  get_qr_login_call_offset: 0x286930,
  send_picmsg_call_offset1: 0x5ccb50,
  send_picmsg_call_offset2: 0x6f5c0,
  send_picmsg_call_offset3: 0x3e3490,
  send_attatch_call_offset1: 0x5ccb50,
  send_attatch_call_offset2: 0x5ccb10,
  send_attatch_call_offset3: 0x5ccb50,
  send_attatch_call_offset4: 0x5ccb50,
  send_attatch_call_offset5: 0x074c90,
  send_attatch_call_offset6: 0x2e2720,
  send_attatch_call_para: 0x19a7350,
  chatroom_member_nick_call_offset1: 0x558cb0,
  chatroom_member_nick_call_offset2: 0x3b0fe0,
  chatroom_member_nick_call_offset3: 0x55f6e0,
  chatroom_member_nick_call_offset4: 0x34cb10,
};
//3.3.0.115


/*------------------global-------------------------------------------*/
const availableVersion = 1661141107 ////3.3.0.115
const moduleBaseAddress = Module.getBaseAddress('WeChatWin.dll')
const moduleLoad = Module.load('WeChatWin.dll')
let currentVersion = 0

let nodeList = []  //for contact
let contactList = [] //for contact

let chatroomNodeList = [] //for chatroom
let chatroomMemberList = []//for chatroom
let loggedIn = false

const hookLogoutEventCallback = (() => {
  const nativeCallback = new NativeCallback(() => { }, 'void', ['int32'])
  const nativeativeFunction = new NativeFunction(nativeCallback, 'void', ['int32'])

  Interceptor.attach(moduleBaseAddress.add(offset.hook_on_logout_offset), {
    onEnter: function (args) {
      const bySrv = args[0].toInt32()
      console.log(bySrv)
      return bySrv
      setImmediate(() => nativeativeFunction(bySrv))
    }
  })
  return nativeCallback
})()

const getMyselfInfoFunction = (() => {

  let ptr = 0
  let wx_code = ''
  let wx_id = ''
  let wx_name = ''
  let head_img_url = ''

  wx_id = readString(moduleBaseAddress.add(offset.wxid_offset))
  wx_code = wx_id

  wx_name = readString(moduleBaseAddress.add(offset.nickname_offset))
  head_img_url = readString(moduleBaseAddress.add(offset.head_img_url_offset))


  const myself = {
    id: wx_id,
    code: wx_code,
    name: wx_name,
    head_img_url: head_img_url,
  };

  return JSON.stringify(myself)

})

const callLoginQrcodeFunction = ((forceRefresh = false) => {
  const json = getQrcodeLoginData()
  console.log(json)
  if (!forceRefresh && json.uuid) {
    return
  }

  const callAsm = Memory.alloc(Process.pageSize)
  const loginWnd = moduleBaseAddress.add(offset.get_login_wnd_offset).readPointer()

  Memory.patchCode(callAsm, Process.pageSize, code => {
    var cw = new X86Writer(code, { pc: callAsm })
    cw.putPushfx();
    cw.putPushax();

    cw.putMovRegAddress('ecx', loginWnd)
    cw.putCallAddress(moduleBaseAddress.add(offset.get_qr_login_call_offset))

    cw.putPopax()
    cw.putPopfx()
    cw.putRet()
    cw.flush()
  })

  const nativeativeFunction = new NativeFunction(ptr(callAsm), 'void', [])
  nativeativeFunction()
})

const getQrcodeLoginData = () => {
  const getQRCodeLoginMgr = new NativeFunction(moduleBaseAddress.add(offset.get_qr_login_data_offset), 'pointer', [])
  const qlMgr = getQRCodeLoginMgr()
  console.log(qlMgr)
  const json = {
    status: 0,
    uuid: '',
    wxid: '',
    avatarUrl: '',
  }

  if (!qlMgr.isNull()) {
    json.uuid = readString(qlMgr.add(8))
    json.status = qlMgr.add(40).readUInt()
    json.wxid = readString(qlMgr.add(44))
    json.avatarUrl = readString(qlMgr.add(92))
  }
  return json
}

const readString = (address) => {
  return readStringPtr(address).readUtf8String()
}

const readStringPtr = (address) => {
  const addr = ptr(address)
  const size = addr.add(16).readU32()
  const capacity = addr.add(20).readU32()
  addr.ptr = addr
  addr.size = size
  addr.capacity = capacity
  if (capacity > 15 && !addr.readPointer().isNull()) {
    addr.ptr = addr.readPointer()
  }
  addr.ptr._readCString = addr.ptr.readCString
  addr.ptr._readAnsiString = addr.ptr.readAnsiString
  addr.ptr._readUtf8String = addr.ptr.readUtf8String
  addr.readCString = () => { return addr.size ? addr.ptr._readCString(addr.size) : '' }
  addr.readAnsiString = () => { return addr.size ? addr.ptr._readAnsiString(addr.size) : '' }
  addr.readUtf8String = () => { return addr.size ? addr.ptr._readUtf8String(addr.size) : '' }

  // console.log('readStringPtr() address:',address,' -> str ptr:', addr.ptr, 'size:', addr.size, 'capacity:', addr.capacity)
  // console.log('readStringPtr() str:' , addr.readUtf8String())
  // console.log('readStringPtr() address:', addr,'dump:', addr.readByteArray(24))

  return addr
}

The main index.ts file

import fs from 'fs'
import path from 'path'
import {
  Sidecar,
  SidecarBody,
  Call,
  Hook,
  Ret,
  RetType,
  ParamType,
  attach,
  detach,
  agentTarget
} from 'sidecar'

import { codeRoot } from '../commonjs/code-root'

const initAgentScript = fs.readFileSync(path.join(
  codeRoot,
  'src',
  'init-agent-script.js',
), 'utf-8')

@Sidecar(
  'WeChat.exe', 
  initAgentScript,
)
class ChatboxSidecar extends SidecarBody {
  @Call(agentTarget('callLoginQrcodeFunction'))
  callLoginQrcode (
    forceRefresh: boolean,
  ):Promise<null> { return Ret(forceRefresh) }

  @Call(agentTarget('getMyselfInfoFunction'))
  getMyselfInfo ():Promise<string> { return Ret() }

  @Hook(agentTarget('hookLogoutEventCallback'))
  logoutEvent (
    @ParamType('int32', 'U32') bySrv: number,
  ) { return Ret(bySrv) }
}

async function main () {
  const sidecar = new ChatboxSidecar()
  await attach(sidecar)

  console.log(await sidecar.getMyselfInfo())

  sidecar.on('hook', ({ method, args }) => {
    console.log('method:', method)
    console.log('args:', args)
  })

  process.on('SIGINT',  () => detach(sidecar))
  process.on('SIGTERM', () => detach(sidecar))
}

main().catch(console.error)

Some of this code was taken from wechaty-xp, just experimenting with sidecar because this is my first time. Will later use this with a newer version of WeChat. I am currently using the latest version of "sidecar": "^1.0.19".

jwwang2003 avatar Mar 07 '22 00:03 jwwang2003

Thanks for the new information.

I will take a look when I got time with a windows VPS . (Currently I have no windows dev machine)

Have you joined the XP WeChat room? If not, please feel free to san the below qrcode to join and ask your question over there, with other sidecar users.

Screenshot_20220307-085900

huan avatar Mar 07 '22 01:03 huan

Enable experimentalDecorators and emitDecoratorMetadata in tsconfig.json

KevinGong2013 avatar Dec 13 '23 11:12 KevinGong2013

Hi, anyone interested in Puppet XP will be welcome to join the Discord for future discussion. Invitation link: https://discord.gg/uE8Tb77VBm

Happy New Year 2024!

huan avatar Jan 01 '24 19:01 huan