Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Help] Подмена данных GPU при помощи MS Detours 3, Не получается перехватить и подменить 
:(
    Опции темы
SuprSonic
  Дата 15.11.2017, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Привет всем,
Пытаюсь подменить информацию о видеокарте, но столкнулся с проблемой. Данные о видеокарте (GPU) в большинстве случаев тянутся посредством Win32_VideoController. То бишь это выглядит примерно так:
Код

IWbemServices* services = NULL;
...
IEnumWbemClassObject* instanceEnum = NULL;
services->CreateInstanceEnum(
                            _bstr_t("Win32_VideoController"),
                            WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
                            NULL, 
                            &instanceEnum);


Т.е. вначале создается объект класса IWbemServices (допустим *services), а далее вызывается метод services->CreateInstanceEnum("Win32_VideoController"..., &instanceEnum); и данные записываются в заранее созданный объект IEnumWbemClassObject (здесь это instanceEnum).

Используя MS Detours 3.0 пробовал перехватить IEnumWbemClassObject::CreateInstanceEnum следующим образом:

Попытка получить указатель:
Код

typedef HRESULT(WINAPI IWbemServices::*tm_CreateInstanceEnum) (const BSTR strClass, LONG lFlags, IWbemContext *pCtx, IEnumWbemClassObject **ppEnum);
tm_CreateInstanceEnum True_CreateInstanceEnum = &IWbemServices::CreateInstanceEnum;


Функция для подмены:
Код

__declspec(dllexport) HRESULT WINAPI Hooked_CreateInstanceEnum(const BSTR strClass, LONG lFlags, IWbemContext *pCtx, IEnumWbemClassObject **ppEnum)
{
       MessageBox(0, L" Hooked!!!", L"Oh yeah, you did it !", MB_OK);
       //return True_CreateInstanceEnum(strClass, lFlags, pCtx, ppEnum); // я честно хз почему так, но это не верно
       return 0;
}


Inject:
Код

BOOL APIENTRY DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
                DetourRestoreAfterWith();
                DetourTransactionBegin();
                DetourAttach((PVOID*)&True_CreateInstanceEnum, Hooked_CreateInstanceEnum);
                DetourTransactionCommit();
        }
        else if (dwReason == DLL_PROCESS_DETACH)
        {
                DetourTransactionBegin();
                DetourUpdateThread(GetCurrentThread());
                DetourDetach((PVOID*)&True_CreateInstanceEnum, Hooked_CreateInstanceEnum);
                DetourTransactionCommit();
        }
{


Компилируется в DLL, но ничего не перехватывается.  smile  Хотя по идее это все должно было выглядить так, что при перехвате CreateInstanceEnum у меня бы появлялся MessageBox.

Где я напортачил? Знающие, помогите плз...
PM MAIL   Вверх
_zorn_
Дата 15.11.2017, 20:00 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: нет
Всего: 12



ХОЧУ МАЙНИТЬ БАБЛА, но помогите бесплатно.

Как это знакомо даже не в разрезе "майнить"...
PM MAIL   Вверх
SuprSonic
Дата 15.11.2017, 20:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Цитата(_zorn_ @ 15.11.2017,  20:00)
ХОЧУ МАЙНИТЬ БАБЛА, но помогите бесплатно.

Как это знакомо даже не в разрезе "майнить"...

ЧЗНХ?! Без флуда пожалуйста.
Если с головой бобо - то посетите врача

Это сообщение отредактировал(а) SuprSonic - 16.11.2017, 00:07
PM MAIL   Вверх
xvr
Дата 16.11.2017, 10:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(SuprSonic @  15.11.2017,  19:36 Найти цитируемый пост)
Код

typedef HRESULT(WINAPI IWbemServices::*tm_CreateInstanceEnum) (const BSTR strClass, LONG lFlags, IWbemContext *pCtx, IEnumWbemClassObject **ppEnum);
tm_CreateInstanceEnum True_CreateInstanceEnum = &IWbemServices::CreateInstanceEnum;

Это C++ member pointer, а DetourAttach ожидает обычный указатель на функцию. Это две совершенно разных сущности. Более того, IWbemServices::CreateInstanceEnum вообще не существует в виде какого либо указателя - это просто индекс в таблице виртуальных методов. Еще более того - на момент загрузки вашей dll реализации IWbemServices::CreateInstanceEnum в памяти еще нет - она грузится динамически COM подсистемой в момент вызова первого CoCreateInstance.

Вам надо перехватывать CoCreateInstance и ждать, пока не попытаются создать IWbemLocator, а потом патчить таблицы виртуальных методов возвращаемых объектов по цепочке, пока не дойдете до вашего IWbemServices::CreateInstanceEnum

Может проще будет вмешаться в WMI и подменить провайдер, который выдает Win32_VideoController?

Добавлено через 3 минуты и 39 секунд
А если учесть, что ваши Win32_VideoController вообще могут запросить через IWbemServices::ExecQuery ("Select * from Win32_VideoController"), то затея с перехватом вообще становится практически неосуществимой


Это сообщение отредактировал(а) xvr - 16.11.2017, 10:38
PM MAIL   Вверх
SuprSonic
Дата 16.11.2017, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Цитата

А если учесть, что ваши Win32_VideoController вообще могут запросить через IWbemServices::ExecQuery ("Select * from Win32_VideoController"), то затея с перехватом вообще становится практически неосуществимой


Спасибо за ответ. Мне подсказали вешать хук на метод Get. В итоге появился такой код:

Код

#include "stdafx.h"
#pragma comment (lib, "detours.lib")
 
typedef HRESULT (WINAPI * True_GetFn)(LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE *pvtType, LONG *plFlavor);
True_GetFn p_Get = nullptr;
 
__declspec(dllexport) HRESULT WINAPI Hooked_Get(LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE *pvtType, LONG *plFlavor)
{
    if (wcsstr(wszName, L"VideoProcessor") != NULL || wcsstr(wszName, L"Name") != NULL || wcsstr(wszName, L"AdapterCompatibility") != NULL || wcsstr(wszName, L"SystemName") != NULL)
    {
        pVal->vt = VT_BSTR; 
        V_BSTR(pVal) = L"NO_DATA";
    }
    else if (wcsstr(wszName, L"AdapterRAM") != NULL)
    {
        pVal->vt = VT_UI4;
        V_BSTR(pVal) = L"0";
    }
    return p_Get(wszName, lFlags, pVal, pvtType, plFlavor);
}
 
PVOID SetDetour(PVOID* ppTarget, PVOID pHandler)
{
    if (DetourTransactionBegin() != NO_ERROR)
        return FALSE;
 
    if (DetourUpdateThread(GetCurrentThread()) != NO_ERROR)
    {
        DetourTransactionCommit();
        return NULL;
    }
 
    PDETOUR_TRAMPOLINE pTrampoline = NULL;
 
    if (DetourAttachEx(ppTarget, pHandler, &pTrampoline, NULL, NULL) != NO_ERROR)
    {
        DetourTransactionCommit();
        return NULL;
    }
 
    if (DetourTransactionCommit() != NO_ERROR)
    {
        DetourTransactionAbort();
        return NULL;
    }
 
    return pTrampoline;
}
 
BOOL APIENTRY DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
    HMODULE hLib = GetModuleHandle(L"fastprox.dll");
    if (hLib)
    {
        p_Get = (True_GetFn)GetProcAddress(hLib, "?Get@CWbemObject@@UAGJPBGJPAUtagVARIANT@@PAJ2@Z");
        if (p_Get)
        {
            SetDetour(&(PVOID&)p_Get, Hooked_Get);
        }
    }
       return TRUE;
}


