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

holy

Пользователи+
  • Постов

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

  • Посещение

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

    2

Сообщения, опубликованные holy

  1. On 19.09.2016 at 4:00 PM, Korol2010 said:

    Привет) Давно тут не был. Навыки взлома свои практически нулевые, как были они и раньше, решил вот всё таки опять чуть увеличить)) Наткнулся на этот трейнми, но понял что чёт он больно сложный для меня даже самый первый. И собственно вопрос. Взломать я точно его не смогу, но всё же расскажите пожалуйста как найти значение очков, а то просто очень интересно)) Я дак ни как не мог найти, даже визуальное, не говоря уже о реальном.

    Значения очков, я вроде искал через неизвестные значения.

    Т.е. изначально ищем неизвестные значения, потом в игре увеличиваются очки, и в Cheat Engine отсеиваю результаты через "Увеличилось значение"

  2. Ещё как вариант , предположу что BaseAddress у модуля Game.exe смещается. У тебя на скрине статичный адрес это "Game.exe"+016*** (видны на скрине только первые 3 цифры). А в коде у тебя жестко задано число. Однако в зависимости от смещения Game.exe будет разный первоначальный адрес.

  3. По аналогии с этим:

    wchar_t My_Little_String[100];
    swprintf(My_Little_String, L"%d - %s", 24, L"piupiu");

    Все функции printf работают одинаково.

    Либо они выводят инфу в консоль (и тогда первый параметр является сразу форматом строки)

    Либо они выводят инфу в строку (и тогда первый параметр всегда строка в которую будет писаться результат)

    • Плюс 1
  4. 10 hours ago, LongLong said:

    Игра обнаружила несоответствие.Это значит,что коллективная игра потеряла данные синхронизации между игроками

     

    Я вообще не стал бы конкретно эту ошибку патчить.

    Судя по описанию ошибки, она может возникнуть во время любой рассинхронизации, а не только в момент читерства.

    От сюда следует, что эта ошибка, возможно, где-то выше вызывается через call. Возьми отладчик, поставь BP на место где она вызывается, и смотри на стек вызовов.

    Исследуй код который вызывает эту функцию, возможно найдешь как "починить", если повезет.

  5. 1 hour ago, gmz said:

    дада bufferoverflow был запланирован

     

    Память выделяется динамически, в зависимости от входных данных )

    А это значит, что:

    1. Эти данные хранятся не в стеке, а в куче

    2. Эти данные всегда имеют соответствующий входным строкам размер, а значит переполнения не может быть :D

     

    И именно по этому я не люблю когда Visual Studio что-то пытается решить за меня, по этому юзаю Code::Blocks и GCC компилятор )

  6. 9 minutes ago, afro228offical said:

    Ну эт жесть

     

    Вообще-то все эти ошибки гуглятся...

    Столько лишних вопросов, попробуй сам гуглить.

     

    То что студии не нравится swprintf это я знаю, по этому и не люблю Visual Studio, слишком много на себя берет.

    Попробуй вторым параметром передать длину строки, т.е.

    swprintf(My_Little_String, len_string, L"%d - %s", entry.th32ProcessID, entry.szExeFile);

    Может поможет. Если нет, то загугли альтернативные функции.

  7. 10 minutes ago, afro228offical said:

    невозможно преобразовать аргумент 2 из "WCHAR [260]" в "const char *"

     

    так как у тебя ExeFile уже имеет тип WCHAR то тебе уже ничего не надо делать, можешь все что связано с переменной forExeFile удалить, а строку

     

    swprintf(My_Little_String, L"%d - %s", entry.th32ProcessID, forExeFile);

    заменить на

    swprintf(My_Little_String, L"%d - %s", entry.th32ProcessID, entry.szExeFile);
  8. 9 minutes ago, afro228offical said:

    невозможно преобразовать аргумент 1 из "WCHAR [260]" в "const char *"

     

    У меня, в CodeBlocks, в структуре переменная szExeFile имеет тип TCHAR, скорее всего в Visual Studio другой тип.

    Попробуй вместо strlen использовать wcslen (она для WCHAR)

  9. Тестировалось в Code::Blocks

     

    Spoiler
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <tlhelp32.h>
    
    int get_kek_length(DWORD kek) {
        int count_of_numbers = 1;
    
        while (kek >= 10) {
            count_of_numbers++;
            kek /= 10;
        }
    
        return count_of_numbers;
    }
    
    int main()
    {
        PROCESSENTRY32 entry;
        entry.dwSize = sizeof(PROCESSENTRY32);
    
        int sizeOfWCHAR = sizeof(wchar_t);
    
        wchar_t *My_Little_String = NULL;
        wchar_t *forExeFile = NULL;
        int len_string = 0;
        int lenExeFile = 0;
    
        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    
        if (Process32First(snapshot, &entry) == TRUE)
        {
            while (Process32Next(snapshot, &entry) == TRUE)
            {
                lenExeFile = strlen(entry.szExeFile);
    
                len_string = get_kek_length(entry.th32ProcessID); // Длина твоего, как ТЫ выражаешься, DWORD'а
                len_string += 3; // Плюс длина твоей строки L" | "
                len_string += lenExeFile; // Плюс длина строки исполняемого файла
                len_string += sizeOfWCHAR; // Ну а эт прост так )0)))00 на всякий NULL символ в конец и т.п.
    
                // -----------------------
    
                // Умножаем на sizeof(wchar_t) т.к. этот wchar_t не 1 байт
                My_Little_String = (wchar_t *) malloc(sizeOfWCHAR * len_string); // Выделили строку
                memset(My_Little_String, 0, sizeOfWCHAR * len_string); // От греха подальше сразу обнуляем область памяти
    
                // Особое внимание уделяю тому, что я добавляю всегда в конец sizeOfWCHAR для символа конца строки (а он равен NULL)
                forExeFile = (wchar_t *) malloc((sizeOfWCHAR * lenExeFile) + sizeOfWCHAR); // Выделили строку под имя ExeFile
                memset(forExeFile, 0, (sizeOfWCHAR * lenExeFile) + sizeOfWCHAR);
    
                // -----------------------
    
                mbstowcs(forExeFile, entry.szExeFile, lenExeFile); // Конвертируем TCHAR в этот ваш бесполезный wchar_t
    
                swprintf(My_Little_String, L"%d - %s", entry.th32ProcessID, forExeFile);
    
                // -----------------------
    
                wprintf(
                    L"PROCESS INFO: [%s] (len of string = %d)\n",
                    My_Little_String,
                    len_string - sizeOfWCHAR // Из длины строки убираем символ конца строки
                );
    
                // -----------------------
    
                // Освободили наш мусор
                free(forExeFile);
                free(My_Little_String);
            }
        }
    
        CloseHandle(snapshot);
        return 0;
    }

     

    • Плюс 1
  10. DWORD это 32-bit unsigned int

    (Т.е. целое беззнаковое число от 0x00000000 до 0xFFFFFFFF)

     

    Объясни вопрос более подробно и с примером. Иначе не понятно, причем тут число и количество символов в нем.

     

    Если более филосовско рассуждать, то DWORD это 2 WORD'а, которые состоят из 4х CHAR'ов :DD а значит 4 символа :)

    • Плюс 1
  11. Spoiler
    22 minutes ago, Garik66 said:

    Только ты забыл, что вынужден ещё две инструкции прописать

    Только ты забыл, что у тебя 4 операции со стеком, и они увеличиваются арифметически в зависимости от количества твоих действий.

    А в моем случае, операций со стеком всегда 2, а действия с регистром можно делать сколько угодно и это все-равно будет быстрее.

     

  12. Уже оффтоп

    Spoiler
    13 minutes ago, Garik66 said:

    Просто чем короче код, меньше кушает памяти и загружает проц, тем лучше.

    Я понимаю... Я же говорю, я просто поинтересовался )

     

    P.S. Про "короче код" в данном случае не подходит. Количество занимаемых байт инструкциями одинаково, вот только работа со стеком чуть медленней чем работа с регистрами процессора.

    
    6 байт
    FF73 08       PUSH DWORD PTR DS:[EBX+8]
    8F40 08       POP DWORD PTR DS:[EAX+8]
    
    6 байт
    8B4B 08       MOV ECX,DWORD PTR DS:[EBX+8]
    8948 08       MOV DWORD PTR DS:[EAX+8],ECX

     

  13. 1 minute ago, Garik66 said:

    Потому что для передачи данных (кол-во патронов) в данном случае я использую не регистр, а стек и непосредственно память

    Ясно.

    Я просто думал, что была какая-то причина, но раз это просто желание такое, тогда понял )

  14. Garik, извиняюсь за тупой вопрос, но почему в данном куске кода:

    Spoiler
    
      push [ebx+08]     // выгружаем max кол-во патронов в стек, сдвигая его
      pop [eax+08]      // загружаем max кол-во патронов, одновременно
                        // востанавливая стек
      push [ebx+14]     // выгружаем max кол-во патронов в рожке в стек, сдвигая его
      pop [eax+0C]      // загружаем max кол-во патронов в рожке, одновременно
                        // востанавливая стек

     

    ты не использовал регистр? Ведь не важно, использовался он или нет, мы в любом случае сохраняем его значение и восстанавливаем

     

    Например так:

    Spoiler
    
      push ebx          // сохраняем регистры перед использованием
      push ecx
    
      mov ebx,[eax+04]  // загружаем указатель в регистр ebx
    
      mov ecx,[ebx+08]
      mov [eax+08],ecx
    
      mov ecx,[ebx+14]
      mov [eax+0C],ecx
    
      pop ecx
      pop ebx           // восстанавливаем регистры после использования

     

     

    Просто интересуюсь )

  15. 40 minutes ago, 2zolo2 said:

    Koks1k, я понял пиратские сервера? то скачивай исходники сервера и ищи уязвимость в них. 

     

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

     

    9 hours ago, Koks1k said:

    Это реально?

     

    Почти нереально. Не думаю что кто-то возьмется за такое, тем-более если сервера не маленькие.

    • Плюс 1
  16. Пример создавал в Code::Blocks

    Полностью рабочий, но большая концентрация быдлокода.

    Spoiler
    
    #include <tchar.h>
    #include <windows.h>
    #include "windowsx.h"
    
    /*  Declare Windows procedure  */
    LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
    
    int createdWindow = FALSE;
    HINSTANCE main_hThisInstance;
    
    /*  Make the class name into a global variable  */
    TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");
    
    int WINAPI WinMain (HINSTANCE hThisInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR lpszArgument,
                         int nCmdShow)
    {
        main_hThisInstance = hThisInstance;
    
        HWND hwnd;               /* This is the handle for our window */
        MSG messages;            /* Here messages to the application are saved */
        WNDCLASSEX wincl;        /* Data structure for the windowclass */
    
        /* The Window structure */
        wincl.hInstance = hThisInstance;
        wincl.lpszClassName = szClassName;
        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
        wincl.cbSize = sizeof (WNDCLASSEX);
    
        /* Use default icon and mouse-pointer */
        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
        wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wincl.lpszMenuName = NULL;                 /* No menu */
        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
        wincl.cbWndExtra = 0;                      /* structure or the window instance */
        /* Use Windows's default colour as the background of the window */
        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    
        /* Register the window class, and if it fails quit the program */
        if (!RegisterClassEx (&wincl))
            return 0;
    
        /* The class is registered, let's create the program*/
        hwnd = CreateWindowEx (
               0,                   /* Extended possibilites for variation */
               szClassName,         /* Classname */
               _T("Code::Blocks Template Windows App | Example for afro228offical"),       /* Title Text */
               WS_OVERLAPPEDWINDOW, /* default window */
               CW_USEDEFAULT,       /* Windows decides the position */
               CW_USEDEFAULT,       /* where the window ends up on the screen */
               544,                 /* The programs width */
               375,                 /* and height in pixels */
               HWND_DESKTOP,        /* The window is a child-window to desktop */
               NULL,                /* No menu */
               hThisInstance,       /* Program Instance handler */
               NULL                 /* No Window Creation data */
               );
    
        HWND hwndButtonOK = CreateWindow(
            "BUTTON", // predefined class
            "Click here", // button text
            WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // styles
            10, // starting x position
            90, // starting y position
            100, // button width
            30, // button height
            hwnd, // parent window
            (HMENU) 123, // ВОТ ЭТО ЗНАЧЕНИЕ
            main_hThisInstance,
            NULL); // pointer not needed
    
        /* Make the window visible on the screen */
        ShowWindow (hwnd, nCmdShow);
    
        /* Run the message loop. It will run until GetMessage() returns 0 */
        while (GetMessage (&messages, NULL, 0, 0))
        {
            /* Translate virtual-key messages into character messages */
            TranslateMessage(&messages);
            /* Send message to WindowProcedure */
            DispatchMessage(&messages);
        }
    
        /* The program return-value is 0 - The value that PostQuitMessage() gave */
        return messages.wParam;
    }
    
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    
    LRESULT CALLBACK ChildProc(HWND hwnd, UINT Message, WPARAM wparam,LPARAM lparam)
    {
    	if (Message == WM_DESTROY )
    	{
    	    createdWindow = FALSE;
    		return 0;
    	}
    	return DefWindowProc(hwnd,Message,wparam,lparam);
    }
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  /* handle the messages */
        {
             case WM_COMMAND:
                switch (LOWORD(wParam))
                {
                    case 123:
                        if (createdWindow == TRUE)
                            break;
    
                        createdWindow = TRUE;
    
                        // Создание второго окна
                        WNDCLASS w;
                        memset(&w,0,sizeof(WNDCLASS));
                        w.lpfnWndProc = ChildProc;
                        w.hInstance = main_hThisInstance;
                        w.hbrBackground = GetStockBrush(WHITE_BRUSH);
                        w.lpszClassName = "ChildWClass";
                        RegisterClass(&w);
                        HWND newWin = CreateWindowEx (
                           0,                   /* Extended possibilites for variation */
                           w.lpszClassName,         /* Classname */
                           _T("New window"),       /* Title Text */
                           WS_OVERLAPPEDWINDOW, /* default window */
                           CW_USEDEFAULT,       /* Windows decides the position */
                           CW_USEDEFAULT,       /* where the window ends up on the screen */
                           544,                 /* The programs width */
                           375,                 /* and height in pixels */
                           HWND_DESKTOP,        /* The window is a child-window to desktop */
                           NULL,                /* No menu */
                           main_hThisInstance,       /* Program Instance handler */
                           NULL                 /* No Window Creation data */
                           );
                        ShowWindow(newWin, SW_NORMAL);
                        UpdateWindow(newWin);
                        break;
                }
                break;
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }

     

     

    • Плюс 1
  17. 2 hours ago, afro228offical said:

    Пока , получилось только окно в окне . Это мне не совсем подходит...

     

    Тебе не хватает понимания того что ты делаешь. По этому не разобрался в моем примере и в том примере который ты привел по ссылке.

    Но не страшно, метод "тыка" тоже имеет место быть.

     

    В функции CreateWindowEx (которую ты наверняка используешь, ибо в коде по ссылке это именно она) четвертый параметр с конца это родительской HWND окна, установи его в NULL.

    И из стилей созданного окна убери WS_CHILD.

    А лучше, CTRL+C код для создания основного окна, CTRL+V туда где создаешь второе окно по клику.

  18. 14 minutes ago, afro228offical said:

    Никто подсказать не может ?

    А в чем проблема?

     

    1. Создай кнопку OK передав туда параметр HMENU

    Spoiler
    
        hwndButtonOK = CreateWindow(
            "BUTTON", // predefined class
            "OK", // button text
            WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // styles
            10, // starting x position
            90, // starting y position
            100, // button width
            30, // button height
            hwnd, // parent window
            (HMENU) 1, // ВОТ ЭТО ЗНАЧЕНИЕ
            (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
            NULL); // pointer not needed

     

     

    2. В процедуру обработки оконных сообщений WndProc добавь в switch обработку константы WM_COMMAND, пример:

    Spoiler
    
    /*  This function is called by the Windows function DispatchMessage()  */
    
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
      
        switch (message)                  /* handle the messages */
        {
            case WM_COMMAND:
          
                switch (LOWORD(wParam))
                {
                    case 1:
                        // ТУТ ВЫПОЛНИТСЯ ТВОЙ КОД ПРИ НАЖАТИИ НА КНОПКУ
                        break;
                }
          
                break;
            case WM_DESTROY:
                PostQuitMessage(0);       /* send a WM_QUIT to the message queue */
                break;
            default:                      /* for messages that we don't deal with */
                return DefWindowProc(hwnd, message, wParam, lParam);
        }
    
        return 0;
    }

     

     

    3. И просто создавай через CreateWindow новое окно, и в него добавляй что тебе надо.

     

    P.S. Возможно это не самый лучший вариант, но этим вариантом я пользуюсь при создании TrainMe.

  19. Из визуального значения можно как шерлок-холмс выйти на реальное.

    Предлагаю найти строку в памяти куда рендерится значение, например "Х%" или просто "Х" смотря в каком виде там рисуется значение, затем подключившись в OllyDbg и используя memory breakpoint на этой строке дойти до нужных инструкций. Я как раз собирался записать один такой урок как-нибудь в ближайшее время.

  20. 4 hours ago, LIRW said:

    Не знай как будет работать или нет у других, но Base - 00401344 + 0 + 0  У меня всё работает.

    Верно! Правильный подход.

     

    Суть данного TrainMe в том, что он обманывает CheatEngine тем, что выдает якобы "статический" адрес, который на самом деле при перезапуске программы меняется.

    На самом деле существует 3 таких адреса в коде (3 инструкции в которых присутствует адрес):

    1. При инициализации (присвоению значению 100)
    2. При увеличении / уменьшении значения на 10
    3. При освобождении динамически выделенной памяти

    Но суть в том, чтобы добавить в таблицу CE адрес на одну из этих инструкций (например):

    CPU Disasm
    Address   Hex dump             Command                                  Comments
    004013A6  |.  8B15 83604000    MOV EDX,DWORD PTR DS:[406083]

    И добавить к ним оффсет, например в данном случае 004013A6 + 2 (опкод команды MOV в данном случае занимает 2 байта 0x8B15) и получаем указатель на указатель который указывает на значение.
     

    • Плюс 1
×
×
  • Создать...

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

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