MasterGH Опубликовано 5 июля, 2010 Поделиться Опубликовано 5 июля, 2010 TrainMe(hard_1_0).rar Задание. Сделать количество объектов равное 10000. При нажатии кнопки на плюс должно стать 10001. Если нажали на минус, то должно быть 10000-1=9999. Это не единственное задание. После того как все задания будут сформулированы и решены, то в этом посте будет описание как заданий так и их решений. Подсказка и ограничение. Вам нужно найти конструктор объектов и создать 10000 объектов. Они будут подсчитываться при нажатиях на кнопки. Помните, что цель именно такая, а не хак отображения текста. По описаниям ваших действий можно будет судить правильно ли вы сделали. Сам этот трейнми я обманул, так что это реально. Подобный приём используется всё чаще и чаще в играх. Это количество: ножей, стрел, патронов в Сталкере, гранаты и т.п. которые имеют объектный тип. Также объектный тип 100% имеют управляемые единицы в стратегиях (ваши юниты, ваши игроки которыми вы управляете). В каждом из приведённых случаев обман может быть гораздо сложнее чем в этом трейнми, но это основа основ взлома объектных типов. В создании, тестировании трейнми принимали участие: MasterGH и Xipho. СЛЕДУЮЩИЕ ЗАДАНИЯ ВЫПОЛНЕНЫ. Для этого трейнми было 3 задания. Их можно было делать на любом инструменте. Предпочитаемый CheatEngine. 1.Сделать чит-код добавляющий объекты в количестве до 10000. При следующем нажатии на кнопу вычитания объектов должно быть 9999 или при нажатии на плюс 10001. 2.Восполнить разрушенный объект при помощи скриптов CE. Т.е. когда мы нажимаем на кнопку вычитания объектов, то разрушенный объект восполняется одним. 3.Сделать так чтобы при вычитание объектов или при их создании, их количество держалось на отметке не меньше 1000 объектов. Поскольку последнее задание объединяет первые два, то напишу только последнее. Скрипт1 - Главный Скрытый текст /* Процесс: TrainMe(hard_1_0).exe Чит-код: Скрипт на восттановление указанного кол-ва объектов Дата: 7.21.2010 Автор скрипта: MasterGH(c) Версия CE: Cheat Engine 5.6 RUS (v 2.0) ------------------ На _void_RstObj() делалаем два call-а в места: 1) из кода после добавления объектов 2) из кода после уменьшения объектов */ alloc(_newmem,2048) label(_void_RstObj) label(_EAX_GetCountObj) label(_void_AddObject) label(_void_createobj_eax_) label(_ex) label(_loop) label(_a1) label(_a2) registersymbol(_void_RstObj) _newmem: //Восстановить кол-во недостающих объектов _void_RstObj: pushf push eax call _EAX_GetCountObj // возвращает eax = кол-во объектов в данный момент push ebx mov ebx,#1000 sub ebx,eax mov eax,ebx pop ebx cmp eax, 0 // eax объектов которых не хватает jl short _ex // переход если объектов которых не хватает меньше нуля call _void_createobj_eax_ _ex: pop eax popf ret // добавление кол-во объектов _void_createobj_eax_: _loop: pushad call _void_AddObject// добавляем объект popad dec eax cmp eax,0 jg short _loop // пока eax больше нуля ret //Добавление 1-го объекта: _void_AddObject: push 4010C0 push 4 push 4 call 0040187c add esp,04 test eax,eax je short _a1 mov [eax],000003e7 jmp short _a2 _a1: xor eax,eax _a2: push edi lea edi,[esp+08] mov [esp+08],eax call 00401280 add esp,0C ret //Получение кол-ва объектов в eax: _EAX_GetCountObj: mov eax,[4045B0] sub eax,[4045AC] sar eax,2 ret [DISABLE] dealloc(_newmem) unregistersymbol(_void_RstObj) [ENABLE] Скрипт2 Скрытый текст aobscan(_faddress,a1xxxxxxxx2bxxxxxxxxxxxxxxxxxx8dxxxxxxxxc1xxxxxxffxxxxxxxxxx83) alloc(_newmem,2048) label(_returnhere) label(_originalcode) _newmem: call _void_RstObj _originalcode: mov eax,[4045B0] jmp _returnhere _faddress: // 0040118D = About+CD jmp _newmem _returnhere: [DISABLE] aobscan(_faddress,2bxxxxxxxxxxxxxxxxxx8dxxxxxxxxc1xxxxxxffxxxxxxxxxx83) _faddress-5: mov eax,[4045B0] dealloc(_newmem) //Alt: db A1 B0 45 40 00 [ENABLE] Скрипт3 Скрытый текст aobscan(_faddress,8bxxxxxxxxxx8bxxxxxxxxxx8bxx2bxxc1xxxx85xx0fxxxxxxxxxx83) alloc(_newmem,2048) label(_returnhere) label(_originalcode) _newmem: call _void_RstObj _originalcode: mov ecx,[4045B0] jmp _returnhere _faddress: // 00401109 = About+49 jmp _newmem nop _returnhere: [DISABLE] aobscan(_faddress,908bxxxxxxxxxx8bxx2bxxc1xxxx85xx0fxxxxxxxxxx83) _faddress-5: mov ecx,[4045B0] dealloc(_newmem) //Alt: db 8B 0D B0 45 40 00 [ENABLE] Как всё это было сделано вы можете узнать прочитав посты ниже. Конечно, может быть будет что-то не понятно, но лучше всего взять отладчик и попытаться по моим скриптам повторить это. А затем попытаться повторить без моих скриптов. Ссылка на комментарий Поделиться на другие сайты Поделиться
SER[G]ANT Опубликовано 5 июля, 2010 Поделиться Опубликовано 5 июля, 2010 что-то наклевывается, но пока больше ощущения, что я нубас) Ссылка на комментарий Поделиться на другие сайты Поделиться
JIeXA Опубликовано 6 июля, 2010 Поделиться Опубликовано 6 июля, 2010 Нифига не получается разобраться.....Понял ток что всё по XORено и вышел на инструкцию00401297 - 83 c0 08 - add eax,04 если 4 поменять на 8 то при нажитии на + будет в два раза больше прибовляться если 16 32 и тдНи как не могу выйти на конструкторНужна помощь и пояснения а ещё лучше статья по этому ТренМи!!!!!! Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 7 июля, 2010 Автор Поделиться Опубликовано 7 июля, 2010 Там ничего не поксорено, нет никакого шифрования. И всё очень довольно просто решается.Необходимо мыслить логически (эта хоть и сложная, но самая простая задача по объектам). Вам нужно 10000 объектов. Объект создаётся, когда кликаем на кнопку складывания. По кнопке конечно же кликать 10000 раз не следует, но можно циклически выполнить кусок кода конструктора и добавление этого объекта в массив. Этот кусок кода сидит на видном месте и выполняется когда кликаем на кнопку складывания.В скритах CE можно создать поток который с нужными регистрами циклически выполнит этот кусок кода. Также можно это попробовать сделать на Сишном скрипте CE.Я написал этот трейнми на VC++2008 с шаблоном vector, который применяется в реальных играх. В этом я точно уверен. Дальше будет ещё сложнее трейнми в котором будет динамическое привидение объекта класса предка к одному из нескольких родительских.... на подобии в игре Снайпер Гхост Варриор. И тогда вы сможете попробовать взломать гранаты уже в реальной игре, потренировавшись на трейнми.Подожду до воскресения перед тем как дам решение, может быть кто-то взломает трейнми Ссылка на комментарий Поделиться на другие сайты Поделиться
SER[G]ANT Опубликовано 7 июля, 2010 Поделиться Опубликовано 7 июля, 2010 почти победил и уменьшается и увеличивается, правда число здоровенное)капать нужно вот тут008910D0 /. 83EC 54 sub esp , 54h008910D3 |. A1 18408900 mov eax , dword ptr [00894018h]008910D8 |. 33C4 xor eax , esp008910DA |. 894424 4C mov dword ptr [esp+4Ch] , eax008910DE |. 8B4424 5C mov eax , dword ptr [esp+5Ch]008910E2 |. 2D 10010000 sub eax , 00000110h ; Switch (cases 110..111)008910E7 |. 56 push esi008910E8 |. 8B7424 5C mov esi , dword ptr [esp+5Ch]008910EC |. 57 push edi008910ED |. 0F84 DF000000 je 008911D2h008910F3 |. 83E8 01 sub eax , 01h008910F6 |. 0F85 A3000000 jne 0089119Fh008910FC |. 0FB74424 68 movzx eax , word ptr [esp+68h] ; Case 111 of switch 008910E200891101 |. 83E8 02 sub eax , 02h ; Switch (cases 2..3EA)00891104 |. 0F84 AA000000 je 008911B4h0089110A |. 2D E7030000 sub eax , 000003E7h0089110F |. 74 3A je 0089114Bh00891111 |. 83E8 01 sub eax , 01h00891114 |. 0F85 85000000 jne 0089119Fh0089111A |. 8B0D B0458900 mov ecx , dword ptr [008945B0h] ; Case 3EA of switch 0089110100891120 |. 8B15 AC458900 mov edx , dword ptr [008945ACh]00891126 |. 8BC1 mov eax , ecx00891128 |. 2BC2 sub eax , edx0089112A C1F8 02 sar eax , 02h0089112D |. 85C0 test eax , eax0089112F |. 76 6E jbe 0089119Fh00891131 |. 83E9 04 sub ecx , 04h00891134 |. 6A 0A push 0Ah00891136 |. 890D B0458900 mov dword ptr [008945B0h] , ecx0089113C |. 6A 20 push 20h0089113E |. 8D4424 18 lea eax , dword ptr [esp+18h]00891142 |. 2BCA sub ecx , edx00891144 |. 50 push eax00891145 |. C1F9 02 sar ecx , 02h00891148 |. 51 push ecx00891149 |. EB 3D jmp 00891188h0089114B |> 6A 04 push 04h ; Case 3E9 of switch 008911010089114D |. E8 0A070000 call 0089185Ch00891152 |. 83C4 04 add esp , 04h00891155 |. 85C0 test eax , eax00891157 |. 74 08 je 00891161h00891159 |. C700 E7030000 mov dword ptr [eax] , 000003E7h0089115F |. EB 02 jmp 00891163h00891161 |> 33C0 xor eax , eax00891163 |> 8D7C24 0C lea edi , dword ptr [esp+0Ch]00891167 |. 894424 0C mov dword ptr [esp+0Ch] , eax0089116B |. E8 F0000000 call 00891260h00891170 |. A1 B0458900 mov eax , dword ptr [008945B0h]00891175 |. 2B05 AC458900 sub eax , dword ptr [008945ACh]0089117B |. 6A 0A push 0Ah0089117D |. 6A 20 push 20h0089117F |. 8D5424 18 lea edx , dword ptr [esp+18h]00891183 |. 52 push edx00891184 |. C1F8 02 sar eax , 02h00891187 |. 50 push eax00891188 |> FF15 54308900 call dword ptr [00893054h] ; MSVCR90._itow_s0089118E 83C4 10 add esp , 10h00891191 8D4C24 10 lea ecx , dword ptr [esp+10h]00891195 |. 51 push ecx ; /Text00891196 |. 6A FF push FFh ; |ControlID = FFFFFFFF (-1.)00891198 |. 56 push esi ; |hWnd00891199 |. FF15 F0308900 call dword ptr [008930F0h] ; \SetDlgItemTextW0089119F |> 33C0 xor eax , eax ; Default case of switch 00891101008911A1 |. 5F pop edi008911A2 |. 5E pop esi008911A3 |. 8B4C24 4C mov ecx , dword ptr [esp+4Ch]008911A7 |. 33CC xor ecx , esp008911A9 |. E8 DC050000 call 0089178Ah008911AE |. 83C4 54 add esp , 54h008911B1 |. C2 1000 retn 0010h Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 7 июля, 2010 Автор Поделиться Опубликовано 7 июля, 2010 Копать надо там, а лучше выбрать участок кода, который нужно циклически выполнить.Приведите скрипт на CE который решает задание Кто сделает и опишет весь путь взлома, тот получит +3 балла в репутацию. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 9 июля, 2010 Автор Поделиться Опубликовано 9 июля, 2010 Что-то никто не решил задачу, даю ещё подсказкиclass Myobj{ int _id;public: Myobj(int id){_id=id;}};vector <Myobj*> v;// Обработчик сообщенийINT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ UNREFERENCED_PARAMETER(lParam); int wmId, wmEvent; wchar_t istr[32]; switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Разобрать выбор в меню: switch (wmId) { case IDC_BUTTON1: v.push_back(new Myobj(999)); _itow_s(v.size(), istr, 10); SetDlgItemText(hDlg,IDC_STATIC2,istr); break; case IDC_BUTTON2: if (v.size()<=0) break; v.pop_back(); _itow_s(v.size(), istr, 10); SetDlgItemText(hDlg,IDC_STATIC2,istr ); break; case WM_DESTROY: EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)FALSE; break; } } return (INT_PTR)FALSE;}==============================={ signed int result; // eax@7 void *v5; // eax@8 void *v6; // [sp+4h] [bp-48h]@1 wchar_t String; // [sp+8h] [bp-44h]@7 unsigned int v8; // [sp+48h] [bp-4h]@1 v8 = (unsigned int)&v6 ^ dword_404018; if ( a2 == 272 ) { result = 1; } else { if ( a2 != 273 ) return 0; if ( a3 != 2 ) { if ( a3 == 1001 ) { v5 = operator new(4u); if ( v5 ) *(_DWORD *)v5 = 999; else v5 = 0; v6 = v5; sub_401280(); itow_s((signed int)(dword_4045B0 - Src) >> 2, &String, 0x20u, 10); SetDlgItemTextW(hDlg, -1, &String); } else { if ( a3 == 1002 && (signed int)(dword_4045B0 - Src) >> 2 ) { dword_4045B0 = (char *)dword_4045B0 - 4; itow_s((signed int)(dword_4045B0 - Src) >> 2, &String, 0x20u, 10); SetDlgItemTextW(hDlg, -1, &String); return 0; } } return 0; } EndDialog(hDlg, 2); result = 0; } return result;}signed int __stdcall DialogFunc(HWND hDlg, int a2, unsigned __int16 a3, int a4)==============================.text:004010C0 DialogFunc proc near ; DATA XREF: wWinMain(x,x,x,x)+7o.text:004010C0.text:004010C0 var_48 = dword ptr -48h.text:004010C0 String = word ptr -44h.text:004010C0 var_4 = dword ptr -4.text:004010C0 hDlg = dword ptr 4.text:004010C0 arg_4 = dword ptr 8.text:004010C0 arg_8 = word ptr 0Ch.text:004010C0.text:004010C0 sub esp, 48h.text:004010C3 mov eax, dword_404018.text:004010C8 xor eax, esp.text:004010CA mov [esp+48h+var_4], eax.text:004010CE mov eax, [esp+48h+arg_4].text:004010D2 sub eax, 110h.text:004010D7 push esi.text:004010D8 mov esi, [esp+4Ch+hDlg].text:004010DC jz loc_4011EE.text:004010E2 sub eax, 1.text:004010E5 jnz loc_4011BD.text:004010EB movzx eax, [esp+4Ch+arg_8].text:004010F0 sub eax, 2.text:004010F3 jz loc_4011D1.text:004010F9 sub eax, 3E7h.text:004010FE jz short loc_401167.text:00401100 sub eax, 1.text:00401103 jnz loc_4011BD.text:00401109 mov ecx, dword_4045B0.text:0040110F mov edx, Src.text:00401115 mov eax, ecx.text:00401117 sub eax, edx.text:00401119 sar eax, 2.text:0040111C test eax, eax.text:0040111E jbe loc_4011BD.text:00401124 sub ecx, 4.text:00401127 push 0Ah ; Radix.text:00401129 mov dword_4045B0, ecx.text:0040112F push 20h ; SizeInWords.text:00401131 lea eax, [esp+54h+String].text:00401135 sub ecx, edx.text:00401137 push eax ; DstBuf.text:00401138 sar ecx, 2.text:0040113B push ecx ; Val.text:0040113C call ds:_itow_s.text:00401142 add esp, 10h.text:00401145 lea ecx, [esp+4Ch+String].text:00401149 push ecx ; lpString.text:0040114A push 0FFFFFFFFh ; nIDDlgItem.text:0040114C push esi ; hDlg.text:0040114D call ds:SetDlgItemTextW.text:00401153 xor eax, eax.text:00401155 pop esi.text:00401156 mov ecx, [esp+48h+var_4].text:0040115A xor ecx, esp.text:0040115C call sub_4017AA.text:00401161 add esp, 48h.text:00401164 retn 10h.text:00401167 ; ---------------------------------------------------------------------------.text:00401167.text:00401167 loc_401167: ; CODE XREF: DialogFunc+3Ej.text:00401167 push 4 ; unsigned int.text:00401169 call ??2@YAPAXI@Z ; operator new(uint).text:0040116E add esp, 4.text:00401171 test eax, eax.text:00401173 jz short loc_40117D.text:00401175 mov dword ptr [eax], 3E7h.text:0040117B jmp short loc_40117F.text:0040117D ; ---------------------------------------------------------------------------.text:0040117D.text:0040117D loc_40117D: ; CODE XREF: DialogFunc+B3j.text:0040117D xor eax, eax.text:0040117F.text:0040117F loc_40117F: ; CODE XREF: DialogFunc+BBj.text:0040117F push edi.text:00401180 lea edi, [esp+50h+var_48].text:00401184 mov [esp+50h+var_48], eax.text:00401188 call sub_401280.text:0040118D mov eax, dword_4045B0.text:00401192 sub eax, Src.text:00401198 push 0Ah ; Radix.text:0040119A push 20h ; SizeInWords.text:0040119C lea edx, [esp+58h+String].text:004011A0 push edx ; DstBuf.text:004011A1 sar eax, 2.text:004011A4 push eax ; Val.text:004011A5 call ds:_itow_s.text:004011AB add esp, 10h.text:004011AE lea ecx, [esp+50h+String].text:004011B2 push ecx ; lpString.text:004011B3 push 0FFFFFFFFh ; nIDDlgItem.text:004011B5 push esi ; hDlg.text:004011B6 call ds:SetDlgItemTextW.text:004011BC pop edi.text:004011BD.text:004011BD loc_4011BD: ; CODE XREF: DialogFunc+25j.text:004011BD ; DialogFunc+43j ....text:004011BD xor eax, eax.text:004011BF pop esi.text:004011C0 mov ecx, [esp+48h+var_4].text:004011C4 xor ecx, esp.text:004011C6 call sub_4017AA.text:004011CB add esp, 48h.text:004011CE retn 10h.text:004011D1 ; ---------------------------------------------------------------------------.text:004011D1.text:004011D1 loc_4011D1: ; CODE XREF: DialogFunc+33j.text:004011D1 push 2 ; nResult.text:004011D3 push esi ; hDlg.text:004011D4 call ds:EndDialog.text:004011DA xor eax, eax.text:004011DC pop esi.text:004011DD mov ecx, [esp+48h+var_4].text:004011E1 xor ecx, esp.text:004011E3 call sub_4017AA.text:004011E8 add esp, 48h.text:004011EB retn 10h.text:004011EE ; ---------------------------------------------------------------------------.text:004011EE.text:004011EE loc_4011EE: ; CODE XREF: DialogFunc+1Cj.text:004011EE mov ecx, [esp+4Ch+var_4].text:004011F2 pop esi.text:004011F3 xor ecx, esp.text:004011F5 mov eax, 1.text:004011FA call sub_4017AA.text:004011FF add esp, 48h.text:00401202 retn 10h.text:00401202 DialogFunc endp.text:00401202.text:00401202 ; ---------------------------------------------------------------------------<p>.text:00401205 align 10h.text:004010C0 ; BOOL __stdcall DialogFunc(HWND, UINT, WPARAM, LPARAM)Нужно зациклить:v.push_back(new Myobj(999));Также в догонку даю ещё задание.Когда нажимаем на кнопку уменьшения объектов, то при уменьшении объектов нужно их восполнить.Т.е. уменьшили на 1, то сделать нужно +1. Сделать на скриптах CE.Итак два задания.1. В первом посте. Сделать 10000 объектов при помощи скриптов CE.2. Восполнить разрушенный объект при помощи скриптов CE.Т.е. мы нажали активировать чит-код (галочку скрипта) и получаем 10000 объектов. Нажали вторую - объекты не уменьшаются. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 10 июля, 2010 Автор Поделиться Опубликовано 10 июля, 2010 Внимание. Решение первой задачи.Создание 10000 объектов после нажатия на активацию скрипта и нажатия на кнопку создания объекта. Хотя можно было помучить и сделать обновления текста, но посчитал это тратой времени.alloc(_newmem,1024)registersymbol(_newmem)label(_loop)label(_a1)label(_a2)createthread(_newmem)_newmem:pushadpushfpush 4010C0push 4_loop:push 04call 0040187cadd esp,04test eax,eaxje short _a1mov [eax],000003e7jmp short _a2_a1:xor eax,eax_a2:push edilea edi,[esp+08]mov [esp+08],eaxcall 00401280add esp,04inc ebxcmp ebx,#10000jne short _loopadd esp,08popfpopadcall GetCurrentThreadret[DISABLE]dealloc(_newmem)unregistersymbol(_newmem)[ENABLE]Да и отмечу ключевые элементы (над ними пришлось попариться в отладке)[ENABLE]alloc(_newmem,1024)registersymbol(_newmem)label(_loop)label(_a1)label(_a2)createthread(_newmem)_newmem:pushadpushfpush 4010C0 // подглянул в стек, так нужноpush 4 _loop:// прототип оригинального кодаpush 04call 0040187cadd esp,04test eax,eaxje short _a1mov [eax],000003e7jmp short _a2_a1:xor eax,eax_a2:push edilea edi,[esp+08]mov [esp+08],eaxcall 00401280add esp,04 // эта фишка обязательно, смотреть стекinc ebxcmp ebx,#10000jne short _loopadd esp,08 // режем стекpopfpopad call GetCurrentThread // выходим из потокаret[DISABLE]dealloc(_newmem)unregistersymbol(_newmem)Создавая этот скрипт я обратил внимание, что нужно восполнить данные в стеке и вовремя их отсекать. pushad и pushf оставил специально для подстраховки и вы так делайте (действительно ли они там нужны).Ну и в конце после проверок и вырезания ненужных инстуркций получил:alloc(_newmem,1024)registersymbol(_newmem)label(_loop)label(_a1)label(_a2)createthread(_newmem)_newmem:push 4010C0push 4_loop:push 04call 0040187cadd esp,04test eax,eaxje short _a1mov [eax],000003e7jmp short _a2_a1:xor eax,eax_a2:push edilea edi,[esp+08]mov [esp+08],eaxcall 00401280add esp,04inc ebxcmp ebx,#10000jne short _loopadd esp,08ret[DISABLE]dealloc(_newmem)unregistersymbol(_newmem)[ENABLE]Решение второй задачи будет и пока остаётся за вами. У вас уже есть пример решения первой задачи. Вот теперь попробуйте решить вторую. Затем будет трейнми2 который я сделаю по предполагаемому коду из реальной игры. Ссылка на комментарий Поделиться на другие сайты Поделиться
SER[G]ANT Опубликовано 11 июля, 2010 Поделиться Опубликовано 11 июля, 2010 Убери под спойлер (не прочел решение). Со времени моего первого поста тут, совсем не было времени ковырять, ибо ремонт. А охота добить полностью. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 20 июля, 2010 Автор Поделиться Опубликовано 20 июля, 2010 Оказывается я дал решение скрипта не для того скомпилированного трейнми. Теперь презалил - ссылка в первом посте. Так что можете скачать и проверить мой скрипт первого решения.Второе решение оставляю за вами.Следующее задание - задание3На примере двух предыдущих решений делаем общий чит-код создающий 1000 объектов, которые не будут уменьшаться. С учётом того, что объекты могут уменьшаться от внешнего влияния (которого в трейнми нет). Это условие характерно, когда в играх начинается новый уровень и объекты создаются с новым уровнем в меньшем количестве.Подсказки:1) Внедрить прыг в код трейнми создания объектов на функцию1(1000)2) Внедрить прыг в код трейнми уменьшения объектов на функцию1(1000)Функция1 (int a) //количество гранат{1) a1= Подсчитать количество гранат2) a2= a-a1; // Вычислить недостатающее количество3) функция2(a2); // Создать недостающее кол-во гранат }функция2 (int a){}Попробуйте сделать это решение как через автоассемблер так и через C-script.Если приводить аналогии с игрой, то нужно учитывать, что инструкций создания и уменьшения объектов может быть множество. Надо будет внедрять либо в одну из них, либо в некоторые, либо во все, либо создавать поток в игре, которые через интервал времени будет проверять кол-во объектов и создавать недостающие. Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 23 июля, 2010 Автор Поделиться Опубликовано 23 июля, 2010 Решение 3-го задания (которое объединяет решения первого и второго) имеет следующий вид.Скрипт1 - Главный/*Процесс: TrainMe(hard_1_0).exeЧит-код: Скрипт на восттановление указанного кол-ва объектовДата: 7.21.2010Автор скрипта: MasterGH(c)Версия CE: Cheat Engine 5.6 RUS (v 2.0) ------------------На _void_RstObj() делалаем два call-а в места:1) из кода после добавления объектов2) из кода после уменьшения объектов*/alloc(_newmem,2048)label(_void_RstObj)label(_EAX_GetCountObj)label(_void_AddObject)label(_void_createobj_eax_)label(_ex)label(_loop)label(_a1)label(_a2)registersymbol(_void_RstObj)_newmem://Восстановить кол-во недостающих объектов_void_RstObj: pushf push eax call _EAX_GetCountObj // возвращает eax = кол-во объектов в данный момент push ebx mov ebx,#1000 sub ebx,eax mov eax,ebx pop ebx cmp eax, 0 // eax объектов которых не хватает jl short _ex // переход если объектов которых не хватает меньше нуля call _void_createobj_eax__ex: pop eax popf ret // добавление кол-во объектов _void_createobj_eax_: _loop: pushad call _void_AddObject// добавляем объект popad dec eax cmp eax,0 jg short _loop // пока eax больше нуля ret //Добавление одного объекта:_void_AddObject: push 4010C0 push 4 push 4 call 0040187c add esp,04 test eax,eax je short _a1 mov [eax],000003e7 jmp short _a2_a1: xor eax,eax_a2: push edi lea edi,[esp+08] mov [esp+08],eax call 00401280 add esp,0C ret //Получение кол-ва объектов в eax:_EAX_GetCountObj: mov eax,[4045B0] sub eax,[4045AC] sar eax,2 ret [DISABLE]dealloc(_newmem)unregistersymbol(_void_RstObj)[ENABLE]Скрипт2 aobscan(_faddress,a1xxxxxxxx2bxxxxxxxxxxxxxxxxxx8dxxxxxxxxc1xxxxxxffxxxxxxxxxx83) alloc(_newmem,2048) label(_returnhere) label(_originalcode)_newmem: call _void_RstObj_originalcode: mov eax,[4045B0] jmp _returnhere_faddress: // 0040118D = About+CD jmp _newmem_returnhere:[DISABLE] aobscan(_faddress,2bxxxxxxxxxxxxxxxxxx8dxxxxxxxxc1xxxxxxffxxxxxxxxxx83)_faddress-5: mov eax,[4045B0] dealloc(_newmem)//Alt: db A1 B0 45 40 00[ENABLE]Скрипт3 aobscan(_faddress,8bxxxxxxxxxx8bxxxxxxxxxx8bxx2bxxc1xxxx85xx0fxxxxxxxxxx83) alloc(_newmem,2048) label(_returnhere) label(_originalcode)_newmem: call _void_RstObj_originalcode: mov ecx,[4045B0] jmp _returnhere_faddress: // 00401109 = About+49 jmp _newmem nop_returnhere:[DISABLE] aobscan(_faddress,908bxxxxxxxxxx8bxx2bxxc1xxxx85xx0fxxxxxxxxxx83)_faddress-5: mov ecx,[4045B0] dealloc(_newmem)//Alt: db 8B 0D B0 45 40 00[ENABLE]Изучил я скрипты на С-коде в CheatEngine и в MHS. К сожалению, обе программы не поддерживают ассемблерные вставки в C-коде. В связи с чем, как мне показалось, лучше писать автоассемблерскими скриптами, как я написал выше. Конечно, все три скрипта лучше объединить в один, но задача в целом уже решена Спасибо всем, кто принимал участие в решение этого очень сложного трейнми. Если я сделаю ещё трейнми, то уже в отдельной в новой теме. Ссылка на комментарий Поделиться на другие сайты Поделиться
zabiyako Опубликовано 16 августа, 2016 Поделиться Опубликовано 16 августа, 2016 ЗдОрово! Сейчас будем учиться! Ссылка на комментарий Поделиться на другие сайты Поделиться
SnedS91 Опубликовано 16 января, 2017 Поделиться Опубликовано 16 января, 2017 Вставлю свои 5 копеек=) Добавляет недостающих объектов до 10000 и не дает удалять, если объектов меньше тех же 10000. Скрытый текст [ENABLE] alloc(obj_add, $1000) label(delete) label(exit) label(exit2) obj_add: mov eax,#10000 sub eax,dword ptr [esp] cmp eax,0 jl @f add esp,14 jmp TrainMe(hard_1_0).exe+1167 @@: add esp,10 lea ecx,[esp+0C] jmp exit delete: cmp eax,#10000 jbe TrainMe(hard_1_0).exe+11BD jmp exit2 TrainMe(hard_1_0).exe+111C: jmp delete db 90 90 90 exit2: TrainMe(hard_1_0).exe+11AB: jmp obj_add db 90 90 exit: [DISABLE] TrainMe(hard_1_0).exe+111C: test eax,eax jbe TrainMe(hard_1_0).exe+11BD TrainMe(hard_1_0).exe+11AB: add esp,10 lea ecx,[esp+0C] dealloc(obj_add) 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
srg91 Опубликовано 24 января, 2017 Поделиться Опубликовано 24 января, 2017 Ура, я наконец-то разобрался с данным TrainMe. Дополнил решение комментариями, чтобы тем кто пробует решить было проще разобраться. Так же я "заморочился" и добавил обновление надписи, так что все опции влияют сразу и сразу видно изменение. Ссылка на скачивание таблицы: https://yadi.sk/d/rCgbzaXO3AgAf4 Функции по пунктам: 0. Основные функции: Spoiler [ENABLE] // функция апдейта надписи globalalloc(update_label, 2048) // функция получения текущего количества объектов globalalloc(get_count, 2048) // функция добавления одного объекта globalalloc(create_object, 2048) // здесь будем хранить число строкой globalalloc(update_label_buffer, 32) update_label: // принимает один параметр - число mov eax,[esp+4] // передаваемые парметры: // - десятичная система счисления // - размер буффера - 32 байта // - ссылка на буфер // - собственно число push #10 push #32 push update_label_buffer push eax // собственно зовем функцию преобразования call dword ptr [TrainMe(hard_1_0).exe+30B8] { ->MSVCR90.itow_s } // поухаживаем за ленивой функцией и сдвинем стек за нее >.> add esp,10 // берем handle окна // выдрал из ESI при вычитании mov eax,[uxtheme.dll+50C5C] // передаваемые параметры // - наша строка с числом // - ID надписи // - хендл окна push update_label_buffer push -1 push eax call dword ptr [TrainMe(hard_1_0).exe+30F0] { ->USER32.SetDlgItemTextW } // это хорошая функция, она сама почистила стек за собой // принимали один dword, значит и удаляем один dword из стека при выходе ret 4 get_count: // не принимаем параметры, просто считаем количество объектов // берем текущее смещение с объектом mov ecx,[TrainMe(hard_1_0).exe+45B0] { [009E7C00] } // берем начальное смещение mov edx,[TrainMe(hard_1_0).exe+45AC] { [009E7BC8] } // вычисляем разницу в байтах mov eax,ecx sub eax,edx // делим на 4 sar eax,02 ret create_object: // наши объекты - 4 байта с записанными в них 999 // с помощью оператора new выделяем память в 4 байта push 4 call TrainMe(hard_1_0).exe+187C // опять двигаем за ленивую функцию стек обратно add esp,04 // записываем 999 в новую память (new записывает адрес в eax) mov [eax],000003E7 // следующая функция творит магию (= я не разбирался) // но она перезаписывает ссылки на текущий объект и т.д. // передаем функции новый адрес объекта через регистр edi // да, она так работает О_о mov edi,eax call TrainMe(hard_1_0).exe+1280 ret [DISABLE] dealloc(update_label) unregistersymbol(update_label) dealloc(update_label_buffer) unregistersymbol(update_label_buffer) dealloc(get_count) unregistersymbol(get_count) dealloc(create_object) unregistersymbol(create_object) 1. Сделать чит-код добавляющий объекты в количестве до 10000. Spoiler [ENABLE] globalalloc(make_10000, 2048) label(exit) // Процедура для создания объектов до 10000 make_10000: // Смотрим на текущее значение объектов call get_count // Наша функция пишет результат в eax - сравним его с 10000 cmp eax,#10000 // Если объектов >= 10000 - выходим из цикла / процедуры jge exit // Создаем объект call create_object // Возвращаемся в начало к нашей проверке jmp make_10000 // Завершаем наш сюжет, отпускает нас уже exit: // Обновим надпись, для красоты push eax call update_label ret // Создаем новый поток, который выполнит нашу процедуру createthread(make_10000) [DISABLE] dealloc(make_10000) unregistersymbol(make_10000) 2. Восполнить разрушенный объект при помощи скриптов CE Spoiler [ENABLE] alloc(make_new, 2048) globalalloc(current_count, 4) label(returnhere) label(originalcode) label(exit) make_new: // мы врываемся в самое серце программы, поэтому // побудем хорошими людьми и сохраним всё что ей дорого pushfd pushad // восстанавлием 1 объект call create_object // записываем текущее количество call get_count mov [current_count],eax // возвращаем значения регистров и флагов popad popfd originalcode: // в ecx хранилось значение количества объектов после вычитания // мы возмем текущее значение и передадим его // push ecx push [current_count] call dword ptr [TrainMe(hard_1_0).exe+30B8] exit: jmp returnhere // В данно месте начинается вывод текущего числа объектов // после вычитания, а значит мы можем досоздать объект // и вывести новое значение количества "TrainMe(hard_1_0).exe"+113B: jmp make_new nop nop returnhere: [DISABLE] dealloc(make_new) dealloc(current_count) unregistersymbol(current_count) "TrainMe(hard_1_0).exe"+113B: push ecx call dword ptr [TrainMe(hard_1_0).exe+30B8] //Alt: db 51 FF 15 B8 30 37 01 3. Сделать так чтобы при вычитание объектов или при их создании, их количество держалось на отметке не меньше 1000 объектов Spoiler [ENABLE] // собственно весь смысл в том, что при удалении // и создании мы должны проверять, а не досоздать ли до 1000 // решил сделать функцию, которую буду вызывать после // прибавления / вычитания // собственно функция globalalloc(make_1000, 2048) // сюда будем писать адрес, откуда нас вызвали globalalloc(return_addr, 4) globalalloc(current_count, 4) label(return) label(loop) current_count: dd 0 make_1000: // переносим адрес возврата во вспомогательный регистр // как-будто мы ничего и не вызывали pop [return_addr] // сохраняем состояние регистров pushfd pushad // смотрим, а нужно ли вообще что-то добавлять? loop: call get_count cmp eax,#1000 jge return // если было нужно - досоздаем объект и так пока не будет 1000 call create_object jmp loop // самая маковка return: // записываем текущее количество объектов mov [current_count],eax // возвращаем значения регистров на место popad popfd // довызываем функцию itow_s push [current_count] call dword ptr [TrainMe(hard_1_0).exe+30B8] // возвращаем адрес откуда нас вызвали в стек // иначе ret не знает куда прыгать push [return_addr] ret // встраиваемся в itow_s при создании объекта TrainMe(hard_1_0).exe+11A4: call make_1000 nop nop // встраиваемся в itow_s при вычитании объекта TrainMe(hard_1_0).exe+113B: call make_1000 nop nop [DISABLE] dealloc(make_1000) unregistersymbol(make_1000) dealloc(current_count) unregistersymbol(current_count) TrainMe(hard_1_0).exe+11A4: push eax call dword ptr [TrainMe(hard_1_0).exe+30B8] { ->MSVCR90.itow_s } TrainMe(hard_1_0).exe+113B: push ecx call dword ptr [TrainMe(hard_1_0).exe+30B8] { ->MSVCR90.itow_s } 4. Так же для чуть более легкого тестирования добавил функцию сброса объектов в 0: Spoiler [ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat globalalloc(make_zero, 2048) make_zero: // просто делаем то, что и вычитание, только сразу до нуля // фактически сдвигая текущий указатель на последний объект до нуля mov eax,[TrainMe(hard_1_0).exe+45AC] mov [TrainMe(hard_1_0).exe+45B0],eax // обновим строку call get_count push eax call update_label ret createthread(make_zero) [DISABLE] //code from here till the end of the code will be used to disable the cheat dealloc(make_zero) unregistersymbol(make_zero) 3 Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 24 января, 2017 Автор Поделиться Опубликовано 24 января, 2017 Отличная работа 1 час назад, srg91 сказал: // это хорошая функция, она сама почистила стек за собой Ссылка на комментарий Поделиться на другие сайты Поделиться
GameHacker Опубликовано 18 марта, 2018 Поделиться Опубликовано 18 марта, 2018 Я не смотрел ващи ну эти скрипты, сам взломал вот таблица http://rgho.st/8grPswkRr Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 18 марта, 2018 Автор Поделиться Опубликовано 18 марта, 2018 Можно написать скрипт в теге кода под спойлером и пару слов как было сделано. Таблицы некогда проверять Ссылка на комментарий Поделиться на другие сайты Поделиться
srg91 Опубликовано 18 марта, 2018 Поделиться Опубликовано 18 марта, 2018 6 hours ago, GameHacker said: Я не смотрел ващи ну эти скрипты, сам взломал вот таблица http://rgho.st/8grPswkRr Не очень похоже, цифра меняется (причем даже близко не на 10000) и сразу после этого вылетает. Плюс весь смысл в том, чтобы досоздать нужное количество объектов не сломав TrainMe, мне кажется твоя таблица этого не делает. Ссылка на комментарий Поделиться на другие сайты Поделиться
LIRW Опубликовано 18 марта, 2018 Поделиться Опубликовано 18 марта, 2018 Сейчас я попробую... Скрипты не смотрел - у мня тут своя техника PS: Сейчас только лазить перестанут по квартирам со своими выборами.. Хотя тут уже не докажешь - смотрел я или не смотрел.. Будем ждать новую подобную версию. Без готового решения. Ссылка на комментарий Поделиться на другие сайты Поделиться
JustHack Опубликовано 18 марта, 2018 Поделиться Опубликовано 18 марта, 2018 20 минут назад, LIRW сказал: Сейчас я попробую... Го лучше есп врагов и аномалий на сталкера пилить)) Ссылка на комментарий Поделиться на другие сайты Поделиться
X86Jumps Опубликовано 18 марта, 2018 Поделиться Опубликовано 18 марта, 2018 хм интересно, ответы через 7 8 лет)) а актуально делать ответ когда даже сам автор выложил его?) Ссылка на комментарий Поделиться на другие сайты Поделиться
xapek Опубликовано 18 марта, 2018 Поделиться Опубликовано 18 марта, 2018 выложите новый траинми Ссылка на комментарий Поделиться на другие сайты Поделиться
MasterGH Опубликовано 18 марта, 2018 Автор Поделиться Опубликовано 18 марта, 2018 3 часа назад, X86Jumps сказал: а актуально делать ответ когда даже сам автор выложил его?) 5 часов назад, LIRW сказал: Будем ждать новую подобную версию. Без готового решения. Окей. Решение выложили, тему закрываю Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения