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

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

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

Создано: 11 января 2016 01:54 · Поправил: bolvai
· Личное сообщение · #1

Хочу восстановить функцию из .dll и немного ее изменить
Ее представление в IDA Hex rays
Code:
  1. int __thiscall sub_200D7CE0(int this, int a2)
  2. {
  3.   int v3; // [sp+8h] [bp-10h]@1
  4.   int v4; // [sp+14h] [bp-4h]@1
  5.  
  6.   sub_200D6990(this, a2);
  7.   v4 = 0;
  8.   *(_DWORD *)a2 = &off_2054182C;
  9.   *(_DWORD *)(a2 + 16) = 128;
  10.   *(_DWORD *)(a2 + 20) = 0;
  11.   FName__FName(&v3, L"Package.a", 1);
  12.   *(_DWORD *)(a2 + 48) = v3;
  13.   *(_DWORD *)(a2 + 64) = 2;
  14.   *(_DWORD *)(a2 + 56) = 1;
  15.   *(_DWORD *)(a2 + 72) = 1;
  16.   return a2;
  17. }

Особых проблем в доступе к переменным этой функции нету, описываю я этот класс таким образом
Code:
  1. bool SetHooks(void)
  2. {
  3. int AbnormalSleep;
  4. AbnormalSleep = 0x200D7D10;
  5. Hook::HookFunctionWithTrampoline(reinterpret_cast<unsigned char*>(AbnormalSleep), reinterpret_cast<unsigned char*>(AbnormalSleep_hookNew), trampoline);
  6.  
  7. }
  8. typedef struct
  9. {
  10.  
  11.     void(__fastcall *subUnk1) (void* ecx, void* dummy,int unkA2); sub_200D6990
  12. }   hookedAbnSleep_class;
  13. int __stdcall AbnormalSleep_hookNew(int unkA2) //sub_200D7CE0
  14. {
  15.     int r = 0;
  16.  
  17.     hookedAbnSleep_class *T;
  18.         __asm{mov T, ecx}
  19.     T->subUnk1(0, 0, unkA2);//sub_200D6990
  20.     return unkA2;
  21. }

Но вся загвоздка у меня в том что я не могу понять как следует вызвать и описать эту функцию sub_200D6990 внутри моей AbnormalSleep_hookNew (так чтобы можно было поместить в нее аргументы и она работала как оригинальная) ?
Это можно проделать через Module Handle,GetProcAddress, или может еще как то.
Плиз знающие люди объясните =)) замучался....



Ранг: 71.2 (постоянный), 33thx
Активность: 0.050.12
Статус: Участник

Создано: 11 января 2016 02:15 · Поправил: kunix
· Личное сообщение · #2

Если компилятор VisualC++, то создайте класс и сделайте AbnormalSleep_hookNew(int a2) его методом. Компиллер создаст вам функцию, которая принимает this в ECX.
Вызов оригинальной функции делайте через оператор ->*.
В противном случае пишите на ASM обертки для обеих функций.




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

Создано: 11 января 2016 02:43
· Личное сообщение · #3

--> Link <--
--> Link <--



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

Создано: 11 января 2016 15:07
· Личное сообщение · #4

kunix пишет:
Если компилятор VisualC++, то создайте класс и сделайте AbnormalSleep_hookNew(int a2) его методом. Компиллер создаст вам функцию, которая принимает this в ECX.
Вызов оригинальной функции делайте через оператор ->*.
В противном случае пишите на ASM обертки для обеих функций.

Если вы имейте ввиду вызов _fastcal Где первый аргумент кладётся в ECX, второй в EDX, остальные в стек То я не где не видел полного примера - это можно показать ?
Я к примеру пытался сделать это так
Code:
  1. typedef struct
  2. {
  3.  
  4.     void(__fastcall *subUnk1) (void* ecx, void* dummy,int unkA2); sub_200D6990
  5. }   hookedAbnSleep_class;

