CELua[RU]
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы
    • Зарегистрироваться
    • Войти

    Ветвления кода связанные с адресом (старые записи)

    Запланировано Прикреплена Закрыта Перенесена MasterGH
    2 Сообщения 1 Posters 61 Просмотры 1 Watching
    Загружаем больше сообщений
    • Сначала старые
    • Сначала новые
    • По количеству голосов
    Ответить
    • Ответить, создав новую тему
    Авторизуйтесь, чтобы ответить
    Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
    • MasterGHM В сети
      MasterGH Администраторы
      отредактировано

      В этой записи блога не будет чего-то, что показало бы "вау, это что-то новое и есть результат". Все сырое и результат пока мне только снится — быстрый поиск условий и включение, и выключение ветвей по этим условиям. Мыслю я не инструкциями, не группой инструкций, а ветвлениями кода и условиями, которые их запускают. Проще 20 ветвлений по 5 окон, чем тонна инструкций... Жаль пока теория, практики с результатом нет.

      Рисунок. На нем слева прототип, справа текущий сырой вариант

      1. ставим брейкпоинт на адрес патронов

      2. от него расплетаются ветви кода от каждого хита, от каждой инструкции, и по ретам ветвление выходит из рутины

      Кружи означают ret-ы. Клик на круг будет переходлм в дизассемблер

      Стрелки будут показывать входы и выход связанные с соседними рутинами (поиск общих адресов будет стрелками)

      e3ab56bb-c1a6-4626-bead-f41fbb327a0d-image.png
      На экране справа вариант без стрелок, т.к. не успел еще их отладить. 4 ветки трассера по ретам из рутины связанные с адресом патронов, выстрелами.

      Потом я продолжал стрелять, перезаряжаться, выкидывать и поднимать оружие. В итоге собрал 20 ветвлений по ретам от инструкций связанные с патронами

      07232118 - 8B 85 90060000  		- mov eax,[ebp+00000690]
      0721C03F - 0FB7 8E 90060000  	- movzx ecx,word ptr [esi+00000690]
      0722FE69 - 39 86 58030000 		- cmp [esi+00000358],eax
      0722FEA8 - 83 BE 58030000 00 	- cmp dword ptr [esi+00000358],00
      0721C4A0 - 0FB6 96 B0030000  	- movzx edx,byte ptr [esi+000003B0]
      0723155C - 83 BE B0030000 00 	- cmp dword ptr [esi+000003B0],00
      07230357 - 83 BE 90060000 00 	- cmp dword ptr [esi+00000690],00
      0721E00C - 8B BE 90060000  		- mov edi,[esi+00000690]
      0722330C - 01 BE 90060000  		- add [esi+00000690],edi
      0722FFC7 - 83 BE 58030000 00 	- cmp dword ptr [esi+00000358],00
      072306DF - 83 BE 90060000 00 	- cmp dword ptr [esi+00000690],00
      0722E808 - 8B 86 90060000  		- mov eax,[esi+00000690]
      07231150 - 8B 8E 90060000  		- mov ecx,[esi+00000690]
      07231186 - 83 86 90060000 01	- add dword ptr [esi+00000690],01
      072311D4 - 8B 86 90060000 		- mov eax,[esi+00000690]
      0723121A - 3B 96 90060000		- cmp edx,[esi+00000690]
      07231FE9 - 83 BE 90060000 00	- cmp dword ptr [esi+00000690],00
      0721CA71 - 0FB6 86 B0030000		- movzx eax,byte ptr [esi+000003B0]
      0721E9B7 - 83 BE 90060000 00	- cmp dword ptr [esi+00000690],00
      0721EA26 - DA BE 90060000		- fidivr [esi+00000690]
      

      a80c8713-7d3b-48ee-9fd4-bb2ed6058b0c-image.png

      Как видно, довольно все еще сырое, но видно, что все 20 ветвлений по ретам сформировались до корневого цикла.

      Потом можно будет, я надеюсь, увидеть связи между этим ветвлениями, когда я прикручу стрелки. По кружкам кликать и переходить в дизассемблер и смотреть условия выше. На условии искать другие адреса, которое запускает ветвь кода. На адресах опять делать ветвления (новое окно с ветвлениями о ретам)... На практике будет получаться более двух таких окон (для патронов). Нужно будет искать адреса связанные с условиями в новом окне.

      ClassSettings = {}
      ClassSettings.__index = ClassSettings
      function ClassSettings:New(_fileName, _maskFile)
      
      	local obj = {}
      	obj.stringList = createStringlist()
      	obj.fileName = _fileName
      	obj.maskFile = _maskFile
      	
      	obj.directoryPath = getCheatEngineDir()..'autorun'
      	obj.filePath = obj.directoryPath..'\\'..obj.fileName
      	
      	-- Есть ли такой ключ
      	function obj:HasKey(keyString)
      		local stringCount = self.stringList.Count
      		for i=0,stringCount-1 do
      			local items = self:Split(self.stringList[i])
      			if(keyString == items[1]) then
      				return true 
      			end
      		end
      	end
      	
      	-- Получить значение ключа
      	function obj:Get(keyString, defaultValue)
      		if(obj:HasKey(keyString)) then
      			local stringCount = self.stringList.Count
      			for i=0,stringCount-1 do
      				local items = self:Split(self.stringList[i])
      				if(keyString == items[1]) then
      					return  items[2]
      				end
      			end
      		end
      		return defaultValue
      	end
      	
      	-- Записать ключ
      	function obj:Set(keyString, stringOrDigitalValue)
      		-- Искать номер строки
      		local stringCount = self.stringList.Count
      		for i=0,stringCount-1 do
      			local items = self:Split(self.stringList[i])
      			if(keyString == items[1]) then
      				items[2] = stringOrDigitalValue
      				self.stringList.remove(self.stringList[i])
      				break
      			end
      		end
      		
      		self.stringList.add (keyString..' '..stringOrDigitalValue)
      	end
      	
      
      	-- Возвращает числовой вариант
      	function obj:GetDigital(keyString, defaultValue)
      		if(obj:HasKey(keyString)) then
      			return tonumber(obj:Get(keyString))
      		end
      		return defaultValue
      	end
      
      	-- Сохранить все ключи
      	function obj:Save()
      		self.stringList.saveToFile(obj.filePath)
      	end
      
      	function obj:FileExist(directoryPath, pathToFile, mask)
      		local paths = getFileList(directoryPath, mask, false)
      		for i=1,#paths do
      			if(paths[i] == pathToFile) then
      				return true
      			end
      		end
      		return false
      	end
      	
      	function obj:Split(argString)
      		local resultTable = {}
      		for i in string.gmatch(argString, "%S+") do
      			table.insert(resultTable, i)
      		end
      		return resultTable
      	end
      
      	
      	-- Загрузка ключей в память
      	if(obj:FileExist(obj.directoryPath, obj.filePath, obj.maskFile)) then
      		obj.stringList.loadFromFile(obj.filePath)
      	end	
      	setmetatable(obj, self)
      	return obj
      end
      	
      	
      classSettings = ClassSettings:New('userdata2.txt', '*.txt')
      \----------
      function DeleteAllBreakPoints()
      	local tableAddressOnBreakPoint = debug_getBreakpointList()
      	for i =1, #tableAddressOnBreakPoint do
      		debug_removeBreakpoint(tableAddressOnBreakPoint[i])
      	end
      end
      
      
      ClassTraceBranch = {}
      function ClassTraceBranch:New(_dataAddress, _onEnd)
      
      	local obj  = {}
      	obj.address 		= _dataAddress
      	obj.OnEnd 			= _onEnd
      	obj.Is64Bit 		= targetIs64Bit()
      	obj.tableData 		= {}
      
      	--Breakpoint methods: 				bpmInt3=0, bpmDebugRegister=1, bpmException=2
      	--breakpoint continue methods:      co_run=0, co_stepinto=1, co_stepover=2
      	--Breakpoint triggers:				bptExecute=0, bptAccess=1, bptWrite=2
      	--debug_setBreakpoint(self.address, 1, bptExecute, bpmDebugRegister)
      	
      	
      	function obj:OnBreakpoint() 
      	
      	
      		local XIP = 0
      		if(self.Is64Bit) then XIP = RIP else XIP = EIP end
      		
      		local someFind = false
      		local endAction = false
      		
      		for i=1,#self.tableData do
      			--if(self.tableData[i].XIP == XIP) then
      			if(self.tableData[i].XIP == XIP) then
      				self.tableData[i].Count = self.tableData[i].Count + 1
      				someFind = true
      				if(self.tableData[i].Count > 100) then
      					endAction = true
      				end
      				break
      			end
      		end
      		
      		if(endAction) then
      			--table.insert ( self.tableData, {XIP = XIP, Count = 1})
      			--self:PrintData()
      			--print('-->'..string.format('%08X',XIP))
      			DeleteAllBreakPoints()
      			debug_continueFromBreakpoint(co_run)
      			self.OnEnd()
      		else
      			if(not someFind) then
      				local _,opcode,_,_ = splitDisassembledString(disassemble(XIP))
      				local isRet = string.match(opcode,'ret')
      				--if(isRet) then
      				--	print('ret '..string.format('%08X', XIP))
      				--end
      				table.insert ( self.tableData, {XIP = XIP, Count = 1, isRet = isRet})
      				debug_continueFromBreakpoint(co_stepover)
      			end
      		end
      		return 1
      	end
      
      	function obj:PrintData()
      		local s = ''
      		local addressPrevious = getPreviousOpcode(self.address)
      		local _,opcode,_,_ = splitDisassembledString(disassemble(addressPrevious))
      		print(string.format('%08X - %s:\r\n', addressPrevious, opcode))
      		
      		for i=1,#self.tableData do
      			local _,opcode,_,_ = splitDisassembledString(disassemble(self.tableData[i].XIP))
      			s = s..string.format('%08X - %s - %s\r\n', self.tableData[i].XIP, self.tableData[i].Count, opcode)
      		end
      		print(s)
      	end	
      
      	debug_continueFromBreakpoint(co_stepover)
      	
      	setmetatable (obj, self)
      	obj.__index = ClassTraceBranch
      	return obj
      end
      
      ClassManagerBranches = {}
      function ClassManagerBranches:New(mainAddress, sizeBreakPoint)
      
      	local obj  = {}
      
      	
      	obj.tableData 				= {} --XIP = 0, traceBranch = nil
      	obj.mainAddress				= mainAddress
      	obj.sizeBreakPoint 			= sizeBreakPoint
      	obj.currentTraceBranch 		= nil
      	obj.isLogBranch				= false
      	
      	local Is64Bit 				= targetIs64Bit()
      
      	function obj:Containts(XIP)
      		for i=1, #self.tableData do
      			if(self.tableData[i].XIP == XIP) then 
      				return true
      			end
      		end
      		return false
      	end
      	
      	function obj:Stop()
      		
      		DeleteAllBreakPoints()
      		
      		for i = 1, #self.tableData do
      			local addressPrevious = getPreviousOpcode(self.tableData[i].traceBranch.address)
      			local _,opcode,_,_ = splitDisassembledString(disassemble(addressPrevious))
      			print(string.format('%08X %s', addressPrevious, opcode))
      		end
      		
      		print('\r\n')
      		
      		for i = 1, #self.tableData do
      			self.tableData[i].traceBranch:PrintData()
      		end
      		
      		debug_continueFromBreakpoint(co_run)
      	end	
      	
      	function obj:OnBreakpoint()
      	
      		if(self.isLogBranch) then
      			return self.currentTraceBranch:OnBreakpoint() 
      		end
      
      		local XIP = 0
      		if(Is64Bit) then XIP = RIP else XIP = EIP end
      		
      		if(not self:Containts(XIP)) then
      	
      			local hitAddress = getPreviousOpcode(XIP)
      			local _,opcode,_,_ = splitDisassembledString(disassemble(hitAddress))
      			--print(string.format('Start Trace at : %08X %s', hitAddress, opcode))
      			
      			DeleteAllBreakPoints()
      			
      			self.currentTraceBranch = ClassTraceBranch:New
      			(	
      				XIP, 
      				function ()
      					--print('Stop')
      					self.isLogBranch = false
      					debug_setBreakpoint(self.mainAddress, self.sizeBreakPoint, bptAccess, bpmDebugRegister)
      				end
      			)
      
      			table.insert (self.tableData, {XIP = XIP, traceBranch = self.currentTraceBranch})
      			
      			self.isLogBranch = true
      		end
      		
      		return 1
      	end
      	
      	
      	print('Start at: '.. obj.mainAddress)
      	debug_setBreakpoint(obj.mainAddress, obj.sizeBreakPoint, bptAccess, bpmDebugRegister)
      		
      	setmetatable (obj, self)
      	obj.__index = ClassManagerBranches
      	return obj
      end
      
      
      \--if(getOpenedProcessID() == 0) then openProcess('test.exe') end
      
      if(getOpenedProcessID() == 0) then 
      	openProcess('xrengine.exe')
      end
      
      managerBranches = ClassManagerBranches:New('37859970',4)
      
      function debugger_onBreakpoint()
      	return managerBranches:OnBreakpoint()
      end
      
      
      \--managerBranches:Stop()
      
      \-----------------------------
      
      \-- КЛАСС ClassMapBranch
      ClassMapBranch = {}
      ClassMapBranch.__index = ClassMapBranch
      function ClassMapBranch:New(_frmMarkers, _managerBranches)
      
      	local _frmMapBranch = createForm(false) --frmDissassembler -- createForm(false)
      	
      	_frmMapBranch.DoubleBuffered = true
      	_frmMapBranch.Caption 	= 'Map branches'
      	_frmMapBranch.Width 	= classSettings:GetDigital('obj.frmMapBranch.Width', 500)
      	_frmMapBranch.Height 	= classSettings:GetDigital('obj.frmMapBranch.Height', 900)
      	_frmMapBranch.Left		= classSettings:GetDigital('obj.frmMapBranch.Left', 0)
      	_frmMapBranch.Top 		= classSettings:GetDigital('obj.frmMapBranch.Top', 0)
      		
      
      	if(classSettings:Get('obj.frmMapBranch.Visible', '1') == '1') then
      		_frmMapBranch.show()
      	end
      	_frmMapBranch.show()
      		
      	_frmMapBranch.setBorderStyle(bsSizeable)
      	_frmMapBranch.FormStyle = 'fsNormal'
      	
      	
      	local obj = {}
      	
      	
      	obj.classManagerBranches = _managerBranches
      	obj.frmMapBranch 		= _frmMapBranch
      	obj.frmMarkedBranches	= _frmMarkers
      	obj.selectedAddress 	= -1
      	obj.mainCanvas 			= obj.frmMapBranch.Canvas
      	obj.bufferGraphic 		= createBitmap(obj.frmMapBranch.Canvas.Width, obj.frmMapBranch.Canvas.Height)
      	
      	obj.dy 					= 20
      	obj.column0_X 			= 30	-- маркер X
      	obj.column1_X 			= 65
      	obj.column2_X 			= 70 + 50
      	obj.column3_X 			= 70 + 50 + 40
      	obj.extraLineRender_Y	= -20
      	obj.tableVisibleAddress = {}		-- содержит данные рисуемой таблицы (см. свойства инже по коду)
      	
      	-- Можно поставить другие цвета для фона и шрифта
      	obj.colorBackground 	=  classSettings:GetDigital('obj.colorBackground', 0x00525252)
      	obj.colorFont 			=  0x00FFFFFF --classSettings:GetDigital('obj.colorFont', )
      	
      	
      	obj.frmMapBranch.Color 		= obj.colorBackground
      	obj.frmMapBranch.Font.Color = obj.colorFont 
      	
      	obj.isDirtyData = true
      	setProperty(obj.frmMapBranch, 'OnPaint', function () 
      		
      		if(obj.isDirtyData) then
      			obj.isDirtyData = false
      			obj:Draw()
      		end
      
      		obj.mainCanvas.draw(0, 0, obj.bufferGraphic)
      	end)
      	
      	setProperty(obj.frmMapBranch, 'OnResize', function ()
      		if(obj.bufferGraphic.Width ~= obj.mainCanvas.Width or
      			obj.bufferGraphic.Height ~= obj.mainCanvas.Height) then
      			obj.isDirtyResize = true
      		  end
      		end
      	)
      
      	-- Не уничтожать окно при закрытии
      	setProperty(obj.frmMapBranch, 'OnClose', function (sender) 
      		return caHide --Possible options: caHide, caFree, caMinimize, caNone
      	end
      	)		
      
      	
      	obj.checkTimer = createTimer(obj.frmMapBranch)
      	obj.checkTimer.Interval = 50
      	obj.lastTopAddress = 0
      	obj.isDirtyResize = false
      	obj.needUpdateDraw = false
      	
      	obj.checkTimer.OnTimer = function ()
      	
      		obj.needUpdateDraw = true
      		if(	obj.needUpdateDraw) then
      			obj.needUpdateDraw = false
      			obj.frmMapBranch.repaint()
      		end
      
      		if(obj.isDirtyResize) then
      			obj.isDirtyResize = false
      			obj.bufferGraphic.destroy()
      			obj.bufferGraphic = createBitmap(obj.frmMapBranch.Canvas.Width, obj.frmMapBranch.Canvas.Height)
      			obj.bufferGraphic.Canvas.Brush.Color 	= obj.colorBackground
      			obj.bufferGraphic.Canvas.Font.Color 	= obj.colorFont
      			obj.bufferGraphic.Canvas.floodFill(x,y)
      			obj.isDirtyData = true
      			obj.frmMapBranch.repaint()
      		end		
      	end
      	
      	
      	obj.mainAddress = string.format('%08X',obj.classManagerBranches.mainAddress)
      	
      	-- Рисует дизассемблерный код и может рисовать пути
      	function obj:Draw()
      		
      		local bufferGraphicCanvas = obj.bufferGraphic.Canvas
      		
      		bufferGraphicCanvas.Font.Size 		= sizeFont
      		bufferGraphicCanvas.Font.Color 		= obj.colorFont
      		bufferGraphicCanvas.Pen.Style 		= 'psSolid'
      		bufferGraphicCanvas.Brush.Style 	= 'bsClear'
      		bufferGraphicCanvas.Brush.Color 	= obj.colorBackground
      		
      		
      		bufferGraphicCanvas.clear()
      		obj.frmMapBranch.color = 0xFFFFFFFF -- obj.colorBackground
      		bufferGraphicCanvas.Brush.Color = 0xFFFFFFFF
      		bufferGraphicCanvas.Pen.Style   = 0xFFFFFFFF
      		
      		--bufferGraphicCanvas.Brush.Style = 'bsClear'
      		
      		local mainPoint = 
      		{
      			x = obj.frmMapBranch.Width / 2,
      			y =  obj.frmMapBranch.Height  - 50
      		}
      		
      		bufferGraphicCanvas.textOut(mainPoint.x, mainPoint.y, obj.mainAddress)
      		bufferGraphicCanvas.line(mainPoint.x - 300, mainPoint.y - 30, mainPoint.x + 300, mainPoint.y - 30)
      		
      		local tableData = obj.classManagerBranches.tableData
      		for i = 1, #tableData do
      			--local addressPrevious = getPreviousOpcode(tableData[i].traceBranch.address)
      			--local _,opcode,_,_ = splitDisassembledString(disassemble(addressPrevious))
      			--local s = string.format('%08X %s', addressPrevious, opcode)
      			--bufferGraphicCanvas.textOut(100, 100 + i * 20, 'Test: '.. s)
      			local dx = i*40
      			local dy = 20
      			
      			--bufferGraphicCanvas.line
      			--(
      			--	mainPoint.x - 300 + dx,
      			--	mainPoint.y - 30 - dy,
      			--	mainPoint.x - 300 + dx,
      			--	mainPoint.y - 30
      			--)
      			
      			local tableDataFromBranche = tableData[i].traceBranch.tableData
      			local countRets = 0
      			for j = 1, #tableDataFromBranche do
      				--table.insert ( self.tableData, {XIP = XIP, Count = 1, isRet = string.match(opcode,'ret')})
      				--table.insert ( self.tableData, {XIP = XIP, Count = 1, isRet = string.match(opcode,'ret')})
      				if(tableDataFromBranche[j].isRet) then
      					countRets = countRets + 1
      					bufferGraphicCanvas.ellipse
      					(	
      						mainPoint.x - 300 + dx - 5,
      						mainPoint.y - 30 - dy - countRets * 20 - 5,
      						mainPoint.x - 300 + dx + 6,
      						mainPoint.y - 30 - dy - countRets * 20 + 6
      					)
      				end
      			end
      			
      			bufferGraphicCanvas.line
      			(
      				mainPoint.x - 300 + dx,
      				mainPoint.y,
      				mainPoint.x - 300 + dx,
      				mainPoint.y - dy - countRets * 20 - 10
      			)
      		end	
      		
      		--local priority1 = math.random(0,155)
      		--local someColor = byteTableToDword({priority1,priority1,priority1,0})
      		--bufferGraphicCanvas.Font.Color = someColor
      				
      
      			
      
      		obj.mainCanvas.draw(0, 0, obj.bufferGraphic)
      	end	
      	
      
      	function obj:DrawArrow(point1, point2, distance, colorArrow, minY, a1_IsFarTop, a1_IsFarBottom, a2_IsFarTop, a2_IsFarBottom, a1_IsFarTop, a1_IsFarBottom, a2_IsFarTop, a2_IsFarBottom)
      
      		local bufferCanvas = obj.bufferGraphic.Canvas
      		
      		bufferCanvas.Pen.Color = colorArrow
      		bufferCanvas.Pen.Style = 'psDot'	
      		
      		local height = bufferCanvas.Height
      		
      		isDrawSideLine1 = true
      		if(point1.y < minY) 			then	point1.y = minY  isDrawSideLine1 = false
      		elseif (point1.y > height) 	then	point1.y = height isDrawSideLine1 = false
      		end
      		
      		isDrawRow = true
      		if(point2.y < minY) 			then	point2.y = minY	  isDrawRow = false
      		elseif (point2.y > height) 	then	point2.y = height isDrawRow = false
      		end
      		
      		if(isDrawSideLine1) then
      			bufferCanvas.line(point1.x, point1.y, point2.x - distance, point1.y)
      		end
      		bufferCanvas.line(point2.x - distance, point1.y, point2.x - distance, point2.y)
      		
      
      	
      		if(isDrawRow) then
      			bufferCanvas.line(point1.x, point2.y, point2.x - distance, point2.y)
      			obj.bufferGraphic.Canvas.Pen.Style = 'psSolid' --'psSolid'
      			local x1 = point2.x - 5
      			local x2 = point2.x 
      			local y2 = point2.y
      			
      			-- Рисование стрелки костыльным способом
      			bufferCanvas.line(x1,		y2 - 3,			x2,		y2)
      			bufferCanvas.line(x1,		y2 - 7 + 10,	x2,		y2)
      			bufferCanvas.line(x1,		y2 - 3,			x1,		y2 - 7 + 10)
      			bufferCanvas.line(x1 + 1,	y2 - 2,			x1 + 1, y2 - 7 + 9)
      			bufferCanvas.line(x1 + 2,	y2 - 1,			x1 + 2, y2 - 7 + 9)
      			bufferCanvas.line(x1,		y2 - 1,			x1 + 6, y2)
      		end
      
      	end
      				
      		
      	obj.frmMapBranch.OnDestroy = function (sender)
      		obj:SaveParameters()
      	end
      	
      	function obj:SaveParameters()
      	
      		classSettings:Set('obj.frmMapBranch.Width', obj.frmMapBranch.Width)
      		classSettings:Set('obj.frmMapBranch.Height', obj.frmMapBranch.Height)
      		classSettings:Set('obj.frmMapBranch.Left', obj.frmMapBranch.Left)
      		classSettings:Set('obj.frmMapBranch.Top', obj.frmMapBranch.Top)
      		
      		classSettings:Set('obj.colorBackground', obj.colorBackground)
      		
      		if(obj.frmMapBranch.Visible) then
      			classSettings:Set('obj.frmMapBranch.Visible', '1')
      		else
      			classSettings:Set('obj.frmMapBranch.Visible', '0')
      		end
      			
      		classSettings:Save()
      	end			
      		
      	obj:Draw()
      
      	setmetatable(obj, self)
      	return obj
      end	
      
      
      
      mapBranch = ClassMapBranch:New(frmMarkedBranches, managerBranches)
      
      1 ответ Последний ответ Ответить Цитировать 0
      • MasterGHM В сети
        MasterGH Администраторы
        отредактировано

        Трассеровка по ретам

        -------
        857b57ff-3395-4d71-9f76-e191f66fc90b-image.png

        На скриншоте 22 ветви трассеровки от адреса патронов не входя в call-ы до корневого цикла. Корневой цикл определяется, когда поиск происходит более трех секунд и не находит ничего. Вполне хватает этого времени. Буду еще повторно тестить и проверять доходит ли он цикла или надо еще что-то придумывать.

        Желтым выделяется точка, вертикальная полоса ветви и связи с такими же узлами. Узел это адрес выхода из ret

        Внизу ряд счетчиков от 00 до 99. Если более 99 то отсчет заного. Показывает дианамику обращения к ветвям после нахождения корневого цикла

        Есть еще несколько функций, которых не видно на скриншоте — в контекстном меню.

        Анализ можно запустить из окна CE из главной таблицы, выделив адрес и опцию либо на чтение, либо на доступ.

        При тестах увидел, что логи неполные. Например, первый кружок это инструкция читающая патроны очень часто. От этой инструкции идут вверх множество вариантов ветвей,а у меня один вариант — вертикальная полоска с кружками. От первого круга надо сделать ветвление влево и вправо.

        Занялся модернизацией этого рисования и оптимизацией. Например, чтобы определить является ли проход по ret, то не нужен дизассемблер. Залез в доки и посмотрел опкоды

        function IsRet(address)
        		local value = readBytes(address,1, false)
        		return value == 0xC3 or value == 0xCB or  value == 0xC2 or value == 0xCA
        	end
        

        Скорость трассеровки должна в несколько раз увеличиться. К сожалению, смогу это узнать, когда перепишу текущий плагин.

        Там были уже сделаны изменения (все еще сырое для публикации плагина, пока не публикую)

        • Нумерация ветвей
        • Клик на круг — переход в дефоттный дизассемблер
        • Подсвечивать выбранный круг
        • Перерасчет позиций, когда поменялся размер окна
        • Счетчики выполнений инструкций срабатывающих к обращению на адрес
        • Изменен способ рисования связей между ветвями
        • Контекстное меню Показать ветку
        • Контекстное меню Скрыть ветку
        • На скрытой ветви не показываются связи упрощая обзор. Код поднимается снизу вверх. Если одна ветвь ниже другой, то можно её скрыть. Ориентируемся по счетчикам хитов на инструкции
        • Контекстное меню Сброс хитов
        • Оптимизация поиска корневого цикла
        • Выделение связей
        • Оптимизация рисования новых свзей
        • Контекстное меню пауза/продолжение
        • Запуск из контекстного меню при выделеии адреса в главной таблице
        • При закрытии окна снимаются все брейкпоинты
        • Возможность ставить логи на запись из контекстного меню и на чтение в главной таблице CE
        1 ответ Последний ответ Ответить Цитировать 0
        • MasterGHM MasterGH сослался на эту тему в

        • 1 / 1
        • Первое сообщение
          Последнее сообщение
        Powered by NodeBB | Contributors
        СeLua[RU] 2025©