Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Hotkey DBVM

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
titomane
How do I cheat?
Reputation: 0

Joined: 03 Nov 2023
Posts: 6

PostPosted: Sun Aug 31, 2025 5:08 pm    Post subject: Hotkey DBVM Reply with quote

Hi


Im trying to create a Lua script that execute DBVM "Find out what writes to this address" at specific address with a hotkey "F7" Then print 4 addresses with highest count value

Is this posible with lua script? because when I execute my script print DBVM isnt load or available in this version, If I do right-click and click DBVM "Find out what writes to this address" with default options:
Lock page checked
Log FPU data unchecked
Log stack unchecked
Max Buffer 32
works flawless.

CE version 7.4.1



My script


Code:
-- === CONFIGURACIÓN ===
local instruction_address = 0x7FF63DB10258   -- Dirección de la instrucción que accede memoria
local access_type = 2                   -- 0 = execute, 1 = write, 2 = read/write
local trace_duration_ms = 2000          -- Tiempo de trazado en milisegundos
local hotkey = VK_F7                    -- Tecla para iniciar el tracking

-- === VARIABLES ===
local dbvm_bp_id = nil
local access_log = {}

-- Callback: se llama cada vez que la instrucción accede a memoria
function onMemoryAccess(bp_id, accessed_from, accessed_address)
  if accessed_address then
    if access_log[accessed_address] then
      access_log[accessed_address] = access_log[accessed_address] + 1
    else
      access_log[accessed_address] = 1
    end
  end
end

-- Inicia el tracking DBVM
function startDBVMTrace()
  if dbvm_bp_id then
    print("[CE Lua] Ya hay un breakpoint activo.")
    return
  end

  access_log = {}

  -- Coloca el breakpoint DBVM
  dbvm_bp_id = dbvm.watch_writes(instruction_address, 1, access_type, onMemoryAccess)

  if dbvm_bp_id == nil then
    print("[CE Lua] ERROR: No se pudo establecer el breakpoint DBVM.")
    return
  end

  print(string.format("[CE Lua] DBVM tracing iniciado en 0x%X durante %.1f segundos.", instruction_address, trace_duration_ms / 1000))

  -- Detiene el tracking después del tiempo definido
  local stop_timer = createTimer()
  stop_timer.Interval = trace_duration_ms
  stop_timer.OnTimer = function(t)
    t.destroy()
    stopDBVMTrace()
  end
end

-- Detiene el tracking y muestra resultados
function stopDBVMTrace()
  if dbvm_bp_id then
    dbvm.removeBreakpoint(dbvm_bp_id)
    dbvm_bp_id = nil
  end

  -- Ordena y muestra las direcciones accedidas
  local sorted = {}
  for addr, count in pairs(access_log) do
    table.insert(sorted, {addr = addr, count = count})
  end

  table.sort(sorted, function(a, b) return a.count > b.count end)

  print("\n=== RESULTADO DEL DBVM TRACING ===")
  for i, entry in ipairs(sorted) do
    print(string.format("[%02d] 0x%X - %d accesos", i, entry.addr, entry.count))
    if i >= 10 then break end
  end
end

-- Asigna la hotkey F7 para iniciar el tracing
createHotkey(startDBVMTrace, hotkey)
print("[CE Lua] Script cargado. Presiona F7 para iniciar tracing DBVM.")




Thanks in advance
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25765
Location: The netherlands

PostPosted: Sun Aug 31, 2025 5:50 pm    Post subject: Reply with quote

what is the exact issue you have with your script?

try running the code without hotkey and see if it works and the errors it gives

maybe it's your implementation of the 'dbvm' table which seems to have some functions defined but it's not part of CE. Read celua.txt for the documentation on dbvm
e.g it often needs the physical address so check of your wrapper function handles that properly

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
titomane
How do I cheat?
Reputation: 0

Joined: 03 Nov 2023
Posts: 6

PostPosted: Mon Sep 01, 2025 10:57 am    Post subject: Reply with quote

Thanks for answer

I explain bad, sorry english isnt my language Smile
When I said works manual I want to say
I open Memory viewer Ctrl + B
then Ctrl + G write address Enter
Then I do secondary click first line of memory viewer "41 89 90 80F7FFFF mov [r8-00000880]"]
And click on "DBVM find out what writes to this address"
In the next windows use default settings

Virtual Address=7FF7D51220258
Lock page checked
Log FPU data unchecked
Max Buffer 32

And click start watch and stop after 1-2 seconds

Then use 4 addresses with more counts.



Could I do that with lua script?

I tried that


Code:
local virtualAddress = 0x7FF634320258  -- Dirección que introduces manualmente (¡verifica!)
local watchDurationMs = 2000          -- Tiempo para observar (en milisegundos)
local internalEntryCount = 32         -- Máximo de registros internos
local watchOptions = 0                -- Opciones: 0 = sin FPU, sin stack, sin duplicados

