Code (Text): lea edi, [ebp + x] lea eax, [edi + 3] and eax, 0FFFFFFFCh mov esi, ds:InitializeCriticalSection push eax call esi как соотносится структура x и RTL_CRITICAL_SECTION ?
Структуры x нет, есть только RTL_CRITICAL_SECTION. Просто перед вызовом идёт выравнивание edi на четырёхбайтовую границу.
в таком коде Code (Text): model flat, stdcall struc X fied_0 dd z dd field_8 dd 10 dup(?) X ends fun proto: x:X lea edi, [x + X.z] lea eax, [edi + 3] and eax, 0FFFFFFFCh mov esi, ds:InitializeCriticalSection push eax call esi fun endp структура X выглядит так? Code (Text): struc X fied_0 dd z RTL_CRITICAL_SECTION ... X ends
Код написан на Си и "структура" там выглядит так: struct X { RTL_CRITICAL_SECTION CriticalSection; ... };
критическая секция является частью большей структуры. вопрос - начало RTL_CRITICAL_SECTION расположено по смещению 4 или 0? и ради интереса, такое обращение к критической секции это какой-то антиотладочный приём или особенности кодогенерации?
Нет. Начало RTL_CRITICAL_SECTION расположено по смещению x, где 0 <= x <= 3 -- число байт, нехватающих до выравнивания адреса до кратного четырём. Если структура X расположена по адресу xxx0, xxx4, xxx8 или xxxC, то x = 0. Если по xxx1, xxx5, xxx7, xxxD, то x = 3 и т.д.
Особенности кодогенерации. Правда мне не понятно почему компилятор вставил такой стаб - по умолчанию в Си все локальные переменные и члены структур выравниваются на четырёхбайтовую границу (в 32-хбитных системах). Если вы хотите написать аналог на ассемблере, выглядеть будет так: Code (Text): lea edi, [ebp + x] push edi call InitializeCriticalSection Но нужно тогда убедиться что edi делится без остатка на 4, если делиться не будет, то фунцкии для работы CRITICAL_SECTION будут работать некорректно.
Code (Text): struct A { BYTE z[0x17]; X x; }; структура A создаётся оператором new, X - вышеобсуждаемая структура, значит ли это, что смещение равно 1? Ezrah большое спасибо
Видимо так оно и есть. Но я был уверен, что X уже будет выравнена путём добавления "пустых" байтов перед X x. Видимо, компилятор думает по-другому. Рад помочь.
ну видимо было так: Code (Text): #pragma pack (push, 1) struct A { BYTE z[0x17]; X x; }; #pragma pack (pop)
Сомневаюсь. Однако, не могу опровергнуть. Можно, в принципе, поэкспериментировать и посмотреть, что получается на выходе. Кстати, если , то как переменные оказываются на стеке?
это же указатель на структуру, а не структура Code (Text): struct A { BYTE z[0x17]; X x; }; void stdcall foo(A *a) { InitializeCriticalSection(&a->x.CritSec); }; void main() { A *a = new A(); foo(a); }
Code (Text): .text:007940C8 228 push size A ; nBytes = 0xE44 .text:007940CD 22C call new .text:007940D2 22C add esp, 4 .text:007940D5 228 cmp eax, zero .text:007940D7 228 jz short allocation_failed_2 .text:007940D9 228 push eax ; this .text:007940DA 22C call A_ctor .text:00792660 ; A *__stdcall A_ctor(A *this) .text:00792660 A_ctor proc near .text:00792660 .text:00792660 this = dword ptr 4 .text:00792660 .text:00792660 this_0 = ebp .text:00792660 000 push ebx .text:00792661 004 push this_0 .text:00792662 008 mov this_0, [esp+8+this] .text:00792666 008 push esi .text:00792667 00C mov esi, ds:InitializeCriticalSection_0 .text:0079266D 00C push edi .text:0079266E 010 xor ebx, ebx .text:00792670 010 lea edi, [this_0+1Bh] .text:00792673 010 mov dword ptr [this_0+4], offset aModule ; "module" .text:0079267A 010 mov [this_0+8], bl .text:0079267D 010 mov byte ptr [this_0+12h], 1 .text:00792681 010 mov [this_0+9], bl .text:00792684 010 mov [this_0+0Ah], ebx .text:00792687 010 mov [this_0+0Eh], ebx .text:0079268A 010 mov dword ptr [this_0+13h], offset off_F1ACB0 .text:00792691 010 mov dword ptr [this_0+17h], offset `__vtable__'[XBase] .text:00792698 010 lea eax, [edi+3] .text:0079269B 010 and eax, 0FFFFFFFCh .text:0079269E 010 mov dword ptr [this_0+0], offset off_F1AA50 .text:007926A5 010 mov dword ptr [this_0+13h], offset off_F1AAD0 .text:007926AC 010 mov dword ptr [this_0+17h], offset `__vtable__'[X] .text:007926B3 010 push eax ; lpCriticalSection .text:007926B4 014 mov dword ptr [edi+28h], offset aObjectmanager ; "ObjectManager" .text:007926BB 014 call esi ; InitializeCriticalSection_0 вот кусок вызывающей функции и кусок вызывемой. на первый взгляд выглядит, что по смещению 0x17 расположен указатель на таблицу виртальных методов