-
Постов
47 -
Зарегистрирован
-
Посещение
-
Победитель дней
2
Тип контента
Профили
Форумы
Загрузки
Блоги
Сообщения, опубликованные holy
-
-
On 30.08.2016 at 11:39 AM, JIeXA said:
Что это такое
Не знаю
Вроде ничем не паковал. А если и пакую, то UPX'ом
-
Ещё как вариант , предположу что BaseAddress у модуля Game.exe смещается. У тебя на скрине статичный адрес это "Game.exe"+016*** (видны на скрине только первые 3 цифры). А в коде у тебя жестко задано число. Однако в зависимости от смещения Game.exe будет разный первоначальный адрес.
-
Прикольно вам
-
По аналогии с этим:
wchar_t My_Little_String[100]; swprintf(My_Little_String, L"%d - %s", 24, L"piupiu");
Все функции printf работают одинаково.
Либо они выводят инфу в консоль (и тогда первый параметр является сразу форматом строки)
Либо они выводят инфу в строку (и тогда первый параметр всегда строка в которую будет писаться результат)
- 1
-
10 hours ago, LongLong said:
Игра обнаружила несоответствие.Это значит,что коллективная игра потеряла данные синхронизации между игроками
Я вообще не стал бы конкретно эту ошибку патчить.
Судя по описанию ошибки, она может возникнуть во время любой рассинхронизации, а не только в момент читерства.
От сюда следует, что эта ошибка, возможно, где-то выше вызывается через call. Возьми отладчик, поставь BP на место где она вызывается, и смотри на стек вызовов.
Исследуй код который вызывает эту функцию, возможно найдешь как "починить", если повезет.
-
1 hour ago, gmz said:
дада bufferoverflow был запланирован
Память выделяется динамически, в зависимости от входных данных )
А это значит, что:
1. Эти данные хранятся не в стеке, а в куче
2. Эти данные всегда имеют соответствующий входным строкам размер, а значит переполнения не может быть
И именно по этому я не люблю когда Visual Studio что-то пытается решить за меня, по этому юзаю Code::Blocks и GCC компилятор )
-
9 minutes ago, afro228offical said:
Ну эт жесть
Вообще-то все эти ошибки гуглятся...
Столько лишних вопросов, попробуй сам гуглить.
То что студии не нравится swprintf это я знаю, по этому и не люблю Visual Studio, слишком много на себя берет.
Попробуй вторым параметром передать длину строки, т.е.
swprintf(My_Little_String, len_string, L"%d - %s", entry.th32ProcessID, entry.szExeFile);
Может поможет. Если нет, то загугли альтернативные функции.
-
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);
-
9 minutes ago, afro228offical said:
невозможно преобразовать аргумент 1 из "WCHAR [260]" в "const char *"
У меня, в CodeBlocks, в структуре переменная szExeFile имеет тип TCHAR, скорее всего в Visual Studio другой тип.
Попробуй вместо strlen использовать wcslen (она для WCHAR)
-
8 minutes ago, afro228offical said:
А вывести в MessageBox получится ?
Используй MessageBoxW
MessageBoxA для ASCII строк (там где символы 1 байт), MessageBoxW для UNICODE строк (там символы обычно 2 байта)
- 1
-
Тестировалось в 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
-
Spoiler
#include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { DWORD kek = 43289; int count_of_numbers = 1; while (kek >= 10) { count_of_numbers++; kek /= 10; } printf("Count of numbers = %d", count_of_numbers); return 0; }
- 1
-
DWORD это 32-bit unsigned int
(Т.е. целое беззнаковое число от 0x00000000 до 0xFFFFFFFF)
Объясни вопрос более подробно и с примером. Иначе не понятно, причем тут число и количество символов в нем.
Если более филосовско рассуждать, то DWORD это 2 WORD'а, которые состоят из 4х CHAR'ов :DD а значит 4 символа
- 1
-
Spoiler22 minutes ago, Garik66 said:
Только ты забыл, что вынужден ещё две инструкции прописать
Только ты забыл, что у тебя 4 операции со стеком, и они увеличиваются арифметически в зависимости от количества твоих действий.
А в моем случае, операций со стеком всегда 2, а действия с регистром можно делать сколько угодно и это все-равно будет быстрее.
-
Уже оффтоп
Spoiler13 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
-
1 minute ago, Garik66 said:
Потому что для передачи данных (кол-во патронов) в данном случае я использую не регистр, а стек и непосредственно память
Ясно.
Я просто думал, что была какая-то причина, но раз это просто желание такое, тогда понял )
-
Garik, извиняюсь за тупой вопрос, но почему в данном куске кода:
Spoilerpush [ebx+08] // выгружаем max кол-во патронов в стек, сдвигая его pop [eax+08] // загружаем max кол-во патронов, одновременно // востанавливая стек push [ebx+14] // выгружаем max кол-во патронов в рожке в стек, сдвигая его pop [eax+0C] // загружаем max кол-во патронов в рожке, одновременно // востанавливая стек
ты не использовал регистр? Ведь не важно, использовался он или нет, мы в любом случае сохраняем его значение и восстанавливаем
Например так:
Spoilerpush 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 // восстанавливаем регистры после использования
Просто интересуюсь )
-
40 minutes ago, 2zolo2 said:
Koks1k, я понял пиратские сервера? то скачивай исходники сервера и ищи уязвимость в них.
Раздел "Платный запросы", ему подсказки не нужны, ему требуется выполнение запроса за деньги.
9 hours ago, Koks1k said:Это реально?
Почти нереально. Не думаю что кто-то возьмется за такое, тем-более если сервера не маленькие.
- 1
-
Пример создавал в 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
-
2 hours ago, afro228offical said:
Пока , получилось только окно в окне . Это мне не совсем подходит...
Тебе не хватает понимания того что ты делаешь. По этому не разобрался в моем примере и в том примере который ты привел по ссылке.
Но не страшно, метод "тыка" тоже имеет место быть.
В функции CreateWindowEx (которую ты наверняка используешь, ибо в коде по ссылке это именно она) четвертый параметр с конца это родительской HWND окна, установи его в NULL.
И из стилей созданного окна убери WS_CHILD.
А лучше, CTRL+C код для создания основного окна, CTRL+V туда где создаешь второе окно по клику.
-
20 minutes ago, afro228offical said:
Чет не помогло
У меня работает ) Значит что-то не так у тебя. А разбираться придется тебе самому, врядли кто-то решится копаться в чужой шахте.
-
14 minutes ago, afro228offical said:
Никто подсказать не может ?
А в чем проблема?
1. Создай кнопку OK передав туда параметр HMENU
SpoilerhwndButtonOK = 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.
-
Из визуального значения можно как шерлок-холмс выйти на реальное.
Предлагаю найти строку в памяти куда рендерится значение, например "Х%" или просто "Х" смотря в каком виде там рисуется значение, затем подключившись в OllyDbg и используя memory breakpoint на этой строке дойти до нужных инструкций. Я как раз собирался записать один такой урок как-нибудь в ближайшее время.
-
4 hours ago, LIRW said:
Не знай как будет работать или нет у других, но Base - 00401344 + 0 + 0 У меня всё работает.
Верно! Правильный подход.
Суть данного TrainMe в том, что он обманывает CheatEngine тем, что выдает якобы "статический" адрес, который на самом деле при перезапуске программы меняется.
На самом деле существует 3 таких адреса в коде (3 инструкции в которых присутствует адрес):
- При инициализации (присвоению значению 100)
- При увеличении / уменьшении значения на 10
- При освобождении динамически выделенной памяти
Но суть в том, чтобы добавить в таблицу CE адрес на одну из этих инструкций (например):
CPU Disasm Address Hex dump Command Comments 004013A6 |. 8B15 83604000 MOV EDX,DWORD PTR DS:[406083]
И добавить к ним оффсет, например в данном случае 004013A6 + 2 (опкод команды MOV в данном случае занимает 2 байта 0x8B15) и получаем указатель на указатель который указывает на значение.
- 1
TrainME by Xipho
in Train Me
Опубликовано · Изменено пользователем holy
Значения очков, я вроде искал через неизвестные значения.
Т.е. изначально ищем неизвестные значения, потом в игре увеличиваются очки, и в Cheat Engine отсеиваю результаты через "Увеличилось значение"