This is a simple signature generator and scanner. Put the file in the "autorun" folder. And when using the CE memory view form there will be a new menu item "Generate signature and scan for matches" (with the shortcut "Ctrl+Shift+B"). It really just removes hardcoded address and 4 byte offsets. It will use an AOB module scan if the selected lines (instruction addresses) exist within a module, else it will just use AOB scan.
You can then select the lines you want the signature to consist of (minimum of 8 bytes is required) and press "Ctrl+Shift+B" you get an output like this:
Code: Select all
--------------------------------------------------------------------------------
Scanning process: Tutorial-x86_64.exe
Using signature:
488B8Bxxxxxxxx31D2488B83xxxxxxxx488B00
Signature addresses:
Start: Tutorial-x86_64.exe+2B327
end: Tutorial-x86_64.exe+2B337
Scanning module: Tutorial-x86_64.exe
Matches Found: 7
Tutorial-x86_64.exe+2B327 <---- Start address
Tutorial-x86_64.exe+2B706
Tutorial-x86_64.exe+2BF5D
Tutorial-x86_64.exe+2D832
Tutorial-x86_64.exe+2E079
Tutorial-x86_64.exe+F1ECB
Tutorial-x86_64.exe+F4E90
Code: Select all
--------------------------------------------------------------------------------
Scanning process: Tutorial-x86_64.exe
Using signature:
488B8Bxxxxxxxx31D2488B83xxxxxxxx488B00FF90xxxxxxxxC783F0070000
Signature addresses:
Start: Tutorial-x86_64.exe+2B327
end: Tutorial-x86_64.exe+2B340
Scanning module: Tutorial-x86_64.exe
Matches Found: 1
Tutorial-x86_64.exe+2B327 <---- Start address
Code: Select all
--------------------------------------------------------------------------------
Scanning process: Tutorial-x86_64.exe
Using signature:
488B83xxxxxxxx488B00
Signature addresses:
Start: Tutorial-x86_64.exe+2B3D7
end: Tutorial-x86_64.exe+2B3DE
Scanning module: Tutorial-x86_64.exe
Matches Found: 39
Code: Select all
local WildCard = 'x'
local MinamumBytes = 8
local MaxResultsPrinted = 20
local MenuItemCaption = translate('Generate signature and scan for matches')
local MenuItemShortcut = 'Ctrl+Shift+B'
local CopySignatureToClipboard = false -- true
local AOBScanModule
local status = pcall(require, 'I2CETLua.functions')
if not status then
AOBScanModule = function(moduleName, signature, aobSignaturePrivileges, alignmentType, alignmentParam)
if not moduleName then return end
if not signature then return end
index = index or 1
local modStartAddr = getAddress(moduleName)
local modEndAddr = modStartAddr + getModuleSize(moduleName)
local ms = createMemScan()
if type(signature) == 'table' then
local sig = ''
for i, byte in ipairs(signature) do
sig = sig..string.format('%02X', byte)
end
signature = sig
end
ms.firstScan(soExactValue, vtByteArray, nil, signature, nil, modStartAddr, modEndAddr,
aobSignaturePrivileges, alignmentType, alignmentParam, true, true, false, false)
ms.waitTillDone()
local results = createFoundList(ms)
results.initialize()
ms.destroy()
return results
end
else
AOBScanModule = _G['AOBScanModule']
end
local function generateSignature()
local disassemblerView = getVisibleDisassembler()
local dv_address1 = getMemoryViewForm().DisassemblerView.SelectedAddress
local dv_address2 = getMemoryViewForm().DisassemblerView.SelectedAddress2
local startAddress = math.min(dv_address1, dv_address2)
local endAddress = math.max(dv_address1, dv_address2)
local length = endAddress + getInstructionSize(endAddress) - startAddress
local position = startAddress
local signature = ''
while position < endAddress + getInstructionSize(endAddress) do
local instLength = getInstructionSize(position)
local disStr
synchronize(function()
disStr = disassemblerView.disassemble(position)
end)
local _, _, bytes, _ = splitDisassembledString(disStr)
bytes = bytes:gsub(string.rep('%x', 8)..'%s*$', string.rep(WildCard, 8)):gsub(' ', '')
signature = signature..bytes
position = position + instLength
end
return signature:gsub(WildCard..'*$', '')
end
local function checkAob()
local dv_address1 = getMemoryViewForm().DisassemblerView.SelectedAddress
local dv_address2 = getMemoryViewForm().DisassemblerView.SelectedAddress2
local startAddress = math.min(dv_address1, dv_address2)
local endAddress = math.max(dv_address1, dv_address2)
local length = endAddress + getInstructionSize(endAddress) - startAddress
print(string.rep('-', 80))
if length < MinamumBytes then
print(string.format(translate('You must select more then %d bytes'), MinamumBytes))
return
end
local moduleName
if inModule(startAddress) and inModule(endAddress) then
moduleName = getNameFromAddress(startAddress)
moduleName = moduleName:match('^(.*)[+-]%x*$')
end
local results
local signature = generateSignature()
print(translate('Scanning process')..': '..process)
print('\t'..translate('Using signature')..':')
print('\t\t'..signature)
print('\t'..translate('Signature addresses')..':')
print('\t\t'..translate('Start')..': '..getNameFromAddress(startAddress))
print('\t\t'..translate('end')..': '..getNameFromAddress(endAddress))
if moduleName then
print(translate('\tScanning module: '..moduleName))
results = AOBScanModule(moduleName, signature)
else
results = AOBScan(signature)
end
if results then
if CopySignatureToClipboard then writeToClipboard(signature) end
print(string.format('\t'..translate('Matches Found')..': %d', results.Count))
if results.Count < MaxResultsPrinted then
for i = 0, results.Count - 1 do
if tonumber(results[i], 16) == startAddress then
print('\t\t'..getNameFromAddress(results[i])..
' <---- '..translate('Start address'))
else
print('\t\t'..getNameFromAddress(results[i]))
end
end
end
else
print(translate('Error scanning AOB'))
end
end
local function run()
createThread(function(thread)
checkAob()
thread.terminate()
end)
end
local function addMenuItem()
local popupmenu = getMemoryViewForm().DisassemblerView.PopupMenu
mi = createMenuItem(popupmenu)
mi.Caption = '-'
popupmenu.Items.add(mi)
mi = createMenuItem(popupmenu)
mi.Caption = MenuItemCaption
mi.onClick = run
mi.Shortcut = MenuItemShortcut
popupmenu.Items.add(mi)
end
addMenuItem()