#1 01-01-2013 14:49

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Exception handler?

Не получается вызвать функцию, которая использует "обработку исключений".

.text:005C1F50     ; CFxSystem *__thiscall CParticleData__RegisterFxSystem(CParticleData *list, char *flname, FILE *file)
.text:005C1F50     CParticleData__RegisterFxSystem proc near
.text:005C1F50                                             ; CODE XREF: CParticleData__ReadEffectsFile+140p
.text:005C1F50
.text:005C1F50     var_120         = byte ptr -120h
.text:005C1F50     param           = dword ptr -114h
.text:005C1F50     var_110         = dword ptr -110h
.text:005C1F50     var_10C         = byte ptr -10Ch
.text:005C1F50     var_C           = dword ptr -0Ch
.text:005C1F50     var_4           = dword ptr -4
.text:005C1F50     flname          = dword ptr  4
.text:005C1F50     file            = dword ptr  8
.text:005C1F50
.text:005C1F50 000                 push    0FFFFFFFFh
.text:005C1F52 004                 push    offset _eh_handler_5c1f50
.text:005C1F57 008                 mov     eax, large fs:0
.text:005C1F5D 008                 push    eax
.text:005C1F5E 00C                 mov     large fs:0, esp
.text:005C1F65 00C                 sub     esp, 108h
.text:005C1F6B 114                 push    ebx
.text:005C1F6C 118                 mov     ebx, [esp+118h+file]
.text:005C1F73 118                 push    esi
.text:005C1F74 11C                 push    edi
.text:005C1F75 120                 push    100h            ; int
.text:005C1F7A 124                 lea     eax, [esp+124h+var_10C]
.text:005C1F7E 124                 push    eax             ; char *
.text:005C1F7F 128                 push    ebx             ; FILE *
.text:005C1F80 12C                 mov     edi, ecx
.text:005C1F82 12C                 call    j_CFileMgr__GetLine

Два параметра в стеке, один в ecx.

.text:005C2555     loc_5C2555:                             ; CODE XREF: CParticleData__ReadEffectsFile+19Dj
.text:005C2555 210                 mov     eax, [esp+210h+fileName]
.text:005C255C 210                 push    ebx             ; file
.text:005C255D 214                 push    eax             ; fileName
.text:005C255E 218                 mov     ecx, ebp        ; this
.text:005C2560 218                 call    CParticleData__RegisterFxSystem

Обьявляю так (__thiscall в VC++ можно обьявить только в классе):

CFxSystem *(__fastcall *_RegisterFxSystem)(CParticleData *particleData, int i, const char *filename, FILE *file) = 
    (CFxSystem *(__fastcall *)(CParticleData *, int, const char *, FILE *)) 0x5C1F50;

Вызов (без вызова вылета нет):

int RegisterFxSystem(const char* filename, FILE *file)
{
    int i;
    fpos_t pos;
    char lineBuf[256], buf[8], name[32];

    fgetpos(file, &pos);
    for(i=0; i<4; i++)
        fgets(lineBuf, 256, file);
    sscanf(lineBuf, "%s %s", buf, name);
    if(!FindFxSystemByName(g_PrtData, 0, name))
    {
        if(g_Debug)
        {
            for(i=0; i<30; i++)
            {
                if(name[i] == '\0')
                {
                    while(i<31)
                    {
                        name[i] = ' ';
                        i++;
                    }
                }
            }
            sprintf(lineBuf, "  fx system %s loaded from ""%s""\n", name, filename);
            fputs(lineBuf, g_DebugFile);
            g_DebugNumEffects++;
        }
        fsetpos(file, &pos);
        _RegisterFxSystem(g_PrtData, i, filename, file);
        return TRUE;
    }
    if(g_Debug)
    {
        sprintf(lineBuf, "!fx system %s WAS NOT loaded from ""%s"" because it was already loaded\n", name, filename);
        fputs(lineBuf, g_DebugFile);
    }
    return FALSE;
}

Вылетают получаю в ntdll.dll:

771D8C16  mov         eax,ecx  
771D8C18  sub         eax,edx  
771D8C1A  mov         ebx,eax  
771D8C1C  mov         eax,ecx  
771D8C1E  lock cmpxchg dword ptr [edi],ebx  
771D8C22  cmp         eax,ecx  
771D8C24  jne         771D8A82  
771D8C2A  xor         eax,eax  
771D8C2C  mov         dword ptr [ebp+0Ch],eax  
771D8C2F  mov         dword ptr [ebp+8],eax  
771D8C32  mov         eax,dword ptr [esi]  
771D8C34  cmp         eax,0FFFFFFFFh  
771D8C37  je          771D8C3C  
771D8C39  inc         dword ptr [eax+14h]  //////////////////////////////// В EAX - 0
771D8C3C  mov         ebx,dword ptr [ebp-0Ch]  
771D8C3F  mov         edi,dword ptr [ebp-10h]  
771D8C42  cmp         byte ptr ds:[7FFE0382h],0  
771D8C49  jne         7722259B  
771D8C4F  mov         eax,dword ptr [ebp-4]  
771D8C52  push        edi  
771D8C53  push        0  
771D8C55  cmp         eax,0FFFFFFFFh  
771D8C58  je          772225F3  
771D8C5E  push        eax  
771D8C5F  call        771BF85C  
771D8C64  cmp         eax,102h

38001440.png

89999614.png

Last edited by DK22Pac (01-01-2013 14:51)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#2 02-08-2013 18:59

VintProg_Pro
Registered: 17-06-2010
Posts: 153

Re: Exception handler?

CFxSystem *(__thiscall *_RegisterFxSystem)(CParticleData *particleData, int i, const char *filename, FILE *file) =     (CFxSystem *(__thiscall *)(CParticleData *, int, const char *, FILE *)) 0x5C1F50;

Если объявить так, то имей введу, что перед вызовом, надо каким-то образом передать указатель на объект в регистр ecx.

DWORD address;  //Сюда присваиваем наш адрес объекта через 
__asm mov ecx, address;
_RegisterFxSystem(&particleData, i, filename, &file);

Что-то должно выглядеть так. Ибо функция начинает обращаться регистру ecx, где вообще нету нашего адреса нужного объекта.

Last edited by VintProg_Pro (02-08-2013 19:00)

Offline

#3 05-08-2013 12:29

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Exception handler?

__thiscall * мобжно объявлять где угодно. первый параметр автоматом пойдет в ECX.

__fastcall - это совсем не то (два параметра в регистрах). Вылет - по рассыпанию стека из-за несовпадения ожидаемого и реального количества параметров на стеке


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

#4 05-08-2013 14:50

Alien
Registered: 12-10-2008
Posts: 564

Re: Exception handler?

Из разряда грязных хаков, fastcall можно использовать для более или менее компиляторо-независимого вызова MSVC методов:

void __fastcall a_method(void *obj, int dummy, int param1, ...)

Могу ошибаться, т.к. говорю на память, но в этом случае первый параметр передается в ecx, второй в eax - а он все равно clobbered для метода...

Offline

#5 05-08-2013 15:03

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Exception handler?

Мне еще ни разу не приходилось пользоваться fastcall. Обычные методы либо cdecl, либо stdcall, либо thiscall, а то, что генерируется линкером, обычно получает параметры так, что без declspec(naked) не обойтись (тем более, что о сохранении регистров там тоже стоит позаботиться самому).

auto _RegisterFxSystem = reinterpret_cast<CFxSystem * (__thiscall *)(CParticleData *particleData, const char *filename, FILE *file)>(0x5C1F50);

PS. Я, кстати, научился инжектить нормально методы, так что последняя часть соответствующей статьи будет дописана (не прошло и пяти лет)


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

#6 05-08-2013 15:27

Alien
Registered: 12-10-2008
Posts: 564

Re: Exception handler?

@listener's PS - учитывая Ваш огромный опыт на этом поприще, было бы очень интересно почитать.
PS. Если "стол заказов" еще работает, то хотелось бы еще что-нибудь про ABI "альтернативных" платформ (PPC, ARM).:blush:

Offline

#7 05-08-2013 23:55

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Exception handler?

listener, увы, но проблема тут не в этом.
Стек не рассыпается, так как я заведомо передаю вторым дамми-параметр.
Получается такая картина:

CFxSystem *(__fastcall *_RegisterFxSystem)(CParticleData *_ecx, int _edx, const char *filename, FILE *file)

А вообще, я уже позже и как __thiscall пробовал вызывать, и используя asm-вставку.
Я уже пытался переписывать всё дерево этих функций, начиная от _RegisterFxSystem и далее. Но когда дошло до того, что мне нужно было обьявлять ~30 классов (для каждого из видов эмиттеров партиклов), со своими методами, - я сдался.
PS разве дамп-информация не говорит о том, что вылет происходит из-за того, что функция "прошита" exception-handler'ом?

Last edited by DK22Pac (05-08-2013 23:56)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#8 06-08-2013 14:19

listener
From: Vice City
Registered: 09-11-2006
Posts: 615
Website

Re: Exception handler?

@Alien - Не надо на "Вы" - я чувствую себя от этого древним и ветхим.
Заказ принят. С ARM я сам особо не разбирался (это еще впереди: нужно будет покопаться CTW/iOS и VC/iOS), а вот очередная часть по PPC будет точно, предположительно, где-то в районе выхода пятерки.

@DK22Pac - Хорошо, доберусь до дома, попробую заглянуть в базу (у меня с собой ее нет). exception-handlerы, если не происходит исключения, ничем не отличаются от любых других функций. Место в ntdll гораздо больше похоже на случайное, чем на обработчик исключения (точно можно сказать, если включить в студии загрузку  debug-info с микрософтовских серверов)


C5 - GTA IV/RDR/GTA V script compiler.
~ 60% done.

Offline

Board footer

Powered by FluxBB