Привет всем. Не был уверен в какую ветку ложить, поэтому пишу сюда. Пытаюсь вызвать компилированную функцию (а именно <critInf>) из инъектированной библиотеки, написанной на c++. Целевое приложение, вероятно, писалось на MSVС 7+. Кусок кода, содержащий функцию выглядит так (захватил с запасом, на всякий): Код (Text): 0047AF90 . 84DB test bl, bl 0047AF92 . 0F85 44010000 jnz 0047B0DC 0047AF98 . 8B8E D87A0000 mov ecx, dword ptr [esi+7AD8] 0047AF9E . 8B96 F4830000 mov edx, dword ptr [esi+83F4] 0047AFA4 . 8B86 DC7A0000 mov eax, dword ptr [esi+7ADC] 0047AFAA . 03D1 add edx, ecx 0047AFAC . 895424 5C mov dword ptr [esp+5C], edx 0047AFB0 . 8B96 F8830000 mov edx, dword ptr [esi+83F8] 0047AFB6 . 03D0 add edx, eax 0047AFB8 . 895424 60 mov dword ptr [esp+60], edx 0047AFBC . 8B96 FC830000 mov edx, dword ptr [esi+83FC] 0047AFC2 . 03D1 add edx, ecx 0047AFC4 . 8B8E 00840000 mov ecx, dword ptr [esi+8400] 0047AFCA . 6A FF push -1 0047AFCC . 6A 00 push 0 0047AFCE . 03C8 add ecx, eax 0047AFD0 . 68 80000000 push 80 0047AFD5 . 894C24 74 mov dword ptr [esp+74], ecx 0047AFD9 . 6A 4D push 4D 0047AFDB . 8BCD mov ecx, ebp 0047AFDD . 895424 74 mov dword ptr [esp+74], edx 0047AFE1 . E8 8AFCF9FF call <critInf> ;искомая функция. тип декларации не могу определить, пробовал cdecl stdcall, оба выдают rtc failure 0047AFE6 . 50 push eax 0047AFE7 . 68 11100000 push 1011 0047AFEC . 56 push esi 0047AFED . E8 1EB9FBFF call <prinID> ;print by value and text id - тут вроде понятно, классичекий cdecl 0047AFF2 . 83C4 0C add esp, 0C В c++ я пытаюсь ее описать так: Код (Text): typedef DWORD (cdecl *GETCRITINFO)(DWORD a,DWORD b,DWORD c,DWORD d); GETCRITINFO getcritinfo; И соответственно вызываю с параметрами из первого листинга: Код (Text): getcritinfo(0x80,0x4d,0,-1); Листинг самой функции выглядит так: Код (Text): 0041AC70 <critInf> /$ 56 push esi 0041AC71 |. 57 push edi 0041AC72 |. 8B7C24 0C mov edi, dword ptr [esp+C] 0041AC76 |. 8B04BD 980B90>mov eax, dword ptr [edi*4+900B98] 0041AC7D |. 8BF1 mov esi, ecx 0041AC7F |. 85C0 test eax, eax 0041AC81 |. 74 5E je short 0041ACE1 0041AC83 |. 837E 24 10 cmp dword ptr [esi+24], 10 0041AC87 |. 72 05 jb short 0041AC8E 0041AC89 |. 8B4E 10 mov ecx, dword ptr [esi+10] 0041AC8C |. EB 03 jmp short 0041AC91 0041AC8E |> 8D4E 10 lea ecx, dword ptr [esi+10] 0041AC91 |> 51 push ecx 0041AC92 |. 68 48CE5B00 push 005BCE48 ; ASCII "CCritter::GetParam : " 0041AC97 |. 50 push eax 0041AC98 |. E8 E3E30900 call 004B9080 0041AC9D |. 83C4 0C add esp, 0C 0041ACA0 |. 84C0 test al, al 0041ACA2 |. 74 3D je short 0041ACE1 0041ACA4 |. 56 push esi 0041ACA5 |. E8 26CF0900 call 004B7BD0 0041ACAA |. 83C4 04 add esp, 4 0041ACAD |. 80BF 702C9000>cmp byte ptr [edi+902C70], 0 0041ACB4 |. 74 09 je short 0041ACBF 0041ACB6 |. 8B04BD E02A90>mov eax, dword ptr [edi*4+902AE0] 0041ACBD |. EB 02 jmp short 0041ACC1 0041ACBF |> 33C0 xor eax, eax 0041ACC1 |> 8BCF mov ecx, edi 0041ACC3 |. 2BC8 sub ecx, eax 0041ACC5 |. 51 push ecx 0041ACC6 |. E8 A5CE0900 call 004B7B70 0041ACCB |. 83C4 04 add esp, 4 0041ACCE |. E8 3DCF0900 call 004B7C10 0041ACD3 |. 84C0 test al, al 0041ACD5 |. 74 0A je short 0041ACE1 0041ACD7 |. E8 C4CF0900 call 004B7CA0 0041ACDC |. 5F pop edi 0041ACDD |. 5E pop esi 0041ACDE |. C2 0400 retn 4 0041ACE1 |> 83FF 4B cmp edi, 4B ; Switch (cases 0..4B) 0041ACE4 |. 0F87 F2000000 ja 0041ADDC 0041ACEA |. 0FB697 A0AE41>movzx edx, byte ptr [edi+41AEA0] 0041ACF1 |. FF2495 50AE41>jmp dword ptr [edx*4+41AE50] 0041ACF8 |> 8BCE mov ecx, esi ; Case 0 of switch 0041ACE1 0041ACFA |. E8 71EEFFFF call 00419B70 0041ACFF |. 5F pop edi 0041AD00 |. 5E pop esi 0041AD01 |. C2 0400 retn 4 0041AD04 |> 8BCE mov ecx, esi ; Case 1 of switch 0041ACE1 0041AD06 |. E8 C5EEFFFF call 00419BD0 0041AD0B |. 5F pop edi 0041AD0C |. 5E pop esi 0041AD0D |. C2 0400 retn 4 0041AD10 |> 8BCE mov ecx, esi ; Case 2 of switch 0041ACE1 0041AD12 |. E8 19CBFFFF call 00417830 0041AD17 |. 5F pop edi 0041AD18 |. 5E pop esi 0041AD19 |. C2 0400 retn 4 0041AD1C |> 8BCE mov ecx, esi ; Case 3 of switch 0041ACE1 0041AD1E |. E8 3DCBFFFF call 00417860 0041AD23 |. 5F pop edi 0041AD24 |. 5E pop esi 0041AD25 |. C2 0400 retn 4 0041AD28 |> 8BCE mov ecx, esi ; Case 4 of switch 0041ACE1 0041AD2A |. E8 F1EEFFFF call 00419C20 0041AD2F |. 5F pop edi 0041AD30 |. 5E pop esi 0041AD31 |. C2 0400 retn 4 0041AD34 |> 8BCE mov ecx, esi ; Case 5 of switch 0041ACE1 0041AD36 |. E8 55CBFFFF call 00417890 0041AD3B |. 5F pop edi 0041AD3C |. 5E pop esi 0041AD3D |. C2 0400 retn 4 0041AD40 |> 8BCE mov ecx, esi ; Case 6 of switch 0041ACE1 0041AD42 |. E8 79CBFFFF call 004178C0 0041AD47 |. 5F pop edi 0041AD48 |. 5E pop esi 0041AD49 |. C2 0400 retn 4 0041AD4C |> 8BCE mov ecx, esi ; Case 7 of switch 0041ACE1 0041AD4E |. E8 9DCBFFFF call 004178F0 0041AD53 |. 5F pop edi 0041AD54 |. 5E pop esi 0041AD55 |. C2 0400 retn 4 0041AD58 |> 8BCE mov ecx, esi ; Case C of switch 0041ACE1 0041AD5A |. E8 51EFFFFF call 00419CB0 0041AD5F |. 5F pop edi 0041AD60 |. 5E pop esi 0041AD61 |. C2 0400 retn 4 0041AD64 |> 8BCE mov ecx, esi ; Case 8 of switch 0041ACE1 0041AD66 |. E8 B5CBFFFF call 00417920 0041AD6B |. 5F pop edi 0041AD6C |. 5E pop esi 0041AD6D |. C2 0400 retn 4 0041AD70 |> 8BCE mov ecx, esi ; Case 9 of switch 0041ACE1 0041AD72 |. E8 39D1FFFF call 00417EB0 0041AD77 |. 5F pop edi 0041AD78 |. 5E pop esi 0041AD79 |. C2 0400 retn 4 0041AD7C |> 8BCE mov ecx, esi ; Case A of switch 0041ACE1 0041AD7E |. E8 ADEFFFFF call 00419D30 0041AD83 |. 5F pop edi 0041AD84 |. 5E pop esi 0041AD85 |. C2 0400 retn 4 0041AD88 |> 8BCE mov ecx, esi ; Case B of switch 0041ACE1 0041AD8A |. E8 D1EEFFFF call 00419C60 0041AD8F |. 5F pop edi 0041AD90 |. 5E pop esi 0041AD91 |. C2 0400 retn 4 0041AD94 |> 8BCE mov ecx, esi ; Case D of switch 0041ACE1 0041AD96 |. E8 D5CBFFFF call 00417970 0041AD9B |. 5F pop edi 0041AD9C |. 5E pop esi 0041AD9D |. C2 0400 retn 4 0041ADA0 |> 8BCE mov ecx, esi ; Case E of switch 0041ACE1 0041ADA2 |. E8 19CCFFFF call 004179C0 0041ADA7 |. 5F pop edi 0041ADA8 |. 5E pop esi 0041ADA9 |. C2 0400 retn 4 0041ADAC |> 8BCE mov ecx, esi ; Case F of switch 0041ACE1 0041ADAE |. E8 5DCCFFFF call 00417A10 0041ADB3 |. 5F pop edi 0041ADB4 |. 5E pop esi 0041ADB5 |. C2 0400 retn 4 0041ADB8 |> 8BCE mov ecx, esi ; Case 1E of switch 0041ACE1 0041ADBA |. E8 81CCFFFF call 00417A40 0041ADBF |. 5F pop edi 0041ADC0 |. 5E pop esi 0041ADC1 |. C2 0400 retn 4 0041ADC4 |> 8BCE mov ecx, esi ; Case 1F of switch 0041ACE1 0041ADC6 |. E8 C5CCFFFF call 00417A90 0041ADCB |. 5F pop edi 0041ADCC |. 5E pop esi 0041ADCD |. C2 0400 retn 4 0041ADD0 |> 8BCE mov ecx, esi ; Case 4B of switch 0041ACE1 0041ADD2 |. E8 B968FEFF call 00401690 0041ADD7 |. 5F pop edi 0041ADD8 |. 5E pop esi 0041ADD9 |. C2 0400 retn 4 0041ADDC |> 8D47 E9 lea eax, dword ptr [edi-17] ; Default case of switch 0041ACE1 0041ADDF |. 83F8 06 cmp eax, 6 0041ADE2 |. 77 10 ja short 0041ADF4 0041ADE4 |. 83C7 EA add edi, -16 0041ADE7 |. 57 push edi 0041ADE8 |. 8BCE mov ecx, esi 0041ADEA |. E8 51D1FFFF call 00417F40 0041ADEF |. 5F pop edi 0041ADF0 |. 5E pop esi 0041ADF1 |. C2 0400 retn 4 0041ADF4 |> 8D4F F0 lea ecx, dword ptr [edi-10] 0041ADF7 |. 83F9 06 cmp ecx, 6 0041ADFA |. 77 10 ja short 0041AE0C 0041ADFC |. 83C7 F1 add edi, -0F 0041ADFF |. 57 push edi 0041AE00 |. 8BCE mov ecx, esi 0041AE02 |. E8 89D3FFFF call 00418190 0041AE07 |. 5F pop edi 0041AE08 |. 5E pop esi 0041AE09 |. C2 0400 retn 4 0041AE0C |> 3B3D B84E6200 cmp edi, dword ptr [624EB8] 0041AE12 |. 72 15 jb short 0041AE29 0041AE14 |. 3B3D BC4E6200 cmp edi, dword ptr [624EBC] 0041AE1A |. 77 0D ja short 0041AE29 0041AE1C |. 57 push edi 0041AE1D |. 8BCE mov ecx, esi 0041AE1F |. E8 1CD6FFFF call 00418440 0041AE24 |. 5F pop edi 0041AE25 |. 5E pop esi 0041AE26 |. C2 0400 retn 4 0041AE29 |> 3B3D F04E6200 cmp edi, dword ptr [624EF0] 0041AE2F |. 72 15 jb short 0041AE46 0041AE31 |. 3B3D F44E6200 cmp edi, dword ptr [624EF4] 0041AE37 |. 77 0D ja short 0041AE46 0041AE39 |. 57 push edi 0041AE3A |. 8BCE mov ecx, esi 0041AE3C |. E8 4FD0FFFF call 00417E90 0041AE41 |. 5F pop edi 0041AE42 |. 5E pop esi 0041AE43 |. C2 0400 retn 4 0041AE46 |> 8B44BE 78 mov eax, dword ptr [esi+edi*4+78] ; return value 0041AE4A |. 5F pop edi 0041AE4B |. 5E pop esi 0041AE4C \. C2 0400 retn 4 0041AE4F 90 nop Ключевые слова: Cpp Function-call Conventions MASM
А посты редактировать нельзя. Регистрация нагло врет =) Собственно сам вопрос - как правильно организовать вызов функции<critInf>?
Судя по: 0041AE4C \. C2 0400 retn 4 и началу ф-ии это stdcall. Высчитываем адрес относительно модуля, делаем call. В чем проблема?
Ну, я как всегда, невнимательно прочитал, что надо . Во-первых, у ф-ии critInf одинпараметр, а не четыре. Во-вторых, как я уже сказал, stdcall.
Mika0x65, большое спасибо. Блин! Точно же один параметр. Надо было код нормально разобрать. А есть идеи - зачем перед этим в стэк кладутся:-1, 0 и 0х80? Код (Text): 0047AFCA . 6A FF push -1 0047AFCC . 6A 00 push 0 0047AFCE . 03C8 add ecx, eax 0047AFD0 . 68 80000000 push 80 0047AFD5 . 894C24 74 mov dword ptr [esp+74], ecx 0047AFD9 . 6A 4D push 4D 0047AFDB . 8BCD mov ecx, ebp 0047AFDD . 895424 74 mov dword ptr [esp+74], edx 0047AFE1 . E8 8AFCF9FF call <critInf> ;искомая функция. тип декларации не могу определить, пробовал cdecl stdcall, оба выдают rtc failure
Зачем в стек кладутся я точно не знаю, м.б. потом как-то используются. Кстати, сейчас посмотрел внимательнее, это может быть и thiscall -- перед вызовом ф-ии есть: 0047AFDB . 8BCD mov ecx, ebp А в самой ф-ии: Код (Text): 0041AC7D |. 8BF1 mov esi, ecx 0041AC7F |. 85C0 test eax, eax 0041AC81 |. 74 5E je short 0041ACE1 0041AC83 |. 837E 24 10 cmp dword ptr [esi+24], 10 Так что для успешного вызова надо либо на ассемблере написать (что проще), либо на С++ вызывать (но тут уже класс надо делать и т.д.)
В виде: Код (Text): typedef DWORD (__stdcall *GETCRITINFO)(DWORD d); OutpuDebugA("getcritinfo: %u",getcritinfo(0x4c)); Выдает совершенно не то, что должно. thiscall вроде подразумевает же, что нет параметров? Прошу прощения, а как сделать вызов в виде ассемблерной вставки? Просто ни разу еще этого не делал.
Имеется в виду, что для ф-ий с переменным числом параметров this передается немного по-другому, через стек. Здесь же число параметров известно, поэтому this передается в ecx. Чтобы вызвать такую ф-ию (точнее, это метод объекта), надо знать, адрес какого объекта содержится в ebp. Адрес может быть динамическим, что немного усложняет задачу. Тут возможны такие варианты: 1. Самое простое: объект статический, живет в секции данных. Просто берем адрес. 2. Сложнее: объект динамический, создается с помощью new, но указатель сохраняется в секции данных. Берем указатель. 3. Почти самое неприятное: объект динамический, создается с помощью new, указатель сохраняется в стеке. Это уже задача не из легких, вероятно, самое простое -- перехватить ф-ию malloc и анализировать адрес возврата, но тут могут быть подводные камни. 4. Самое неприятное: объект создается в стеке. Тут, думаю, надо перехватить ф-ию, которая его создает, чтобы сохранить адрес где-то в глобальной переменной, а по выходу из ф-ии этот адрес обнулять, например. Может быть можно перехватить уже существующую ф-ию. В общем, вариантов может быть много, решение сильно зависит от ситуации.
Адрес хранения экземпляра (точнее указатель на него) при каждом запуске я знаю. Допустим кладу этот значение в ekzAdress. Тогда как правильней оформить этот вызов в виде:
*на правах редактирования ошибок в предыдущем посте. Адрес хранения экземпляра (точнее указатель на него) при каждом запуске я знаю. Допустим, кладу этот значение в ekzAdress. Тогда как правильней оформить вызов этого метода в виде ассемблерной вставки: Код (Text): DWORD getCritInfo(DWORD this, DWORD param) { DWORD retVal=0; _asm{ push param) mov ecx, this mov dword ptr [esp+74], edx call <critInf> mov retVal,eax; } return retval; } dword aliluya=getCritInfo(ekzAdress,0x4c);
crit* obj_ptr; // адрес объекта известен struct crit { typedef unsigned (__thiscall crit::* critInfo)(unsigned); }; void* critInfoRawAddress = (void*)0x41AC70; crit::critInfo mf_ptr = *reinterpret_cast<crit::critInfo*>(&critInfoRawAddress); (obj_ptr->*mf_ptr)(0x4d);
J0E, большое спасибо, было действительно интересно узнать как это сделать по-взрослому. Mika0x65, спасибо за потраченное время и понимание. Для истории - я остановился на таком варианте вызова: Код (Text): DWORD getCritInfo(DWORD _this, DWORD param) { __asm push param __asm mov ecx, _this __asm call <critInfo> //function raw adress }