myAOBInjectionTemplates = {} myAOBInjectionTemplates.Templates = { { displayName="Alternative AOB", templateSections= [==[ <> // Game : %processName% // Version: // Date : // Author : %authorName% <> <> aobscan%isModuleScan%(aob_%cheatName%,%moduleNameC%%searchPattern%) registersymbol(aob_%cheatName%) alloc(newmem_%cheatName%,1024%CmoduleName%) label(return_%cheatName%) newmem_%cheatName%: %_originalCodeLines% jmp return_%cheatName% aob_%cheatName%%aobAdjust%: jmp newmem_%cheatName% %_nopLines% return_%cheatName%: <> <> aob_%cheatName%%aobAdjust%: db %originalBytes% unregistersymbol(aob_%cheatName%) dealloc(newmem_%cheatName%) %additionalInfo% <> ]==] }, { displayName="Alternative AOB with bracketsRegsOffset", templateSections= [==[ <> // Game : %processName% // Version: // Date : // Author : %authorName% <> <> aobscan%isModuleScan%(aob_%cheatName%,%moduleNameC%%searchPattern%) registersymbol(aob_%cheatName%) alloc(newmem_%cheatName%,1024%CmoduleName%) label(return_%cheatName%) label(set_%cheatName%) label(quit_%cheatName%) newmem_%cheatName%: jmp quit_%cheatName% set_%cheatName%: mov %bracketsRegsOffset%,0 //jmp quit_%cheatName% quit_%cheatName%: %_originalCodeLines% jmp return_%cheatName% aob_%cheatName%%aobAdjust%: jmp newmem_%cheatName% %_nopLines% return_%cheatName%: <> <> aob_%cheatName%%aobAdjust%: db %originalBytes% unregistersymbol(aob_%cheatName%) dealloc(newmem_%cheatName%) %additionalInfo% <> ]==] }, { displayName="Alternative AOB with Stealth", templateSections= [==[ <> // Game : %processName% // Version: // Date : // Author : %authorName% <> <> aobscan%isModuleScan%(aob_%cheatName%,%moduleNameC%%searchPattern%) stealtheditex(See_%cheatName%,aob_%cheatName%%aobAdjust%,3) label(SeeReg_%cheatName%) registersymbol(SeeReg_%cheatName%) alloc(newmem_%cheatName%,1024%CmoduleName%) label(return_%cheatName%) newmem_%cheatName%: %_originalCodeLines% jmp return_%cheatName% See_%cheatName%: SeeReg_%cheatName%: jmp newmem_%cheatName% %_nopLines% return_%cheatName%: <> <> SeeReg_%cheatName%: db %originalBytes% unregistersymbol(SeeReg_%cheatName%) dealloc(newmem_%cheatName%) %additionalInfo% <> ]==] }, { displayName="predprey's Mono Inject", templateSections= [==[ <> // Game : %processName% // Version: // Date : // Author : %authorName% <> <> alloc(newmem_%cheatName%,1024%CmoduleName%) label(%cheatName%) registersymbol(%cheatName%) label(return_%cheatName%) newmem_%cheatName%: %_originalCodeLines% jmp return_%cheatName% %monoAddress%: %cheatName%: jmp newmem_%cheatName% %_nopLines% return_%cheatName%: <> <> %cheatName%: db %originalBytes% unregistersymbol(%cheatName%) dealloc(newmem_%cheatName%) %additionalInfo% <> ]==] }, { displayName="Csimbi's AOB", templateSections= [==[ <> // Game : %processName% // Version: // Date : // Author : %authorName% <> <> aobscan%isModuleScan%(aob%cheatName%,%moduleNameC%%searchPattern%) alloc(newmem%cheatName%,4096%CmoduleName%) label(%cheatName%_r) label(%cheatName%_i) registersymbol(%cheatName%_r) registersymbol(%cheatName%_i) label(lbl%cheatName%) label(lbl%cheatName%Skip) label(lbl%cheatName%Ret) label(bEnable%cheatName%) registersymbol(bEnable%cheatName%) newmem%cheatName%: bEnable%cheatName%: dd 1 lbl%cheatName%: %CoriginalCodeLines% //db %originalBytes% %reassembleReplacedInstructions(aob%cheatName%%aobAdjust%)% cmp dword ptr [bEnable%cheatName%],1 jne short lbl%cheatName%Skip // Place your code here lbl%cheatName%Skip: jmp lbl%cheatName%Ret %cheatName%_i: readmem(aob%cheatName%%aobAdjust%,%replacedInstructionsSize%) //%injectAddress%: aob%cheatName%%aobAdjust%: %cheatName%_r: jmp lbl%cheatName% %nopLines% lbl%cheatName%Ret: <> <> //%injectAddress%: %CoriginalCodeLines% //db %originalBytes% %cheatName%_r: readmem(%cheatName%_i,%replacedInstructionsSize%) unregistersymbol(%cheatName%_r) unregistersymbol(%cheatName%_i) unregistersymbol(bEnable%cheatName%) dealloc(newmem%cheatName%) %additionalInfo% <> ]==] }, } function myAOBInjectionTemplates.formCreateNotify(form) if form.ClassName~="TfrmAutoInject" then return end local timer=createTimer() timer.Interval=100 timer.OnTimer = function (t) if (form.Menu==nil) then return end t.destroy() myAOBInjectionTemplates.addMenuEntries(form) end end function myAOBInjectionTemplates.addMenuEntries(form) local m,mi=form.emplate1,nil for i=1,#myAOBInjectionTemplates.Templates do mi = createMenuItem(m); m.add(mi) mi.OnClick = function (sender) myAOBInjectionTemplates.generate(sender,myAOBInjectionTemplates.Templates[i].templateSections) end mi.Caption = myAOBInjectionTemplates.Templates[i].displayName mi.Name = 'miAlternativeAOBtemplate'..i end end registerFormAddNotification(myAOBInjectionTemplates.formCreateNotify) function myAOBInjectionTemplates.generate(sender,template) local form=sender.Owner.Owner local origScript = form.Assemblescreen.Lines.Text form.Assemblescreen.Lines.Text = '' -- clear form.menuAOBInjection.doClick() -- generate generic script processMessages() local newScript = form.Assemblescreen.Lines.Text form.Assemblescreen.Lines.Text = origScript -- restore if newScript=='' then return end -- note: 'origScript' and 'newScript' will have "carriage return & line feed" at the end of each line -- because it is taken from TSynEdit object -- 'template' has only "line feed" -- it succeeded ? if newScript:match('No Process Selected') or newScript:match('Could not find unique AOB') then showMessage("No process selected or could not find unique AOB!") return end --start parsing generated generic script local cheatName = newScript:match('registersymbol%((.-)%)') local cheatName2 = cheatName --user can still revert by clicking cancel in "type name" window if cheatName=='INJECTION_POINT' then return end --gather existing names from origScript from registersymbol existingNames = {} for existingName in origScript:gmatch('registersymbol%(%s*(.-)%s*%)') do existingNames[1+#existingNames] = existingName end -- also from define for existingName in origScript:gmatch('define%(%s*(.-)%s*,') do existingNames[1+#existingNames] = existingName end local function checkForCollides(str,tab) for i,v in ipairs(tab) do if v:find(str, 1, true)~=nil then return 'Name "'..str..'" collides with existing "'..v..'"' end if str:find(v, 1, true)~=nil then return 'Existing "'..v..'" collides with name "'..str..'"' end end return nil end --do not allow default name or those already existing/colliding or empty ::setValidname:: while cheatName:lower()=='test' or cheatName=='INJECT' or cheatName=='' do cheatName=inputQuery('Caution!', 'Ugly name. Change it.', cheatName) or '' cheatName=cheatName:gsub('%s','') -- remove spaces end -- check if already exist or collides with each other local collides = checkForCollides(cheatName,existingNames) if collides~=nil then cheatName=inputQuery('Caution!', collides..'. Change it.', cheatName) or '' cheatName=cheatName:gsub('%s','') -- remove spaces goto setValidname end local authorName = newScript:match('Author : (.-)\r\n') local processName = newScript:match('Game : (.-)\r\n') local isModuleScan = newScript:match('aobscan(module)') or '' local searchPattern = newScript:match('aobscan.-%(.*,(.-)%).-should be unique') local moduleName, moduleName_comma, comma_moduleName if isModuleScan=='module' then moduleName = newScript:match('aobscan.-%('..cheatName2..',(.-),') moduleName_comma = moduleName..',' comma_moduleName = ','..moduleName else moduleName = '' moduleName_comma = '' comma_moduleName = '' end local _originalCodeLines = newScript:match('code:..(.-).. jmp return') local aobAdjust = newScript:match('code:.-'..cheatName2..'(.-):') local _nopLines = newScript:match(' jmp code..(.-)..return:') or '' if _nopLines=='' then -- other case _nopLines = newScript:match(' jmp newmem..(.-)..return:') or '' end local originalBytes = newScript:match(' db (.-)\r\n') local additionalInfo = newScript:match('...// ORIGINAL CODE %- INJECTION POINT.*') local origfirstLine = (_originalCodeLines..'\r\n'):match( "(.-)\r\n" ) local bracketsRegsOffset = origfirstLine:match('[dq]?word ptr %[.-%]') or origfirstLine:match('byte ptr %[.-%]') or origfirstLine:match('%[.-%]') or '' local regsOffset = origfirstLine:match('%[(.-)%]') or '' local originalCodeLines = _originalCodeLines:sub(3):gsub('\r\n ','\r\n') -- indent less version local nopLines = _nopLines=='' and '' or _nopLines:sub(3):gsub('\r\n ','\r\n') -- indent less version local db90s = _nopLines=='' and '' or 'db'..(nopLines..'\r\n'):gsub('nop\r\n',' 90') local CoriginalCodeLines = '//Alt: '.._originalCodeLines:sub(3):gsub('\r\n ','\r\n//Alt: ')-- commented version local replacedInstructionsSize = 5 -- replacedInstructionsSize = jumpSize + NopCount; jumpSize is 5 db90s:gsub(' 90',function (c) replacedInstructionsSize=replacedInstructionsSize+1 end) -- number of NOPs --Mono & Hook Address local injectAddress = newScript:match('INJECTING HERE %-%-%-%-%-%-%-%-%-%-\r\n(.-):') local injectAddressNum = getAddress(injectAddress) local monoAddress = '' if template:find('%%monoAddress%%') then -- remove lag for templates without mono if LaunchMonoDataCollector~=nil and LaunchMonoDataCollector()~=0 then monoAddress = mono_addressLookupCallback(injectAddressNum) or '' end end --reassembleReplacedInstructions local tmp = getInstructionSize(injectAddressNum) local reassembleReplacedInstructions = 'reassemble(~)' while tmp < replacedInstructionsSize do reassembleReplacedInstructions = reassembleReplacedInstructions .. '\nreassemble(~+'..string.format('%X',tmp)..')' tmp = tmp + getInstructionSize(injectAddressNum+tmp) end -- use the template template = template:gsub('%%cheatName%%', cheatName) template = template:gsub('%%authorName%%', authorName) template = template:gsub('%%processName%%', processName) template = template:gsub('%%isModuleScan%%', isModuleScan) template = template:gsub('%%searchPattern%%', searchPattern) template = template:gsub('%%CmoduleName%%', comma_moduleName) template = template:gsub('%%moduleNameC%%', moduleName_comma) template = template:gsub('%%moduleName%%', moduleName) template = template:gsub('%%replacedInstructionsSize%%', replacedInstructionsSize) template = template:gsub('%%_originalCodeLines%%', _originalCodeLines) template = template:gsub('%%originalCodeLines%%', originalCodeLines) template = template:gsub('%%CoriginalCodeLines%%', CoriginalCodeLines) template = template:gsub('%%originalBytes%%', originalBytes) template = template:gsub('%%aobAdjust%%', aobAdjust) template = template:gsub('%%additionalInfo%%', additionalInfo) template = template:gsub('%%bracketsRegsOffset%%', bracketsRegsOffset) template = template:gsub('%%regsOffset%%', regsOffset) template = template:gsub('%%injectAddress%%', injectAddress) template = template:gsub('%%monoAddress%%', monoAddress) template = template:gsub('%%reassembleReplacedInstructions%((.-)%)%%', function (a) return reassembleReplacedInstructions:gsub('~',a) end) if db90s~='' then template = template:gsub('%%nopLines%%', nopLines) template = template:gsub('%%_nopLines%%', _nopLines) template = template:gsub('%%db90s%%', db90s) else -- remove whole line when NOP'ing is not needed template = template:gsub('%%nopLines%%.-\n', '') template = template:gsub('%%_nopLines%%.-\n', '') template = template:gsub('%%db90s%%.-\n', '') end local enablePart = template:match('<>.(.*).<>') local disablePart = template:match('<>.(.*).<>') local infoPart = template:match('<>.(.*).<>') if origScript=='\r\n' then origScript='' end --after manually deleting all lines, there's always one empty line local pos=origScript:find('%[DISABLE]') if pos then newScript=origScript:sub(1,pos-1)..'\r\n'..enablePart..'\r\n'..origScript:sub(pos)..'\r\n'..disablePart else newScript=origScript..'[ENABLE]\r\n'..enablePart..'\r\n[DISABLE]\r\n'..disablePart end if pos==nil and infoPart~=nil then newScript=infoPart..'\r\n'..newScript end form.Assemblescreen.Lines.Text = newScript -- update end