Ykidia Хорошо, значит ты понимаешь что ntvdm это эмулятор и можно проигнорировать. Да. STATUS_INVALID_SYSTEM_SERVICE возвращается если несущестующий сервис вызван, тоесть при вызове сервиса указан его номер, индексирующий дескриптор, находящейся за пределами sst/shadow sst. Не вижу смысла юзоть это. Бред какойто. Регистр Eip увеличится на 2, указывая на следующую за Int2e инструкцию. Нужно соблюдать модель вызова, ты хотябы понимаешь как укозать номер вызываемого сервиса ? Конечно, ведь входные параметры случайны.
Clerk Где именно случайны? EAX я задаю раньше, т.е. EAX тоже задан. А EDX=0, потому что по вышеуказанной ссылке говорится, что если EDX=0, тогда никакие параметры не берутся, а возвращается STATUS_ACCESS_VIOLATION. Это так? Наверное плохо сформулировал, я имел в виду, что EAX я задаю вполне осознанным значением номера функции. Да, это автор статьи как-то перемудрил
Ykidia Edx указывает на параметры сервиса в стеке, ты его обнулил вот и возвращаетсо STATUS_ACCESS_VIOLATION.
Clerk Дык в том-то и дело, что не возвращается! Должно возвратиться либо STATUS_INVALID_SYSTEM_SERVICE (при отсутствии функции), либо STATUS_ACCESS_VIOLATION (при наличии функции), но ничего этого нет, а приходит какая-нибудь лажа, например на одной машине это 0x800000XX (точно не помню) для любого номера функции, на другой - 0x00000004, на третьей - еще один вариант... Я об этом. Что не так делаю?
Ykidia хз нужно в сурцы лезть смотреть, я никогда не юзол дос. Правильно вызов составь и вызывай, хотя наверно сегментные регистры надо подрихтовать.
Не пашет int2E в NTVDM!!!11 Проверял на реверсировоной ф-кцеи Sleep кернела32, который в свю очередь делает хинт в Ntdll (NtDelayExecution), и уже оно юзает Int 2E Так вот... Win32 версия работает и делает задержку, а вот скажем после обработки WDOSx-ом - нифига... Код (Text): program sleepNT; procedure NtDelayExecution; //ZwDelayExecution proc near //; CODE XREF: sub_77F89D5D+3Dp // //; .text:77F8A02Fp ... const arg_0 = {byte ptr} 4; asm mov eax, 32h //; NtDelayExecution lea edx, [esp+arg_0] int 2Eh //; DOS 2+ internal - EXECUTE COMMAND //; DS:SI -> counted CR-terminated command string ret 8 end; //ZwDelayExecution endp procedure sub_77F82890;// proc near ; CODE XREF: _allmul+Ej const arg_0 = {dword ptr} 4; arg_C = {dword ptr} $10; asm push ebx mul ecx mov ebx, eax mov eax, [esp+4+arg_0] mul [esp+4+arg_C] add ebx, eax mov eax, [esp+4+arg_0] mul ecx add edx, ebx pop ebx ret 10h end; //sub_77F82890 endp procedure _allmul; //_allmul proc near ; CODE XREF: sub_77F83340+4Dp // ; sub_77F89C22+88p ... const arg_0 = {dword ptr} 4; arg_4 = {dword ptr} 8; arg_8 = {dword ptr} $0C; arg_C = {dword ptr} $10; asm mov eax, [esp+arg_4] mov ecx, [esp+arg_C] or ecx, eax mov ecx, [esp+arg_8] jnz sub_77F82890 mov eax, [esp+arg_0] mul ecx ret 10h end; //_allmul endp procedure sub_77E86740;// proc near ; CODE XREF: SleepEx+Ep // ; WaitForSingleObjectEx+46p ... const arg_0 = {dword ptr} 4; arg_4 = {dword ptr} 8; //; FUNCTION CHUNK AT 77E8695A SIZE 00000007 BYTES asm cmp [esp+arg_4], 0FFFFFFFFh jz @@loc_77E8695A push 0 push 2710h push 0 push [esp+0Ch+arg_4] call _allmul mov ecx, [esp+arg_0] mov [ecx], eax mov [ecx+4], edx mov eax, [ecx] neg eax adc edx, 0 mov [ecx], eax neg edx mov [ecx+4], edx mov eax, ecx @@locret_77E86776: //; CODE XREF: sub_77E86740+21Cj ret 8 @@loc_77E8695A: //; CODE XREF: sub_77E86740+5j xor eax, eax jmp @@locret_77E86776 end; //sub_77E86740 endp //; DWORD __stdcall SleepEx(DWORD dwMilliseconds, BOOL bAlertable) procedure SleepEx; //SleepEx proc near ; CODE XREF: Sleep+6p Beep+143p const var_8 = {dword ptr} -8; var_4 = {dword ptr} -4; dwMilliseconds = {dword ptr} 8; bAlertable = {dword ptr} $0C; //; FUNCTION CHUNK AT 77EA0894 SIZE 00000010 BYTES //; FUNCTION CHUNK AT 77EB8533 SIZE 00000024 BYTES asm push ebp mov ebp, esp push ecx push ecx push esi push edi push [ebp+dwMilliseconds] lea eax, [ebp+var_8] push eax call sub_77E86740 mov edi, eax test edi, edi jz @@loc_77EB8533 @@loc_77E867A4: //; CODE XREF: SleepEx+31DB9j // mov esi, ds:NtDelayExecution push edi push [ebp+bAlertable] call NtDelayExecution cmp [ebp+bAlertable], 0 jnz @@loc_77EA0894 @@loc_77E867BA: //; CODE XREF: SleepEx+1A112j mov ecx, 0C0h cmp eax, ecx jz @@loc_77EB8550 xor eax, eax @@loc_77E867C9: // ; CODE XREF: SleepEx+31DCBj pop edi pop esi leave ret 8 @@loc_77EB8533: //; CODE XREF: SleepEx+17j and [ebp+var_8], eax mov [ebp+var_4], 80000000h lea edi, [ebp+var_8] jmp @@loc_77E867A4 @@loc_77EA0894: //; CODE XREF: SleepEx+2Dj //; SleepEx+31DC4j cmp eax, 101h jnz @@loc_77E867BA jmp @@loc_77EB8545 @@loc_77EB8550: //; CODE XREF: SleepEx+3Aj mov eax, ecx jmp @@loc_77E867C9 @@loc_77EB8545: //; CODE XREF: SleepEx+1A118j push edi push [ebp+bAlertable] call NtDelayExecution jmp @@loc_77EA0894 end; //SleepEx endp //; void __stdcall Sleep(DWORD dwMilliseconds) // public Sleep //Sleep proc near procedure Sleep; const dwMilliseconds = {dword ptr} 4; asm push 0// ; bAlertable push [esp+4+dwMilliseconds]// ; dwMilliseconds call SleepEx ret 4 //Sleep endp end; // Начало програмы asm push 1000 Call Sleep end. Cудя по тому что творицо в коде, (казалось бы простейшей функции!!), м$ не привыкли искать лёгких и быстрых путей...
Ykidia Верно. Номера зависят от версии винды. И похоже номера ф-ий в пределах WinVer.Major - WinVer.Minor не меняются. Номер ф-ии для каждого варианта Major-Minor легко узнать: берём ntdll.dll от каждой версии окошек и скармливаем их ИДЕ. Смотрим интересующие нас ф-ии и определеяем их системные номера. У меня была как то идея определения версии Major-Minor вот таким способом: Код (Text): function i2SysCall(sysfunc: DWORD): DWORD; assembler; // EAX = sysfunc asm xor ecx, ecx push ecx // 3C push ecx // 38 push ecx // 34 push ecx // 30 push ecx // 2C push ecx // 28 push ecx // 24 push ecx // 20 push ecx // 1C push ecx // 18 push ecx // 14 push ecx push ecx push ecx push ecx db $E8, 02, 00, 00, 00 // call $+7 jmp @next lea edx, dword ptr ss:[esp+4] int $2E // sys call db $C2, $3C, $00 // retn $3C @next: end; var i, res: Cardinal; winver: Byte; begin winver := 0; for i:=$0190 downto $00F7 do begin res := i2SysCall(i); if res <> STATUS_INVALID_SYSTEM_SERVICE then begin if i > $018D then winver := 61 else // 0190 = последняя команда в win61 6801 if i > $011B then winver := 60 else // 018D = последняя команда в win60 SP0 if i > $00F7 then winver := 51 else // 011B = последняя команда в win51 SP1 SP2 SP3 if i = $00F7 then winver := 50; // 00F7 = последняя команда в win50 SP4 if winver > 0 then Break; end; end; Writeln('winver = ', winver); end; Но так и не решился заюзать такое "определение" версии окошек. Слишком стрёмно.
А.. соори, не розобралсо... Как выеснелос венда делает подмену IDT в режиме работы подсистемы NTVDM, в принципе это не мешает юзать SYSENTER в 32-битных NTVDM прогах (для связи напр. с дровом предоставляющим дополнительные возможности)... Хоть вкусняшка, и свободно доступна в win2к, однако Sice 4.05, уходит на ней в синьку Старые добрые Int-ы получше будут.. да.