Перейти к содержанию

MasterGH

Ветераны
  • Постов

    2 999
  • Зарегистрирован

  • Победитель дней

    129

Весь контент MasterGH

  1. Бывают случаи, когда нужно показать сообщение с какой-то информацией. Можно это сделать в простом окне сообщения с кнопкой Ок используя скрипты АА. globalalloc(MyMessageBox,2048)label(message)label(caption)MyMessageBox: push ebp mov ebp,esp push #0 push caption push message push #0 call MessageBoxA pop ebp ret 10message: db 'blablablaa',0caption: db 'XD',0createthread(MyMessageBox)test.exe+54690 - E8 9FFFFFFF - call test.exe+54634test.exe+54695 - C3 - ret test.exe+54690 - E8 7BC10900 - call MyMessageBoxtest.exe+54695 - C3 - ret
  2. В отладочном коде частенько вижу инструкцию leave ближе к концу функции. Полез в поиск и узнал, что используется совместно с инструкцией enter, но enter вообще не помню в отладке. Полез в поиск и вот, что узнал. Вместо enter аналог из других инструкций выполняется быстрее. Пример. Выполняется за 2 такта push ebpmov ebp,espsub esp,16leave Пример. Выполняется за 14 тактов enter 16,0leave Источник ------------ Решил скомпилить я следующий код на C# using UnityEngine;using System.Collections;public class SEH : MonoBehaviour { int someCount, decCount; public void OnClickBtn(){ try{ someCount++; }catch{ decCount--; } }} Затем полез в CE и вот они знакомые инструкции 04599CD0 - 55 - push ebp04599CD1 - 8B EC - mov ebp,esp04599CD3 - 83 EC 18 - sub esp,1804599CD6 - 8B 45 08 - mov eax,[ebp+08]04599CD9 - 8B 48 10 - mov ecx,[eax+10]04599CDC - 41 - inc ecx someCount++;04599CDD - 89 48 10 - mov [eax+10],ecx04599CE0 - EB 31 - jmp 04599D1304599CE2 - 8B 45 E8 - mov eax,[ebp-18]04599CE5 - 8B 45 08 - mov eax,[ebp+08]04599CE8 - 89 45 EC - mov [ebp-14],eax04599CEB - 8B 45 EC - mov eax,[ebp-14]04599CEE - 8B C8 - mov ecx,eax04599CF0 - 8B 49 14 - mov ecx,[ecx+14]04599CF3 - 49 - dec ecx decCount--;04599CF4 - 89 48 14 - mov [eax+14],ecx04599CF7 - E8 C48BFDFF - call 045728C004599CFC - 89 45 FC - mov [ebp-04],eax04599CFF - 83 7D FC 00 - cmp dword ptr [ebp-04],0004599D03 - 74 0C - je 04599D1104599D05 - 8B 45 FC - mov eax,[ebp-04]04599D08 - 83 EC 0C - sub esp,0C04599D0B - 50 - push eax04599D0C - E8 6770C6FF - call 04200D7804599D11 - EB 00 - jmp 04599D1304599D13 - C9 - leave 04599D14 - C3 - ret Такие дела
  3. В первый пост добавлено руководство "Сравнение структур после перезагрузки. Поиск фильтра свой-чужой-дружественый (Tiny dumper 1.2) Функцию-обработчик подключения процесса нельзя вызывать в файлах-плагинах иначе её не смогут использовать другие луа скрипты function onOpenProcess(processid)...endЭта функция ниже, возвращающая id открытого процесса возвращает id-кешированный, когда процесс был уже закрыт, т.е. она не возвращает ноль, когда процесс был закрыт getOpenedProcessID() : Returns the currently opened process. If none is open, returns 0Все. Больше нет простых возможностей определить, что процесс был переоткрыт или отключен. Названные функции выше использовать нельзя для включения Rewrite dumpsВ версиии Tiny dumper 1.2 временные файлы дампов практически больше не нужны. Так как теперь есть функция Rewrite dumps в контекстном меню. Её можно вызывать после переподключения к процессу. Сохранения и загрузки дампов по сути вообще не нужны. Только для подстраховки, что CE зависнет, например, при работе с Ultimap или DBVM ИМХО лишняя функция - сохранение выделенных дампов в файл. Это все равно, что сохранять выделенные записи-читы в главной таблице CE. Для "расклассифицирования" ты можешь называть дампы особым образом, чтобы отличать их. При это сохранять в один файл. Если хочешь, можешь открыть дампы текстовым редактором, чтобы вручную править дампы и названия меток. Там обычный текст.
  4. Думаю это всё RockHamer : И еще у него в подписи А сегодня пятница И еще, вот он выдал Наверно, это он решил подЭдОсить сегодня в пятницу и захватить мир
  5. Новая версия Функция потери процесса в CE Lua Engine не работает. Так что переписывание дампов нужно делать вручную через контекстную функцию. Dalloс из АА тоже не робит, память засоряется. Но 4Кб погоды не сделает, а это средний размер дампа для сравнения структуры.
  6. Еще бан может быть в теории: 1. бан с занесением шифрованной информации на локальный комп и когда зайдешь под другим акком, то будет палево 2. бан по ip и палевом на остальные аккаунты по этому ip
  7. Мне тоже интересно. Если узнаешь, то можешь написать об этом. Согласен. Ну, Dead Trigger 2 на Андроиде довольно известен, хотя я поиграл пару уровней и забил. Меня больше интересовала графика.
  8. Unity 5.0 • Unity 5.0 is our biggest and boldest release ever. Powerful new features in Unity 5 include: • The Physically-based Standard Shader to make your materials look consistent in any lighting environment, cross platform. • Real-time Global Illumination, built on Geomerics Enlighten technology. • The Audio Mixer, to massively improve audio in your game. • HDR Reflection Probes to enhance visual fidelity. • PhysX 3.3 to bring massive performance improvements to 3D physics. • Major updates to the animation system. • WebGL preview. And of course, many more new features and updates. Keep reading to learn more. Download Release notes Unity 5 engine overview Tutorials Unity Manual Unity Scripting Reference Теперь в бесплатной версии много возможностей, которые были вырезаны в прошлых бесплатных версиях 64 - разрядная среда, когда раньше была доступна только 32 Языки: C#, JavaScript(его еще называют UnityScript). По поводу С++ ничего нет, к сожалению. Поддерживаются разве, что сторонние плагины в виде *.dll или что-то связанное с WebGL (по этой технологии пока глухо, я ничего не знаю, в документации нет, только в блогах). На видео ниже можно посмотреть эффекты в рантайм, т.е. это игровые эффекты, а не отрендеренный игровой ролик. В ранних версиях такой графики не было. Она была значительно хуже на уровне DirectX 9.0, а сейчас значительно лучше. Не могу сравнить с другими движками, лучше это или хуже других игровых движков по качеству графики. Можете оценить сами.
  9. Про баны это понятно. Конечно, за инфу спасибо. Напоминаю другим, что запуская чужой "софт - ломалку" - можно легко потерять пасс и логин от стима. Так что будьте блительны, господа! Если еще пароли одинаковы с почтой, то и почта может слететь.
  10. Общие понятия Авторитарный сервер (или мастер сервер) На этом сервере хранятся все данные или наиболее важные данные и логика игры. Клиенты просят сервер что-то сделать, сервер пропускает через функции, условия игры и выдает ответ отвечающему или еще и на другие клиенты. Клиент На клиенте как правило хранятся данные копии. В зависимости от игры расчеты могут быть и на клиенте, чтобы снять нагрузку на цпу сервера и разгрузить траффик. Как правило расчеты физики, столкновений в сетевых играх стараются либо избежать, либо отводят на клиент или мастер клиент. Мастер-клиент Мастер клиент как правило, тот кто создает комнату, игру, лобби. Снимает всю или бОльшую часть нагрузки на серверную сторону. Мастер клиент берет полный или частичный контроль над игрой. А серверная сторона либо передает тупо пакеты между мастер-клиентами и клиентами, либо серверная сторона еще и контролирует как-то игру. Связи Авторитарный + клиенты Авторитарный сервер принимает "вопросы и предложения от клиентов" в течении игры. Реагирует на них и отправляет результаты тому кто спрашивал или еще и тем кто в игре. Не авторитарный + мастер клиент + клиенты Игрок, который создал игру примает "вопросы и предложения от клиентов" в течении игры. Реагирует на них и отправляет результаты тому кто спрашивал или еще и тем кто в игре. Т.е. мастер клиент хранит данные, все что происходит в игре синхронизируется с ним. Не авторитарный сервер выступает в качестве посредника рассылки пакетов между игроками минуя NAT. Частично автоританый + мастер клиент + клиенты Авторитарный сервер может влиять на игру между мастер клиентом и клиентами. Чем это влияние сильнее, тем больше ограничений в сетевой игре получается. Например. Сервер ведет счет времени на игру между клиентами и мастер клиентами. Если у кого-то так называемая "энергия" закончилась, то сервер, говорит, что Вам нельзя начать новую игру. Пример игры Трагедия Белок. Но я не уверен, что там есть мастер клиент. Возможно там полный контроль авторитарного сервера, т.е. физика и движения рассчитаются не мастер клиентом, а сервером. Пример того как выглядят система Клиент + Частично авторитарный сервер Игра-пример с yahoogames про игру поиск грибов игроками в темноте. Частично авторитарный сервер создает грибы в темноте по интервалу времени. В этом всего лишь и заключается авторитарность. Сервер только создает грибы, когда посчитает нужным. Взятие грибов серверная сторона НЕ КОТРОЛИРУЕТ. В общем этот пример для тех, кто хочет задуматься. Роль сервера и роль клиентов очень гибкая и в задачу разработчика входит много проблем, чтобы не допустить читов. Если разраб ничего делать не будет, будет чит на чите. Разраб преследует концепцию "никогда не доверять клиентам" //-----------------------------------------------------------------------------------------------------------------// // Mushroom Example// Created by : Luis Filipe (filipe@seines.pt)// Dec 2010//// Source code in this example is in the public domain.// The naruto character model in this demo is copyrighted by Ben Mathis.// See Assets/Models/naruto.txt for more details////-----------------------------------------------------------------------------------------------------------------using UnityEngine;using System.Collections;using System.Collections.Generic;using PlayerIOClient;public class ChatEntry { public string text = ""; public bool mine = true;}public class GameManager : MonoBehaviour { public GameObject target; public GameObject PlayerPrefab; public GameObject ToadPrefab; private Connection pioconnection; private List<PlayerIOClient.Message> msgList = new List<PlayerIOClient.Message>(); // Messsage queue implementation private bool joinedroom = false; // UI stuff private Vector2 scrollPosition; private ArrayList entries = new ArrayList(); private string inputField = ""; private Rect window = new Rect(10, 10, 300, 150); private int toadspicked = 0; private string infomsg = ""; void Start() { // create a random userid System.Random random = new System.Random(); string userid = "Guest" + random.Next(0, 10000); Debug.Log("Starting"); PlayerIOClient.PlayerIO.Connect( "[Enter your game id here]", // Game id (Get your own at playerio.com. 1: Create user, 2:Goto admin pannel, 3:Create game, 4: Copy game id inside the "") "public", // The id of the connection, as given in the settings section of the admin panel. By default, a connection with id='public' is created on all games. userid, // The id of the user connecting. This can be any string you like. For instance, it might be "fb10239" if youґre building a Facebook app and the user connecting has id 10239 null, // If the connection identified by the connection id only accepts authenticated requests, the auth value generated based on UserId is added here null, null, delegate(Client client) { Debug.Log("Successfully connected to Player.IO"); infomsg = "Successfully connected to Player.IO"; target.transform.Find("NameTag").GetComponent<TextMesh>().text = userid; target.transform.name = userid; // Uncoment the line below to use the Development Server client.Multiplayer.DevelopmentServer = new ServerEndpoint("localhost",8184); //Create or join the room client.Multiplayer.CreateJoinRoom( "UnityDemoRoom", //Room id. If set to null a random roomid is used "UnityMushrooms", //The room type started on the server true, //Should the room be visible in the lobby? null, null, delegate(Connection connection) { Debug.Log("Joined Room."); infomsg = "Joined Room."; // We successfully joined a room so set up the message handler pioconnection = connection; pioconnection.OnMessage += handlemessage; joinedroom = true; }, delegate(PlayerIOError error) { Debug.Log("Error Joining Room: " + error.ToString()); infomsg = error.ToString(); } ); }, delegate(PlayerIOError error) { Debug.Log("Error connecting: " + error.ToString()); infomsg = error.ToString(); } ); } void handlemessage(object sender, PlayerIOClient.Message m) { msgList.Add(m); } void FixedUpdate() { // process message queue foreach(PlayerIOClient.Message m in msgList) { switch(m.Type) { case "PlayerJoined": GameObject newplayer = GameObject.Instantiate(target) as GameObject; newplayer.transform.position = new Vector3(m.GetFloat(1), 0, m.GetFloat(2)); newplayer.name = m.GetString(0); newplayer.transform.Find("NameTag").GetComponent<TextMesh>().text = m.GetString(0); break; case "Move": GameObject upplayer = GameObject.Find(m.GetString(0)); upplayer.transform.LookAt(new Vector3(m.GetFloat(1), 0, m.GetFloat(2))); // set transform x axis to 0, so the character will be facing forward upplayer.transform.eulerAngles = new Vector3(0, upplayer.transform.eulerAngles.y, upplayer.transform.eulerAngles.z); // get distance between current position and target position, // we'll need to value to know how much the tween will last float dist = Vector3.Distance(upplayer.transform.position, new Vector3(m.GetFloat(1), 0, m.GetFloat(2))); // create a tween between current and target position iTween.MoveTo(upplayer, iTween.Hash("x", m.GetFloat(1), "z", m.GetFloat(2), "onstart", "startwalk", "oncomplete", "stopwalk", "time", dist, "delay", 0, "easetype", iTween.EaseType.linear)); break; case "Harvest": GameObject hvplayer = GameObject.Find(m.GetString(0)); hvplayer.transform.LookAt(new Vector3(m.GetFloat(1), .5f, m.GetFloat(2))); // set transform x axis to 0, so the character will be facing forward hvplayer.transform.eulerAngles = new Vector3(0, hvplayer.transform.eulerAngles.y, hvplayer.transform.eulerAngles.z); // get distance between current position and target position, // we'll need to value to know how much the tween will last float distance = Vector3.Distance(hvplayer.transform.position, new Vector3(m.GetFloat(1), 0, m.GetFloat(2))); // create a tween between current and target position iTween.MoveTo(hvplayer, iTween.Hash("x", m.GetFloat(1), "z", m.GetFloat(2), "onstart", "startwalk", "oncomplete", "stopharvest", "time", distance, "delay", 0, "easetype", iTween.EaseType.linear)); break; case "Picked": // remove the object when it's picked up GameObject removetoad = GameObject.Find("Toad" + m.GetInt(0)); Destroy(removetoad); break; case "Chat": if(m.GetString(0) != "Server") { GameObject chatplayer = GameObject.Find(m.GetString(0)); chatplayer.transform.Find("Chat").GetComponent<TextMesh>().text = m.GetString(1); chatplayer.transform.Find("Chat").GetComponent<MeshRenderer>().material.color = Color.white; chatplayer.transform.Find("Chat").GetComponent<chatclear>().lastupdate = Time.time; } ChatText(m.GetString(0) + " says: " + m.GetString(1), false); break; case "PlayerLeft": // remove characters from the scene when they leave GameObject playerd = GameObject.Find(m.GetString(0)); Destroy(playerd); break; case "Toad": // adds a toadstool to the scene GameObject newtoad = GameObject.Instantiate(ToadPrefab) as GameObject; newtoad.transform.position = new Vector3(m.GetFloat(1), 0.1f, m.GetFloat(2)); newtoad.name = "Toad" + m.GetInt(0); break; case "ToadCount": // updates how many toads have been picked up by the player toadspicked = m.GetInt(0); break; } } // clear message queue after it's been processed msgList.Clear(); } void OnMouseDown() { // this function responds to mouse clicks on the ground // it will send a move request to the server // ignore user input if we're not inside a room if(!joinedroom) return; Vector3 targetPosition = new Vector3(0, 0, 0); var playerPlane = new Plane(Vector3.up, target.transform.position); var ray = Camera.main.ScreenPointToRay(Input.mousePosition); var hitdist = 0.0f; if(playerPlane.Raycast(ray, out hitdist)) { targetPosition = ray.GetPoint(hitdist); pioconnection.Send("Move", targetPosition.x, targetPosition.z); } } void OnGUI() { window = GUI.Window(1, window, GlobalChatWindow, "Chat"); GUI.Label(new Rect(10, 160, 150, 20), "Toadstools picked: " + toadspicked); if(infomsg != "") { GUI.Label(new Rect(10, 180, Screen.width, 20), infomsg); } } public void HarvestAt(float posx, float posz) { pioconnection.Send("MoveHarvest", posx, posz); } public void TryPickup(string id) { pioconnection.Send("Pickup", id); } void GlobalChatWindow(int id) { if(!joinedroom) return; GUI.FocusControl("Chat input field"); // Begin a scroll view. All rects are calculated automatically - // it will use up any available screen space and make sure contents flow correctly. // This is kept small with the last two parameters to force scrollbars to appear. scrollPosition = GUILayout.BeginScrollView(scrollPosition); foreach(ChatEntry entry in entries) { GUILayout.BeginHorizontal(); if(!entry.mine) { GUILayout.Label(entry.text); } else { GUI.contentColor = Color.yellow; GUILayout.Label(entry.text); GUI.contentColor = Color.white; } GUILayout.EndHorizontal(); GUILayout.Space(3); } // End the scrollview we began above. GUILayout.EndScrollView(); if(Event.current.type == EventType.keyDown && Event.current.keyCode == KeyCode.Return && inputField.Length > 0) { GameObject chatplayer = GameObject.Find(target.transform.name); chatplayer.transform.Find("Chat").GetComponent<TextMesh>().text = inputField; chatplayer.transform.Find("Chat").GetComponent<MeshRenderer>().material.color = Color.white; chatplayer.transform.Find("Chat").GetComponent<chatclear>().lastupdate = Time.time; ChatText(target.transform.name + " says: " + inputField, true); pioconnection.Send("Chat", inputField); inputField = ""; } GUI.SetNextControlName("Chat input field"); inputField = GUILayout.TextField(inputField); GUI.DragWindow(); } void ChatText(string str, bool own) { var entry = new ChatEntry(); entry.text = str; entry.mine = own; entries.Add(entry); if(entries.Count > 50) entries.RemoveAt(0); scrollPosition.y = 1000000; }}using System;using System.Collections.Generic;using System.Text;using System.Collections;using PlayerIO.GameLibrary;using System.Drawing;namespace MushroomsUnity3DExample { public class Player : BasePlayer { public float posx = 0; public float posz = 0; public int toadspicked = 0; } public class Toad { public int id = 0; public float posx = 0; public float posz = 0; } [RoomType("UnityMushrooms")] public class GameCode : Game<Player> { private int last_toad_id = 0; private List<Toad> Toads = new List<Toad>(); // This method is called when an instance of your the game is created public override void GameStarted() { // anything you write to the Console will show up in the // output window of the development server Console.WriteLine("Game is started: " + RoomId); // spawn 10 toads at server start System.Random random = new System.Random(); for(int x = 0; x < 10; x++) { int px = random.Next(-9, 9); int pz = random.Next(-9, 9); Toad temp = new Toad(); temp.id = last_toad_id; temp.posx = px; temp.posz = pz; Toads.Add(temp); last_toad_id++; } // respawn new toads each 5 seconds AddTimer(respawntoads, 5000); // reset game every 2 minutes AddTimer(resetgame, 120000); } private void resetgame() { // scoring system Player winner = new Player(); int maxscore = -1; foreach(Player pl in Players) { if(pl.toadspicked > maxscore) { winner = pl; maxscore = pl.toadspicked; } } // broadcast who won the round if(winner.toadspicked > 0) { Broadcast("Chat", "Server", winner.ConnectUserId + " picked " + winner.toadspicked + " Toadstools and won this round."); } else { Broadcast("Chat", "Server", "No one won this round."); } // reset everyone's score foreach(Player pl in Players) { pl.toadspicked = 0; } Broadcast("ToadCount", 0); } private void respawntoads() { if(Toads.Count == 10) return; System.Random random = new System.Random(); // create new toads if there are less than 10 for(int x = 0; x < 10 - Toads.Count; x++) { int px = random.Next(-9, 9); int pz = random.Next(-9, 9); Toad temp = new Toad(); temp.id = last_toad_id; temp.posx = px; temp.posz = pz; Toads.Add(temp); last_toad_id++; // broadcast new toad information to all players Broadcast("Toad", temp.id, temp.posx, temp.posz); } } // This method is called when the last player leaves the room, and it's closed down. public override void GameClosed() { Console.WriteLine("RoomId: " + RoomId); } // This method is called whenever a player joins the game public override void UserJoined(Player player) { foreach(Player pl in Players) { if(pl.ConnectUserId != player.ConnectUserId) { pl.Send("PlayerJoined", player.ConnectUserId, 0, 0); player.Send("PlayerJoined", pl.ConnectUserId, pl.posx, pl.posz); } } // send current toadstool info to the player foreach(Toad t in Toads) { player.Send("Toad", t.id, t.posx, t.posz); } } // This method is called when a player leaves the game public override void UserLeft(Player player) { Broadcast("PlayerLeft", player.ConnectUserId); } // This method is called when a player sends a message into the server code public override void GotMessage(Player player, Message message) { switch(message.Type) { // called when a player clicks on the ground case "Move": player.posx = message.GetFloat(0); player.posz = message.GetFloat(1); Broadcast("Move", player.ConnectUserId, player.posx, player.posz); break; case "MoveHarvest": // called when a player clicks on a harvesting node // sends back a harvesting command to the player, a move command to everyone else player.posx = message.GetFloat(0); player.posz = message.GetFloat(1); foreach(Player pl in Players) { if(pl.ConnectUserId != player.ConnectUserId) { pl.Send("Move", player.ConnectUserId, player.posx, player.posz); } } player.Send("Harvest", player.ConnectUserId, player.posx, player.posz); break; case "Pickup": // called when the player is actually close to the harvesting node int pickupid = int.Parse(message.GetString(0).Replace("Toad", "")); // Find a toad by its id Toad result = Toads.Find( delegate(Toad td) { return td.id == pickupid; } ); if(result != null) { // sends everyone information that a toad as been picked up // increases player toad count Broadcast("Picked", result.id); Toads.Remove(result); player.toadspicked++; player.Send("ToadCount", player.toadspicked); } else { // id of the toad doesn't exist, either the player // is trying to cheat, or someone else already picked // that toadstool Console.WriteLine("Not found: {0}", pickupid); } break; case "Chat": foreach(Player pl in Players) { if(pl.ConnectUserId != player.ConnectUserId) { pl.Send("Chat", player.ConnectUserId, message.GetString(0)); } } break; } } }}
  11. Все, что я напишу ниже, это я вижу в теории. Практики у меня никакой нет. Вот к таким играм, я более лояльно отношусь. Там продают преимущество через донат. Это мое ИМХО. 1. Шифрование пакетов + сжатие + контроль последовательности пакетов. Это может быть как защита так и с целью уменьшения трафика. 2. Может не быть шифрования и нет сжатия, передаются через пакет данные о действий игрока. Логируй пакеты и пытайся отличить их одинаковое количество с количеством событий в игре, которые ты делаешь. Попробуй повторить отправку разных пакетов один за одним или в разной последовательности с разными скоростями и разными скоростями ответов на эти пакеты, которые могли бы к чему-то перевести. Эксперименты со скоростью отправки разных пакетов может помочь в том, что две транзакции могут не обработать условие последовательно как задумывалось, наверно как правило транзакции обрабатываются параллельно. Я так случайно вроде, начислил себе монеток в Трагедии Белок, у меня тогда были перебои с модемом. И я так себе начислил 26 монет, через функцию пригласить друга, за которую давали меньше монет. Но, случайно, а не специально. Похоже либо пакет много кратно отправился до записи на серверной стороне, что он обработан и были монеты начислены, либо что-то другое. Т.к. в игре донат, и там не глупые люди наверно сидят в программистах. Логика игры и данные наверняка полностью обрабатываются на серваке, а ты как бы, когда отправляешь пакет звонишь по телефону и говоришь сделай то и сделай то. Если сервак согласиться, то он сделает. Если действия будут идти не по правилам игры и есть проверка на авторитарном сервере, то ничего не получиться. Но могут быть условия, которые разрабы могут перед носом не видеть - в параллельной логике обработки транзакций. Два или несколько условий, обрабатываемых параллельно и не учитывая какие-то нюансы не законченных транзакций. Ну и если с покетами ничего не придумаешь, то как писал Xipho выдергивать флеш приложение и декопилишь его, чтобы узнать лучше, что там происходит. У нас было пара тем как декомпилировать. Ну и искать слабости. Все, что я написал, это я вижу в теории. Но практики у меня нет. Может я что и неправильно написал.
  12. Надо что-то придумать, чтобы у тех кто не хочет чужой шрифт, чтобы стоял шрифт по умолчанию. Но наверно это без своего кодинга (финтов с браузером и перекрытиями стилей) не сделать.
  13. Keng, почему-то любит нестандартный шрифт
  14. Я думаю, это чит безобидный, не все будут против него. Назову я его "Добивание с одной тычки " Для того чтобы чужой, свой крип или чужой герой не умер сам или его бы не убили,то его нужно точно добить с расчетом одной тычки. С расчетом, что хватит урона и его не убьют раньше другие крипы, боты, или свои же из команды. Т.е. любой крип, который оказался в радиусе доступа, чтобы он автоматом добивался. Как в теории это сделать? Ну, в соревнования я конечно не полезу, но с ботами и игроками можно пофаниться. Тема экспериментальная. Давайте посмотрим на популярность этой темы. Будет ли это обсуждаться. Будет ли негативной или позитивной.
  15. RockHamer, ты правда не знаешь ответ на первый вопрос? Ну, ты даешь.
  16. push eaxmov eax,["metro.exe"+00D012D0]mov eax, [eax+448]mov eax, [eax+27]mov [eax+10], #1000pop eaxmov [рассчитанный адрес],#1000
  17. Написал бы короче. Нужен движок трейнера на С++ и все бы поняли
  18. [[["metro.exe"+00D012D0]+448]+27]+10 Если не напутал, то так push eaxmov eax, ["metro.exe"+00D012D0]mov eax, [eax+448]mov eax, [eax+27]mov eax, [eax+10]mov [rsi+00000448],eaxpop eax
  19. Задача. Нужно вызывать функции с копией стека, но так чтобы игра не вылетала, если это произошло с неудачей. Т.е. нужно вписать обработку исключительной ситуации, чтобы поток корректно закрылся. Я могу сам сделать, но уже несколько недель все никак не могу этим заняться. Если у кого желание есть,то код ниже и файлы плагина в аттаче. --Author: MasterGH, 03.01.2015, Gamehacklab[RU] (http://gamehacklab.ru)frmRepeater = createFormFromFile(getCheatEngineDir().."\\autorun\\frmRepeater.xml")if(frmRepeater == nil) then messageDialog('Can not find frmRepeater', mtError, mbOK) returnendfunction OnClickMenuItemRepeater() frmRepeater.Show()endfunction DEC_HEX( IN ) return string.format( '%x', IN )end function HEX_DEC( IN ) return tonumber(IN, 16)end local menuItems = getMemoryViewForm().findComponentByName('MainMenu1').Itemslocal count = menuItems.Count - 1for i = 0, count-1 do local item = menuItems.getItem(i) if(item.Caption == 'Tools') then local mi = createMenuItem(popupmenu) menuItem_setCaption(mi, '* Repeater [Plugin]') menuItem_onClick(mi, OnClickMenuItemRepeater) item.add(mi) break endendlocal countLine = 1tableBtn = {}frmRepeater.CEEdit1.Text = 'Action1'frmRepeater.CEEdit2.Text = '00454690' --'00000000'frmRepeater.Caption = 'Repeater [CE Lua Plugin, ver 1.0]'function OnClickBtnCaller(sender) for i,v in ipairs(tableBtn) do if(tableBtn[i].btnCall == sender) then autoAssemble(tableBtn[i].AACallThread) end endendfunction OnClickCreateLine(sender) if (countLine > 10) then print('Records > 15') return end local labelName = frmRepeater.CEEdit1.Text local addressCode = frmRepeater.CEEdit2.Text if (labelName == '') then messageDialog('Label is empty', mtError, mbOK) return end if (addressCode == '') then messageDialog('AddressCode is empty', mtError, mbOK) return end for i,v in ipairs(tableBtn) do if(tableBtn[i].userLabel == labelName) then print('Name "'..labelName..'" is not unical') return end if(tableBtn[i].addressCall == addressCode) then print('AddressCode "'..addressCode..'" is not unical') return end end local btnCall = createButton(frmRepeater) btnCall.Caption = labelName..' (Do action in the game!)' btnCall.Top = (countLine - 1) * 50 + 10 btnCall.Width = 300 btnCall.Left = 80 btnCall.OnClick = OnClickBtnCaller btnCall.Enabled = false tableBtn[countLine] = {} tableBtn[countLine].btnCall = btnCall tableBtn[countLine].userLabel = labelName tableBtn[countLine].addressCall = addressCode tableBtn[countLine].addressCallNumber = HEX_DEC(addressCode) tableBtn[countLine].StackDump = false tableBtn[countLine].addressStack = 'StackMemRepeatCall'..countLine tableBtn[countLine].addressMemThread = 'ThreadMemRepeatCall'..countLine tableBtn[countLine].AACallThread = '' debug_setBreakpoint(addressCode, 1, bptExecute) frmRepeater.CEEdit1.Text = 'Action1' frmRepeater.CEEdit2.Text = '00000000' frmRepeater.CEPanel1.Top = countLine * 50 countLine = countLine + 1endfunction CallAction(itemTable) debug_removeBreakpoint(itemTable.addressCall) if (getOpenedProcessID() == 0) then messageDialog('No target any process', mtError, mbOK) return end autoAssemble(string.format([[alloc(%s,10000)registersymbol(%s)%s+1000:readmem(%x, 3000)]],itemTable.addressStack, itemTable.addressStack, itemTable.addressStack, ESP)) itemTable.StackDump = true--EFLAGS--32-bit: EAX, EBX, ECX, EDX, EDI, ESP, EBP, ESP, EIP--64-bit: RAX, EBX, RBX, RDX, RDI, RSP, RBP, RSP, RIP, R8, R9, R10, R11, R12, R13, R14, R15 : The value of the register local lineDissassemble = disassemble(itemTable.addressCall) extrafield, opcode, bytes, adressReturnHere = splitDisassembledString(lineDissassemble) --local _ebp = DEC_HEX(getAddress(itemTable.addressStack..'+'..DEC_HEX(EBP-ESP), false)) --string.format('getAddress(%s,10000) --local _ebp = DEC_HEX(getAddress(DEC_HEX(EBP)..'-'..DEC_HEX(ESP)..'+'..itemTable.addressStack, false)) --local _esp = DEC_HEX(getAddress(itemTable.addressStack)) local scriptAA0 = '' if(targetIs64Bit()) then print(RBP) print(RSP) print(DEC_HEX(RBP-RSP)) local _rbp = DEC_HEX(getAddress(itemTable.addressStack..'+'..DEC_HEX(RBP-RSP), false)) local _rsp = DEC_HEX(getAddress(itemTable.addressStack)) --call qword ptr [7FEF06C9C88] local _,_,x = string.find(opcode, '%[(.*)%]') ddDistanation = x --ddDistanation = getNameFromAddress(x) --opcode = 'call '..getNameFromAddress(x) scriptAA0 = string.format([[alloc(%s,4096)label(storyESP)label(ddAddress)registersymbol(%s)%s:mov rax,%xmov rbx,%xmov rcx,%xmov rdx,%xmov rsi,%xmov rdi,%xmov [storyESP],rspmov rsp,%s+1000mov rbp,%s+1000call qword ptr [ddAddress]mov rsp,[storyESP]retddAddress:dd %sstoryESP:dd 0]], itemTable.addressMemThread, itemTable.addressMemThread, itemTable.addressMemThread, RAX, RBX, RCX, RDX, RSI, RDI, _rsp, _rbp, ddDistanation) --opcode else local _ebp = DEC_HEX(getAddress(itemTable.addressStack..'+'..DEC_HEX(EBP-ESP), false)) local _esp = DEC_HEX(getAddress(itemTable.addressStack)) scriptAA0 = string.format([[alloc(%s,4096)label(storyESP)registersymbol(%s)%s:mov eax,%xmov ebx,%xmov ecx,%xmov edx,%xmov esi,%xmov edi,%xmov [storyESP],espmov esp,%s+1000mov ebp,%s+1000%smov esp,[storyESP]retstoryESP:dd 0]], itemTable.addressMemThread, itemTable.addressMemThread, itemTable.addressMemThread, EAX, EBX, ECX, EDX, ESI, EDI, _esp, _ebp, opcode) end print(scriptAA0) autoAssemble(scriptAA0) itemTable.AACallThread = string.format('createthread(%s)',itemTable.addressMemThread) itemTable.btnCall.Enabled = trueendfunction debugger_onBreakpoint() --_test --print(RIP) if(targetIs64Bit()) then for i,v in ipairs(tableBtn) do if(tableBtn[i].addressCallNumber == RIP) then CallAction(tableBtn[i]) return 1 end end else for i,v in ipairs(tableBtn) do if(tableBtn[i].addressCallNumber == EIP) then CallAction(tableBtn[i]) return 1 end end end return 0endfrmRepeater.CEButton2.OnClick = OnClickCreateLine
  20. Похоже релиз откладывается раз происходит вылет из игры. Буду тестить на ошибки. 1. Все дампы, которые отображаются должны фактически указывать на то, что они загружены в игре. Здесь надо решать задачу, чтобы после перезагрузки игры дамп без сохранения и загрузки мог быть в самой игре. Т.е. нужна обработка отключения/подключения к процессу. Также чтобы можно было сохранить дампы даже когда игра была закрыта. 2. Я думал над объединением, но тут мешают уникальные имена дампов. Если старые имена будут совпадать с загружаемыми, то получиться что дампы с существующими именами избирательно не смогут загружаться или их предлагать переименовывать последовательно. Так что я отказался от объединения. Лишние мороки. 3. Опять же из-за уникальности имен дампов нет смысла сохранять отдельные и подключать. Можно удалить ненужные оставив в таблице нужные и сохранить Ближайшие задачи 1. После закрытия игры дампы можно было бы сохранять. Сейчас это сделать нельзя. 2. После повторного подключения к процессу игры дампы находящиеся списке были бы рабочими, а не просто висели в списке, а в памяти игры их нет. 3. Буду проверять вылеты игры Скорее всего, релиз откладывается не раньше следующих выходных.
  21. Как только оно появится, то я с интересом посмотрю такое видео
  22. Бала исправлена критическая ошибка, которая вызывала вылет из игры после загрузки дампов из файла. Так что для тестов, новый файлец TinyDumper 1.2.rar Ну и для тех, кто хочет в первые в своей жизни увидеть сравнения структур после перезагрузки игры. Это просто песня. Нужно распаковать архив, там на два метра очень большой скрин всей этой расструктуризации. Структура из игры Сталкер Чистое Небо, которая хранит патроны на смещении +688. Это не совсем патроны, это счетчик структур патронов. Патроны имеют структурный тип. Этот большой скрин из архива лучше смотреть через баузер - придется скролить CompareStructures.rar
  23. У кого есть желание, время и опыт просьба потестить перед релизом. Начиная от проверки названия новых опций и заканчивая тестированием новых функций. 1. Исправлено подключение к русской версии. Этот способ предложили выше, мне он больше понравился 2. При выделении записи в поля прописываются данные 3. Добавлена опция сохранения дампов 4. Добавлена опция загрузки дампов. Если в таблице что-то есть, то будет диалог с предупреждением о потери данных на инглише. Кнопки Да/нет. Если да, то показывается диалог о выборе файлов. Если выбор подтверждается, то загружаются дампы из файла 5. Добавлена опция очистить таблицу 6. Добавлено несколько проверок с защитой "от дурака", если нужны еще проверки, то предложите * Три новые функции добавлены в контекстное меню. Форма не изменилась.
  24. Звуки есть в операционной системе или в Интернете. По поводу рабочего примера для CE 6.4: 1) добавляем звуки в таблицу. 2) в скрипт АА дописываем: [ENABLE]luacall(PlaySound(findTableFile('notify.wav'))) [DISABLE]luacall(PlaySound(findTableFile('tada.wav')))
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.