 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
xxhehe Expert Cheater
Reputation: 0
Joined: 11 Mar 2015 Posts: 163
|
Posted: Sun Jun 28, 2026 4:32 am Post subject: Title: Unknown scan returns 0 in multi‑segment cus |
|
|
'm writing a Lua script for VBA‑M that scans multiple memory segments (some valid only in GBC or GBA mode). Exact value scan works, but unknown initial value scan (soUnknownValue) always returns 0 results – even though the same segments contain valid data (confirmed by exact scan).
What I tried:
ms.firstScan() with full parameters (soUnknownValue, vtByte, …)
ms.scan() with ScanOption = soUnknownValue
using FoundList (createFoundList + initialize)
protection flags set to "" or "*X*C*W"
removing any ScanValue assignment
Segments resolve correctly (base addresses print), and exact scan yields hundreds of matches. Unknown scan still outputs "Total matches found (unknown): 0". Same behavior for Byte, Word, Dword, etc.
CE 7.7 , target is VBA‑M 32‑bit on Windows 10.
I suspect a known limitation when scanning non‑contiguous regions, or I need to call something after firstScan. Any concrete hints would help.
Simplified script (key parts):
[firstScanUnknown function and relevant setup]
| Code: | -------------------------------------------------------------------------------
-- 首次扫描(精确)
-------------------------------------------------------------------------------
function firstScanExact()
lastResults = {}
lastVarType = nil
lastScanType = "exact"
print("Starting new EXACT first scan...")
-- 选择数据类型
local typeCode = inputQuery("选择数据类型",
"请输入数据类型代号:\n1=字节 2=2字节 3=4字节 4=8字节\n5=浮点 6=双精度 7=字符串", "1")
if typeCode == nil then print("Cancelled.") return end
typeCode = tonumber(typeCode)
local varType
if typeCode == 1 then varType = vtByte
elseif typeCode == 2 then varType = vtWord
elseif typeCode == 3 then varType = vtDword
elseif typeCode == 4 then varType = vtQword
elseif typeCode == 5 then varType = vtSingle
elseif typeCode == 6 then varType = vtDouble
elseif typeCode == 7 then varType = vtString
else varType = vtByte end
lastVarType = varType
print("Using type: " .. tostring(varType))
local val = inputQuery("首次搜索", "请输入要搜索的数值(十进制):", "0")
if val == nil then print("Cancelled.") return end
local validSegments = getValidSegments()
if #validSegments == 0 then print("No valid segments.") return end
local allResults = {}
for _, segInfo in ipairs(validSegments) do
local startAddr = segInfo.base
local stopAddr = startAddr + segInfo.size
print(string.format("Scanning: 0x%X - 0x%X", startAddr, stopAddr))
local ms = createMemScan()
ms.ScanOption = soExactValue
ms.VarType = varType
ms.ScanValue = val
ms.Hexadecimal = false
ms.ScanWritable = 'scanDontCare'
ms.ScanExecutable = 'scanDontCare'
ms.ScanCopyOnWrite = 'scanDontCare'
ms.StartAddress = startAddr
ms.StopAddress = stopAddr
ms.firstScan()
ms.waitTillDone()
local results = ms.Results
if results then
for _, addr in ipairs(results) do
local currentVal = readValueAt(addr, varType)
if currentVal ~= nil then
addResultUnique(allResults, addr, currentVal)
end
end
end
ms.destroy()
end
lastResults = allResults
print(string.format("Total matches found: %d", #lastResults))
printResults(allResults)
if ADD_TO_LIST then addToAddressList(allResults) end
end
-------------------------------------------------------------------------------
-- 首次扫描(模糊 - 未知初始值)
-------------------------------------------------------------------------------
function firstScanUnknown()
lastResults = {}
lastVarType = nil
lastScanType = "unknown"
print("Starting UNKNOWN first scan...")
-- 选择数据类型
local typeCode = inputQuery("选择数据类型",
"请输入数据类型代号:\n1=字节 2=2字节 3=4字节 4=8字节\n5=浮点 6=双精度 7=字符串", "1")
if typeCode == nil then print("Cancelled.") return end
typeCode = tonumber(typeCode)
local varType
if typeCode == 1 then varType = vtByte
elseif typeCode == 2 then varType = vtWord
elseif typeCode == 3 then varType = vtDword
elseif typeCode == 4 then varType = vtQword
elseif typeCode == 5 then varType = vtSingle
elseif typeCode == 6 then varType = vtDouble
elseif typeCode == 7 then varType = vtString
else varType = vtByte end
lastVarType = varType
print("Using type: " .. tostring(varType))
local validSegments = getValidSegments()
if #validSegments == 0 then print("No valid segments.") return end
local allResults = {}
for _, segInfo in ipairs(validSegments) do
local startAddr = segInfo.base
local stopAddr = startAddr + segInfo.size
print(string.format("Scanning (unknown): 0x%X - 0x%X", startAddr, stopAddr))
local ms = createMemScan()
ms.ScanOption = soUnknownValue -- 未知初始值
ms.VarType = varType
-- 未知初始值不需要 ScanValue,不设置或设为空字符串均可
ms.ScanValue = "" -- 设为空字符串,CE 会忽略
ms.Hexadecimal = false
ms.ScanWritable = 'scanDontCare'
ms.ScanExecutable = 'scanDontCare'
ms.ScanCopyOnWrite = 'scanDontCare'
ms.StartAddress = startAddr
ms.StopAddress = stopAddr
ms.firstScan() -- 统一使用 firstScan()
ms.waitTillDone()
local results = ms.Results
if results then
for _, addr in ipairs(results) do
local currentVal = readValueAt(addr, varType)
if currentVal ~= nil then
addResultUnique(allResults, addr, currentVal)
end
end
end
ms.destroy()
end
lastResults = allResults
print(string.format("Total matches found (unknown): %d", #lastResults))
printResults(allResults)
if ADD_TO_LIST then addToAddressList(allResults) end
end
-------------------------------------------------------------------------------
-- 再次扫描(根据上次扫描类型自动适配)
-------------------------------------------------------------------------------
function nextScan()
if not lastResults or #lastResults == 0 then
print("No previous results. Please do a first scan first.")
return
end
if not lastVarType then
print("Unknown data type. Please do a first scan first.")
return
end
local isString = (lastVarType == vtString)
-- 根据上次扫描类型决定再次扫描的选项
local conditionOptions
if lastScanType == "exact" then
conditionOptions = {"等于", "不等于", "大于", "小于", "增大了", "减小了", "变化了", "未变化"}
else -- "unknown"
conditionOptions = {"增大了", "减小了", "变化了", "未变化"}
end
local condListStr = ""
for i, opt in ipairs(conditionOptions) do
condListStr = condListStr .. i .. "=" .. opt .. " "
end
local condCode = inputQuery("选择比较条件",
"请输入条件代号:\n" .. condListStr, "1")
if condCode == nil then print("Cancelled.") return end
condCode = tonumber(condCode)
if condCode < 1 or condCode > #conditionOptions then
print("Invalid condition, using 1")
condCode = 1
end
local compareType = conditionOptions[condCode]
print("Using condition: " .. compareType)
local compareVal = nil
-- 只有“等于/不等于/大于/小于”需要输入数值
if compareType == "等于" or compareType == "不等于" or compareType == "大于" or compareType == "小于" then
local val = inputQuery("再次搜索", "请输入要比较的数值(十进制):", "0")
if val == nil then print("Cancelled.") return end
compareVal = val
end
local newResults = {}
for _, entry in ipairs(lastResults) do
local currentVal = readValueAt(entry.addr, lastVarType)
if currentVal ~= nil then
if meetsExactCondition(currentVal, compareVal, compareType, entry.lastVal, isString) then
addResultUnique(newResults, entry.addr, currentVal) -- 去重
end
end
end
lastResults = newResults
print(string.format("After filtering, matches found: %d", #lastResults))
printResults(newResults)
if ADD_TO_LIST then addToAddressList(newResults) end
end |
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 475
Joined: 09 May 2003 Posts: 25973 Location: The netherlands
|
Posted: Sun Jun 28, 2026 5:16 am Post subject: |
|
|
soUnknownValue always returns 0 results. You must do a normal scan afterwards to get results (e.g. unchanged)
_________________
Tools give you results. Knowledge gives you control.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
xxhehe Expert Cheater
Reputation: 0
Joined: 11 Mar 2015 Posts: 163
|
Posted: Sun Jun 28, 2026 6:24 am Post subject: |
|
|
| Dark Byte wrote: | | soUnknownValue always returns 0 results. You must do a normal scan afterwards to get results (e.g. unchanged) |
Your hint — "soUnknownValue always returns 0. Do a normal scan afterwards" — fixed my problem. I'd been misusing soUnknownValue for a while.
Now I have a working multi‑segment fuzzy scanner for VBA‑M.
Thanks for Cheat Engine and the community support.
| Code: | -------------------------------------------------------------------------------
-- 首次扫描(精确)
-------------------------------------------------------------------------------
function firstScanExact()
lastResults = {}
lastVarType = nil
lastScanType = "exact"
print("Starting new EXACT first scan...")
local typeCode = inputQuery("选择数据类型",
"请输入数据类型代号:\n1=字节 2=2字节 3=4字节 4=8字节\n5=浮点 6=双精度 7=字符串", "1")
if typeCode == nil then print("Cancelled.") return end
typeCode = tonumber(typeCode)
local varType
if typeCode == 1 then varType = vtByte
elseif typeCode == 2 then varType = vtWord
elseif typeCode == 3 then varType = vtDword
elseif typeCode == 4 then varType = vtQword
elseif typeCode == 5 then varType = vtSingle
elseif typeCode == 6 then varType = vtDouble
elseif typeCode == 7 then varType = vtString
else varType = vtByte end
lastVarType = varType
print("Using type: " .. tostring(varType))
local val = inputQuery("首次搜索", "请输入要搜索的数值(十进制):", "0")
if val == nil then print("Cancelled.") return end
local validSegments = getValidSegments()
if #validSegments == 0 then print("No valid segments.") return end
local allResults = {}
local addrSet = {} -- 去重字典
for _, segInfo in ipairs(validSegments) do
local startAddr = segInfo.base
local stopAddr = startAddr + segInfo.size
print(string.format("Scanning: 0x%X - 0x%X", startAddr, stopAddr))
local ms = createMemScan()
ms.ScanOption = soExactValue
ms.VarType = varType
ms.ScanValue = val
ms.Hexadecimal = false
ms.ScanWritable = 'scanDontCare'
ms.ScanExecutable = 'scanDontCare'
ms.ScanCopyOnWrite = 'scanDontCare'
ms.StartAddress = startAddr
ms.StopAddress = stopAddr
ms.firstScan()
ms.waitTillDone()
local results = ms.Results
if results then
for _, addr in ipairs(results) do
if not addrSet[addr] then
local currentVal = readValueFast(addr, varType)
if currentVal ~= nil then
addrSet[addr] = true
table.insert(allResults, {addr = addr, lastVal = currentVal})
end
end
end
end
ms.destroy()
end
lastResults = allResults
print(string.format("Total matches found: %d", #lastResults))
printResults(allResults)
if ADD_TO_LIST then addToAddressList(allResults) end
end
-------------------------------------------------------------------------------
-- 首次扫描(模糊)
-------------------------------------------------------------------------------
function firstScanUnknown()
lastResults = {}
lastVarType = nil
lastScanType = "unknown"
print("Starting UNKNOWN first scan...")
local typeCode = inputQuery("选择数据类型",
"请输入数据类型代号:\n1=字节 2=2字节 3=4字节 4=8字节\n5=浮点 6=双精度 7=字符串", "1")
if typeCode == nil then print("Cancelled.") return end
typeCode = tonumber(typeCode)
local varType
if typeCode == 1 then varType = vtByte
elseif typeCode == 2 then varType = vtWord
elseif typeCode == 3 then varType = vtDword
elseif typeCode == 4 then varType = vtQword
elseif typeCode == 5 then varType = vtSingle
elseif typeCode == 6 then varType = vtDouble
elseif typeCode == 7 then varType = vtString
else varType = vtByte end
lastVarType = varType
print("Using type: " .. tostring(varType))
local validSegments = getValidSegments()
if #validSegments == 0 then print("No valid segments.") return end
local allResults = {}
local addrSet = {} -- 去重字典
for _, segInfo in ipairs(validSegments) do
local startAddr = segInfo.base
local stopAddr = startAddr + segInfo.size
print(string.format("Scanning unknown->unchanged: 0x%X - 0x%X", startAddr, stopAddr))
local ms = createMemScan()
-- 未知初始值
ms.firstScan(
soUnknownValue, varType, rtRounded,
nil, nil, startAddr, stopAddr,
"", -- 保护标志:空表示所有内存
fsmNotAligned, "",
false, false, false, false
)
ms.waitTillDone()
-- 未变化
ms.nextScan(
soUnchanged, rtRounded,
nil, nil,
false, false, false, false, false
)
ms.waitTillDone()
-- 读取结果
local fl = createFoundList(ms)
if fl then
fl.initialize()
local count = fl.Count
if count and count > 0 then
for i = 0, count - 1 do
local addrStr = fl.getAddress(i)
if addrStr then
local addr = tonumber(addrStr, 16)
if addr and not addrSet[addr] then
local val = readValueFast(addr, varType)
if val ~= nil then
addrSet[addr] = true
table.insert(allResults, {addr = addr, lastVal = val})
end
end
end
if i % 1000 == 0 then processMessages() end
end
end
fl.deinitialize()
fl.destroy()
end
ms.destroy()
end
lastResults = allResults
print(string.format("Total matches found (unknown->unchanged): %d", #lastResults))
printResults(allResults)
if ADD_TO_LIST then addToAddressList(allResults) end
end
-------------------------------------------------------------------------------
-- 再次扫描(通用)
-------------------------------------------------------------------------------
function nextScan()
if not lastResults or #lastResults == 0 then
print("No previous results. Please do a first scan first.")
return
end
if not lastVarType then
print("Unknown data type. Please do a first scan first.")
return
end
local isString = (lastVarType == vtString)
local conditionOptions
if lastScanType == "exact" then
conditionOptions = {"等于", "不等于", "大于", "小于", "增大了", "减小了", "变化了", "未变化"}
else
conditionOptions = {"增大了", "减小了", "变化了", "未变化"}
end
local condListStr = ""
for i, opt in ipairs(conditionOptions) do
condListStr = condListStr .. i .. "=" .. opt .. " "
end
local condCode = inputQuery("选择比较条件",
"请输入条件代号:\n" .. condListStr, "1")
if condCode == nil then print("Cancelled.") return end
condCode = tonumber(condCode)
if condCode < 1 or condCode > #conditionOptions then
print("Invalid condition, using 1")
condCode = 1
end
local compareType = conditionOptions[condCode]
print("Using condition: " .. compareType)
local compareVal = nil
if compareType == "等于" or compareType == "不等于" or compareType == "大于" or compareType == "小于" then
local val = inputQuery("再次搜索", "请输入要比较的数值(十进制):", "0")
if val == nil then print("Cancelled.") return end
compareVal = val
end
local newResults = {}
local addrSet = {} -- 确保新结果也去重(虽然理论上不会重复,但安全起见)
for _, entry in ipairs(lastResults) do
local currentVal = readValueFast(entry.addr, lastVarType)
if currentVal ~= nil and not addrSet[entry.addr] then
if meetsCondition(currentVal, compareVal, compareType, entry.lastVal, isString) then
addrSet[entry.addr] = true
table.insert(newResults, {addr = entry.addr, lastVal = currentVal})
end
end
end
lastResults = newResults
print(string.format("After filtering, matches found: %d", #lastResults))
printResults(newResults)
if ADD_TO_LIST then addToAddressList(newResults) end
end
|
|
|
| Back to top |
|
 |
|
|
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
|
|