JohnDeved / memory.ts

enables access to foreign process memory with Node.js
2 stars 0 forks source link

Checkout node-ffi napi #104

Open JohnDeved opened 2 years ago

JohnDeved commented 2 years ago

https://github.com/node-ffi-napi/node-ffi-napi

JohnDeved commented 2 years ago

writes 20k/s about 1.5-2x faster than windbg

JohnDeved commented 2 years ago

write 21254 / sec read 24210 / sec

JohnDeved commented 2 years ago
import * as ffi from 'ffi-napi'

const kernel = ffi.Library('Kernel32.dll', {
  'OpenProcess': [ 'uint', [ 'uint', 'byte', 'uint' ]],
  'ReadProcessMemory': [ 'uint', ['uint', 'uint64', 'uint64', 'uint', 'uint']],
  'WriteProcessMemory': [ 'uint', ['uint', 'uint64', 'uint64', 'uint', 'uint']],
})

const pHandle = kernel.OpenProcess(0x0010 | 0x0020 | 0x0008, 0, 17476)

function readDouble () {
  const outBuffer = Buffer.allocUnsafe(0x8)
  kernel.ReadProcessMemory(pHandle, 0x24C1BC98, outBuffer.address(), outBuffer.byteLength, 0)
}

function writeDouble (num: number) {
  const outBuffer = Buffer.alloc(0x8)
  outBuffer.writeDoubleLE(num)
  kernel.WriteProcessMemory(pHandle, 0x24C1BC98, outBuffer.address(), outBuffer.byteLength, 0)
}

let time = Date.now() + 1000
let index = 0
for (; time >= Date.now(); index++) writeDouble(index)
console.log('write', index, '/ sec')

time = Date.now() + 1000
index = 0
for (; time >= Date.now(); index++) readDouble()
console.log('read', index, '/ sec')
JohnDeved commented 2 years ago

async, even tho benchmarks said otherwise is slower

write 21226 / sec read 27079 / sec write async 11391 / sec read async 14902 / sec

import * as ffi from 'ffi-napi'

const kernel = ffi.Library('Kernel32.dll', {
  'OpenProcess': [ 'uint', [ 'uint', 'byte', 'uint' ]],
  'ReadProcessMemory': [ 'uint', ['uint', 'uint64', 'uint64', 'uint', 'uint']],
  'WriteProcessMemory': [ 'uint', ['uint', 'uint64', 'uint64', 'uint', 'uint']],
})

const pHandle = kernel.OpenProcess(0x0010 | 0x0020 | 0x0008, 0, 18688)

function readDouble () {
  const outBuffer = Buffer.allocUnsafe(0x8)
  kernel.ReadProcessMemory(pHandle, 0x275AC4A0, outBuffer.address(), outBuffer.byteLength, 0)
  return outBuffer.readDoubleLE()
}

function writeDouble (num: number) {
  const outBuffer = Buffer.alloc(0x8)
  outBuffer.writeDoubleLE(num)
  kernel.WriteProcessMemory(pHandle, 0x275AC4A0, outBuffer.address(), outBuffer.byteLength, 0)
}

function readDoubleAsync () {
  const outBuffer = Buffer.allocUnsafe(0x8)
  return new Promise<number>((resolve, reject) => {
    kernel.ReadProcessMemory.async(pHandle, 0x275AC4A0, outBuffer.address(), outBuffer.byteLength, 0, (err) => {
      if (err) return reject(err)
      resolve(outBuffer.readDoubleLE())
    })
  })
}

function writeDoubleAsync (num: number) {
  const outBuffer = Buffer.alloc(0x8)
  outBuffer.writeDoubleLE(num)
  return new Promise((resolve, reject) => {
    kernel.WriteProcessMemory.async(pHandle, 0x275AC4A0, outBuffer.address(), outBuffer.byteLength, 0, (err, res) => {
      if (err) return reject(err)
      resolve(res)
    })
  })
}

async function test () {
  let time = Date.now() + 1000
  let index = 0
  for (; time >= Date.now(); index++) writeDouble(index)
  console.log('write', index, '/ sec')

  time = Date.now() + 1000
  index = 0
  for (; time >= Date.now(); index++) void readDouble()
  console.log('read', index, '/ sec')

  time = Date.now() + 1000
  index = 0
  for (; time >= Date.now(); index++) await writeDoubleAsync(index)
  console.log('write async', index, '/ sec')

  time = Date.now() + 1000
  index = 0
  for (; time >= Date.now(); index++) void await readDoubleAsync()
  console.log('read async', index, '/ sec')
}

test()