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

MasterGH

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

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

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

    129

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

  1. В общем чтобы устроить тех, кто желает учиться C# и тех, кто не желает учиться C# я предоставляю на выбор два варианта. Это заглянуть под спойлер или не заглядывать под него до написания своего решения.
  2. Наверно, так VAM = new VAMemory("game"); IntPtr address = (IntPtr)0x6D459B; address = (IntPtr)(VAM.ReadULong(address)+0xc1) address = (IntPtr)(VAM.ReadULong(address)+0x66c) address = (IntPtr)(VAM.ReadULong(address)+0x37b) address = (IntPtr)(VAM.ReadULong(address)+0x18) VAM.WriteByteArray(address, new byte[1] { 0xC3 });Здесь нет проверок на 1) разрядность системы 2) на существования адреса Если это 64 битное приложение, то адреса надо считать иначе. Если указатели бывают null, то будет исключение перед попыткой добавить смещение к null
  3. Плагин "Plugin AA Maker" штука интересная, но после появления встроенного шаблона генерации сигнатур в меню АА окна, этот плагин можно не использовать. АА Maker подходит для поиска сигнатур, но а) не указывает модуль, в котором ищет (exe или dll) б) пропускаете первый пять байт или больше, которые нужны для проверки инъекций minesweeper.exe+2B75B - F3 0F11 40 20 - movss [rax+20],xmm0Здесь нужен не только байт F3, но и все остальные F30F114020, потому что нужен чтобы был rax, чтобы было смещение +20, и чтобы был регистр xmm0. AA Maker включает байт опкода, но не включает все первый пять байт или более для проверки ключевых данных, которые могут использоваться в инъекциях и могут быть разными на разных версиях игр. Если используете плагин AA Maker, то хотя бы первые пять байт оставляйте цельными и указывайте модуль в котором будет поиск сигны. Либо делайте инъекцию так чтобы она не работала с регистрами, не работала со смещениями относительно базового адреса, но сделать это может быть нелегко (об этом ниже, в последнем абзаце поста) Вообще тема работоспособности читов на разных версия игр актуальна. Я кстати так и не доделал генерацию автоматической инъекции по правилам, по сигнатуре в плагине для CE. Т.е. например мы нашли сигнатуру, а по ней вышли на movss [rax+20],xmm0, но мы не хотим знать ни rax и не хотим знать +20 и не знаем xmm0, мы хотим только знать маску movss [register1+offset1],register2 или знаем маску movss [address1],register1 и знаем правило например "вписать значение 9999". Далее уже в самое игре, после активации чита, должен быть сгенерирован АА скрипт по правилу "Постоянное значение". АА скрипт должен сам создаваться по маске. Данный способ может существенно увеличить живучесть читов, но не на 100%. Я помню пример, когда после выхода новой версии игры, код в ней значительно менялся и никакая сигнатура там не работала. Это значит нужен уже другой подход. Если одни сигнатуры не работают, то могут работать другие и их надо найти имея под рукой множество версий игр... Пока может быть другой способ. Это стараться избегать внутри инъекции регистров, смещений. Это может быть "ноппинг", "исправление прыгов", "правка простых инструкций" и даже может быть работа с первым стековым адресом по ESP или RSP на определенном адресе кода найденного по сигнатуре... Такие дела...
  4. 1. Я не понял, от какой мороки, от которой ты устал? 2. ИМХО позже, скорее всего, ты игру ты не приобретешь, т.к. ты её пройдешь "Ломать пока что времени нет, да и я играю..." (с, Кенг)
  5. 1. Нужен код Функции WriteHEX SearchResult.WriteHEX(0, '01 ?? AA 00'); 2. Попробуй вместо вопросов поставить "XX" 3. Если хочешь помощи, то пиши код функции WriteHEX Если у тебя его тоже нет, тогда как ты себе представляешь помощь от нас? Мы не можем ни определить ошибок кода, ни поддержку пропуска байтов, ни поддерживаем символы для пропуска байт. Можно было бы exe поковырять в дизассемблере, но это вряд ли кто делать будет.
  6. Пример как работать с документацией. Хотим например узнать как в архитектурах Intel® 64 и IA-32 работает pushad. Т.е. главный вопрос. Я хочу сохранить 64 разрядные регистры с помощью pushad, могу ли я это сделать? Открываем 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf И ищем pushad Смотрим на надпись в красной рамке Это означает, что pushad не работает для 64-разрядных регистров, а только для старых регистров 32-разрядных.
  7. Ссылка Intel® 64 and IA-32 Architectures Software Developer’s Manual на сайт для скачивания В руководствах описывается архитектура и среда программирования архитектур Intel® 64 и IA-32. Электронные версии этих документов позволяют быстро добраться до нужной информации и распечатать только те страницы, которые вам необходимы. Руководства пользователя по архитектурам Intel 64 и IA-32 теперь доступны для скачивания. Подробнее смотрите на сайте. Загружайте файлы PDF.
  8. Фигово ассемблируется "call адрес" на CE 64 Bit, но не всегда, а вроде когда адрес находится в каком-то диапазоне, то ли значительно до адреса инъекции. Поэтому пришлось написать вроде этого push rcxmov rcx, адрес // где адрес в новой памятиcall rcxpop rcx Так это зависит от того, что ты делаешь. Если ставить один раз бряк на доступ на инструкцию и больше ничего не делать, то вылезет одна инструкция и ты даже не узнаешь, что код проверяет сам себя... Нужно ставить брейкпоинты на каждой новой появившейся инструкции в окне брейкпоинтов. Тогда узнаешь: Адрес1: код работающий с адресом денег Адрес2: Код проверки адреса1 Адрес3: Код проверки адреса2 и адреса3 Адрес4: Код проверки адреса3 и адреса4 Справа указаны оригинальные байты, которые затираются прыжком на выделенную память и их(оригинальные байты) нужно читать вместо фейковых Адрес1: ACU.exe+55D741F : 32 02 F9 E9 9C 06 00 00 Адрес2 : ACU.exe+55D658F : 32 02 F6 C3 9B Адрес3 : ACU.WriteData+22C8 : 32 02 F5 A8 3F Адрес4(Money) : ACU.exe+FAB5BE : 8B 53 28 03 43 38
  9. Вот что получилось, но что-то не работает Написал я таблицу ACU.CT Пока не отладил толком. Если кто будет запускать таблицу, то инструкцию прочти 1. Запускаем CE и на всякий случай ставим VEH дебаг 2. Запускаем игру в коне и прям на заставке Alt+Tab и переходим в CE 3. Открываем таблицу. На предложение выполнить Луа скрипт отказываем. Он может пригодится только для генерации АА скрипта 4. Останавливаем процесс по горячей клавише (назначить её надо) и активируем Umul1 и Emule2, и отпускаем процесс игры. Тут вылет происходит, а его не должно быть 5. Если вылета нет, то активировать скрипт денег. Войти в игру потратить и посмотреть изменения. Скрипт денег сделал на скорую руку. Пока такие дела.
  10. Я поставил наконец эту игру. Мое маленькое исследование и теоретическое решение. 1. Когда мы меняем код, то через какое-то время 3 участка могут проверить его 2. Проверяющий код проверяет сам себя (!) и другой код Теоретическое решение, оно такое простое, что лежит перед носом. Когда инструкция читает адрес с нашим фейк кодом, то читает фейк байты и обнаруживает ошибку, и происходит вылет из игры. Так вот, нам надо сделать фильтры на адреса фейк кода и подставить не фейк байты. Это надо сделать 3 раза для проверки кода самого себя и + 3*N раз на инъекцию чит-кода. ACU.exe+55D741F - 32 02 - xor al,[rdx] // 1ACU.exe+55D658F - 32 02 - xor al,[rdx] // 2ACU.WriteData+22C8 - 32 02 - xor al,[rdx] // 3На 1 проверить 2,3 и N раз для читаНа 2 проверить 1,3 и N раз для читаНа 3 проверить 1,2 и N раз для чита Для того чтобы не писать лишнего кода можно попробовать придумать вызов call на новую память, в которой будут подставляться оригинальные байты вместо фейковых. Только-только у меня родилась эта идея и поэтому решил о ней написать. Возможно, скоро я сделаю таблицу как минимум на деньги. Еще кстати есть читы встроенные разрабами и даже должно быть дебаг меню, но пока о них даже не думаю.
  11. stringtocompare: db 'a string' ... ... check: //store the registers that get changed pushfd push esi push edi push ecx mov esi,stringtocompare mov edi,[eax+20c] //edi get the pointer to the string you wish to check (use lea if the address itself) mov ecx,8 //number of characters in the string check_loop: mov al,[esi] cmp [edi],al jne incorrect inc edi inc esi loop check_loop //as long as ecx>0 jump to check_loop (loop decreases ecx for you) //if it reaches here, the string is a match //do stuff jmp exit incorrect: //do incorrect handling exit: //restore the changed registers pop ecx pop edi pop esi popfd ...your exit handling...
  12. Ну, так ты дамаг ставь на 10К урона у всех пушек и смотри, что получится. Может вообще дамаг так поставить нельзя. Про спойлер ничего не скажу. Xipho может проверить "барахлит" он или нет.
  13. Весьма полезный скрипт от автора panraven Основная задача - вывод байт-строки вида "11 00 00 00 48 65 6C 6C 6F 20 43 68 65 61 74 45 6E 67 69 6E 65". Благодаря функциям в этом скрипте можно вывести байт строку по адресу памяти и сохранить её в файл. Можно выводить байт-строку целого или вещественного числа положительного или отрицательного Можно выводить байт строку с пробелами или без них Можно выводить байт строку hex числа, тогда она будет в перевернутом виде Можно присоединять к строке байты из таблицы Также не забудьте применять функции, которые есть у CE wordToByteTable(number), dwordToByteTable(number), qwordToByteTable(number), floatToByteTable(number), doubleToByteTable(number), stringToByteTable(string), wideStringToByteTable(string) Примеры там же в скрипте function byte2aob( return type(=='number' and b<256 and b>=0 and string.format('%02X', or '??' end function aob2byte(a) a = tonumber(a,16) return type(a)=='number' and a <256 and a>=0 and a or -1 end function imap(t,f) local s={} for i=1,#t do s[i]=f(t[i]) end return s end function n2bt(n,t) t=type(t)=='string' and t or 'dword' return rawget(_G,t..'ToByteTable')(n) end function t2aob(t,sep) return table.concat(imap(t,byte2aob),type(sep)=='string' and sep or ' ') end function n2aob(n,t) return t2aob(n2bt(n,t)) end function s1aob(s) return t2aob(n2bt(s,'string')) end function s2aob(s) return t2aob(n2bt(s,'wideString')) end function aob2bt(a) local s = a:gsub('%S+',function(r) -- check parts local t,l = {},string.len(r) assert(string.len(r) % 2 == 0, 'some aob part has odds number of hex digits:'..l..'-'..r) for i=1,l/2 do t[i] = byte2aob(aob2byte(string.sub(r,i*2-1,i*2))) end-- extract byte from each 2 hex digits return table.concat(t) end):gsub('%s+','') -- trim all spaces local t,l = {},string.len(s) assert(l % 2 == 0, 'the aob has odds number of hex digits:'..l..'-'..s) for i=1,l/2 do t[i] = aob2byte(string.sub(s,i*2-1,i*2)) end-- extract byte from each 2 hex digits return t end function normalize(a,sep) return t2aob(aob2bt(a),type(sep)=='string' and sep or '') end -- check even hex digits, default no space form function replaceBytes(a,p,r,m) assert(p>0,'replace position must be positive') local t = aob2bt(a) local isTable = type(r)=='table' local l = isTable and #r or r assert(type(l)=='number','replace table or length not valid') l = math.min(l,type(m)=='number' and m or l) for i=#t+1,p+l-1 do t[i]=0 end for i=1,l do t[p+i-1] = isTable and r[i] or -1 end return t2aob(t) end function join(sep,...) return table.concat(imap({...},tostring),type(sep)=='string' and sep or " ") end function ajoin(...) return join(" ",unpack(imap({...},function(a) if type(a) == 'number' then a = byte2aob(a) end if type(a) == 'table' then a = t2aob(a) end return a end))) end -- application function unityString(s,wide) local stoaob = wide == true and s2aob or s1aob return ajoin(n2aob(string.len(s)),stoaob(s)) end -- test print(n2aob(999,'double')) local u = unityString('Hello CheatEngine') local w = unityString('Hello CheatEngine',true) print(u) print(normalize(w)) -- r = aobscan(u) -- local r = 0x451200 - 8 -- unity string struct address at -8 offset of pattern [str-len:4bytes][str-chars] local c = ajoin(0x68,n2aob(r),'50 ?? ?? e8') -- push [string addr] ; push some-eax ; call some-where print(c) local d,e = replaceBytes(c,2,4),replaceBytes(c,10,n2bt(1000000),2) print(d) -- replace with how many wildcard, here 4, at position 2 print(e) -- replace/insert 1st 2 bytes of aob(1000000):0f4240 after e8, give ... e8 40 42 --[[ output 00 00 00 00 00 38 8F 40 11 00 00 00 48 65 6C 6C 6F 20 43 68 65 61 74 45 6E 67 69 6E 65 11000000480065006C006C006F0020004300680065006100740045006E00670069006E006500 68 F8 11 45 00 50 ?? ?? e8 68 ?? ?? ?? ?? 50 ?? ?? E8 68 F8 11 45 00 50 ?? ?? E8 40 42 --]]
  14. Ну, что не разобрался? В общем вот решение. По адресу сохранит строку из байтов. Например строку "55 8B EC 83 C4 F0 B8 C0 46 45 00 E8 40 0D FB FF A1 5C 79 45 00 8B 00 E8 4C D4 FF FF 8B 0D 74 77 45 00 A1 5C 79 45 00 8B" При чем файл выбираешь из диалога сохранения. Если диалог не нужен, путь и файл известны, то поправь скрипт удалив лишнее. local adress = 'test.exe+556D8' -- адрессlocal countBytes = 40 -- количество байтов по адресу, которые нужно сохранитьlocal isBytenormalize = false -- нужны пробелы в сигнатуре?-----------------------------------local fileName = ''function imap(t,f) local s={} for i=1,#t do s[i]=f(t[i]) end return s end function t2aob(t,sep) return table.concat(imap(t,byte2aob),type(sep)=='string' and sep or ' ') endfunction normalize(a,sep) return t2aob(aob2bt(a),type(sep)=='string' and sep or '') endfunction OnCloseSaveDialog(argFrmSaveDialog) local path = argFrmSaveDialog.FileName local isReturnAsTable = true local returnAsTable = readBytes(adress, countBytes, isReturnAsTable) local aob = t2aob(returnAsTable) if(isBytenormalize) then aob = normalize(aob) end local stringList = createStringlist() stringList.add(aob) stringList.saveToFile(path) stringList.destroy()endif (getOpenedProcessID() == 0) then messageDialog('No target any process', mtError, mbOK) return endif(frmSaveDialog == nil) then frmSaveDialog = createSaveDialog(nil) endfrmSaveDialog.DefaultExt = '.txt'frmSaveDialog.FileName = fileNamefrmSaveDialog.Filter = '*.txt'frmSaveDialog.FilterIndex = 0frmSaveDialog.OnClose = OnCloseSaveDialogfrmSaveDialog.Execute()
  15. MasterGH

    Reversing C++

    Я тут презентации нашел интересные по реверсу на С++. На сайте Вот скриншот куда надо зайти, как пример. Так что кому интересно, можно скачать презентации и посмотреть множество диаграм по реверсу С++
  16. Каких еще "для начинающих"? Надо Герберт Шилдт Полный справочник C++. 4-е издание (Дата выхода: сентябрь 2003, Издательство: Вильямс) Стр. 503 Глава 24 Введение в стандартную библиотеку шаблонов Контейнеры Алгоритмы Интераторы Векторы Списки Ассоциативные контейнеры Функторы Далее Стандартные контейнерные классы Глава 33 Стандартные алгоритмы Глава 34 Стандартные итераторы, рапределители памяти и функторы. Глава 35 -------- Я в иде, когда игру ковырял там было примерно так 130 с чем-то типов объектов висело в динамическом списке они приводились через динамик каст к классу и работали еще в его контексте. Так что динамик каст может быть наводкой. Прочитай главу 22 про Динамическую идентификацию типа: различные касты, динамик, статик, реинтерпрет касты ------ Желательно меньше чтения и больше программирования. Примеры можно писать в консольном приложении делая динамический список и брать CE и пытаться извлечь список объектов
  17. Кстати, может кто нибудь объяснить, как такое делается? Я так полагаю, что есть какая-то таблица или список указателей на структуры объектов (какие-то персонажи, будь то онлайн игроки или боты). Как мне его найти? В одной игре пытался сделать, но ничего не вышло. Нашел одноуровневые указатели, рядом все прошерстил - фигня полнейшая, следующий объект с похожей структурой на моего игрока не могу найти Может, есть какие-то способы, как быстро найти такой список? Ибо созерцать содержимое всех указателей желания нет, а смещение на другой указатель найти хочецца Ты можешь пробовать что-то найти, но пока не будет прочного представления как выглядит отладочный код и С++ код, ты будешь двигаться интуитивно и возможно долго, и просто увязнешь. Тебе надо а) Знать С++, STL, WinAPI (примеры по работе со списками объектов завались) б) Написать прототип игры на C++ и пытаешься его же "ломануть". Можешь использовать как встроенный отладчик С++, так и IDA Hex-Rays, CE... После чего возможно ты выработаешь стратегию поиска данных в отладке. Это могут быть массивы структур данных, могут быть массивы ссылок на структуры данных. В STL есть функции перебора элементов на высоком уровне и на низком в отладке может дать достаточное представление как это может выглядеть на ассемблере и что делать с этим кодом. Если будешь С++ ковырять советую: 1) Шилдт (для быстрого разгона понимания С++ и STL) (или другие авторы) 2) MSDN, но надо в нем уметь быстро искать, иначе будешь тупить 3) Функции WinAPI 4) Программирование DirectX игр на С++ (только по примерам, очень быстро, иначе увязнешь) Преимущественно надо искать примеры кода и разбирать функции. Посмотри исходники Сталкера 1.6 в разделе игровые движки. Там должны быть списки объектов игроков. Вот и подумай как с ними работать.
  18. Работа с буфером обмена (clipboard) / C++ для начинающих / C++ В Гугле поиск Функции для работы с буффером (в MSDN есть описание) OpenClipBoardEmptyClipboardSetClipboardDataCloseClipboardGetClipboardData
  19. К сожалению, у меня нет игры, поэтому не могу проверить скрипт. Получается деньги шифрованы через xor О том, как искать адрес денег вот на видео. Хороший пример поиска шифрованного значения "изменилось/не изменилось 4 байта" To Garik66 #7 mov ebx, dword ptr [Old]cmp ebx, dword ptr [ecx+08]Если можно найти экранный адрес, можешь попробовать ставить значение экранного адреса вместо ручной установки в Old метку
  20. По ссылке, что я привел написано как работают деньги. Идем в магазин. На 15 линии пишем деньги на счету и жмем Ок. Если на счету 100$, то "cmp [rdx+rcx*8],#100" (т.е. фильтр по текущему значению денег) Активируем скрипт Пишем в метку newMoney желаемое мани Че-нить покупаем Профит Деактивируем. Вообще я жалею, что привел этот скрипт. Только путает. И я его привел в учебных целях. Можешь скачать таблицу автора по ссылке, что я привел и пользуйсо. Попробуй как я писал. Найти экранный адрес или любой другой текущих денег в игре. Или адрес текстом. Поставь бряк и определи инструкции, которые работают только с этим экранным адресом. Найди смещения до рабочего адреса отталкиваясь от данных и базовых адресов. В инструкцию работающей с экранным адресом и делать инъекцию чтобы записывалось в рабочий адрес.
  21. Ты уверен, что там нужен фильтр? Может ставить бряк надо на экранный адрес. В инструкцию работающей с экранным адресом и делать инъекцию. Я думаю пример ниже это то, что я думаю. [Enable]alloc(sm_1,32,GTA5.exe) //Set Moneyaobscanmodule(sm_aob1,GTA5.exe,48 8B 43 08 48 89 04 CA)registersymbol(sm_aob1)label(returnhere_sm_1)label(newMoney)registersymbol(newMoney)label(isMoney)//--------------------------------------------------//sm_1:cmp [rdx+rcx*8],#0 //<-- PUT YOUR CURRENT CASH HEREje isMoneymov rax,[rbx+08]mov [rdx+rcx*8],raxjmp returnhere_sm_1//--------------------------------------------------//isMoney:mov rax,[newMoney]mov [rdx+rcx*8],raxjmp returnhere_sm_1newMoney:dd 0//--------------------------------------------------//sm_aob1:jmp sm_1nopnopnopreturnhere_sm_1:[Disable]sm_aob1:db 48 8B 43 08 48 89 04 CAunregistersymbol(sm_aob1)dealloc(sm_1)unregistersymbol(newMoney)
  22. Можно сделать на примере TinyDumper. Там сохраняются байты в файл. Только придется делать свой формат сохранения function OnCloseSaveDialog(argFrmSaveDialog)local path = argFrmSaveDialog.FileNamelocal stringList = createStringlist()for i = 1, #tableData dolocal adress = tableData[i][1]local size = tableData[i][2]local unicalName = tableData[i][3]local tablesReadBytes = tableData[i][4] --readBytes(adress, tonumber(size), true)if(tablesReadBytes == nil) thenmessageDialog('TablesReadBytes is nil', mtError, mbOK)returnendlocal strBytes = table.concat(tablesReadBytes, " ")local data = string.format("<TABLE>%s;%s;%s;%s</TABLE>", adress, size, unicalName, strBytes)stringList.add(data)endstringList.saveToFile(path)stringList.destroy()endfunction OnClickMenuItemSaveAllDumps()if (getOpenedProcessID() == 0) thenmessageDialog('No target any process', mtError, mbOK)returnendif (#tableData == 0) thenmessageDialog('Table is empty', mtWarning, mbOK)returnendif(frmSaveDialog == nil) thenfrmSaveDialog = createSaveDialog(nil)endfrmSaveDialog.DefaultExt = '.tinyDumper'frmSaveDialog.FileName = fileNamefrmSaveDialog.Filter = '*.tinyDumper'frmSaveDialog.FilterIndex = 0frmSaveDialog.OnClose = OnCloseSaveDialogfrmSaveDialog.Execute()end
  23. На Lua можно не делать . Через горячие клавиши скопировать в буфер выделенный текст (CTLR+C) и в блокноте через горячие клавиши вставить (CTRL+V) и сохранить файл.
  24. Я думаю, что в 18-ой строчке надо убрать знак точку с запятой ";" Еще есть сомнения по strlen, возможно нужно добавить #include < string.h > Во всяком случае легко проверить ошибку последовательно удаляя функции из кода и добавляя их вновь после того как ошибка пропала.
×
×
  • Создать...

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

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