-
Постов
80 -
Зарегистрирован
-
Посещение
Тип контента
Профили
Форумы
Загрузки
Блоги
Сообщения, опубликованные Dejavu
-
-
Это не указатель, а ссылка на переменную.
Сейчас скриншот, к сожалению, уже недоступны, но почему хук ставится на sub_E713A2?
Судя по коду getSerial вызывается только в main. sub_E713A2 == main?Кроме того, стоит, конечно же, еще учитывать соглашение о вызове функции — может быть причиной краша.
-
Привет,
Пишу 32-битную DLL для мониторинга системных вызовов приложения, в которое она будет заинжекчена.Вот, собственно, код (не выдержка из проекта):
Спойлер#include <Windows.h> static DWORD WINAPI Filter(DWORD magic, DWORD myclass, DWORD id, DWORD result, DWORD* args, DWORD argc) { //void* mem = malloc(10); //if (mem) free(mem); return 0; } BOOL WINAPI IsContainsFrame(DWORD ebp, unsigned int count) { DWORD lpEbp = ebp; DWORD lMax = __readfsdword(4); DWORD lMin = __readfsdword(8); DWORD _sig = 0x01020304; while (count && lpEbp < lMax && lpEbp > lMin) { if (*(DWORD*)(lpEbp + 8) == _sig) return true; count--; lpEbp = *(DWORD*)lpEbp; } return false; } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { LPVOID lpGate = (LPVOID)__readfsdword(0xc0); BYTE pushret[8] = "\x68\xDD\xCC\xBB\xAA\xC3\xCC"; BYTE asm_code[138] = "\x60\x6A\x10\x55\xBA\x33\x33\x33\x33\xFF\xD2\x85\xC0\x75\x77\x61\x55\x89\xE5\x60\x8B\x55\x04\x8B\x12\x80\xFA\xC3\x74\x5A\x80\xFA\xC2\x75\x59\xC1\xEA\x08\x81\xE2\xFF\x00\x00\x00\x52\x85\xD2\x74\x51\x8D\x4D\x0C\x51\x6A\xFF\x50\x68\x44\x44\x44\x44\x74\x0B\xFF\x74\x15\x08\x83\xEA\x04\x85\xD2\x75\xF5\x6A\x00\x68\x55\x55\x55\x55\x8B\x55\xF4\x8B\x4D\xF8\x90\x90\x90\x90\x90\x90\x90\x89\xEC\x60\x89\x45\xD4\x83\xEC\x14\xBA\x66\x66\x66\x66\x68\x04\x03\x02\x01\xFF\xD2\x61\x89\xE5\x5D\xC3\x31\xD2\xEB\xB0\x61\x89\xEC\x5D\xEB\xD5\x6A\x00\xEB\xAB\x61\xEB\xCE"; BYTE OriginalGateBytes[7]; memcpy_s(OriginalGateBytes, sizeof(OriginalGateBytes), lpGate, sizeof(OriginalGateBytes)); byte* lpMyAsmCode = (byte*)VirtualAlloc(0, sizeof(asm_code), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!lpMyAsmCode) break; memcpy_s(lpMyAsmCode, sizeof(asm_code), asm_code, sizeof(asm_code)); *(void**)(lpMyAsmCode + 0x5) = IsContainsFrame; *(void**)(lpMyAsmCode + 0x4d) = lpMyAsmCode + 0x5e; *(void**)(lpMyAsmCode + 0x68) = Filter; memcpy_s(lpMyAsmCode + 0x57, sizeof(OriginalGateBytes), OriginalGateBytes, sizeof(OriginalGateBytes)); *(void**)(pushret + 1) = lpMyAsmCode; MEMORY_BASIC_INFORMATION membasic; if (!VirtualQuery(lpGate, &membasic, sizeof(membasic))) break; if (membasic.AllocationProtect != PAGE_EXECUTE_READWRITE) { if (!VirtualProtect(membasic.BaseAddress, membasic.RegionSize, PAGE_EXECUTE_READWRITE, &membasic.Protect)) return false; memcpy_s(lpGate, sizeof(pushret), pushret, sizeof(pushret)); } break; } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
Вот код asm_code с моим беглым описанием:
Спойлерpushad #сохраняем регистры push 0x10 #кол-во проверок ebp push ebp #пушим текущий ebp mov edx, 0x33333333 #кладем адрес IsContainsFrame call edx test eax, eax jnz magicDetected #если находим, то восстанавливаем регистры и выполняем без логирования popad #начало обработки push ebp #сохраняем текущий ebp. Он будет опорным элементом для удобной адресации по стеку mov ebp, esp pushad #сохраняем регистры mov edx, dword ptr [ebp + 4] #берем адрес возврата в Nt mov edx, [edx] #читаем оттуда dword, чтобы извлечь кол-во аргументов, которые принимает функция cmp dl, 0xC3 #если C3, значит аргументов нет jz zeroEdx cmp dl, 0xC2 #если C2, значит есть аргументы. Иначе просто выполняем без логирования jnz restoreAndExecuteJmp33 shr edx, 8 #двигаем направо, чтобы получить байт == кол-во аргументов and edx, 0xff #нужен только один байт. Сейчас тут находится кол-во аргументов функции Filter_SaveArgc: push edx #пуш кол-во аргументов test edx, edx jz zeroArgs #если аргументов нет, то и пушим 0 Filter_PushOther: lea ecx, dword ptr [ebp + 12] #иначе берем указатель на первый аргумент push ecx #и пушим его push 0xffffffff #пуш результат выполнения (пока что -1) push eax #пуш id вызова push 0x44444444 #пуш указателя на класс je FakeFrameHijack FakeFramePushArgs: push dword ptr [ebp + edx + 8] #пушим аргументы, с которыми была вызвана функция sub edx, 4 test edx, edx jne FakeFramePushArgs FakeFrameHijack: push 0 #не важно какой вызов был перед Nt push 0x55555555 #вызов моего кода, который будет адресом возврата из x64 (вместо Nt) mov edx, dword ptr [ebp - 12] #восстанавливаем старый edx mov ecx, dword ptr [ebp - 8] #восстанавливаем старый ecx jmp33: #здесь будут оригинальные байты прыжка nop nop nop nop nop nop nop AfterFakeFrameHandler: mov esp, ebp #возвращаемся к ebp, чтобы сохранить регистры pushad #сохраняем регистры mov dword ptr [ebp - 0x2c], eax #сохраняем результат вызова в фильтр sub esp, 0x14 #переходим к стеку с фильтром mov edx, 0x66666666 #адрес моей функции-фильтра push 0x01020304 #пушим magic call edx #вызываем фильтр popad #восстанавливаем сохраненные регистры mov ebp, esp #восстанавливаем старый ebp, с которым была вызвана фнукция pop ebp ret #возвращаем управление zeroEdx: xor edx, edx jmp Filter_SaveArgc restoreAndExecuteJmp33: popa mov esp, ebp pop ebp jmp jmp33 zeroArgs: push 0 jmp Filter_PushOther magicDetected: popad jmp jmp33
Когда происходит системный вызов, управление передается на мой asm_code (lpMyAsmCode). Предварительно функция IsContainsFrame() проверяет нет ли фрейма функции Filter (то есть не системный ли это вызов из моего фильтра, иначе не заходим снова в Filter, а просто выполняем). Далее на стеке наращиваю аргументы под функцию Filter, оставляю место для сохранения регистров (чтобы после всего этого регистры остались прежними) и копирую аргументы, с которыми вызывалась функция, подменяя адрес возврата. Делаю системный вызов (адресом возврата будет lpMyAsmCode + 0x5e), которая в последующем передаст управление.
Проблема заключается в том, что я не могу обрабатывать получаемую информацию в Filter, так как любой вызов необходимой функции (malloc, sprintf_s) — краш (но не при первом вызове, по моим наблюдениям).
В частности такая проблема с .NET приложениями. Я, конечно, грешу в том числе на метод инжекта — CreateProcess (CREATE_SUSPENDED) + CreateRemoteThread + LoadLibraryA.
Но все же хочется услышать мнение знающих людей.
Вот так примерно выглядит стэк вызовов (да, там моего кода не наблюдается, но он точно причастен!):
Спойлерverifier!AVrfpDphPlaceOnUnusedList+8 1891000 cd22000 cd23000 cd22000 verifier!AVrfpDphAddNewPool+35 1891000 0001000 0000000 0000000 verifier!AVrfpDphAllocateNode+197 1891000 0000000 ca1ec7c ca1ec80 verifier!AVrfpDphFindAvailableMemory+12b 1891000 0002000 0000001 866a670 verifier!AVrfDebugPageHeapAllocate+185 1890000 1280002 0000010 261202c ntdll!RtlDebugAllocateHeap+39 0000010 26123f0 1890000 0000010 ntdll!RtlpAllocateHeap+f0 0000010 0000018 0000000 ca1ef48 ntdll!RtlpAllocateHeapInternal+104c 0280000 0000000 ca1f248 26122b4 ntdll!RtlAllocateHeap+3e 1890000 0280000 0000010 261389c ntdll!LdrpLoadDependentModule+bfa 731cf58 0000001 ca1f5ac ca1f5b0 ntdll!LdrpResolveForwarder+8a 1374f58 ca1f600 2613b6c 7e95d00 ntdll!LdrpSnapModule+50b 2613bc0 7e95d00 1368f74 7e95ce0 ntdll!LdrpProcessWork+4d 7da7210 c652f70 c68afb8 7da6d6d ntdll!LdrpWorkCallback+59 ca1f7fc 0000000 c652f70 c3a8ee0 ntdll!TppWorkpExecuteCallback+1dd ca1f7fc c652fe8 26135c4 7da5900 ntdll!TppWorkerThread+472 c3a8ee0 633fa10 ca1f93c 7dd7a9e kernel32!BaseThreadInitThunk+19 c3a8ee0 2613428 0000000 0000000 ntdll!__RtlUserThreadStart+2f fffffff 7df8a4f 0000000 0000000 ntdll!_RtlUserThreadStart+1b 7da5900 c3a8ee0 0000000 0000000
-
17 часов назад, partoftheworlD сказал:
Использовать связку CE + IDA, либо через Hex-Dump копировать адрес, если есть возможность написать свой скрипт для таких целей или плагин HexRaysTool вроде так называется, там можно переходить из hexrays к дизасемблеру в общем одни костыли, так что предложу для отладки использовать x64dbg там есть, то что тебе нужно из коробки.
IDA куда удобнее будет тем, что она распознает уже документированные функции. Лучше уж тогда вручную искать значение.
-
Смотрю код в декомпиляторе. Направляю курсор на переменную. Вижу ее значение.
Как найти его в памяти?
Приходится переписывать адрес вручную.Скрытый текст -
Решаю CrackMe с помощью .NET Reflector, нашел функцию, которая проверяет правильность, но не знаю C#. Времени погружаться в язык пока что нет. Не подскажете, как работает данная функция?
Скрытый текст[return: MarshalAs(UnmanagedType.U1)] internal static unsafe bool modopt(CallConvCdecl) Check(basic_string<char,std::char_traits<char>,std::allocator<char> > modreq(IsCopyConstructed)* MD5, basic_string<char,std::char_traits<char>,std::allocator<char> > modreq(IsCopyConstructed)* Email) { bool flag; try { try { basic_string<char,std::char_traits<char>,std::allocator<char> > local7; std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{ctor}(&local7, &??_C@_00CNPNBAHC@?$AA@); try { sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)* numPtr; basic_string<char,std::char_traits<char>,std::allocator<char> > local; basic_string<char,std::char_traits<char>,std::allocator<char> > modopt(IsConst) local2; basic_string<char,std::char_traits<char>,std::allocator<char> > local3; basic_string<char,std::char_traits<char>,std::allocator<char> > local4; basic_string<char,std::char_traits<char>,std::allocator<char> > local5; basic_string<char,std::char_traits<char>,std::allocator<char> > modopt(IsConst) local6; int start = GetStart(); basic_string<char,std::char_traits<char>,std::allocator<char> > modopt(IsConst)* localPtr7 = &local6; *((int*) (&local6 + 16)) = 0; *((int*) (&local6 + 20)) = 0; std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(&local6, false, 0); std.basic_string<char,std::char_traits<char>,std::allocator<char> >.assign(&local6, Email, 0, uint.MaxValue); basic_string<char,std::char_traits<char>,std::allocator<char> >* localPtr4 = md5(&local5, &local6); try { std.basic_string<char,std::char_traits<char>,std::allocator<char> >.=(Email, localPtr4); } fault { ___CxxCallUnwindDtor(std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{dtor}, (void*) &local5); } std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(&local5, true, 0); basic_string<char,std::char_traits<char>,std::allocator<char> >* localPtr6 = &local4; *((int*) (&local4 + 0x10)) = 0; *((int*) (&local4 + 20)) = 0; std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(&local4, false, 0); std.basic_string<char,std::char_traits<char>,std::allocator<char> >.assign(&local4, Email, 0, uint.MaxValue); basic_string<char,std::char_traits<char>,std::allocator<char> >* localPtr3 = GetString(&local3, (basic_string<char,std::char_traits<char>,std::allocator<char> > modreq(IsCopyConstructed)*) &local4, start); try { std.basic_string<char,std::char_traits<char>,std::allocator<char> >.=(&local7, localPtr3); } fault { ___CxxCallUnwindDtor(std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{dtor}, (void*) &local3); } std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(&local3, true, 0); basic_string<char,std::char_traits<char>,std::allocator<char> > modopt(IsConst)* localPtr5 = &local2; basic_string<char,std::char_traits<char>,std::allocator<char> >* modopt(IsConst) modopt(IsConst) str = std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{ctor}(&local2, (basic_string<char,std::char_traits<char>,std::allocator<char> > modopt(IsConst)* modopt(IsImplicitlyDereferenced)) &local7); basic_string<char,std::char_traits<char>,std::allocator<char> >* localPtr = md5(&local, str); try { std.basic_string<char,std::char_traits<char>,std::allocator<char> >.=(&local7, localPtr); } fault { ___CxxCallUnwindDtor(std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{dtor}, (void*) &local); } std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(&local, true, 0); uint num = *((uint*) (MD5 + 16)); if (16 <= *(((int*) (MD5 + 20)))) { numPtr = *((sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)**) MD5); } else { numPtr = MD5; } flag = std.basic_string<char,std::char_traits<char>,std::allocator<char> >.compare((basic_string<char,std::char_traits<char>,std::allocator<char> > modopt(IsConst)* modopt(IsConst) modopt(IsConst)) &local7, 0, *((uint*) (&local7 + 16)), numPtr, num) == 0; } fault { ___CxxCallUnwindDtor(std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{dtor}, (void*) &local7); } std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(&local7, true, 0); } fault { ___CxxCallUnwindDtor(std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{dtor}, MD5); } std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(MD5, true, 0); } fault { ___CxxCallUnwindDtor(std.basic_string<char,std::char_traits<char>,std::allocator<char> >.{dtor}, Email); } std.basic_string<char,std::char_traits<char>,std::allocator<char> >._Tidy(Email, true, 0); return flag; }
-
Почему так много грамматических ошибок?
-
pusha/pushad — сохраняет все значения регистров, popa/popad — восстанавливает.
-
Если ты пишешь статью (тем более для новичков), нужно хотя бы описать для чего это, где это используется, показать на конкретном примере, пояснить каждую строчку кода.
- 2
-
45 минут назад, IzerodayI сказал:
24000000 + 4035C0 =244035C0
Я вбил этот адрес через CTRL + G. Выходит на client.dll (в контре). Не важно из какой модуля ты ищешь
-
38 минут назад, IzerodayI сказал:
как в olly dbg найти в модуле client такой адрес 24000000 + 4035C0 =244035C0
если обращаться в модуле client на go to то поиск отправляет в какой-то main thread и потому если делать сигнатуру , то он ее не находит в модуле client, как правильно найти то смещение в olly dbg ?
Что ты ищешь, где ты ищешь, скрины какие нибудь прикрепи еще. Мало информации
-
2 часа назад, IzerodayI сказал:
да , я понял о чем ты , координаты и хп хранятся в разных структурах, никнейм тоже в другой структуре хранится.
пробовал заморозить хп, графически морозится , реально нет
Значит, это экранное значение
-
1 минуту назад, IzerodayI сказал:
ммм.... игра онлайн и я не пробовал (попробую)
хп я находил (игра похожа на dota, только от русской компании (Nival))
это как делается в СЕ ?
Координаты, жизни, деньги и прочее находятся в структуре игрока. Для того, чтобы найти эту структуру, тебе нужно найти указатель на эту структуру. Указатель и будет указывать на начало структуры. Смещения — как раз таки нужные тебе поля( жизни, деньги и т.д и т.п)
-
4 часа назад, IzerodayI сказал:
я так сделал и после перезапуска игры нахожу еще раз нужное значение , (Pointer scan -> Read.... (туда надо ввести новый адрес)) и ничего не остаются (хотя 5 уравневый указатель), поставил 7-уравневый и не хватило времени игры(длится 30-40мин), есть другие идеи по нахождению постоянного указателя на структуры ?
похоже на движке Unity все динамическое(даже указатели) , поэтому подход нужен какой-то другой....
пробовал с 3D координатами(на них выходил по z)
1. Ты точно нашел нужные тебе координаты?
Может быть это не те значения?
Когда морозишь их, у тебя начинает игрок глючить при передвижении?
Если да, то нашел правильно2. Попробуй найти что нибудь другое — жизни, деньги, какие либо ресурсы, относящиеся к игроку. Затем попробуй на это значение найти указатели, там, гляди, может быть получится что еще найти
-
1 минуту назад, IzerodayI сказал:
Да это от головы число, просто я не знаю сколько именно
мах-уравневый указатель в игре
Не думаю, что разработчики игр делаю столь многоуровневые указатели.
Ставь 5-ку и проверяй указатели -
Только что, IzerodayI сказал:
но разве не может быть 15-уравневый указатель в игре(ну или любой выше 5) ?
Жоска чет. Я ни разу еще не встречал такого.
-
4 минуты назад, IzerodayI сказал:
их же будет очень много
Ну а ты как хотел. Посмотри вот это видео, думаю, план действий будет понятен:
-
4 минуты назад, IzerodayI сказал:
да находил свои и чужие сразу в 2D (что достаточно удобно) , хотя следует поискать 3D , потому , что с 2D-коорд. противника не обновляются в тумане войны
Prime World от Nival (может слышал про игру герои меча и магии 5 - она годная (тоже от Nival))
указателя находятся, находил структуры(только через 1 указатель, вместо 5(как СЕ предлагает по умолч.)) и координаты 2D , но они после перезапуска хранятся вообще в другом месте , ну и не обн. в тумане войны , и все в разном месте(структур) , каждого игрока , а их 10 , я в принципе не представляю как их искать , в этом и проблема.
Если короче , то проблема в нахождении координат , которые бы обновлялись в тумане войны(если в СЕ я отсеиваю и каждый раз нахожу разные структуры , где хранится (допустим) мой персонаж, то реализовать их нахождение через код, представляется только через сигнатуры , но я не уверен , что и они будут работать)
Пример разных структур, после перезапуска :
"sakijapi.dll"+001CC1B4+c
"sakijapi.dll"+006CBCFC+12ac
"sakijapi.dll"+0071AC14+2450
Ну какой-то указатель должен всегда указывать на нужную структуру, просто его нужно найти.
Указатель может быть многоуровневым.
Тебе нужно найти указатели(допустим, поставить Max lvl = 5), потом перезапустить игру, потом заново присоединить CE к игре и из них найти указатель, который указывает на нужный тебе адрес. -
2 минуты назад, IzerodayI сказал:
там все динамическое
Для этого нужно искать указатели, через указатели искать структура, затем координаты
Ты уже находил координаты свои/чужие?
Что за игра?
-
Только что, IzerodayI сказал:
по-мойму это называется как "мапхак" - интересно сделать так чтобы я мог отобразить координаты противников на карте.
Нужно выйти на структуры и потом уже через ReadProcessMemory выводить их
-
22 часа назад, IzerodayI сказал:
PS можно ли это реализовать на си++ или на с# делать (хоть что-то) надо (для игр Unity)?
Что именно ты хочешь реализовать?
-
По моему, такая ошибка выскакивает, когда ничего не вводишь в окно поиска
- 1
-
1 час назад, LIRW сказал:
Деньги там в обще по моему вот тут лежат.
[ENABLE] aobscan(BaseCash,F3 0F 2A 83 A0 1C 00 00 F3 * * * * * * * * * * * F2 0F) // should be unique alloc(newmem,$1000) label(code) label(return) newmem: mov [ebx+00001CA0],#50000000 code: cvtsi2ss xmm0,[ebx+00001CA0] jmp return BaseCash: jmp newmem db 90 90 90 return: registersymbol(BaseCash) [DISABLE] BaseCash: db F3 0F 2A 83 A0 1C 00 00 unregistersymbol(BaseCash) dealloc(newmem)
Просто когда то делал уже к ней чит и исход остался Сешный.
Спасибо, сработало.
Подскажите, как мне самому выйти на эту инструкцию?
В каком типе хранятся деньги?
-
57 минут назад, what228 сказал:
Держи скрипт на деньги.
{ Game : SaintsRowTheThird_DX11.exe Version: Date : 2017-08-12 Author : User This script does blah blah blah } [ENABLE] aobscanmodule(MONEY,SaintsRowTheThird_DX11.exe,F3 0F 2A 83 A0 1C 00 00) // should be unique alloc(newmem,$1000) label(code) label(return) label(addmoney) registersymbol(addmoney) newmem: cmp [addmoney],0 je code add [ebx+00001CA0],#100000 mov [addmoney],0 code: cvtsi2ss xmm0,[ebx+00001CA0] jmp return addmoney: dd 0 MONEY: jmp newmem nop nop nop return: registersymbol(MONEY) [DISABLE] MONEY: db F3 0F 2A 83 A0 1C 00 00 unregistersymbol(MONEY) unregistersymbol(addmoney) dealloc(newmem) { // ORIGINAL CODE - INJECTION POINT: "SaintsRowTheThird_DX11.exe"+3F3EE5 "SaintsRowTheThird_DX11.exe"+3F3EBF: 0F 84 DB 01 00 00 - je SaintsRowTheThird_DX11.exe+3F40A0 "SaintsRowTheThird_DX11.exe"+3F3EC5: E8 46 28 07 00 - call SaintsRowTheThird_DX11.exe+466710 "SaintsRowTheThird_DX11.exe"+3F3ECA: 3C 01 - cmp al,01 "SaintsRowTheThird_DX11.exe"+3F3ECC: 75 0A - jne SaintsRowTheThird_DX11.exe+3F3ED8 "SaintsRowTheThird_DX11.exe"+3F3ECE: C7 44 24 1C 03 00 00 00 - mov [esp+1C],00000003 "SaintsRowTheThird_DX11.exe"+3F3ED6: EB 0D - jmp SaintsRowTheThird_DX11.exe+3F3EE5 "SaintsRowTheThird_DX11.exe"+3F3ED8: 53 - push ebx "SaintsRowTheThird_DX11.exe"+3F3ED9: E8 62 8C 1E 00 - call SaintsRowTheThird_DX11.exe+5DCB40 "SaintsRowTheThird_DX11.exe"+3F3EDE: 83 C4 04 - add esp,04 "SaintsRowTheThird_DX11.exe"+3F3EE1: 89 44 24 1C - mov [esp+1C],eax // ---------- INJECTING HERE ---------- "SaintsRowTheThird_DX11.exe"+3F3EE5: F3 0F 2A 83 A0 1C 00 00 - cvtsi2ss xmm0,[ebx+00001CA0] // ---------- DONE INJECTING ---------- "SaintsRowTheThird_DX11.exe"+3F3EED: F3 0F 5A C0 - cvtss2sd xmm0,xmm0 "SaintsRowTheThird_DX11.exe"+3F3EF1: F2 0F 5E 05 C8 6B 2A 01 - divsd xmm0,[SaintsRowTheThird_DX11.exe+EA6BC8] "SaintsRowTheThird_DX11.exe"+3F3EF9: F2 0F 5A C0 - cvtsd2ss xmm0,xmm0 "SaintsRowTheThird_DX11.exe"+3F3EFD: C7 44 24 54 03 00 00 00 - mov [esp+54],00000003 "SaintsRowTheThird_DX11.exe"+3F3F05: F3 0F 11 44 24 5C - movss [esp+5C],xmm0 "SaintsRowTheThird_DX11.exe"+3F3F0B: 8D 44 24 54 - lea eax,[esp+54] "SaintsRowTheThird_DX11.exe"+3F3F0F: 50 - push eax "SaintsRowTheThird_DX11.exe"+3F3F10: 6A 00 - push 00 "SaintsRowTheThird_DX11.exe"+3F3F12: 8B CE - mov ecx,esi "SaintsRowTheThird_DX11.exe"+3F3F14: C7 84 24 88 00 00 00 0D 00 00 00 - mov [esp+00000088],0000000D }
Будет давать по 1000 монет.Не работает
-
[C++] Мониторинг системных вызовов (WOW64)
in Высокоуровневое программирование
Опубликовано
Видимо, никто не в курсе в чем может быть проблема.
Закинул случайно ассемблерный код с ошибкой — неправильно обрабатывает системные вызовы, которые вызываются без аргументов.
Решил избавиться от CRT-зависимых функций (malloc, sprintf_s) — перешел на функции в ntdll + не использую стандартную кучу, а создаю свою — вроде работает.