Я тестирую получившуюся DLL прикрепляя ее к dxdiag.exe с помощью withdll.exe. Но мне походу запуска dxdiag.exe выбрасывается вот такое -
Window #1

Window #2

Window #3

 smile 

Я уже даже не знаю что делать. Хотя если в функции Hooked_Get прописать например MessageBox, то он появится, а это уже хорошо. Значит что-то в итоге перехватывается, но всеравно ошибка..

Это сообщение отредактировал(а) SuprSonic - 16.11.2017, 17:31
PM MAIL   Вверх
SuprSonic
Дата 16.11.2017, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Цитата

Может проще будет вмешаться в WMI и подменить провайдер, который выдает Win32_VideoController?


А можно поподробнее?)
PM MAIL   Вверх
xvr
Дата 17.11.2017, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Функция Get - это метод класса, так что у нее есть еще 1 параметр - this

Цитата(SuprSonic @  16.11.2017,  18:08 Найти цитируемый пост)
А можно поподробнее?) 

В двух словах это не объяснить, читайте в MSDN описание архитектуры WMI

PM MAIL   Вверх
SuprSonic
Дата 17.11.2017, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Впихнул первый параметр под this и....

Код

typedef HRESULT (WINAPI * True_GetFn)(void*, LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE *pvtType, LONG *plFlavor);
....
__declspec(dllexport) HRESULT WINAPI Hooked_Get(void* suslik,LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE *pvtType, LONG *plFlavor)
{
....


ничего, все равно не работет  smile 

Это сообщение отредактировал(а) SuprSonic - 17.11.2017, 12:59
PM MAIL   Вверх
xvr
Дата 17.11.2017, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Для начала поставьте в хуке печать параметров (через MessageBox) и вызов оригинальной функции. Если заработает, будем резать дальше smile

PM MAIL   Вверх
_zorn_
Дата 17.11.2017, 18:40 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 21.8.2007

Репутация: нет
Всего: 12



Цитата(SuprSonic @  16.11.2017,  02:36 Найти цитируемый пост)
Пытаюсь подменить информацию о видеокарте, но столкнулся с проблемой

Цитата(SuprSonic @  16.11.2017,  03:02 Найти цитируемый пост)
Если с головой бобо - то посетите врача

Может стоит быть честным ?

Не могу придумать задачу, где нужно подменять что нибудь, а тем более видеокарту...
PM MAIL   Вверх
SuprSonic
Дата 17.11.2017, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 7.8.2016

Репутация: нет
Всего: нет



Пришел к такому решению, оно наполовину рабочее... в общем вот код:
Код

typedef HRESULT(__stdcall *IWbemClassObject_Get)(void *__this, LPCWSTR, LONG, VARIANT*, CIMTYPE*, LONG*);
IWbemClassObject_Get True_Get;

__declspec(dllexport) HRESULT __stdcall Hooked_Get(void *__this, LPCWSTR wszName, LONG lFlags, VARIANT *pVal, CIMTYPE *pvtType, LONG *plFlavor)
{
    printf("wszName: %S\n", wszName);
    std::cout << "lFlags:" << lFlags << std::endl;
    std::cout << "pVal:" << pVal << std::endl;
    std::cout << "pvtType:" << pvtType << std::endl;
    std::cout << "plFlavor:" << plFlavor << std::endl;
    return True_Get(__this, wszName, lFlags, pVal, pvtType, plFlavor);
}

template<typename T>
void HookFunction(const char *module, char *signature, T &fn_real, PVOID fn_mine)
{
    HookFunction<T>(DetourFindFunction(module, signature), fn_real, fn_mine);
}

template<typename T>
void HookFunction(DWORD address, T &fn_real, PVOID fn_mine)
{
    HookFunction<T>(reinterpret_cast<PVOID>(address), fn_real, fn_mine);
}

template<typename T>
void HookFunction(PVOID target, T &fn_real, PVOID fn_mine)
{
    fn_real = reinterpret_cast<T>(target);

    HookFunction<T>(fn_real, fn_mine);
}

template<typename T>
void HookFunction(T &fn_real, PVOID fn_mine)
{
    DetourAttach(&(PVOID&)fn_real, fn_mine);
}

void ApplyHooks(LPVOID address) //Function address 0x6FD9B723
{
    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    HookFunction<IWbemClassObject_Get>((FARPROC)address, True_Get, Hooked_Get);
    DetourTransactionCommit();
}

BOOL APIENTRY DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
    AllocConsole();
    freopen_s((FILE**)stdout, "CONOUT$", "w", stdout);

    HMODULE hLib = GetModuleHandle(L"fastprox.dll");
    if (hLib)
    {
        FARPROC hAdd = GetProcAddress(hLib, "?Get@CWbemObject@@UAGJPBGJPAUtagVARIANT@@PAJ2@Z");
        if (hAdd)
        {
            if (dwReason == DLL_THREAD_ATTACH)
            {
                                std::cout << "DLL_THREAD_ATTACH" << std::endl;
                DisableThreadLibraryCalls(hinst); // Почему-то если его убрать, то через какой-то время dxdiag.exe выбрасывает ошибку
                CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ApplyHooks, hAdd, 0, 0);
            }
        }
    }
        return TRUE;
}


