-
Постов
2 999 -
Зарегистрирован
-
Победитель дней
129
Тип контента
Профили
Форумы
Загрузки
Блоги
Весь контент MasterGH
-
aamaker_2.3 можно не использовать. У CE есть шаблон с AOB Но, исправление плагина может помочь генерировать АА скрипты особенным образом.
-
1. Если выбрал С++, то тогда тебе не нужна генерация трейнеров на CE. CE тебе пригодится в лучшем случае для сбора данных и генерации исходников на С++. 2. Если выбрал трейнеры на CE да еще и с эффектами, то тогда CE AA, CE Lua и Дельфи. Ибо CE Lua это для тех, кто что-то когда-то писал на Дельфи. CE Lua это обертка Дельфи (особенно что касается визуальных эффектов). Если Дельфи не знаешь, а тем более принципа написания программ, будет довольно сложно или вообще никак. 3. Перевода main.lua скорее всего никогда не будет. Всем влом переводить. 4. С++ можно не учить, а сразу на нем писать. Самый простой пример // Если нажали на кнопку F4if( (GetAsyncKeyState(VK_F4) & 1) == 1){ HWND hWnd; DWORD dwID; HANDLE hProcess; // Ищем существующий hWnd по имени окна hWnd = FindWindow(NULL, "Test"); // Получаем id процесса по hWnd GetWindowThreadProcessId(hWnd, &dwID); // Создать hProcess, открывая по dwID с правами PROCESS_ALL_ACCESS hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, dwID); // Значение 1000000 записать в адрес 0x45B5A4 int value = 1000000; WriteProcessMemory(hProcess, (void*)0x45B5A4, &value, sizeof(&value), NULL); // Закрыть hProcess (мы же его создали в системе, надо и закрыть) CloseHandle(hProcess);}
-
Если уроков по созданию трейнеров на CE нет, то значит учатся без них. Сначала добиваешься своих целей на Дельфи 7 с помощь поисковиков. Вот например не плхой тутор про рисование
-
Скорее всего, у Button или Label с обработкой события Клика будет другой код. Нужно получить ссылку на Font, Canvas, Brush. У меня же просто текст.
-
Здесь цвет меняется по таймеру с интервалом 100 мс от черного до красного на величину 0x10. Как сделать смену прозрачности я не знаю. Похоже нужно вызывать Windows API потоком чтобы делать прозрачность. У Дельфи или у Лазаря сложности с прозрачным текстом и эти сложности переходят в CE Lua. speedInterval = 100function Draw() font.Color = colorRed canvas.TextOut(10, 10, 'Gamehacklab[RU]') if(bForwardPathIncrement) then colorRed = colorRed - 0x10 else colorRed = colorRed + 0x10 end if(colorRed > 0xFF) then bForwardPathIncrement = true colorRed = 0xF0 end if(colorRed < 0x10) then bForwardPathIncrement = false colorRed = 0x10 endendif(myTimer == nil) then UDF1 = createForm(true) UDF1.width = 400 UDF1.height = 200 UDF1.centerScreen() canvas = UDF1.getCanvas() font = canvas.Font font.Size = 25 canvas.Brush.Style = 1 colorRed = 0x10 bForwardPathIncrement = false myTimer = createTimer(UDF1, true) myTimer.Interval = speedInterval myTimer.OnTimer = Drawend
-
Добавлен 14 пункт "Как работать с классом Disassembler?" 1) Можем узнать является ли инструкция: прыжком, условным прыжком, вызовом, ret-ом 2) Можем узнать opcode, например "mov" 3) Можем узнать parameters, например "edx,[ebp-04]" 2) Можем узнать modrmValueType (dvtNone=0, dvtAddress=1, dvtValue=2) 3) Можем узнать parameterValueType (dvtNone=0, dvtAddress=1, dvtValue=2) 4) Можем узнать значение modrmValue 5) Можем узнать значение parameterValue Другие функции класса Disassembler не рассмотрены
-
На CE Lua можно создавать множество одинаковых форм. Если мы хотим работать с ней как с одной, то когда открывается некоторая форма мы должны сравнить класс формы и перезаписать ссылку на форму. Пример function FormCreateNotify(form) -- Эта функция всегда будет срабатывать, когда любая форма открывается if form.getClassName()=='TFormMemoryRegions' then FormMemoryRegions = form -- перезаписываем ссылку и будем работать с формами как с одной FormMemoryRegions print("Found the memory region form and stored it in FormMemoryRegions"); endendFormMemoryRegions = nil -- объявление метки перед регистрациейmyfc = registerFormAddNotification(FormCreateNotify); -- связываем функцию Описание registerFormAddNotification(function(form)): Registers a function to be called when a form is attached to ce's form list. This is useful for extentions that add new functionality to certain existing forms. It returns an object you can use with unregisterFormAddNotificationunregisterFormAddNotification(Object) Для того чтобы убрать связь формы
-
На CE Lua можно рисовать. Пример1. Рисование графика (без шкалы) Chart.CT function CEButton1Click(sender) ClBlack = 0x000000 ClRed = 0x0000FF ClGreen = 0x008000 ClWhite = 0xFFFFFF local CEImage1 = frmChartTool.CEImage1 local canvas = CEImage1.Canvas local pen = canvas.Pen local brush = canvas.Brush local x1 = -10.0 -- Начало оси Ox local x2 = 10.0 -- Конец оси Ox local m = 50.0 -- Масштаб графика -- Центры осей Ox и Oy local x0 = 0 local y0 = 0 -- Координаты, по которым отрисовывается график local x = 0.0 local y = 0.0 canvas.clear() x0 = CEImage1.Width / 2.0 -- x0 = центр Image1 по оси Ox y0 = CEImage1.Height / 2.0 -- y0 = центр Image1 по оси Oy pen.Color = ClGreen -- Цвет пера зеленый pen.Width = 1 -- Ширина пера = 1 canvas.setPenPosition(0, y0) -- Положение курсора = (0,y0) canvas.lineTo(CEImage1.Width, y0) -- Линия от (0,y0) до (width,y0) - линия оси Ox canvas.setPenPosition(x0, 0) -- Положение курсора = (x0,0) canvas.lineTo(x0, CEImage1.Height) -- Линия от (x0,0) до (x0,height) - линия оси Oy pen.Color = ClRed -- Цвет пера = красный pen.Width = 2 -- Ширина пера = 2 x = x1 -- Начальное положение курсора по оси Ox y = math.sin(x) -- Начальное положение курсора по оси Oy canvas.setPenPosition(x0+math.floor(x*m), math.floor(y0-y*m)) -- Переносим курсор на заданные while x < x2 do -- координаты относительно центра осей координат и масштаба x = x + 0.01 y = math.sin(x) canvas.lineTo(x0+math.floor(x*m), math.floor(y0-y*m)) endendfunction Draw() r = math.random(x0) y = y0-r u = u + 1 pen.Color = math.random(0xffffff) x = x0 + math.floor(r * math.sin(u * math.pi/180)) y = y0 - math.floor(r * math.cos(u * math.pi/180)) canvas.line(x0, y0, x, y) if(u > 360) then u = 0 endendif(UDF1 == nil) then UDF1 = createForm(true) UDF1.width = 800 UDF1.height = 800 UDF1.centerScreen() canvas = UDF1.getCanvas() pen = canvas.Pen x0 = UDF1.ClientWidth / 2 y0 = UDF1.ClientHeight / 2 u = 0 r = y0 - 20 x = x0 myTimer = createTimer(UDF1, true) myTimer.Interval = 10 myTimer.OnTimer = DrawendCanvas Class : (Inheritance: CustomCanvas->Object)properties Brush: Brush - The brush object Pen: Pen - The pen object Font: Font - The font object Width: integer - Width of the canvas Height: integer - Height of the canvasmethods getBrush(): Returns the brush object of this canvas getPen(): Returns the pen object of this canvas getFont(): Returns the font object of this canvas getWidth() getHeight() getPenPosition() setPenPosition(x,y) clear() - Clears the canvas line(sourcex, sourcey, destinationx, destinationy) lineTo(destinationx, destinationy) rect(x1,y1,x2,y2) fillRect(x1,y1,x2,y2) textOut(x,y, text) getTextWidth(text) getTextHeight(text) getPixel(x,y) setPixel(x,y,color) floodFill(x,y) ellipse(x1,y1,x2,y2) gradientFill(x1,y1,x2,y2, startcolor, stopcolor, direction) : Gradient fills a rectangle. Direction can be 0 or 1. 0=Vertical 1=Horizontal copyRect(dest_x1,dest_y1,dest_x2,dest_y2, sourceCanvas, source_x1,source_y1,source_x2,source_y2) : Draws an image from one source to another. Usefull in cases of doublebuffering draw(x,y, graphic) : Draw the image of a specific Graphic class getClipRect() : Returns a table containing the fields Left, Top, Right and Bottom, which define the invalidated region of the graphical object. Use this to only render what needs to be rendered in the onPaint event of objectsPen Class : (Inheritance: CustomPen->CanvasHelper->Object)properties Color: Integer - The color of the pen Width: integer - Thickness of the penmethods getColor() setColor(color) getWidth() setWidth(width)</Some><Some>Brush Class : (Inheritance: CustomBrush->CanvasHelper->Object)properties Color : Integermethods getColor() setColor()Font Class : (Inheritance: CustomFont->CanvasHelper->Object)createFont(): Returns a font object (default initialized based on the main ce window)properties Name: string Size: integer Color: integermethods getName(): Gets the fontname of the font setName(string): Sets the fontname of the font getSize(): Gets the size of the font setSize(integer): Sets the size of the font getColor(): Gets the color of the font setColor(integer): Sets the color of the font assign(font): Copies the contents of the font given as parameter to this font</Some>Graphic Class : (Inheritance: Object) : Abstract classproperties Width: integer Height: integer Transparent: booleanmethods getWidth(graphic): Gets the current width in pixels of this graphics object setWidth(graphic, width): Sets thw width in pixels getHeight(graphic) setHeight(graphic, height)</Some>RasterImage class: (Inheritance: Graphic->Object) : Base class for some graphical controlsproperties Canvas: Canvas PixelFormat: PixelFormat - the pixelformat for this image. Will clear the current image if it had one. Supported pixelformats: pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit (recommended) TransparentColor: integermethods getCanvas(): Returns the Canvas object for this image getPixelFormat(): Returns the current pixelformat getPixelFormat(pixelformat): Sets the pixelformat for this image. Will clear the current image if it had one. Supported pixelformats: pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit (recommended) setTransparentColor(integer): Sets the color that will be rendered as transparent when drawn getTransparentColor(): Returns the color set to be transparentBitmap class: (Inheritance: CustomBitmap->RasterImage->Graphic->Object) : Bitmap based Graphic objectcreateBitmap(width, height) - Returns a Bitmap object
-
Нет, не codeinjection. Записать в какой-нибудь памяти (ближе к концу страницы, где место свободное) фейковую структуру. Записать туда данные по смещениям. Найти указатель на оригинальную структуру и подменить его на указатель фейковой структуры. Возможно камера будет следовать по данным фейковой структуры. Никакого изменения кода здесь не будет, только запись/чтение данных. Это мое предположение как избежать правку кода.
-
>>Вот такой вопрос, как заставить его постоянно держать одно значение? Камера может привязываться к позиции из структуры по указателю на эту структуру. Например камера привязывается к игроку по указателю на его структуру и из этой структуры читает координаты и рассчитывает свои. Камера не может улетать далеко от игрока. Если ты создаешь фейковую структуру с фейковыми координатами и прицепишь её к камере, то камера по идеи может стремиться к ним. Т.е. выделить память с адресами по смещениям и записать указатель на эту структуру. Код менять не придется. Забанят или нет не знаю.
-
Просьба в личку по поводу смены статуса не спамить. В последнее время жестко подставляю ребят администраторов по организационным вопросам. С ними очень мало общаюсь и в следствии этого многие вещи они делают без моего участия. Это длится уже много времени. И когда у меня нахлынет желание "навести порядок" я их жестко подставляю или вынужден у них спрашивать, что можно делать, а что нельзя. Спрашивать по каждому поводу, что и как делать я естественно не буду, но и насильно заставлять себя вливаться в общение мне не интересно. Учитывая сложившиеся обстоятельства, есть желание перейти в разработчики, выражать свою позицию не мешая организационным планам. Немного жаль, но такие обстоятельства, человек выбирает место где ему более комфортнее.
- 2 ответа
-
- 1
-
-
Какое оформление запроса на трейнеры и таблицы для вас удобно?
- 1 ответ
-
- 2
-
-
1. Скорее всего "платформозависимый трейнер", т.е. я имел ввиду трейнер зависимый от платформы .net или виртуальных машин на основе .net платформы (например Mono) 2. В трейнере можно вызывать не только функции винапи, а других апи ОС-м 3. Если игра написана на .net, то используя .net функции можно найти объекты, типы, функции и поля и менять их удобным образом, а не работать с функциями ОС-мы. 4. Если игра написана, используя технологию виртуальной машины будь, то Mono (или Java или другие), то вызывая функции Mono можно искать и менять поля экземпляров классов без импорта функции определенной ОС-ы. В терии можешь проверить сам. Устанавливаешь две операционных системы (Линукс и Мак). Устанавливаешь игровой движок Unity3d. Собираешь на нем две игры под две ОС-и. Проверяешь, что обе игры работают с Mono. Если да, то ищешь способ как вызывать функции Mono, а не функции ОС.
-
Последняя ревизия была 18 апреля. Уже месяц ничего нового. Прошлый релиз CE 6.4 был 16 Июня. Возможно CE будет летом или позднее.
-
Кому интересно, Рубик делает ультракил под отрывок трека "F.O.O.L - Punks" ссылки под видео на Ютубе.
-
В теме я публиковал ссылку на исходники. Я вытащил наиболее интересные классы в архиве void CWeapon::SetAmmoElapsed(int ammo_count){ iAmmoElapsed = ammo_count; u32 uAmmo = u32(iAmmoElapsed); if (uAmmo != m_magazine.size()) { if (uAmmo > m_magazine.size()) { CCartridge l_cartridge; l_cartridge.Load (m_ammoTypes[m_ammoType].c_str(), m_ammoType); while (uAmmo > m_magazine.size()) m_magazine.push_back(l_cartridge); } else { while (uAmmo < m_magazine.size()) m_magazine.pop_back(); }; };}void CWeaponMagazined::ReloadMagazine() { m_BriefInfo_CalcFrame = 0; //устранить осечку при перезарядке if(IsMisfire()) bMisfire = false; if (!m_bLockType) { m_pCurrentAmmo = NULL; } if (!m_pInventory) return; if ( m_set_next_ammoType_on_reload != undefined_ammo_type ) { m_ammoType = m_set_next_ammoType_on_reload; m_set_next_ammoType_on_reload = undefined_ammo_type; } if(!unlimited_ammo()) { if (m_ammoTypes.size() <= m_ammoType) return; LPCSTR tmp_sect_name = m_ammoTypes[m_ammoType].c_str(); if (!tmp_sect_name) return; //попытаться найти в инвентаре патроны текущего типа m_pCurrentAmmo = smart_cast<CWeaponAmmo*>(m_pInventory->GetAny(tmp_sect_name)); if(!m_pCurrentAmmo && !m_bLockType) { for(u8 i = 0; i < u8(m_ammoTypes.size()); ++i) { //проверить патроны всех подходящих типов m_pCurrentAmmo = smart_cast<CWeaponAmmo*>(m_pInventory->GetAny( m_ammoTypes[i].c_str() )); if(m_pCurrentAmmo) { m_ammoType = i; break; } } } } //нет патронов для перезарядки if(!m_pCurrentAmmo && !unlimited_ammo() ) return; //разрядить магазин, если загружаем патронами другого типа if(!m_bLockType && !m_magazine.empty() && (!m_pCurrentAmmo || xr_strcmp(m_pCurrentAmmo->cNameSect(), *m_magazine.back().m_ammoSect))) UnloadMagazine(); VERIFY((u32)iAmmoElapsed == m_magazine.size()); if (m_DefaultCartridge.m_LocalAmmoType != m_ammoType) m_DefaultCartridge.Load( m_ammoTypes[m_ammoType].c_str(), m_ammoType ); CCartridge l_cartridge = m_DefaultCartridge; while(iAmmoElapsed < iMagazineSize) { if (!unlimited_ammo()) { if (!m_pCurrentAmmo->Get(l_cartridge)) break; } ++iAmmoElapsed; l_cartridge.m_LocalAmmoType = m_ammoType; m_magazine.push_back(l_cartridge); } VERIFY((u32)iAmmoElapsed == m_magazine.size()); //выкинуть коробку патронов, если она пустая if(m_pCurrentAmmo && !m_pCurrentAmmo->m_boxCurr && OnServer()) m_pCurrentAmmo->SetDropManual(TRUE); if(iMagazineSize > iAmmoElapsed) { m_bLockType = true; ReloadMagazine(); m_bLockType = false; } VERIFY((u32)iAmmoElapsed == m_magazine.size());}void CWeaponMagazined::UnloadMagazine(bool spawn_ammo){ xr_map<LPCSTR, u16> l_ammo; while(!m_magazine.empty()) { CCartridge &l_cartridge = m_magazine.back(); xr_map<LPCSTR, u16>::iterator l_it; for(l_it = l_ammo.begin(); l_ammo.end() != l_it; ++l_it) { if(!xr_strcmp(*l_cartridge.m_ammoSect, l_it->first)) { ++(l_it->second); break; } } if(l_it == l_ammo.end()) l_ammo[*l_cartridge.m_ammoSect] = 1; m_magazine.pop_back(); --iAmmoElapsed; } VERIFY((u32)iAmmoElapsed == m_magazine.size()); if (!spawn_ammo) return; xr_map<LPCSTR, u16>::iterator l_it; for(l_it = l_ammo.begin(); l_ammo.end() != l_it; ++l_it) { if(m_pInventory) { CWeaponAmmo *l_pA = smart_cast<CWeaponAmmo*>(m_pInventory->GetAny(l_it->first)); if(l_pA) { u16 l_free = l_pA->m_boxSize - l_pA->m_boxCurr; l_pA->m_boxCurr = l_pA->m_boxCurr + (l_free < l_it->second ? l_free : l_it->second); l_it->second = l_it->second - (l_free < l_it->second ? l_free : l_it->second); } } if(l_it->second && !unlimited_ammo()) SpawnAmmo(l_it->second, l_it->first); }}
-
Внедряем свою dll-ку в игру на Unity3D с помощью CE AA
MasterGH опубликовал тема в Игрострой и отладка
Зачем вообще надо внедрять длл в Юнити игры? И что такое Моно? Например, я хочу сделать читы, посмотреть игровые объекты или очень сильно модифицировать игру, если это конечно не нарушает авторские права. Например, для просмотра названия объектов их компонентов я сделал такую штуку На Юнити3д будет все больше и больше появляться игрушек так, что кому-то будет интересным их поковырять. Моно образно это классы, функции и прочее на базе .net. Позволяет на многих устройствах играть в игры, а не только на компе. Но на компе можно внедрять длл с помощью CE. Принцип внедрения на высоком уровне рассматривался здесь здесь MonoDomain * domain = mono_jit_init(""); MonoAssembly* msCorlib = mono_domain_assembly_open (domain,"mscorlib"); MonoImage* image = mono_assembly_get_image(msCorlib); MonoClass *klass = mono_class_from_name (image, "System", "Exception"); MonoObject* o = mono_object_new (domain, klass); MonoMethodDesc* methodDesc = mono_method_desc_new("System.Object:ToString", TRUE); MonoMethod* toStringMethod = mono_method_desc_search_in_class(methodDesc, klass); MonoObject* result = mono_runtime_invoke(toStringMethod, o, NULL, NULL);[ENABLE]//mono_assembly_foreach //mono_assembly_getimage alloc(bla, 2048) alloc(testdllpath, 256); alloc(domain,4) alloc(image,4) alloc(classdef,4) alloc(classobject, 4) alloc(methodDesc,4) alloc(method,4) registersymbol(domain) registersymbol(image) registersymbol(classdef) registersymbol(classobject) registersymbol(methodDesc) registersymbol(method) alloc(result,4) registersymbol(result) alloc(result2,4) registersymbol(result2) alloc(strTestLib,64) alloc(strClass1,64) alloc(strSomething,64) alloc(params, 32) alloc(exception,4) registersymbol(exception) strTestLib: db 'NamespaceCheats',0 // пространство имени например NamespaceCheats strClass1: // Название класса db 'Cheats',0 strSomething: // Название метода db '*:Main',0 testdllpath: // Путь до dll db 'D:\Cheat.dll',0 bla: //foreach domain is useful too call mono.mono_get_root_domain mov [domain],eax push eax call mono.mono_thread_attach add esp,4 push testdllpath push [domain] call mono.mono_domain_assembly_open add esp,8 push eax call mono.mono_assembly_get_image add esp,4 mov [image],eax push strClass1 push strTestLib push eax call mono.mono_class_from_name add esp, c mov [classdef],eax //create a class push eax //classdef push [domain] call mono.mono_object_new add esp, 8 mov [classobject],eax push eax call mono.mono_runtime_object_init //execute the nameless constructor (if there is one) add esp,4 //find the method push 0 push strSomething call mono.mono_method_desc_new add esp,8 mov [methodDesc], eax push [classdef] push eax call mono.mono_method_desc_search_in_class add esp,8 mov [method], eax mov [params],0 push exception push params //no params push [classobject] push eax //[method] call mono.mono_runtime_invoke add esp,10 mov [result],eax ret result: dd 0 result2: dd 0 createthread(bla) [DISABLE]//code from here till the end of the code will be used to disable the cheatusing System;using UnityEngine;namespace NamespaceCheats{ public class Cheats { public static void Main() { new GameObject { name = "Cheats" }.AddComponent<LoadAsset>(); } }}public class LoadAsset : MonoBehaviour{ private void OnGUI() { GUI.Label(new Rect(0f, 10f, 500f, 30f), "Status: ON"); } private void Start() { GameObject gameObject = new GameObject(); gameObject.AddComponent<ProviderHierarchy>(); UnityEngine.Object.Destroy(base.gameObject); }}using System;using System.Collections;using System.Collections.Generic;using System.Reflection;using System.Text;using UnityEngine;public class ProviderHierarchy : MonoBehaviour{ public class Inspector { public class DataComponent { public bool hasEnabledState; public bool isUserComponent; public string nameComponent; public Component component; private bool cashStateEnabled; private bool cashWriteStateEnabled; private PropertyInfo propertyInfo; public bool enabled { get { return this.cashStateEnabled; } set { this.cashWriteStateEnabled = value; if (this.cashStateEnabled != this.cashWriteStateEnabled) { this.propertyInfo.SetValue(this.component, this.cashWriteStateEnabled, null); } } } public DataComponent(Component argComponent) { this.component = argComponent; string text = this.component.GetType().ToString(); if (text.Contains("UnityEngine.")) { text = text.Remove(0, "UnityEngine.".Length); } if (argComponent as MonoBehaviour != null) { this.isUserComponent = true; text += " (Script)"; } this.nameComponent = text; Type type = this.component.GetType(); this.propertyInfo = type.GetProperty("enabled"); this.hasEnabledState = (this.propertyInfo != null); if (this.hasEnabledState && this.propertyInfo != null) { this.cashStateEnabled = (this.cashWriteStateEnabled = (bool)this.propertyInfo.GetValue(this.component, null)); } } public void UpdateViewData() { if (this.hasEnabledState && this.component != null && this.propertyInfo != null) { this.cashStateEnabled = (bool)this.propertyInfo.GetValue(this.component, null); } } } public GameObject parentGameObject; public string parentGameObjectName; public List<ProviderHierarchy.Inspector.DataComponent> listComponents = null; private float cashTime; private bool cashStateEnabled; private bool cashWriteStateEnabled; public bool enabledGO { get { return this.cashStateEnabled; } set { this.cashWriteStateEnabled = value; if (this.cashStateEnabled != this.cashWriteStateEnabled) { if (this.parentGameObject != null) { this.parentGameObject.SetActiveRecursively(this.cashWriteStateEnabled); } } } } public Inspector(GameObject argParentGameObject) { this.parentGameObject = argParentGameObject; this.cashStateEnabled = (this.cashWriteStateEnabled = this.parentGameObject.active); this.parentGameObjectName = this.parentGameObject.name; Component[] components = this.parentGameObject.GetComponents<Component>(); this.listComponents = new List<ProviderHierarchy.Inspector.DataComponent>(); Component[] array = components; for (int i = 0; i < array.Length; i++) { Component argComponent = array[i]; ProviderHierarchy.Inspector.DataComponent item = new ProviderHierarchy.Inspector.DataComponent(argComponent); this.listComponents.Add(item); } } public void UpdateViewData() { this.cashTime += Time.deltaTime; if (this.cashTime > 0.3f) { this.cashTime = 0f; if (this.parentGameObject != null) { this.cashStateEnabled = this.parentGameObject.active; } foreach (ProviderHierarchy.Inspector.DataComponent current in this.listComponents) { current.UpdateViewData(); } } } } public class HierarchyData { public Transform tr; public bool isShow = true; public bool isCollapse; public string caption; public List<ProviderHierarchy.HierarchyData> tree = new List<ProviderHierarchy.HierarchyData>(); public GUIStyle privateGuiStyle; public Texture2D imagePlus; public Texture2D imageMinus; public int deeper = 0; public Rect rect; public HierarchyData(Rect rect, Transform tr, string caption, Texture2D imagePlus, Texture2D imageMinus, GUIStyle argGuiStyle, int deeper) { this.tr = tr; this.caption = caption; this.imagePlus = imagePlus; this.imageMinus = imageMinus; this.privateGuiStyle = argGuiStyle; this.deeper = deeper; this.rect = rect; } public void Add(ProviderHierarchy.HierarchyData data) { this.tree.Add(data); } public void Add(Rect rect, Transform tr, string caption, Texture2D imagePlus, Texture2D imageMinus, GUIStyle argGuiStyle, int deeper) { this.tree.Add(new ProviderHierarchy.HierarchyData(rect, tr, caption, imagePlus, imageMinus, argGuiStyle, deeper)); } public void Hide() { foreach (ProviderHierarchy.HierarchyData current in this.tree) { current.isShow = false; current.Hide(); } } public void Show() { foreach (ProviderHierarchy.HierarchyData current in this.tree) { current.isShow = true; if (!current.isCollapse) { current.Show(); } } } public static bool FindChildsStringToBuilder(List<Transform> childs, Transform parent, ref StringBuilder sb, ref int innerCount) { int num = innerCount; bool result = false; innerCount++; string text = string.Empty; for (int i = 0; i < innerCount; i++) { text += " "; } foreach (Transform current in childs) { if (current.parent == parent) { sb.Append(string.Format(" {0}|_{1}", text, current.gameObject.name)); ProviderHierarchy.HierarchyData.FindComponentsStringToBuilder(current, ref sb); ProviderHierarchy.HierarchyData.FindChildsStringToBuilder(childs, current, ref sb, ref innerCount); result = true; } } innerCount = num; return result; } public static void FindComponentsStringToBuilder(Transform parent, ref StringBuilder sb) { sb.Append(" ("); Component[] components = parent.GetComponents(typeof(Component)); Component[] array = components; for (int i = 0; i < array.Length; i++) { Component component = array[i]; sb.Append(component.ToString()); sb.Append(", "); } sb.Remove(sb.Length - 2, 2); sb.AppendLine(" )"); } } public GUISkin myGuiSkin; public bool isShowBtnCopyToBuffer; public bool isShowButtonFogState; private Color colorSelected = new Color32(62, 255, 239, 255); private Color colorSelectedNoActive = new Color32(113, 178, 173, 255); private Color colorNoActiveObject = new Color32(146, 146, 146, 255); private Color colorNull = new Color32(129, 0, 0, 255); private string caption = "Tree view"; private float timeUpdate = 5f; private float dx = 0.7f; private float dy = 1.72f; private float dx1 = 10f; private float dy1 = 12.45f; private Texture2D imagePlus = null; private Texture2D imageMinus = null; private Rect rectPosition = new Rect(30f, 30f, 350f, 500f); private Rect rectView = new Rect(30f, 0f, 40f, 500f); private Rect rectInspector = new Rect(388f, 30f, 247f, 500f); private bool isCopyText; private bool isHierarchy; private bool isInSpector = true; private bool isHide; private float lstTime; private float viewHeight; private Rect parentRect; private Rect bottomPanel; private Vector2 scrollView; private ProviderHierarchy.HierarchyData treeData = null; private List<Transform> trList = new List<Transform>(); private ProviderHierarchy.HierarchyData selectedHierarchyData; private List<ProviderHierarchy.HierarchyData> listFroward = new List<ProviderHierarchy.HierarchyData>(); private List<ProviderHierarchy.HierarchyData> cashFroward = new List<ProviderHierarchy.HierarchyData>(); private ProviderHierarchy.Inspector inspector = null; private float bottomHeight = 30f; private float resizeGUITime; private GUIStyle privateGuiStyle; private GameObject herold = null; private CharacterController characterController; private GameObject gameCamera = null; private bool heroldCheat; private bool isMovingLeft; private bool isMovingRight; private float currentSpeed = 5f; private Vector3 deltaCameraPosition; private bool isBeginUpdate; private void FillInspector(Transform transformselected) { this.inspector = new ProviderHierarchy.Inspector(transformselected.gameObject); } private void Awake() { UnityEngine.Object.DontDestroyOnLoad(this); } private void OnLevelWasLoaded() { this.UpdateTreeView(); } private IEnumerator Start() { this.bottomPanel = new Rect(0f, (float)Screen.height - 30f, (float)Screen.width, 30f); this.privateGuiStyle = new GUIStyle(); this.privateGuiStyle.normal.textColor = Color.white; this.privateGuiStyle.fontSize = 22; this.privateGuiStyle.fontStyle = FontStyle.Normal; this.privateGuiStyle.alignment = TextAnchor.MiddleLeft; this.privateGuiStyle.wordWrap = false; this.privateGuiStyle.imagePosition = ImagePosition.ImageLeft; this.privateGuiStyle.fixedHeight = 20f; this.timeUpdate = 10000f; this.dx = 0f; this.dy = 30f; this.dx1 = 10f; this.dy = 20f; this.caption = "Tree view"; this.rectPosition = new Rect(30f, 30f, 350f, 500f); this.rectView = new Rect(30f, 0f, 450f, 500f); this.rectInspector = new Rect(388f, 30f, 247f, 500f); this.myGuiSkin = ScriptableObject.CreateInstance<GUISkin>(); this.myGuiSkin.button.onFocused.textColor = new Color32(0, 0, 0, 255); this.myGuiSkin.button.border = new RectOffset(6, 6, 46, 4); this.myGuiSkin.button.margin = new RectOffset(4, 4, 4, 4); this.myGuiSkin.button.padding = new RectOffset(6, 6, 3, 3); this.myGuiSkin.button.normal.textColor = new Color32(255, 141, 34, 255); this.myGuiSkin.button.fontSize = 23; this.myGuiSkin.button.alignment = TextAnchor.MiddleCenter; this.myGuiSkin.button.wordWrap = false; this.myGuiSkin.button.imagePosition = ImagePosition.TextOnly; this.myGuiSkin.button.stretchWidth = false; this.myGuiSkin.button.stretchHeight = false; this.myGuiSkin.customStyles = new GUIStyle[0]; WWW wWW = new WWW("file://localhost//D://Minus.png"); // создайте свою иконку узла в TreeView yield return wWW; this.imageMinus = wWW.texture; WWW wWW2 = new WWW("file://localhost//D://Plus.png");// создайте свою иконку узла в TreeView yield return wWW2; this.imagePlus = wWW2.texture; this.UpdateTreeView(); yield break; } private void IncreacedZoomGUI() { this.myGuiSkin.button.fontSize++; this.privateGuiStyle.fontSize++; } private void DecreasedZoomGUI() { this.myGuiSkin.button.fontSize--; this.privateGuiStyle.fontSize--; } private void OnGUI() { if (this.isHide) { GUILayout.BeginArea(this.bottomPanel); GUILayout.BeginHorizontal(new GUILayoutOption[0]); if (GUILayout.Button("Tools", this.myGuiSkin.button, new GUILayoutOption[] { GUILayout.Width(120f) })) { this.isHide = !this.isHide; } GUILayout.EndHorizontal(); GUILayout.EndArea(); } else { GUILayout.BeginArea(this.bottomPanel); GUILayout.BeginHorizontal(new GUILayoutOption[0]); if (GUILayout.Button("Hierarchy", this.myGuiSkin.button, new GUILayoutOption[0])) { this.isHierarchy = !this.isHierarchy; } this.resizeGUITime += Time.deltaTime; if (this.resizeGUITime > 1f && Event.current.type == EventType.Repaint) { this.resizeGUITime = 0f; this.bottomHeight = GUILayoutUtility.GetLastRect().height; this.bottomPanel.y = (float)Screen.height - this.bottomHeight; this.bottomPanel.width = (float)Screen.width; this.bottomPanel.height = this.bottomHeight; } GUILayout.Space(5f); GUI.enabled = this.isHierarchy; if (GUILayout.Button("Inspector", this.myGuiSkin.button, new GUILayoutOption[0])) { this.isInSpector = !this.isInSpector; if (this.isInSpector) { if (this.selectedHierarchyData != null && this.selectedHierarchyData.tr != null) { this.FillInspector(this.selectedHierarchyData.tr); } } } GUILayout.Space(5f); GUI.enabled = true; if (this.isShowBtnCopyToBuffer) { if (GUILayout.Button("Hierarchy Coppy To Buffer", this.myGuiSkin.button, new GUILayoutOption[0])) { Type typeFromHandle = typeof(GUIUtility); PropertyInfo property = typeFromHandle.GetProperty("systemCopyBuffer", BindingFlags.Static | BindingFlags.NonPublic); property.SetValue(null, this.GetTextInfo().ToString(), null); } } GUILayout.Space(5f); if (this.isShowButtonFogState) { if (GUILayout.Button("FOG state", this.myGuiSkin.button, new GUILayoutOption[0])) { RenderSettings.fog = !RenderSettings.fog; } } GUILayout.Space(5f); if (GUILayout.Button("GUI+", this.myGuiSkin.button, new GUILayoutOption[0])) { this.IncreacedZoomGUI(); } GUILayout.Space(5f); if (GUILayout.Button("GUI-", this.myGuiSkin.button, new GUILayoutOption[0])) { this.DecreasedZoomGUI(); } GUILayout.Space(5f); if (GUILayout.Button("Update", this.myGuiSkin.button, new GUILayoutOption[0])) { this.UpdateTreeView(); } GUILayout.Space(5f); if (GUILayout.Button("HIDE", this.myGuiSkin.button, new GUILayoutOption[0])) { this.isHide = !this.isHide; } GUILayout.EndHorizontal(); GUILayout.EndArea(); if (this.treeData != null && !this.isCopyText && !this.isBeginUpdate) { if (this.isHierarchy) { GUI.Box(this.rectPosition, this.caption); this.rectView.height = this.parentRect.y + 10f; this.scrollView = GUI.BeginScrollView(this.rectPosition, this.scrollView, this.rectView, true, true); float num = 0f; float num2 = 0f; Color contentColor = GUI.contentColor; foreach (ProviderHierarchy.HierarchyData current in this.listFroward) { if (current.isShow) { num2 += this.dy; Rect position = new Rect(current.rect); position.y += num; if (current.tree.Count > 0) { Rect position2 = new Rect(position.x, position.y, 16f, 16f); if (GUI.Button(position2, (!current.isCollapse) ? this.imageMinus : this.imagePlus, this.privateGuiStyle)) { if (current.tree.Count > 0) { if (current.isCollapse) { current.isCollapse = false; current.Show(); } else { current.isCollapse = true; current.Hide(); } } } } position.x += 20f; position.y -= 2f; if (this.selectedHierarchyData == current) { if (current != null && current.tr != null) { GUI.contentColor = (current.tr.gameObject.active ? this.colorSelected : this.colorSelectedNoActive); } else { GUI.contentColor = this.colorNull; } } else { if (current != null && current.tr != null) { GUI.contentColor = (current.tr.gameObject.active ? contentColor : this.colorNoActiveObject); } else { GUI.contentColor = this.colorNull; } } if (GUI.Button(position, current.caption, this.privateGuiStyle)) { this.selectedHierarchyData = current; if (this.selectedHierarchyData != null && this.selectedHierarchyData.tr != null) { this.FillInspector(this.selectedHierarchyData.tr); } } if (GUI.contentColor != contentColor) { GUI.contentColor = contentColor; } } else { num -= this.dy; } } if (num2 < this.rectPosition.height) { num2 = this.rectPosition.height; } this.viewHeight = num2; GUI.EndScrollView(); if (this.isInSpector) { GUI.Box(this.rectInspector, string.Empty); if (this.inspector != null) { GUILayout.BeginArea(this.rectInspector); GUILayout.BeginVertical(new GUILayoutOption[0]); GUILayout.BeginHorizontal(new GUILayoutOption[0]); if (GUILayout.Button(this.inspector.enabledGO ? this.imagePlus : this.imageMinus, this.privateGuiStyle, new GUILayoutOption[0])) { this.inspector.enabledGO = !this.inspector.enabledGO; } this.inspector.enabledGO = GUILayout.Toggle(this.inspector.enabledGO, this.inspector.parentGameObjectName, this.privateGuiStyle, new GUILayoutOption[0]); GUILayout.EndHorizontal(); Color color = GUI.color; foreach (ProviderHierarchy.Inspector.DataComponent current2 in this.inspector.listComponents) { if (current2.isUserComponent) { GUI.color = Color.green; } if (!current2.hasEnabledState) { GUILayout.Label(current2.nameComponent, this.privateGuiStyle, new GUILayoutOption[0]); } else { GUILayout.BeginHorizontal(new GUILayoutOption[0]); if (GUILayout.Button(current2.enabled ? this.imagePlus : this.imageMinus, this.privateGuiStyle, new GUILayoutOption[0])) { current2.enabled = !current2.enabled; } current2.enabled = GUILayout.Toggle(current2.enabled, current2.nameComponent, this.privateGuiStyle, new GUILayoutOption[0]); GUILayout.EndHorizontal(); } GUI.color = color; } GUILayout.EndVertical(); GUILayout.EndArea(); } } } } } } private void Update() { if (Input.GetMouseButton(0)) { Screen.lockCursor = false; Screen.set_showCursor(true); } if (this.inspector != null) { this.inspector.UpdateViewData(); } this.parentRect.y = this.viewHeight + 20f; if (!this.isCopyText) { this.lstTime += Time.deltaTime; if (this.lstTime > this.timeUpdate) { this.lstTime = 0f; this.UpdateTreeView(); } } } private void UpdateTreeView() { this.isBeginUpdate = true; bool flag = this.listFroward != null && this.listFroward.Count > 0; if (flag) { this.cashFroward.Clear(); foreach (ProviderHierarchy.HierarchyData current in this.listFroward) { this.cashFroward.Add(current); } } UnityEngine.Object[] array = UnityEngine.Object.FindObjectsOfType(typeof(GameObject)); this.trList = new List<Transform>(); UnityEngine.Object[] array2 = array; for (int i = 0; i < array2.Length; i++) { UnityEngine.Object @object = array2[i]; if ((@object as GameObject).name != "Hack_Tools") { this.trList.Add((@object as GameObject).transform); } } if (flag) { foreach (ProviderHierarchy.HierarchyData current2 in this.cashFroward) { if (current2.tr != null && current2.tr.parent == null && !current2.tr.gameObject.active) { bool flag2 = false; foreach (Transform current3 in this.trList) { if (current3 == current2.tr) { flag2 = true; break; } } if (!flag2) { this.trList.Add(current2.tr); } } } } List<Transform> list = new List<Transform>(); List<Transform> list2 = new List<Transform>(); foreach (Transform current3 in this.trList) { if (current3.parent == null) { list.Add(current3); } else { list2.Add(current3); } } this.parentRect = new Rect(this.rectPosition.x + 10f, 20f, this.rectPosition.width - 10f, this.rectPosition.height - 10f); this.treeData = new ProviderHierarchy.HierarchyData(new Rect(this.parentRect.x + this.dx + 0f * this.dx1, 0f, this.parentRect.width, this.dy1), null, "Game Objects", this.imageMinus, this.imageMinus, this.privateGuiStyle, 0); this.listFroward.Clear(); foreach (Transform current4 in list) { ProviderHierarchy.HierarchyData hierarchyData = new ProviderHierarchy.HierarchyData(new Rect(this.parentRect.x + this.dx + 1f * this.dx1, this.parentRect.y, this.parentRect.width, this.dy1), current4, current4.gameObject.name, this.imagePlus, this.imageMinus, this.privateGuiStyle, 1); this.treeData.Add(hierarchyData); this.listFroward.Add(hierarchyData); this.FindChilds(list2, hierarchyData, 2); this.parentRect.y = this.parentRect.y + this.dy; } this.isBeginUpdate = false; if (flag) { foreach (ProviderHierarchy.HierarchyData current2 in this.cashFroward) { foreach (ProviderHierarchy.HierarchyData current in this.listFroward) { if (current.tr == current2.tr) { if (current2.isCollapse) { current.isCollapse = true; current.Hide(); } } } } } } private void FindChilds(List<Transform> childs, ProviderHierarchy.HierarchyData parentData, int currentDeeper) { Transform tr = parentData.tr; foreach (Transform current in childs) { if (current.parent == tr) { this.parentRect.y = this.parentRect.y + this.dy; ProviderHierarchy.HierarchyData hierarchyData = new ProviderHierarchy.HierarchyData(new Rect(this.parentRect.x + this.dx + (float)currentDeeper * this.dx1, this.parentRect.y, this.parentRect.width, this.dy1), current, current.gameObject.name, this.imageMinus, this.imageMinus, this.privateGuiStyle, currentDeeper + 3); parentData.Add(hierarchyData); this.listFroward.Add(hierarchyData); this.FindChilds(childs, hierarchyData, currentDeeper + 1); } } } private StringBuilder GetTextInfo() { StringBuilder stringBuilder = new StringBuilder(); this.isCopyText = true; UnityEngine.Object[] array = UnityEngine.Object.FindObjectsOfType(typeof(GameObject)); this.trList = new List<Transform>(); UnityEngine.Object[] array2 = array; for (int i = 0; i < array2.Length; i++) { UnityEngine.Object @object = array2[i]; this.trList.Add((@object as GameObject).transform); } List<Transform> list = new List<Transform>(); List<Transform> list2 = new List<Transform>(); foreach (Transform current in this.trList) { if (current.parent == null) { list.Add(current); } else { list2.Add(current); } } this.parentRect = new Rect(this.rectPosition.x + 10f, this.rectPosition.y, this.rectPosition.width - 10f, this.rectPosition.height - 10f); this.treeData = new ProviderHierarchy.HierarchyData(new Rect(this.parentRect.x + this.dx + 0f * this.dx1, this.parentRect.y + this.dy, this.parentRect.width, this.dy1), null, "Game Objects", this.imageMinus, this.imageMinus, this.privateGuiStyle, 0); int num = 0; foreach (Transform current2 in list) { stringBuilder.AppendLine(string.Format(" {0}", current2.gameObject.name)); num = 0; ProviderHierarchy.HierarchyData.FindChildsStringToBuilder(list2, current2, ref stringBuilder, ref num); } this.isCopyText = false; return stringBuilder; }} -
Я бы попробовал искать следующим образом. Если это шутер и есть вертикальная стена. Мы можем скриптами ставить игрока в две точные позиции отличающиеся на известную величину напротив вертикальной стены и при этом камеру можем не двигать (мы должны быть во временном меню игры или окно игры не должно иметь фокус). Затем переключая позицию игрока скриптами по горячим клавишам например на +2 и -2 по горизонтали мы можем искать адрес места попадания. Он будет сначала неизвестным, а потом отличаться по глобальной горизонтальной оси примерно на +2 и примерно на -2. Во всяком случае как бы там не было. Экспериментально надо ставить игрока на место куда смотрим, а затем смотреть на это место и искать похожие коодринаты. Конечно, надо выбрать ось. Влево-вправо, вверх-вниз, но не вперед-назад.
-
Написал сегодня утром скриптец и не дописал. Если хотите, то можете помочь. Скрипт трейсит код приложения от брейкпоинта на адресе кода и логирует границы исполняемого кода. Ну, вот... а получается ерунда под конец Там где красное, те регионы лишние. Они не должны создаваться tableCode = {}isStartFindingCode = falselocal maxCountStep = 10000 -- количество шагов трассеровкиlocal maxCountRegions = 10000 -- количество формируемых регионов в таблицеlocal targetAdress = 0local startTimer = 0local isCallExecute = false-- Выводит таблицуfunction PrintTable() print('Регионы кода пройденные трассировкой:') if(targetIs64Bit()) then for i = 1, #tableCode do print(string.format('%16X - %16X <==== мы здесь были', tableCode[i][1],tableCode[i][2])) end else for i = 1, #tableCode do print(string.format('%08X - %08X <==== мы здесь были', tableCode[i][1],tableCode[i][2])) end end print(string.format('Кол-во регионов : %s', #tableCode)) print(string.format("Время : %.2f секунд(ы)", os.clock() - startTimer)) print('Поиск регионов кода завершен\n')endfunction ReadAdressCode(addressCode) for i = 1, #tableCode do if(tableCode[i][1] >= addressCode and addressCode <= tableCode[i][2]) then return end end for i = 1, #tableCode do --print(string.format('> %X == %X',tableCode[i][2]+1, addressCode)) if(tableCode[i][2]+1 == addressCode) then tableCode[i][2] = tableCode[i][2] + getInstructionSize(addressCode) return end end -- Код не был пройден и далеко от найденных границ table.insert(tableCode, {addressCode, addressCode + getInstructionSize(addressCode)-1})endfunction debugger_onBreakpoint() if(isStartFindingCode) then countStep = countStep + 1 if(targetIs64Bit()) then ReadAdressCode(RIP) else ReadAdressCode(EIP) end if(countStep >= maxCountStep) then isStartFindingCode = false print("Превышено макс. кол-во адресов трассировки ") debug_removeBreakpoint(targetAdress) debug_continueFromBreakpoint(co_run) PrintTable() return 1 end if(#tableCode >= maxCountRegions) then isStartFindingCode = false print("Превышено макс. кол-во регионов кода ") debug_removeBreakpoint(targetAdress) debug_continueFromBreakpoint(co_run) PrintTable() return 1 end -- Иначе делать шаг по коду if(isCallExecute) then debug_continueFromBreakpoint(co_stepinto) --co_run (just continue), co_stepinto(when on top of a call, follow it), co_stepover else debug_continueFromBreakpoint(co_stepover) end return 1 -- не показывать дизассемблер во время поиска isStartFinding end return 0 -- показывать дизассемблерendfunction Start(address) print("Старт! Дождитесь завершения...") print(string.format("Макс. кол-во адресов трассировки : %s", maxCountStep)) print(string.format("Макс. кол-во регионов кода : %s", maxCountRegions)) if(isCallExecute) then print("Трейсить : Call") else print("Не трейсить : Call") end isStartFindingCode = true countStep = 0 tableCode = {} targetAdress = address startTimer = os.clock() debug_setBreakpoint(address)end--Start('test.exe+5B5A4')--0045464A - FF 05 A4B54500 - inc [0045B5A4] : [000003EC]Start('0045464A')
-
Ни одна инструкция не компилируется cmp rdx, qword ptr 1455d741fcmp rdx, qword 1455d741fcmp rdx, qword ptr [1455d741f]cmp rdx, [1455d741f]Зато компилируется 4-х байтовое число cmp rdx,[455D741F]cmp rdx, qword ptr [455d741f]; будет например 01150026 - 48 3B 14 25 1F745D45 - cmp rdx,[455D741F]Можно например через стек push 4 байтаpush 4 байта; или push qword[метка]; или mov rax, большое число и push raxcmp rdx, [esp]sub rsp,8 ; правим указатель на стекА "cmpeq" это не инструкция, а обозначение группы инструкций сравнения со схожем корнем "cmpeq" из набора SIMD. Из документа 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf, который можно найти официальном сайте Интел PCMPEQB/PCMPEQW/PCMPEQD— Compare Packed Data for Equal PCMPEQQ — Compare Packed Qword Data for EqualPCMPESTRI — Packed Compare Explicit Length Strings, Return IndexPCMPESTRM — Packed Compare Explicit Length Strings, Return MaskPCMPGTB/PCMPGTW/PCMPGTD—Compare Packed Signed Integers for Greater ThanPCMPGTQ — Compare Packed Data for Greater ThanPCMPISTRI — Packed Compare Implicit Length Strings, Return IndexPCMPISTRM — Packed Compare Implicit Length Strings, Return Mask Я не нашел ни одного способа сравнить большой число с "cmpeq". Да и работает уже со 128 разрядными и меньше регистрами и на мой взгляд только усложняет.
-
Под отладкой игра может работать ощутимо медленнее чем без неё. Тормоза в первую очередь зависят от того, как часто будет прерываться инструкция под отладкой и как как быстро выполнится Lua код. Ничего не могу сказать про трейнеры с PG. Только код чужих трейнеров не публикуйте и скрипт без ссылки на источник. Мне придется его удалить.