-- AOBScanNot('XX XX XX !YY XX XX !ZZ XX'); -- AOBScanNot('XX XX XX !YY XX XX !AA!BB!CC!DD ... XX'); function AOBScanNot(aob) -- only string if (type(aob) == 'string') then aob = aob:gsub('[^%x%!%s%?]+',''):gsub('%s+',' '); -- clean up and remove exceesive space local NotOffset,NotOffsetSize,byteNum = {},0,0; for byte in aob:gmatch('%S+') do byteNum = byteNum+1; -- total bytes if (byte:match('!')) then NotOffset[byteNum] = {}; NotOffsetSize = NotOffsetSize + 1; for NotByte in byte:gmatch('[^!]+%x+') do -- incase some genius would want to do xx|yy|?? table.insert(NotOffset[byteNum],tonumber(NotByte,16)); end end end local newAob = aob:gsub('!%x+','??'):gsub('%?+','??'); local aobs = AOBScan(newAob) -- get rid of the 'Not' bytes if (aobs) then for i=0,aobs.Count-1 do local address = aobs.getString(i); local bytes,matchCount = readBytes(address,byteNum,true); -- better than multiple readBytes; local isValid = true; for offset,NotBytes in pairs(NotOffset) do for _,byte in pairs(NotBytes) do if (byte == bytes[offset]) then print('found bad byte:',byte); isValid = false break; end end if (not isValid) then break; end end if (isValid) then aobs.destroy(); return address end end aobs.destroy(); end end end registerAutoAssemblerCommand('aobscanNot',function(line) local name,bytes = line:match('([^,]+),(.+)'); local address = AOBScanNot(bytes); return ('define(%s,%s)'):format(name,address); end)