И он мне выдает вот такой списочек в консоли:

user posted image

Но есть два непонятных для меня момент -
1). Без DisableThreadLibraryCalls(hinst) в DllMain(...) через какое-то время dxdiag.exe выбивает ошибку, хотя какие-то данные в консоли отобразились.
2). Потерпел фиаско при попытке изменить какие-либо значения, в dxdiag.exe они не поменялись. Предполагаю, что это как-то связано с DisableThreadLibraryCalls... но см.п.1

Пример кода того как пытался поменять значения у строковых переменных. Причем если после изменения вывести в консоль pVal, то оно будет изменено на "NO_DATA", а в dxdiag.exe изменениями и не пахнет.
Код

        pVal->vt = VT_BSTR; 
        V_BSTR(pVal) = L"NO_DATA";


 smile 

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  eBTqAyE.png 88,42 Kb
PM MAIL   Вверх
xvr
Дата 20.11.2017, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(SuprSonic @  17.11.2017,  20:52 Найти цитируемый пост)
1). Без DisableThreadLibraryCalls(hinst) в DllMain(...) через какое-то время dxdiag.exe выбивает ошибку, 

Без этого каждый новый thread для вызова ApplyHooks будет вызывать эту точку входа вновь и вновь. В результате в системе кончится либо стек либо очередь на вызов DllMain

Цитата(SuprSonic @  17.11.2017,  20:52 Найти цитируемый пост)
Потерпел фиаско при попытке изменить какие-либо значения, в dxdiag.exe они не поменялись. 

Скорее всего это связано с тем, что dxdiag извлекает данные не через этот метод. Там очень и очень много способов эти данные извлечь.

Ну и ясности ради - возвращать BSTR так (V_BSTR(pVal) = L"NO_DATA";) нельзя - см SysAllocString

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.1525 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.