-- Paso 1: Convertir dirección virtual a física
local physicalAddress = dbk_getPhysicalAddress(virtualAddress)
if not physicalAddress then
  print("❌ No se pudo obtener dirección física desde: " .. string.format("0x%X", virtualAddress))
  return
end
print("✔ Dirección física: " .. string.format("0x%X", physicalAddress))

-- Paso 2: Iniciar rastreo
local watchID = dbvm_watch_writes(physicalAddress, 4096, watchOptions, internalEntryCount)
if not watchID then
  print("❌ Falló dbvm_watch_writes.")
  return
end
print("⏳ Observando escritura por " .. (watchDurationMs/1000) .. " segundos...")

-- Paso 3: Esperar N milisegundos
sleep(watchDurationMs)

-- Paso 4: Detener rastreo
dbvm_watch_disable(watchID)

-- Paso 5: Recuperar resultados
local results = dbvm_watch_retrievelog(watchID)
if not results or #results == 0 then
  print("❌ No se encontraron accesos en el período.")
  return
end

print("✔ Se encontraron " .. #results .. " eventos. Procesando...")

-- Paso 6: Contar ocurrencias por RIP (instrucción ejecutora)
local ripCount = {}
for _, entry in ipairs(results) do
  local rip = entry.RIP
  ripCount[rip] = (ripCount[rip] or 0) + 1
end

-- Paso 7: Ordenar por cantidad de accesos
local sorted = {}
for rip, count in pairs(ripCount) do
  table.insert(sorted, {rip=rip, count=count})
end
table.sort(sorted, function(a, b) return a.count > b.count end)

-- Paso 8: Mostrar los 4 principales
print("📊 Top 4 instrucciones que escribieron a esa dirección:")
for i=1, math.min(4, #sorted) do
  local entry = sorted[i]
  print(string.format("[%d] RIP: 0x%X - Accesos: %d", i, entry.rip, entry.count))
end


But cant find addresses when execute script.

I tried this script but didnt find addresses

Code:
-- CONFIGURACIÓN
local symbol = 'game.desktop.x64.exe+1230258'
local offset = 0x880
local traceStepCount = 1
local watchDurationMs = 5000    -- Aumentado a 5 segundos
local internalEntryCount = 64   -- Buffer más grande
-- Usa opciones que incluyan registros FPU y duplicados, para no perder datos
local watchOptions = (1 << 0) + (1 << 2)  -- Opciones: permitir entradas duplicadas y log FPU

-- Obtener direcciones
local va = getAddressSafe(symbol)
local pa = dbk_getPhysicalAddress(va)
if not va or not pa then
  print('❌ Error al resolver direcciones.')
  return
end

print('Instrucción VA: 0x' .. string.format('%X', va) .. ' | PA: 0x' .. string.format('%X', pa))

-- Breakpoint oculto DBVM
if not dbvm_traceonbp(pa, traceStepCount, va, {logFPU=true, logStack=false}) then
  print('❌ Falló dbvm_traceonbp.')
  return
end
print('Esperando ejecución para capturar R8...')

-- Espera activa con timeout
local timeout = 12000 -- 12 segundos
local elapsed = 0
while elapsed < timeout do
  sleep(250); elapsed = elapsed + 250
  local status, count = dbvm_traceonbp_getstatus()
  if status == 3 and count > 0 then
    print('➡ Instrucción ejecutó, obteniendo log...')
    break
  end
end
if elapsed >= timeout then
  print('⏱ Timeout sin captura de instrucción.')
  dbvm_traceonbp_stoptrace()
  dbvm_traceonbp_remove(pa, true)
  return
end

-- Obtener R8
local entries = dbvm_traceonbp_retrievelog()
local r8 = entries[1].R8
local targetAddr = r8 - offset
print('R8: 0x' .. string.format('%X', r8) .. ', Dirección [R8-0x880]: 0x' .. string.format('%X', targetAddr))

-- Convertir y rastrear
local targetPA = dbk_getPhysicalAddress(targetAddr)
print('Dir física rastreable: 0x' .. string.format('%X', targetPA))

local watchID = dbvm_watch_writes(targetPA, 8, watchOptions, internalEntryCount)
print('Observando escrituras por ' .. (watchDurationMs/1000) .. ' segundos...')
sleep(watchDurationMs)
dbvm_watch_disable(watchID)

-- Recuperar resultados
local res = dbvm_watch_retrievelog(watchID)
if not res or #res == 0 then
  print('No se detectaron escrituras.')
else
  local ripCount = {}
  for _, e in ipairs(res) do
    ripCount[e.RIP] = (ripCount[e.RIP] or 0) + 1
  end
  local sorted = {}
  for rip, cnt in pairs(ripCount) do
    table.insert(sorted, {rip=rip, count=cnt})
  end
  table.sort(sorted, function(a,b) return a.count > b.count end)
  print('Top escrituras:')
  for i=1, math.min(4, #sorted) do
    print(string.format("[%d] RIP: 0x%X - %d veces", i, sorted[i].rip, sorted[i].count))
  end
end

dbvm_traceonbp_remove(pa, true)



Thanks
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites