MasterGH Опубликовано 20 мая, 2011 Поделиться Опубликовано 20 мая, 2011 В этом коротком туторе я покажу пример снятия данных регистров.pmAddress=getAddress("1F72152C")max = 10count = 0function debugger_onBreakpoint() -- срабатывает всегда, когда срабатывает брейкпоинт count = count + 1-- если понадобятся все регистры или некоторые, то вы можете исправить код ниже s = string.format("%3d) 0x%08X: EAX = 0x%08X EBX = 0x%08X ECX = 0x%08X",count, EIP, EAX, EBX, ECX) print(s) if count>=max then debug_removeBreakpoint(pmAddress); end --Breakpoint continue methods: co_run=0, co_stepinto=1, co_stepover=2 debug_continueFromBreakpoint(co_run) -- return 1 --I handled it so dont tell the user -- return 0 --unexpected breakpoint, show the the userend--Breakpoint triggers: bptExecute=0, bptAccess=1, bptWrite=2--Variable types: (ref http://ce.colddot.nl/browser/Cheat%20Engine%206/bin/defines.lua) debug_setBreakpoint(pmAddress, vtDword, bptWrite)Обращу внимание, что именно по этому примеру можно делать другие не менее полезные. Помимо различных сравнений и ведения логов можно сделать определение адресов на прерывающихся инструкциях больше одного. Результат будет означать, что инструкции за все время своей работы работали только с одним адресом... Так же обращу внимание на "частоты" срабатываний тех или иных инструкций, это тоже можно вести в логе.В нужный момент можно "не отпускать процесс" и проанализировать ситуацию.Можно вести трассировку...Сравнение структур!И т.п. что вам в голову придёт.И ещё. Если вам надо снять брейкпоинты установленные через LUA, то это можно сделать вручную в функциях окна меню дизассемблера. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 18 июля, 2011 Автор Поделиться Опубликовано 18 июля, 2011 Ведение лога инструкций, которые работают с адресом, если в момент срабатывания бряка по адресу находится заданное вами значение.В моем примере выводятся инструкции, которые записывают значение 1080 типа Integer по адресу "Test.exe+5B5A4". Дальше смотрите код.Автор: MasterGH 2011Скрпит для идентификации инструкции работающием с адресом, когда в нём оказывается определённое значения.Требования: - предварительно приаттачить 32-х разрядный процесс игры через иконку Компьютера в главном окне CE - Если тип данных сравниваемого значения не Integer, то изменить в скрипте "readInteger"Информация по Lua поддержке: http://ce.colddot.nl/browser/Cheat%20Engine%206/bin/main.luaИнформация по Lua константам: http://ce.colddot.nl/browser/Cheat%20Engine%206/bin/defines.luaХотите доработать скрипт? -- Вы можете создать графический интерфейс пользователя -- Вы можете сделать так чтобы не выводились повторяющиеся инструкции]]---- Значения для настройкиlocal myValue = 1080 -- сравниваемое значение, в моем случае 1080типа Integerlocal myValueSize = 4 -- размер данных по адресу, в моём случае Integer, значит "4"local myAddress = getAddress("Test.exe+5B5A4") -- получение адреса в целочисленный тип, мой адрес "Test.exe+5B5A4"-- тип бряка "ставим на запись"local typeBreak = 2 --( другие: bptExecute=0, bptAccess=1, bptWrite=2)-- Если игра вылетает, то попробовать типы отладки: VEHDebug и Kerneldebuglocal typeDebug = 1 -- тип отладки (0=default, 1=windows debug, 2=VEHDebug, 3=Kerneldebug)local criticalCount = 5000 -- если лог постоянно показыватеся, что его нельзя остановить, то этот предел остановит отладкуlocal count = 0------------------------------------- Вызвать в консоли эту функцию если нужно удалить бряк и преркатить слежение-- В этой функции ничего менять не надоfunction RemoveBreakpoint() debug_removeBreakpoint(myAddress);end------------------------------------- Функция обработки события точки останова-- В этой функции можно поменять readInteger на нужный тип данныхfunction debugger_onBreakpoint()-- если значение по адресу равно 1080, то выводить инструкции в лог if readInteger(myAddress)== myValue then print(disassemble(getPreviousOpcode(EIP))) count = count + 1 if (count > criticalCount) then RemoveBreakpoint() end end return 1 -- не показывать отладчик, если 0 - то показыватьend-- Далее ничего менять не надоdebugProcess(typeDebug) -- установка режима отладки-- Утановка брейкпоинта-- В этой функции ничего менять не надоdebug_setBreakpoint(myAddress, myValueSize, typeBreak) -- установка самого брякак--[[Скриншот на котором показано как работать с этим скриптом:Желаю успехов! Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 18 июля, 2011 Автор Поделиться Опубликовано 18 июля, 2011 Заготовка скрипта для ведения лога данных на функции TranslateMessage. Функция TranslateMessage переводит сообщения виртуальных клавиш в символьные сообщения. Символьные сообщения помещаются в очередь сообщений вызывающего потока для прочтения в следующий раз, когда поток вызовет функцию GetMessage или PeekMessage.Теория (на практике всю теорию не проверял, только где-то как-то кусками)В игре подгружаются модули dll, которые вызывают translateMessage. Например directXInput8 dll-ка вызывала эту функцию когда я кликнул левой кнопкой мыши по области окна игры. Я мог бы остановить текущую отладку в этот момент и повесить условный бряк уже на функцию обработки именно этого уже оттранслированного сообщения. Ведь именно его обработка это начало пути определённых действий в коде... концом пути уже будет бряк на некотором адресе. В OllyDbg можно найти развилку между начальным и конечным путями при автоматическом трейсинге по ретам. И уже на этой развилке хорошо думать, почему именно эта развилка кода имела место быть... Скрипт установки условного брейкпоинта на функции TranslateMessage. В параметрах сравнения участвует код сообщения "UINT message" Если сообщение равно сравниваемому, то отладчик прервётся и в поле лога выведет параметры структуры MSG BOOL TranslateMessage( const MSG* lpMsg // Указатель на структуру MSG, которая содержит информацию о сообщении извлеченную из очереди сообщений вызывающего потока при помощи использования функции GetMessage или PeekMessage. ); typedef struct { HWND hwnd; // Дескриптор окна, оконная процедура которого принимает сообщение. UINT message; // Определяет код сообщения. Приложения могут использовать только младшее слово; старшее слово зарезервировано системой. WPARAM wParam; // Определяет дополнительную информацию о сообщении. Точное значение зависит от значения члена структуры message. LPARAM lParam; // Определяет дополнительную информацию о сообщении. Точное значение зависит от значения члена структуры message. DWORD time; // Определяет время, в которое сообщение было помещено в очередь. POINT pt; // Устанавливает позицию курсора, в экранных координатах, в момент, когда сообщение было помещено в очередь. } MSG, *PMSG; Пример использования. Пример1. Установка условного брейкпоинта функции TranslateMessage в сравнении с параметром MSG: -- Сработает когда пользователь отпустит левую кнопку мышки WM_LBUTTONUP = 0x202 (другие коды сообщени ищите в Интернете) StartDebug_TranslateMessageCondition_onMSG(WM_LBUTTONUP) Пример2. Установика безусловного брейкпоинта с логировнием всех сообщений: StartDebug_TranslateMessage() Пример3. Если необходимо только прерваться на некоторой функции без сбора параметров: StartDebugSomeFunction(functionName) Пример4. Если необоходимо остановить отладку, то вызывать: StopDebug()]]--local mode = 0local addressesBreakPoint = {}local countAddressesBreakPoint = 0function AddBreakPointExecut(addressFunction) countAddressesBreakPoint = table.getn(addressesBreakPoint) countAddressesBreakPoint = countAddressesBreakPoint + 1 addressesBreakPoint[countAddressesBreakPoint] = addressFunction debug_setBreakpoint(addressFunction, 1, bptExecute)endfunction DeleteAllBreakPoint() for i=1, countAddressesBreakPoint do debug_removeBreakpoint(addressesBreakPoint[i]) end countAddressesBreakPoint = 0end-- Единая функция обработки сообщений о прерыванииfunction debugger_onBreakpoint() local withIn = false for i=1, countAddressesBreakPoint do if (EIP == addressesBreakPoint[i]) then withIn = true break end end if (not withIn) then return 1 end if ( (mode == 1) or (mode == 2) ) then local pMSG = readInteger(ESP+0x4) local MSG = readInteger(pMSG+0x4) if ((mode == 1) and (MSG ~= _iMSGBreak)) then return 1 end local s = string.format(" • Call to %s from \"%s\" •\n\r\n>> hWnd = %X\n\r\n>> MSG = %X\n\r\n>> wParam = %X\n\r\n>> lParam = %08X\n\r\n>> Time = %X\n\r\n>> Point = %i x %i\n\r\n", getNameFromAddress(EIP), getNameFromAddress(readInteger(ESP)), readInteger(pMSG), MSG, readInteger(pMSG+0x8), readInteger(pMSG+0xC), readInteger(pMSG+0x10), readInteger(pMSG+0x14), readInteger(pMSG+0x18)) if (mode == 1) then -- WM_LBUTTONUP print(s) -- записываем в лог LuaEngine текст из loglist return 0 -- ставим бряк else -- в случае если условие не выполнено print(s) -- записываем в лог LuaEngine текст из loglist при не выполненом условии return 1 -- продолжаем без бряка end end return 0endfunction StartDebug_TranslateMessageCondition_onMSG(iMSGBreak) DeleteAllBreakPoint() mode = 1 _iMSGBreak = iMSGBreak local addressFunction = getAddress("TranslateMessage") AddBreakPointExecut(addressFunction) print(string.format("Включен режим остановки на фунции TranslateMessage с условием: MSGBreak == %X",iMSGBreak))endfunction StartDebug_TranslateMessage() DeleteAllBreakPoint() mode = 2 local addressFunction = getAddress("TranslateMessage") AddBreakPointExecut(addressFunction) print("Включен режим остановки на фунции TranslateMessage без условий")endfunction StartDebugSomeFunction(functionName) mode = 0 local addressFunction = getAddress(functionName) AddBreakPointExecut(addressFunction)endfunction StopDebug() DeleteAllBreakPoint() _iMSGBreak = 0end--[[ Ссылка на комментарий Поделиться на другие сайты Поделиться
Ramil Опубликовано 21 июля, 2011 Поделиться Опубликовано 21 июля, 2011 Подскажите пожалуйста, чтобы научиться писать Lua скрипты что надо учить, какой язык программирования. Ссылка на комментарий Поделиться на другие сайты Поделиться
Xipho Опубликовано 21 июля, 2011 Поделиться Опубликовано 21 июля, 2011 Собственно, Lua и надо учить ))) Ссылка на комментарий Поделиться на другие сайты Поделиться
Ramil Опубликовано 21 июля, 2011 Поделиться Опубликовано 21 июля, 2011 И долго ли надо учить его, или весь. Или много не надо учить Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 22 июля, 2011 Автор Поделиться Опубликовано 22 июля, 2011 Учить вообще ничего не надо и стоит ли задаваться такими вопросами?. Надо сразу писать код по примерам и пытаться писать свой код. В это время голова будет запоминать то, что надо. Ссылка на комментарий Поделиться на другие сайты Поделиться
Cmbt Опубликовано 2 июня, 2012 Поделиться Опубликовано 2 июня, 2012 если нужно удалить бряк и преркатить слежениеfunction RemoveBreakpoint() debug_removeBreakpoint(myAddress);end столкнулся с ситуациями когда некоторые участки кода не реагируют на функциюdebug_removeBreakpoint(myAddress);интуитивно предполагаю что это связано с "высокочастотными" участками кода.иногда помогает выйти из ситуации простая приостановка процесса.debug_removeBreakpoint(myAddress)pause()unpause()....но не всегда.и даже попытки удалить бряк вручную из панели "список точек останова", порой не приводит к успеху.независимо от типа отладки (0=default, 1=windows debug, 2=VEHDebug, 3=Kerneldebug)В связи с этим, два вопроса.1. Если кто-то сталкивался с похожей ситуацией, то какими способами решается проблема?2. Неплохо-бы попросить ДаркБайта обогатить набор функций Lua в СЕнеким способом "жёсткого" безусловного выхода из режима "debug"но это к Андрею, думаю вопрос.*прим. наблюдалось на версиях CE 6,1 и 6,2 , на разных компах и версиях Win. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 2 июня, 2012 Автор Поделиться Опубликовано 2 июня, 2012 >> 1. Если кто-то сталкивался с похожей ситуацией, то какими способами решается проблема?Я к сожалению не сталкивался>>неким способом "жёсткого" безусловного выхода из режима "debug"Выход из отладки1) detachIfPossible() - вообще вырубить отладчик (функция должна работать в CE 6.2)2) debug_removeBreakpoint(address) лишь удаляет брейкпоинты (можно постараться удалить все). Поэтому это не совсем выход из отладочного режима.Возможно функциюdebug_removeBreakpoint(address)не стоит вызывать в недрах debugger_onBreakpoint(), когда debugger_onBreakpoint() работает очень часто, а вызывать из чего-то другого. Из функции таймера или потока. Да-да =), На Lua можно работать с потоками существует специальный класс Thread Class.К сожалению я не могу помочь примерами кода как работать с потоками или как с таймером. Мне лень. Я могу что-то подправить или подсказать. Ссылка на комментарий Поделиться на другие сайты Поделиться
X86Jumps Опубликовано 29 августа, 2017 Поделиться Опубликовано 29 августа, 2017 (изменено) а как можно трейсить step by step? например как встроенный трейсер, чтоб записал весь лог? как он пошагово идет? debug_continueFromBreakpoint? а если несколько потоков то это как то разделяется или в куче будет? вроде в последней CE с контекстом потоков что то есть Изменено 29 августа, 2017 пользователем X86Jumps Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 10 сентября, 2017 Автор Поделиться Опубликовано 10 сентября, 2017 Есть два варианта пошаговой трассеровки 1. debug_continueFromBreakpoint(continueMethod) -- описание в справке 2. Самому рассчитывать каким должен быть следующий адрес и на него ставить брейкпоинт. Этот способ показался мне быстрее, но уже не помню на сколько. Код в репозитории. В 30.08.2017 в 03:42, X86Jumps сказал: а если несколько потоков то это как то разделяется или в куче будет? вроде в последней CE с контекстом потоков что то есть Что-то есть, надо разбираться. Я один и тот же поток отслеживал через второй способ. Ссылка на комментарий Поделиться на другие сайты Поделиться
X86Jumps Опубликовано 10 сентября, 2017 Поделиться Опубликовано 10 сентября, 2017 т.е. снимать один бряк и ставить следующий? странно что это получается быстрее чем lua функцией)) Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 10 сентября, 2017 Автор Поделиться Опубликовано 10 сентября, 2017 22 минуты назад, X86Jumps сказал: т.е. снимать один бряк и ставить следующий? странно что это получается быстрее чем lua функцией)) Да. Есть какие-то shadow брейкпоинты, у меня их было довольно много из-за первого способа (если не ошибаюсь больше 15 на Сталкере Зов Припяти), когда трейсил на адресе патронов. Когда я стал использовать способ2, shadow бряки не включались. Было на мой взгляд быстрее. В общем надо все проверять, замерять и прочее. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения