Гость YRain Опубликовано 12 апреля, 2016 Поделиться Опубликовано 12 апреля, 2016 Добрый день! Уже не один вечер пытаюсь понять, в чём же проблема (в том числе искал не в одном топике здесь, на форуме) Прошу понимания и совета - это первые эксперименты в чём-то низкоуровневом (и хотя тема не самая основная, но вызывающая любопытство). Скрипт для CodeCave написан в CheatEngine и скопирован оттуда. Переход на CodeCave осуществляется успешно. CodeCave выполняется тоже - ставил (когда отлаживал, держал CheatEngine присоединённым к процессу) в CheatEngine брекпоинт на инструкцию в самом CodeCave, и он срабатывал, показывая содержимое регистров. Но JMP, который должен был бы вернуть выполнение к исходному коду промахивается очень сильно, на сотни и тысячи позиций куда-то в пустые области. (причём какие бы типы данных и способы расчёта - часть из которых оставил в комментариях, не использовал (расчёт reverseJump). С++, Код Visual Studio 2015, ОС Win64, Компилируется для x86, все настройки проекта - "по умолчанию": *Приведение типов пока оставил в стиле Си, в остальном коде канонично плюсовые касты.* Скрытый текст HINSTANCE hInst = NULL; HWND _hWnd = NULL; ProcessManager pm;// Класс, обеспечивающий взаимодействие с процессом. DWORD64 addr = 0x0100282D; // Адрес первоначальной инструкции (откуда прыгать DWORD64 addr_to = 0; // Адрес созданного CodeCave void Injection() { BOOL r = pm.FindProcessByName(L"myprocess.exe"); if (r == FALSE) MessageBoxW(NULL, L"Error to find", szWindowClass.c_str(), MB_OKCANCEL); else { byte buffer[10]; pm.ReadMemory(addr, (LPVOID)&buffer[0], 10); addr_to = (DWORD64)pm.VirtualAllocMemory(30); if (addr_to == 0) { MsgBoxLastError(); return; } // 4 байта в середине - адрес смещения. Скопировано из ЧитЭнджин, но тут заменяем своими. byte jumpInst[6] = { 0xE9, 0xCE, 0xD7, 0x10, 0xFF, 0x90 }; DWORD addrJump = (DWORD)addr_to - (DWORD)addr - 0x5; memcpy(&jumpInst[1], &addrJump, sizeof(DWORD)); pm.WriteMemory(addr, (LPVOID)&jumpInst, 6); /*0 - (from - desination) - 5 0 - ($6259326B - $02980000) - 5 */ //long reverseJump = 0 - ((long)((DWORD)addr_to) - (long)addr -0x5);//addr_to - 0x5 - addr - 0x1; //DWORD reverseJump = addr_to - addr + 0x1 - 0x5); const DWORD CC_size = 0x16;//22 dec, размер кода в КодеКейве //DWORD reverseJump = addr_to + CC_size - addr + 0x1 - 0x5; DWORD reverseJump = (DWORD)pm.CalculateJump_X86C((unsigned char *)(addr_to + CC_size), (unsigned char *)addr); //long reverseJump = -1*reverseJump0; /*CodeCave code: 4 байта в конце - наш адрес возврата, reverseJump*/ byte code[22] = { 0xC7, 0x05, 0x9C, 0x57, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x3D, 0x9C, 0x57, 0x00, 0x01, 0xE9, 0x1E, 0x28, 0xEF, 0x00}; memcpy((code+ 22-4), &reverseJump, sizeof(DWORD)); pm.WriteMemory(addr_to, (LPVOID)&code, 23); } } Пожалуйста, скажите как должен был выглядеть расчёт reverseJump-а? (Другую критику по делу тоже хотелось бы увидеть.) Некоторые использованные функции (Остальные представляют из себя примитивные обёртки и сомнения в работе не вызывают): Скрытый текст inline static unsigned int CalculateJump_X86C(unsigned char* from, unsigned char* to) { return 0 - (from - to) - 5; } inline static DWORD CalculateJump_X86(DWORD from, DWORD to) { return 0 - (from - to) - 5; } Скрытый текст // Возвращает адрес выделенного фрагмента LPVOID ProcessManager::VirtualAllocMemory(SIZE_T dwSize) { HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, m_PID); if (hProcess == 0) return nullptr; const LPVOID addr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); CloseHandle(hProcess); return addr; } Ссылка на комментарий Поделиться на другие сайты Поделиться
gmz Опубликовано 12 апреля, 2016 Поделиться Опубликовано 12 апреля, 2016 (изменено) дааа еще бы dword64 тд тп *facepalm через call лучше: DWORD_PTR RemoteCodeBuffer = (DWORD_PTR)VirtualAllocEx((HANDLE)-1,0,4096,MEM_COMMIT,PAGE_EXECUTE_READWRITE); DWORD_PTR aOption1 = 0x004011B4; BYTE callCode[] = {0xE8,0x00,0x00,0x00,0x00,0x90}; BYTE bOption1[] = {0x90,0x90,0x90,0x90,0x90,0xC3}; WriteProcessMemory((HANDLE)-1,(LPVOID)RemoteCodeBuffer,bOption1,sizeof bOption1,0); DWORD_PTR temp = RemoteCodeBuffer-aOption1-5; memcpy(&callCode[1],&temp,sizeof temp); VirtualProtectEx((HANDLE)-1,(LPVOID)aOption1,sizeof callCode,PAGE_EXECUTE_READWRITE,&temp); WriteProcessMemory((HANDLE)-1,(LPVOID)aOption1,callCode,sizeof callCode,0); VirtualProtectEx((HANDLE)-1,(LPVOID)aOption1,sizeof callCode,temp,&temp); RemoteCodeBuffer = RemoteCodeBuffer+sizeof bOption1; BYTE bOption2[] = {0x90,0x90,0x90,0x90,0x90,0xC3}; WriteProcessMemory((HANDLE)-1,(LPVOID)RemoteCodeBuffer,bOption2,sizeof bOption2,0); также можно весь "хак код" в 1 буффер загнать xD Изменено 12 апреля, 2016 пользователем gmz Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения