Сейчас на форуме: vsv1 (+5 невидимых)

 eXeL@B —› Вопросы новичков —› Как подменить реализацию виртуального метода, без доступа к конструктору класса !
Посл.ответ Сообщение

Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 23 февраля 2016 22:43
· Личное сообщение · #1

Хочу понять возможно ли подменить данный метод, так чтобы оставался прямой доступ - к переменным как тут
Code:
  1.         void UStruct::Serialize( FArchive& Ar )
  2.     {
  3.              Super::Serialize( Ar ); //UFiled Serialize
  4.          Ar << ScriptText << Children;
  5.     }

ScripText, Children доступны напрямую, без переопределения класса Ustruct.

Если это возможно, то как следует представить функцию перехватчик чтобы в ней был тот самый доступ напрямую и без переопределения ?
Я пытался представить эту функцию таким образом

Code:
  1.     void __fastcall UStructS_hookNew(void* _this,int edx,FArchive& Ar)//, UStruct &st)
  2.     {
  3.     
  4.          hUField__Serialize(_this,edx,Ar);
  5.          UStruct* st = (UStruct*)malloc(sizeof(UStruct));
  6.          Ar << st->ScriptText << st->Children;
  7.     }

Code:
  1. void __cdecl UStructS_hookNew(FArchive& Ar)
  2.     {
  3.     
  4.          hUField__Serialize(Ar);
  5.          UStruct* st = (UStruct*)malloc(sizeof(UStruct));
  6.          Ar << st->ScriptText << st->Children;
  7.     }


Но так программа падает с ошибкой. В самом классе есть так же несколько конструкторов

Code:
  1.     UStruct( ENativeConstructor, INT InSize, const TCHAR* InName, const TCHAR* InPackageName, DWORD InFlags, UStruct* InSuperStruct );
  2.     UStruct( EStaticConstructor, INT InSize, const TCHAR* InName, const TCHAR* InPackageName, DWORD InFlags );
  3.     UStruct( UStruct* InSuperStruct );


Но я не очень понимаю - когда идет прямой доступ
Code:
  1.  `UStruct::Serialize`
,разве для него используется конструктор ?
И как тогда следует правильно представить это ?




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 23 февраля 2016 22:50
· Личное сообщение · #2

Code:
  1.        void UStruct::Serialize( FArchive& Ar )
  2.     {
  3.              Super::Serialize( Ar ); //UFiled Serialize
  4.          Ar << ScriptText << Children;
  5.     }

скомпилируйте, и в визуал студии или ida посмотрите что там сгенерируется в asm коде

может тогда поймете как сделать правильно



Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 23 февраля 2016 22:57
· Личное сообщение · #3

reversecode пишет:
скомпилируйте, и в визуал студии или ida посмотрите что там сгенерируется в asm коде

может тогда поймете как сделать правильно

Я знаю что там генерируется идой, я хочу понять - возможно ли подменить на свое имея почти полный сурс того же что и там!
ScriptText выглядит там к примеру так v4 = sub_10101965(v2, (char *)v3 + 64); а это не очень.




Ранг: 251.8 (наставник), 17thx
Активность: 0.120
Статус: Участник
Seeker

Создано: 23 февраля 2016 23:56
· Личное сообщение · #4

Непонятно зачем там передаётся edx и Ar.
Если там действительно __fastcall, то третьим параметром портится стек.

-----
DREAMS CALL US




Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 24 февраля 2016 00:54
· Личное сообщение · #5

=TS= пишет:
Непонятно зачем там передаётся edx и Ar.
Если там действительно __fastcall, то третьим параметром портится стек.

IDA из этого метода
Code:
  1.         void UStruct::Serialize( FArchive& Ar )
  2.     {
  3.              Super::Serialize( Ar ); //UFiled Serialize
  4.          Ar << ScriptText << Children;
  5.     }

делает __thiscall,
Code:
  1. int __thiscall UStruct__Serialize(void *this, int a2)
  2. int v2; // edi@1
  3.   void *v3; // esi@1
  4.   int v4; // eax@1
  5.   int v5; // eax@5
  6.   int result; // eax@7
  7.   char v7; // [sp+0h] [bp-2Ch]@1
  8.   void *v8; // [sp+10h] [bp-1Ch]@1
  9.   int v9; // [sp+18h] [bp-14h]@7
  10.   char *v10; // [sp+1Ch] [bp-10h]@1
  11.   int v11; // [sp+28h] [bp-4h]@1
  12.  
  13.   v10 = &v7;
  14.   v3 = this;
  15.   v8 = this;
  16.   v11 = 0;
  17.   v2 = a2;
  18.   UField__Serialize(a2);
  19.   v4 = sub_10101965(v2, (char *)v3 + 64);
  20.   sub_10103210(v4, (char *)v3 + 72);
  21.   (*(void (__thiscall **)(int, char *))(*(_DWORD *)v2 + 28))(v2, (char *)v3 + 80);
  22. }

a3 это FArchive& Ar, который как раз и должен присутствовать в стеке, я сделал __fastcall потому что так удобнее, edx не нужный параметр просто.

Но вопрос вообще в другом - если это возможно использовать описания класса внутри такой вот функции перехватчика,




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 24 февраля 2016 01:10
· Личное сообщение · #6

это вывод из hexrays, а не из ida asm листинг
asm откройте и в него смотрите и вникайте



Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 24 февраля 2016 01:22 · Поправил: bolvai
· Личное сообщение · #7

Я немного про другое спрашивал, если в моей функции перехватчике заместо - статичного обращения через "::" к переменным класса, будет обращение через указатель на объект ->, будет ли это равносильно или это не правильно ?
Если будет, то как следует представить сам объект, используя конструктор либо как то по другому ? Должно же быть какое то распространенное решение подобных задач, не верю просто я что имея почти полное описание того же объекта, в итоге нельзя - подменить своим.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 24 февраля 2016 01:37
· Личное сообщение · #8

если бы вы не строчили а делали то что вам говорят и вдумчиво смотрели да еще в оригинале и дебаггером побегали,то все бы поняли

скопилить код в студии,далее начать отладку и включить показ asm кода
пройтись и стало бы все ясно и понятно


Code:
  1.   v10 = &v7;
  2.   v3 = this;
  3.   v8 = this;
  4.   v11 = 0;
  5.   v2 = a2;
  6.   UField__Serialize(a2); <-- здесь фейл, и фейл в вашей реализации, и все от незнания и нежелания понимать с++




Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 24 февраля 2016 01:59 · Поправил: bolvai
· Личное сообщение · #9

Хотите сказать что я не правильно реализовал UField__Serialize; точнее его вызов ?
Code:
  1. #define UField__Serialize ((int(_fastcall*)(void*,int,FArchive& Ar)) (0x11261810))
  2. int _fastcall hUField__Serialize(void* _this,int edx, FArchive& Ar)
  3. {
  4.          return UField__Serialize(_this,edx,Ar);
  5.  
  6. }


P.S.
Я и так дебагером пользуюсь практически постоянно от VS
http://pastebin.com/25uF2EHF
, просто это не как не помогает в понимании того что и как следует писать в C++, точнее возможно ли писать то что требуется.

Добавлено спустя 42 минуты
Я возможно дал вам не совсем полную инфу чтобы вы меня поняли, дополню !

Если я обозначу функцию перехватчик через статичное обращение "::"
Code:
  1. void __cdecl UStruct::Serialize(FArchive& Ar)//, UStruct &st)
  2. {
  3.  
  4.          hUField__Serialize_cdl(Ar);
  5.          Ar <<  ScriptText << Children;
  6.          Ar << FriendlyName;
  7. }

То мой хук попросту не будет иметь имени выражения чтобы заинжектится, как следует это решить ?
Через #define, или может есть метод по проще ? плиз помогите.




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 24 февраля 2016 02:51
· Личное сообщение · #10

полнота информации граничит с нулем
все вообще вырвано из контекста и подается какими то кусками несвязно, хрен что поймешь



Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 24 февраля 2016 03:12
· Личное сообщение · #11

reversecode пишет:
полнота информации граничит с нулем
все вообще вырвано из контекста и подается какими то кусками несвязно, хрен что поймешь

У меня есть весь класс UStruct цельный, то есть полный сурс, но я хочу перехватить оригинальный метод класса(UStruct::serialize), и подменить на свой, используя хук Trampoline
Code:
  1. Hook::HookFunctionWithTrampoline(reinterpret_cast<unsigned char*>(UStructS), reinterpret_cast<unsigned char*>(fUStructS_hookNew), trampoline_9);

Как следует объявить функцию перехватчик чтобы оставался доступ к членам класса, т.е ScriptText Children.

Так яснее ?




Ранг: 1053.6 (!!!!), 1078thx
Активность: 1.060.81
Статус: Участник

Создано: 24 февраля 2016 03:33 · Поправил: reversecode
· Личное сообщение · #12

Code:
  1.     void __fastcall fUStructS_hookNew(void* _this, int edx, FArchive & Ar)
  2.     {
  3.     
  4.          hUField__Serialize(_this, edx, Ar); ?? хз как вы там перехватили, если правильно то работать должно
  5.  
  6.          UStruct* st = (UStruct*)_this;
  7.          Ar << st->ScriptText << st->Children;
  8.     }




Ранг: 4.2 (гость)
Активность: 0.020
Статус: Участник

Создано: 24 февраля 2016 03:49
· Личное сообщение · #13

Вот спасибо в 3 часа ночи наконец то добил это )

Решение вот тут
Code:
  1. UStruct* st = (UStruct*)_this;


Теперь хоть значение правильное считывается, но полюбому крит дает(но это уже из-за другого) так что всеравно спасибо вам ! решили всетаки


 eXeL@B —› Вопросы новичков —› Как подменить реализацию виртуального метода, без доступа к конструктору класса !
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати