Какими несколькими инструкциями можно заменить CreateFIle(...)? Чтобы потом,дизассемблируя код,нельзя было так просто вычленить "кусок" с созданием хендла? Может,кто-нибудь сталкивался?Заранее спасибо
Cr4sh +1. еще добавить самомодифицирующийся код в этом районе, чтобы инструкции в окресности INT 2E генерились на ходу и выполнялись под оберткой антиотладочных приемов.
Большое спасибо за быстрый ответ,но сам я не настолько искушен в ассемблере, а в имеющейся у меня литературе не нашел описания прерывания 2Eh. Где можно про него прочитать?Или,может,у кого-нибудь листинг есть? Хэндл мне нужен, чтоб запретить доступ другим программам к файлу исполняемого экзешника, вызов такой: hF=CreateFile("имя файла",GENERIC_EXECUTE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
Это интерфейс взаимодействия с ядром, наряду с SYSENTER. В первых версиях NT был именно этот интерфейс. Все native-api вызывались именно через int 2e. Потом, с появлением инструкции SYSENTER в системе команд процессоров, специально для этого предназначенной, стала использоваться именно она (насколько я знаю, начиная толи с XP, толи с 2000й). А INT 2E так и остался для совместимости. Про архитектуру Windows в курсе? Рассмотрю на примере CreateFile. CreateFile из kernel32.dll является оберткой над Native API Nt(Zw)CreateFile из ntdll.dll Native API из ntdll.dll вызывает соответствующую API из ядра через гейт INT 2E / SYSENTER. В ядре инициируется менеджер ввода-вывода и посылает IRP_MJ_CREATE соответствующему драйверу. Остальное не интересно Так вот, открываешь отладчик и останавливаешься внутри CreateFile на команде CALL NTDLL.ZwCreateFile Смотрим, что же внутри: 7C90D682 >/$ B8 25000000 MOV EAX,25 7C90D687 |. BA 0003FE7F MOV EDX,7FFE0300 7C90D68C |. FF12 CALL DWORD PTR DS:[EDX] 7C90D68E \. C2 2C00 RETN 2C 25h - это номер сискала ZwCreateFile в ядре в таблице SSDT 7FFE0300 - это адрес переменной нтддл, где лежит адрес шлюза для SYSENTER, в чем можно убедиться, зайдя в него: 7C90EB8B >/$ 8BD4 MOV EDX,ESP 7C90EB8D |. 0F34 SYSENTER Но в NTDLL.DLL опять же для совместимости оставлен и старый шлюз для INT 2E. Его легко найти, и он находится по соседству с SYSENTER: 7C90EBA5 >/$ 8D5424 08 LEA EDX,DWORD PTR SS:[ESP+8] 7C90EBA9 |. CD 2E INT 2E 7C90EBAB \. C3 RETN Таким образом, для вызова INT 2E нужно поместить: EDX - указатель на параметры EAX - номер сискола Таким образом, через INT 2E можно вызвать Native API, минуя ntdll.
Спасибо за такой развернутый ответ-очень интересно! Возник вопрос-как параметры передавать?Т.е. я понял,что надо в EDX заносить содержащий их адрес,но сами параметры какие?Те же,что скидываются в стек при вызове call CreateFileA? Их загнать в массив DWORD'ов или как? Попробовал нарыть инфу про 2e в других источниках-встретил только как вызывать выполнение команды DOS...
нет, параметры у ZwCreateFile свои. Смотри документацию по Native API. Код (Text): NTSTATUS ZwCreateFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength ); Ну не совсем если пишешь на си, то могу дать некоторые стабы для использования.
Код (Text): // // Fast system call using INT 2E // __declspec(naked) FastSystemCall( ) { __asm { lea edx, dword ptr ss:[esp+8] int 0x2e ret } } DWORD dwNtCreateFileCtlServiceNum; // // Perform NtCreateFile call // __declspec(naked) NTSTATUS WINAPI Int2eNtCreateFile(...) { __asm { MOV EAX, dword ptr [dwNtCreateFileCtlServiceNum] CALL FastSystemCall RETN } } Предварительно вытаскиваешь из ntdll номер NtCreateFile и пихаешь в dwNtCreateFileCtlServiceNum Потом вызываешь Int2eNtCreateFile как обычную NtCreateFile. Вытаскивать из ntdll примерно так: Код (Text): PVOID fNtCreateFile = (PVOID) GetProcAddress(GetModuleHandle("ntdll"), "NtCreateFile"); dwNtCreateFileCtlServiceNum = *(DWORD*)((DWORD)fNtCreateFile + 1);
tyomitch Ээ, SYSCALL, насколько я помню, это уже из IA-64 (SYSCALL/SYSRET), а на IA-32 используется SYSENTER/SYSEXIT
tyomitch хе, не знал но ведь SYSENTER должен поддерживаться AMD? Точнее, обязан просто. А в intel'е IA-64 свои SYSCALL/SYSRET есть, насколько я помню..
Сомнительно. (Это, кстати, про EM64T, а не IA64.) Надо найти где-нибудь Атлон и проверить, но вокруг меня одни Пентиумы...
Попробовал скомпилить все это в библиотеку,вот так: Код (Text): // CF.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" DWORD dwNtCreateFileCtlServiceNum; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { PVOID fNtCreateFile = (PVOID) GetProcAddress(GetModuleHandle("ntdll"), "NtCreateFile"); dwNtCreateFileCtlServiceNum = *(DWORD*)((DWORD)fNtCreateFile + 1); return TRUE; } // // Fast system call using INT 2E // __declspec(naked) FastSystemCall( ) { __asm { lea edx, dword ptr ss:[esp+8] int 0x2e ret } } // // Perform NtCreateFile call // __declspec(naked) NTSTATUS WINAPI Int2eNtCreateFile(...) { __asm { MOV EAX, dword ptr [dwNtCreateFileCtlServiceNum] CALL FastSystemCall RETN } } Студия 2003 ругается на NTSTATUS: CF.cpp(35) : error C2143: syntax error : missing ';' before '__stdcall' CF.cpp(35) : error C2501: 'NTSTATUS' : missing storage-class or type specifiers CF.cpp(35) : error C2488: 'NTSTATUS' : 'naked' can only be applied to non-member function definition Попробовал заменить NTSTATUS на void, тогда все компилится, библиотека загружается,но функция Int2eNtCreateFile нет. Вызываю так: Код (Text): CrFile=(CFH)GetProcAddress(hDll,TEXT("Int2eNtCreateFile")); if(CrFile==NULL){ i=GetLastError(); T=SysErrorMessage(i); T="Can't get procedure address!\nError Code:"+(AnsiString)i+"\nReason:"+T; MessageBox(0,T.c_str(),0,MB_OK); }