Обфускация CreateFile()

Тема в разделе "WASM.RESEARCH", создана пользователем OOuph, 27 май 2007.

  1. OOuph

    OOuph New Member

    Публикаций:
    0
    Регистрация:
    27 май 2007
    Сообщения:
    6
    Какими несколькими инструкциями можно заменить CreateFIle(...)?
    Чтобы потом,дизассемблируя код,нельзя было так просто вычленить "кусок" с созданием хендла?
    Может,кто-нибудь сталкивался?Заранее спасибо
     
  2. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    можно syscall/int 2Eh юзать, это будет не так палевно
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Cr4sh
    +1. еще добавить самомодифицирующийся код в этом районе, чтобы инструкции в окресности INT 2E генерились на ходу и выполнялись под оберткой антиотладочных приемов.
     
  4. OOuph

    OOuph New Member

    Публикаций:
    0
    Регистрация:
    27 май 2007
    Сообщения:
    6
    Большое спасибо за быстрый ответ,но сам я не настолько искушен в ассемблере, а в имеющейся у меня литературе не нашел описания прерывания 2Eh.
    Где можно про него прочитать?Или,может,у кого-нибудь листинг есть?
    Хэндл мне нужен, чтоб запретить доступ другим программам к файлу исполняемого экзешника, вызов такой:
    hF=CreateFile("имя файла",GENERIC_EXECUTE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Это интерфейс взаимодействия с ядром, наряду с 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.
     
  6. OOuph

    OOuph New Member

    Публикаций:
    0
    Регистрация:
    27 май 2007
    Сообщения:
    6
    Спасибо за такой развернутый ответ-очень интересно!
    Возник вопрос-как параметры передавать?Т.е. я понял,что надо в EDX заносить содержащий их адрес,но сами параметры какие?Те же,что скидываются в стек при вызове
    call CreateFileA?
    Их загнать в массив DWORD'ов или как?
    Попробовал нарыть инфу про 2e в других источниках-встретил только как вызывать выполнение команды DOS...
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    нет, параметры у ZwCreateFile свои. Смотри документацию по Native API.
    Код (Text):
    1. NTSTATUS  
    2.   ZwCreateFile(
    3.     OUT PHANDLE  FileHandle,
    4.     IN ACCESS_MASK  DesiredAccess,
    5.     IN POBJECT_ATTRIBUTES  ObjectAttributes,
    6.     OUT PIO_STATUS_BLOCK  IoStatusBlock,
    7.     IN PLARGE_INTEGER  AllocationSize  OPTIONAL,
    8.     IN ULONG  FileAttributes,
    9.     IN ULONG  ShareAccess,
    10.     IN ULONG  CreateDisposition,
    11.     IN ULONG  CreateOptions,
    12.     IN PVOID  EaBuffer  OPTIONAL,
    13.     IN ULONG  EaLength
    14.     );
    Ну не совсем
    если пишешь на си, то могу дать некоторые стабы для использования.
     
  8. OOuph

    OOuph New Member

    Публикаций:
    0
    Регистрация:
    27 май 2007
    Сообщения:
    6
    Да, пишу на си. Было бы очень хорошо:)
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Код (Text):
    1. //
    2. // Fast system call using INT 2E
    3. //
    4.  
    5. __declspec(naked) FastSystemCall( )
    6. {
    7.     __asm
    8.     {
    9.         lea edx, dword ptr ss:[esp+8]
    10.         int 0x2e
    11.         ret
    12.     }
    13. }
    14.  
    15. DWORD dwNtCreateFileCtlServiceNum;
    16.  
    17. //
    18. // Perform NtCreateFile call
    19. //
    20.  
    21. __declspec(naked) NTSTATUS WINAPI Int2eNtCreateFile(...)
    22. {
    23.     __asm
    24.     {
    25.         MOV EAX, dword ptr [dwNtCreateFileCtlServiceNum]
    26.         CALL FastSystemCall
    27.         RETN
    28.     }
    29. }
    Предварительно вытаскиваешь из ntdll номер NtCreateFile и пихаешь в dwNtCreateFileCtlServiceNum
    Потом вызываешь Int2eNtCreateFile как обычную NtCreateFile.

    Вытаскивать из ntdll примерно так:
    Код (Text):
    1.     PVOID fNtCreateFile = (PVOID) GetProcAddress(GetModuleHandle("ntdll"), "NtCreateFile");
    2.     dwNtCreateFileCtlServiceNum = *(DWORD*)((DWORD)fNtCreateFile + 1);
     
  10. tyomitch

    tyomitch New Member

    Публикаций:
    0
    Регистрация:
    15 май 2006
    Сообщения:
    15
    Начиная с XP. Причём используются разные команды на процессорах Intel (SYSENTER) и AMD (SYSCALL).
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    tyomitch
    Ээ, SYSCALL, насколько я помню, это уже из IA-64 (SYSCALL/SYSRET), а на IA-32 используется SYSENTER/SYSEXIT
     
  12. tyomitch

    tyomitch New Member

    Публикаций:
    0
    Регистрация:
    15 май 2006
    Сообщения:
    15
    http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/21086.pdf
     
  13. OOuph

    OOuph New Member

    Публикаций:
    0
    Регистрация:
    27 май 2007
    Сообщения:
    6
    Great спасибо тебе,Great!
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    tyomitch
    хе, не знал:) но ведь SYSENTER должен поддерживаться AMD? Точнее, обязан просто.

    А в intel'е IA-64 свои SYSCALL/SYSRET есть, насколько я помню..
     
  15. tyomitch

    tyomitch New Member

    Публикаций:
    0
    Регистрация:
    15 май 2006
    Сообщения:
    15
    Сомнительно.

    (Это, кстати, про EM64T, а не IA64.)

    Надо найти где-нибудь Атлон и проверить, но вокруг меня одни Пентиумы...
     
  16. OOuph

    OOuph New Member

    Публикаций:
    0
    Регистрация:
    27 май 2007
    Сообщения:
    6
    Попробовал скомпилить все это в библиотеку,вот так:
    Код (Text):
    1. // CF.cpp : Defines the entry point for the DLL application.
    2. //
    3.  
    4. #include "stdafx.h"
    5.  
    6. DWORD dwNtCreateFileCtlServiceNum;
    7. BOOL APIENTRY DllMain( HANDLE hModule,
    8.                        DWORD  ul_reason_for_call,
    9.                        LPVOID lpReserved
    10.                      )
    11. {
    12.     PVOID fNtCreateFile = (PVOID) GetProcAddress(GetModuleHandle("ntdll"), "NtCreateFile");
    13.     dwNtCreateFileCtlServiceNum = *(DWORD*)((DWORD)fNtCreateFile + 1);
    14.     return TRUE;
    15. }
    16. //
    17. // Fast system call using INT 2E
    18. //
    19.  
    20. __declspec(naked) FastSystemCall( )
    21. {
    22.     __asm
    23.     {
    24.         lea edx, dword ptr ss:[esp+8]
    25.         int 0x2e
    26.         ret
    27.     }
    28. }
    29.  
    30.  
    31. //
    32. // Perform NtCreateFile call
    33. //
    34.  
    35. __declspec(naked) NTSTATUS WINAPI Int2eNtCreateFile(...)
    36. {
    37.     __asm
    38.     {
    39.         MOV EAX, dword ptr [dwNtCreateFileCtlServiceNum]
    40.         CALL FastSystemCall
    41.         RETN
    42.     }
    43. }
    Студия 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):
    1. CrFile=(CFH)GetProcAddress(hDll,TEXT("Int2eNtCreateFile"));
    2.         if(CrFile==NULL){
    3.                 i=GetLastError();
    4.                 T=SysErrorMessage(i);
    5.                 T="Can't get procedure address!\nError Code:"+(AnsiString)i+"\nReason:"+T;
    6.                 MessageBox(0,T.c_str(),0,MB_OK);
    7.         }
     
  17. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    OOuph
    typedef ULONG NTSTATUS;