Code:
  1. int __stdcall AbnormalSleep_hookNew(int unkA2) //sub_200D7CE0
  2. {
  3.     int r = 0;
  4.  
  5.     hookedAbnSleep_class *T;
  6.         __asm{mov T, ecx}
  7.     T->subUnk1(0, 0, unkA2);//sub_200D6990
  8.     return unkA2;
  9. }

Но помоему это не правильно, ибо я положил в сам класс ECX, а должно видно по другому

reversecode пишет:

--> Link <--
--> Link <--


Спасибо за линк, сейчас попробую разобрать - но вот я смотрю там опять же описывается - про _fastcall
JKornev пишет:
В _fastcall первый аргумент кладётся в ECX, второй в EDX, остальные в стек. Следовательно вам надо перехватить указатель на класс и засунуть его в первый аргумент(т.к. он передаётся в ECX), второй аргумент не используется, в нём можно передавать что угодно(напр. 0), остальные аргументы как и в классе. Например:


Но не полностью !



Ранг: 21.0 (новичок), 19thx
Активность: 0.010.03
Статус: Участник

Создано: 11 января 2016 15:47
· Личное сообщение · #5

Code:
  1. typedef void(__fastcall* oAbnormalSleep)(void*, int);
  2. oAbnormalSleep pAbnormalSleep;
  3.  
  4. void __fastcall hAbnormalSleep((void* pThis, int unkA2)
  5. {
  6.          return pAbnormalSleep(pThis, unkA2);
  7. }
  8.  
  9. DWORD AbnormalSleep = 0x200D7D10;
  10. pAbnormalSleep = (oAbnormalSleep )DetourFunction((PBYTE)AbnormalSleep,(PBYTE)hAbnormalSleep);




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

Создано: 11 января 2016 16:00
· Личное сообщение · #6

soft пишет:
Code:
typedef void(__fastcall* oAbnormalSleep)(void*, int);
oAbnormalSleep pAbnormalSleep;
 
void __fastcall hAbnormalSleep((void* pThis, int unkA2)
{
         return pAbnormalSleep(pThis, unkA2);
}
 
DWORD AbnormalSleep = 0x200D7D10;
pAbnormalSleep = (oAbnormalSleep )DetourFunction((PBYTE)AbnormalSleep,(PBYTE)hAbnormalSleep);


Так а где тут вызов sub_200D6990 ?



Ранг: 21.0 (новичок), 19thx
Активность: 0.010.03
Статус: Участник

Создано: 11 января 2016 16:14
· Личное сообщение · #7

hAbnormalSleep обертка для оригинальной функи 0x200D7D10. как я понял вы хотите подменять значение указателя unkA2? ну так подменяйте перед вызовом оригинала pAbnormalSleep в hAbnormalSleep. если нужен хук на sub_200D6990, так на него и делайте. все тоже самое.

Добавлено спустя 26 минут
если нужно просто объявить функу sub_200D6990 для вызова, попробуйте что то типа такого:
Code:
  1. #define sub_200D6990 ((int(__fastcall*)(void*, int)) 0x200D6990)
  2.  
  3. void __fastcall hMainHook((void* pThis, int unkA2)
  4. {
  5.          sub_200D6990(pThis, unkA2);
  6.          ....
  7. }


| Сообщение посчитали полезным: bolvai

Ранг: 71.2 (постоянный), 33thx
Активность: 0.050.12
Статус: Участник

Создано: 11 января 2016 17:14
· Личное сообщение · #8

bolvai пишет:
Если вы имейте ввиду вызов _fastcal Где первый аргумент кладётся в ECX, второй в EDX, остальные в стек То я не где не видел полного примера - это можно показать ?
Я к примеру пытался сделать это так

Я ничего про __fastcall не говорил, я сказал сделать AbnormalSleep_hookNew(int a2) методом класса.
Вот так вот
Code:
  1. class HookClass
  2. {
  3. public:
  4.          typedef DWORD (HookClass::*P_AbnormalSleep)(int a2);
  5.  
  6.          P_AbnormalSleep pf_call_AbnormalSleep;
  7.  
  8.          DWORD hook_AbnormalSleep(int a2)
  9.          {
  10.                  return (this->*pf_call_AbnormalSleep)(a2);
  11.          }
  12. };
  13.  
  14. int _tmain(int argc, _TCHAR* argv[])
  15. {
  16.          HookClass                              hook;
  17.          HookClass::P_AbnormalSleep         pf_hook = &HookClass::hook_AbnormalSleep;
  18.  
  19.          *(DWORD*)&hook.pf_call_AbnormalSleep = (DWORD)DetourAttach((PBYTE)0x200D7D10, (PBYTE)*(DWORD*)&pf_hook);
  20.  
  21.          return 0;
  22. }

Все эти *(DWORD*)& нужны лишь потому, что иначе P_AbnormalSleep и DWORD друг в друга не конвертируются.

soft, в __fastcall первые два аргумента передаются в ECX и EDX, верно?
Тогда unkA2 ваша функция возьмет из EDX, тогда как должна взять из стека, ибо sub_200D7CE0 это __thiscall.
Нужно сделать
Code:
  1. void __fastcall hAbnormalSleep(void* pThis, void* edx, int unkA2)


| Сообщение посчитали полезным: bolvai

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

Создано: 12 января 2016 02:44
· Личное сообщение · #9

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



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

Создано: 13 января 2016 18:48
· Личное сообщение · #10

soft пишет:

Добавлено спустя 26 минут
если нужно просто объявить функу sub_200D6990 для вызова, попробуйте что то типа такого:


kunix пишет:
Тогда unkA2 ваша функция возьмет из EDX, тогда как должна взять из стека, ибо sub_200D7CE0 это __thiscall.
Нужно сделать
Code:
void __fastcall hAbnormalSleep(void* pThis, void* edx, int unkA2)


Спасибо за метод в итоге у меня получилось - подобное

Code:
  1. #define sub_200D6990 ((int(__fastcall*)(void*, int)) 0x200D6990)
  2. typedef struct
  3. {
  4.          void __fastcall hMainHook (void* pThis,void* edx, int unkA2)
  5.          {
  6.                  sub_200D6990(pThis, unkA2);
  7.  
  8.          }
  9. }hookedAbnSleep_class;

Но я не понимаю как следует передать эти самые параметры ECX И EDX, Через ASM, внутри тела AbnormalSleep_hookNew sub_200D7CE0 т.е

Code:
  1. int __stdcall AbnormalSleep_hookNew(int unkA2) //sub_200D7CE0 
  2. {
  3.  
  4.         hookedAbnSleep_class *T;
  5.         __asm{mov T,ecx};
  6.          T->hMainHook(unkA2);
  7.  
  8. };

Если так сделать то в T->hMainHook, будут не доставать 2 параметра ? А если чисто через ASM то - помоему не хватает еще каких то аргументов - вызова, не так ли ?



Ранг: 101.0 (ветеран), 344thx
Активность: 1.150
Статус: Участник

Создано: 13 января 2016 21:53
· Личное сообщение · #11

bolvai пишет:
Но я не понимаю как следует передать эти самые параметры ECX И EDX, Через ASM, внутри тела AbnormalSleep_hookNew sub_200D7CE0 т.е

32-х битный __fastcall --> Link <--
64-х битный --> Link <--



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

Создано: 14 января 2016 01:02
· Личное сообщение · #12

Так а асемблерные вставки в - моем примере, нужны или нет ?
Code:
  1.  T->hMainHook(unkA2);

Тут к примеру отсуствуют 2 аргрумента - при таком вызове.




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

Создано: 14 января 2016 02:49 · Поправил: reversecode
· Личное сообщение · #13

я хренею
сколько сылок вам дали. сколько рабочих примеров предоставили
все равно пофиг. выкручиваете в нерабочее и спрашиваете что не так
ЧИТАТЬ И ВНИКАТЬ! основное в нашем деле
если не поняли. опять ЧИТАТЬ И ВНИКАТЬ!
и так пока не прийдет понимание
а иначе вагоны разгружать



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

Создано: 14 января 2016 14:06
· Личное сообщение · #14

reversecode пишет:
ЧИТАТЬ И ВНИКАТЬ! основное в нашем деле

Это да, но я ведь спросил про конкретный пример =) И привел то что я делаю, Я сделал вот так - но думаю это не совсем правильно ?
Code:
  1. int __stdcall AbnormalSleep_hookNew(int unkA2)
  2. {
  3.          __asm{
  4.                      mov _ecx,ecx
  5.                      mov _edx,edx};
  6.  
  7.                     T->hMainHook(_ecx,_edx,unkA2);
  8. }





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

Создано: 14 января 2016 14:13
· Личное сообщение · #15

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



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

Создано: 14 января 2016 14:27
· Личное сообщение · #16

Я вообще то спрашивал не про указатель а про то как поместить ECX и EDX через вставку ASM либо по другому,
я уже решал подобные задачи - но там не было вызовов функций, там была простая работа с переменными класса, а тут у меня возникли затруднения, зачем вы задаете эти вопросы которые не имеют ни какого отношения к решению моего вопроса - я что то сложное для вас задал ?




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

Создано: 14 января 2016 14:32 · Поправил: reversecode
· Личное сообщение · #17

ответ как поместить находится как раз в понимании как обьявить и использовать указатель на функцию

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

хотите разбираться, открывайте учебник по С/C++, гугл, итд
и изучайте как обьявляется и используется указатель на фунцию

вам в этой теме дали 100% нужных ответов

Добавлено спустя 3 минуты
форум это там где люди улучшают свои знания
а не где ищут что бы за них что то сделали



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

Создано: 14 января 2016 14:43
· Личное сообщение · #18

Я вам про одно, вы мне опять про другое, и если вы не заметили я привел пример кода - который отличается от того что привел kunix, У него там метод Detour, А у меня Trampoline которые не совсем одинаковы в использовании, я бы хотел на моем примере понять - как следует передать ECX и EDX, именно при обращение в моем примере - T->hMainHook(0,0,unkA2); Может быть по вашему - этот ответ и не нужен, поскольку вы в этом прошарены - но конкретно этот вопрос у меня и создает затруднение чтобы я мог продолжить далее работать. Вы вместо того чтобы разводить серинады на тему того кто кем является или не является, попросту представили как оно должно выглядить на моем примере - если вам не лень конечно.




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

Создано: 14 января 2016 15:04 · Поправил: reversecode
· Личное сообщение · #19

Code:
  1. int __stdcall AbnormalSleep_hookNew(int unkA2)
  2. {
  3.          __asm{
  4.                      mov _ecx,ecx
  5.                      mov _edx,edx};
  6.  
  7.                     T->hMainHook(_ecx,_edx,unkA2);
  8. }

это чушь, в перехваченном AbnormalSleep_hookNew уже потеряны все ecx как минимум потому что он stdcall

T->hMainHook(0,0,unkA2);

зачем вы туда пихаете edx вам лучше знать
я в оригинальном посте про edx вообще ничего не вижу
Code:
  1. int __thiscall sub_200D7CE0(int this, int a2)
  2. {
  3. int v3; // [sp+8h] [bp-10h]@1
  4. int v4; // [sp+14h] [bp-4h]@1
  5.  
  6. sub_200D6990(this, a2);


у кого есть вагон времени что бы вас обучать и объяснять как, да что, сделать - велкам



Ранг: 71.2 (постоянный), 33thx
Активность: 0.050.12
Статус: Участник

Создано: 14 января 2016 16:15 · Поправил: kunix
· Личное сообщение · #20

bolvai, Я вам подскажу 100% способ, как добиться успеха.
Компилите ваш код, а потом берете в руки отладчик и смотрите, что у вас получилось, и сравниваете с тем, что должно получиться. И никакие форумы не нужны.

И я таки не понял, чем это отличаются detour и trampoline?



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

Создано: 14 января 2016 23:58
· Личное сообщение · #21

все разобрался - спасибо!

надо было поменять stdcall на fastcall int __fastcall AbnormalSleep_hookNew(void * _this, int edx,int unkA2)
{}


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


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