-
Постов
2 999 -
Зарегистрирован
-
Победитель дней
129
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент MasterGH
-
Еще этот код можно встраивать в таблицы. Ведь пользователю не нужна форма CE для поиска значений.
-
Активация и деактивация function SetStateRecord(description, state) local addressList = getAddressList() local memoryRecord = addressList.getMemoryRecordByDescription(description) memoryRecord.Active = stateend -- ВключитьSetStateRecord('No description', true)-- Выключить--SetStateRecord('No description', false)Гдеdescription - название чита в главной таблице state - состояние заморозки или активации
-
У нас -35 в Новосибирске и 3 м/с ветер, все друг-друга купаться зовут прямо с утра.
-
Если нужно попытаться найти рабочий адрес среди его копий через изменение на +1 его значения и через изменение имени записи в главной таблице CE, то можно попробовать использовать следующий скрипт. local addressList = getAddressList()local max = addressList.Countlocal address = 0local value = 0for i = 0,max-1 do address = addressList[i].getCurrentAddress() value = value + 1 writeInteger(address,value) addressList[i].Description = valueendwriteFloat(address,value)writeDouble(address,value)writeQword(address, value)writeString(address,text, widechar OPTIONAL)
-
Xipho, Garik66 я полностью с вами согласен. По поводу даты создания видео и количества просмотров. Видео судя по титрам снято в 2014 году, что немногим меньше двух лет учитывая, что был недавно новый год. Под 3 млн просмотров. Я посчитал, вроде, под 4 тысячи просмотров в сутки в среднем.
-
"Можете ли вы нарисовать 7 перпендикулярных красных линий? Можете ли нарисовать из линии котёнка? Ведь это было бы здорово! Нет, не перебивай. Ты - эксперт и должен знать как это сделать." Начальство говорит "сделай". О том как придется выкручиваться человеку, от которого требуют невозможное.
- 4 ответа
-
- 1
-
-
Скрипт, который я привел в пример, вызывается отдельным потоком. Ret - для выхода из этого потока. mov ecx,[0] это специально для вызова исключения. Т.е. тебе нужно - убрать ret-ы - убрать mov ecx,[0] - убрать "je code" fs:[0] содержит адрес текущей структуры исключений. Мы подставляем адрес своей создаваемой структуры исключений, при этом сохраняем предыдущий. На Wasm есть интересная переведенная статья по SEH. Часть1 Часть2 Часть3 Можешь все не читать, а посмотреть пример ниже //==================================================// MYSEH - Мэт Питрек 1997// Microsoft Systems Journal, Январь 1997// FILE: MYSEH.CPP// To compile: CL MYSEH.CPP//==================================================#define WIN32_LEAN_AND_MEAN#include #include DWORD scratch;int main(){ DWORD handler = (DWORD)_except_handler; __asm { // Создаем структуру EXCEPTION_REGISTRATION: push handler // Адрес функции обработчика исключений. push FS:[0] // Адрес предыдущего EXECEPTION_REGISTRATION. mov FS:[0],ESP // Добавляем в связанный список EXECEPTION_REGISTRATION. } __asm { mov eax,0 // Обнуляем значение регистра EAX. mov [eax], 1 // Чтобы преднамеренно вызвать исключение, делаем запись // по нулевому адресу. } printf( " After writing!\n" ); __asm { // Удаляем из связанного списка EXECEPTION_REGISTRATION. mov eax,[ESP] // Получаем указатель на предыдущий // EXECEPTION_REGISTRATION. mov FS:[0], EAX // Устанавливаем в начале списка предыдущий // EXECEPTION_REGISTRATION. add esp, 8 // Удаляем из стека структуру EXECEPTION_REGISTRATION. } return 0;}
-
Я ошибся, т.к. спешил. У тебя там сравнения идут вложенные 1. Можно проверить на Lua по таймеру, но это не интересно. 2. Можно написать обработку исключения на АА. Только, что сделал по примеру Xipho с темы, которую привели label(Handler)label(NoException)label(ExceptionHandled)label(lpCaption)label(lpText)00270000: pushad mov esi, Handler push esi push fs:[0] mov fs:[0], esp // Код в этом месте будет проверен на исключения mov ecx, [0] // специальная ошибка доступа к адресу Jmp NoExceptionHandler: mov esp,[esp+0x08] pop fs:[0] add esp, 4 popad // Код в этом месте будет выполнен, если исключение произойдет Jmp ExceptionHandled Jmp NoExceptionNoException: pop fs:[0] // востанавливаем старое исключение add esp, 0x24 //32+4 retExceptionHandled: // исключение было обработано push 0 //uType (0=mb_ok) push lpCaption push lpText push 0 //hWnd call MessageBoxA retlpCaption: db 'Exception!' 0lpText: db 'You have exception' 0
-
label(dqValue) // метка ддя double00280000: // случайный адрес новой памятиdqValue: dq (double)100.1 // 8 байт = (4 байта) + (4 байта)// здесь должна быть метка памяти, сюда прыг// 1- примерfld qword ptr [dqValue]fstp qword ptr [ecx]//----------------------// 2 - пример c сохранением флаговpushffld qword ptr [dqValue]fstp qword ptr [ecx]popf//------------------------// 3 - пример работа с двумя 4-х байтовымиpush eax // сохранить регистр// первая половина (4 байта)mov eax, [dqValue]mov [ecx+00], eax// вторая половина (4 байта)mov eax, [dqValue+4]mov [ecx+04], eaxpop eax // восстановить регистр
-
Поставь процесс игры на паузу из CE (смотри горячие клавиши) Включи скрипт Поставь бряк в дизассемблере на прыжке F5 Далее отпускай паузу процесса и сделай так чтобы выполнилась инструкция с инъекцией Затем F7 и по шагам смотри где ошибка (игра вылетает) Там где ошибка, там догадаешься как исправить. Эти действия можно использовать в любой ситуации, когда игра закрывается из-за ошибки.
-
Результат В CE появилась новая функция в классе DessectCode, которая позволяет получить список функций. -- 1. Поиск адресов функций и ссылок на них-- 2. Вывод результата на консольprocessName = 'test.exe' -- подключенный заранее процесс (у вас другой)function convert(T) local tmp={} for k,v in pairs(T) do tmp[#tmp+1]={k,v} end table.sort(tmp,function (a, return a[1]<b[1] end) return tmpendif (dissectCode == nil) then dissectCode = getDissectCode()enddissectCode.clear()dissectCode.dissect(processName)-- Получить таблицу адресов функцийtableReferencedFunctions = dissectCode.getReferencedFunctions()local is64Bit = targetIs64Bit()stringlist = createStringlist()for i = 1, #tableReferencedFunctions do -- Выводим адрес функции if(is64Bit) then stringlist.add(string.format('%016X:', tableReferencedFunctions[i])) else stringlist.add(string.format('%08X:', tableReferencedFunctions[i])) end tableRefData = dissectCode.getReferences(tableReferencedFunctions[i]) referencesConv = convert(tableRefData) -- Выводим адреса инструкций, которые ссылаются на адрес функции for j=1,#referencesConv do local ref = referencesConv[j][1] --local refhex = string.format('%X', ref) local type = referencesConv[j][2] -- type = 0 - jtCall, -- type = 1 - jtUnconditional (jmp dword ptr [00458014], jmp 00402DDC ...) -- type = 2 - jtConditional (je 0041F2D4, jae 00414B48, jl 00414428...) -- type = 3 - jtMemory ( mov [esi+30],00422950, mov eax,0040FD4C...) stringlist.add(string.format(' %s, type : %d', disassemble(ref), type)) end endstringlist.add('')stringlist.add(string.format('Найдено функций : %d', #tableReferencedFunctions))print(stringlist.Text)stringlist.destroy()
-
CE Lua. Поиск адресов строк и инструкций работающих со строками
MasterGH опубликовал тема в Cheat Engine
Результат -- 1. Поиск адресов строк и ссылок на них-- 2. Вывод результата на консольprocessName = 'test.exe' -- подключенный заранее процесс (у вас другой)function convert(T) local tmp={} for k,v in pairs(T) do tmp[#tmp+1]={k,v} end table.sort(tmp,function (a, return a[1]<b[1] end) return tmpendif (dissectCode == nil) then dissectCode = getDissectCode()enddissectCode.clear()dissectCode.dissect(processName)-- Получить таблицу адресов строкreferencedStrings = dissectCode.getReferencedStrings() referencedStringsConv = convert(referencedStrings)local is64Bit = targetIs64Bit()stringlist = createStringlist()for i = 1, #referencedStringsConv do if(referencedStringsConv[i][1] ~= '') then -- Выводим адрес строки if(is64Bit) then stringlist.add(string.format('%016X:', referencedStringsConv[i][1])) else stringlist.add(string.format('%08X:', referencedStringsConv[i][1])) end -- Значение строки (первые 120 символов без поиска символа конца строки и для одной кодировки без widechar) stringlist.add(string.format(' %s', readString(referencedStringsConv[i][1],120))) -- Теперь ищем адреса ссылки на строку выше tableRefData = dissectCode.getReferences(referencedStringsConv[i][1]) referencesConv = convert(tableRefData) -- Выводим адреса инструкций, которые ссылаются на адрес функции for j=1,#referencesConv do local ref = referencesConv[j][1] --local refhex = string.format('%X', ref) local type = referencesConv[j][2] -- type = 0 - jtCall -- type = 1 - jtUnconditional (jmp dword ptr [00458014], jmp 00402DDC ...) -- type = 2 - jtConditional (je 0041F2D4, jae 00414B48, jl 00414428...) -- type = 3 - jtMemory ( mov [esi+30],00422950, mov eax,0040FD4C...) stringlist.add(string.format(' %s, type : %d', disassemble(ref), type)) end end endstringlist.add('')stringlist.add(string.format('Найдено адресов строк : %d', #referencedStringsConv))print(stringlist.Text)stringlist.destroy() -
Правильно test = readInteger('Dishonored.exe')По поводу глюков. Сообщение внутри игры должно показаться и скрыться. Пока оно не скрылось нельзя вызывать снова ShowMessageInGame и нельзя закрывать CE или трейнер CE, потому что там общие переменные и не они не работают с отдельными сообщениями или одновременными сообщениями. Так написан скрипт. Так что его придется переписывать.
-
gmz, по многим отзывам можно судить, что трейнерами на CE пользуются и довольны ими какими бы они не были жуткими и гигантскими. Кстати формат *.CT для CE 6.5 не плохой. С ним можно не делать никаких трейнеров.
-
Появилась возможность делать прозрачные области в форме трейнера (в том числе генерируемого как exe) WinControl Class: (Inheritance: Control->Component->Object)setLayeredAttributes(Key, Alpha, Flags) : Sets the layered state for the control if possible (Only Forms are supported in in windows 7 and earlier)608 flags can be a combination of LWA_ALPHA and/or LWA_COLORKEY609 See msdn SetLayeredWindowAttributes for more informationformname.setLayeredAttributes(Color, Alpha, flags)
-
Добавлен пример рисования графика в первый пост
-
Запуск lua скрипта происходит автоматически один раз в начале работы трейнера, таблицы .cetrainer, но не .ct. Можно, но с каждым включением будут создаваться новый тамер и стрим звука, а при выключнии скрипта таймер будет отключаться всего лишь. Поэтому надо либо разрушать их под disable, либо не создавать повторно. Лучше последнее.
-
Когда в коде игры происходит какое-то условие, то нельзя просто так взять и взывать CE Lua функцию, т.к. код игры ничего не знает о CE. Здесь нужно немного пошаманить на ассемблере и вот два примера. [ENABLE] {$lua} function testFunc(param) print("Hello world!") print("Calling LUA from ASM!!!:)") print(param) end {$asm} ///#region untouched - Call CE lua function loadlibrary(luaclient-i386.dll) luacall(openLuaServer('CELUASERVER')) globalalloc(luainit, 128) globalalloc(LuaFunctionCall, 128) label(luainit_exit) globalalloc(luaserverinitialized, 4) globalalloc(luaservername, 12) luaservername: db 'CELUASERVER',0 luainit: cmp [luaserverinitialized],0 jne luainit_exit push luaservername call CELUA_Initialize //this function is defined in the luaclient dll mov [luaserverinitialized],eax luainit_exit: ret LuaFunctionCall: push ebp mov ebp,esp call luainit push [ebp+c] push [ebp+8] call CELUA_ExecuteFunction pop ebp ret 8 //luacall call example: //push integervariableyouwishtopasstolua //push addresstostringwithfunction //(The lua function will have access to the variable passed by name "parameter") //call LuaFunctionCall //When done EAX will contain the result of the lua function ///#endregion globalalloc(myVar,4) myVar: dd 0 alloc(luaCallExample, $200) label(funcName) createThread(luaCallExample) luaCallExample: push 1 push funcName call LuaFunctionCall mov [myVar],eax inc [myVar] ret funcName: db 'testFunc',0 [DISABLE]callers={} function store(parameter) if (callers[parameter]==nil) then callers[parameter]=1 else callers[parameter]=callers[parameter]+1 end end function getCallers() for caller,count in pairs(callers) do print(string.format("%x : %d", caller, count)) end end autoAssemble([[ loadlibrary(luaclient-i386.dll) luacall(openLuaServer('CELUASERVER')) globalalloc(luainit, 128) globalalloc(LuaFunctionCall, 128) label(luainit_exit) globalalloc(luaserverinitialized, 4) globalalloc(luaservername, 12) luaservername: db 'CELUASERVER',0 luainit: cmp [luaserverinitialized],0 jne luainit_exit push luaservername call CELUA_Initialize //this function is defined in the luaclient dll mov [luaserverinitialized],eax luainit_exit: ret LuaFunctionCall: push ebp mov ebp,esp call luainit push [ebp+c] push [ebp+8] call CELUA_ExecuteFunction pop ebp ret 8 alloc(newmem,2048) alloc(storecaller, 2048) label(returnhere) label(originalcode) label(exit) storecaller: db 'store(parameter)',0 //------------Modify this part:-------------------- newmem: mov eax,[esp] push eax push storecaller call LuaFunctionCall originalcode: mov edi,edi push ebp mov ebp,esp exit: jmp returnhere "USER32.dll"+205BA: //peekMessageW jmp newmem returnhere: ]])
-
Насколько я знаю, этот косяк только у Интернет браузера Опера. 1. Необходимо читать весь указатель, а не часть его. Потому что на протяжении игры путь указателя может поменяться 2. Необходимо быть точно уверенным, что при чтении float адреса корректно условие if (Bodies > 0). Т.е. надо посмотреть значение Bodies до и после изменений с помощью функции print. Можно обратить внимание на someValue > 0.0 (ниже в скрипте), надо в консоли lua (из окна отладчика) используя print(readFloat ('[[[[Dishonored.exe+01084EE0]+40]+10]+1D8]+0x4')) посмотреть чему равно значение до и после "тревоги" 3.. Можно сделать так, чтобы звук тревоги играл всегда, когда по указателям находятся значения отличные от нуля. С помощью следующего скрипта сможешь как отключить таймер, так и запустить его снова Повесить на хот кей на обычный АА скрипт в таблицу с луа в ставками [Enable]{$lua}alarmTimer.Enabled = true[Disable]{$lua}alarmTimer.Enabled = falsefunction OnTimer() -- должны читать всегда указатель полностью, т.к. его путь может меняться local bodies = readInteger ('[[[[Dishonored.exe+01084EE0]+40]+10]+1D8]+4') -- заменить цепочку указателей для чтения float local someValue = readFloat ('[[[[Dishonored.exe+01084EE0]+40]+10]+1D8]+4') -- Если удалось прочитать значение указателя и bodies > 0 if (bodies ~= nil and bodies > 0) then -- ирать файл, если он не играет playSound(streamTada, true) end if (someValue != nil and someValue > 0.0) then -- ирать файл, если он не играет playSound(streamTada, true) end end-- Должно вызываться один разstreamTada = createMemoryStream()streamTada.loadFromFile('d:\\Files\\wav\\Sound.wav') -- заменить на свой звукalarmTimer = createTimer()alarmTimer.Interval = 1000alarmTimer.OnTimer = OnTimer