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

Проблема рассчёта и прыжка обратно к исходному коду. С++, Visual Studio 2015


Рекомендуемые сообщения

Добрый день! Уже не один вечер пытаюсь понять, в чём же проблема (в том числе искал не в одном топике здесь, на форуме)

Прошу понимания и совета - это первые эксперименты в чём-то низкоуровневом (и хотя тема не самая основная, но вызывающая любопытство).

 

Скрипт для 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;
}

 

 

Ссылка на комментарий
Поделиться на другие сайты

дааа еще бы 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

Изменено пользователем gmz
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

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

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