Как на Си получить значение регистра CS ?

Тема в разделе "WASM.BEGINNERS", создана пользователем M0rg0t, 27 янв 2025.

Метки:
  1. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.582
    Как на Си получить значения CS ? Для GS / FS есть операторы вида https://learn.microsoft.com/ru-ru/c...dfsdword-readfsqword-readfsword?view=msvc-170 , но для cs такого нет.

    Я знаю про GetThreadContext, ровно как и про асм вставки, линк асм листинга. Интересно более простое решение, если оно есть конечно.
     
  2. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.874
    M0rg0t нравится это.
  3. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    491
  4. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    223
    Где то рядом ходит функа GetThreadSelectorEntry() из kernel32.dll - можешь в неё заглянуть.
    А так все Win вроде одинаково выстраивают таблицу GDT, т.е. селекторы всегда одинаковые:

    Код (Text):
    1. 0: kd> dg 0 80
    2.                                                     P Si Gr Pr Lo
    3. Sel        Base              Limit          Type    l ze an es ng Flags
    4. ---- ----------------- ----------------- ---------- - -- -- -- -- --------
    5. 0000 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    6. 0008 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    7. 0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P  Lo 0000029b
    8. 0018 00000000`00000000 00000000`ffffffff Data RW Ac 0 Bg Pg P  Nl 00000c93
    9. 0020 00000000`00000000 00000000`ffffffff Code RE Ac 3 Bg Pg P  Nl 00000cfb
    10. 0028 00000000`00000000 00000000`ffffffff Data RW Ac 3 Bg Pg P  Nl 00000cf3
    11. 0030 00000000`00000000 00000000`00000000 Code RE Ac 3 Nb By P  Lo 000002fb
    12. 0038 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    13. 0040 00000000`00b9b000 00000000`00000067 TSS32 Busy 0 Nb By P  Nl 0000008b
    14. 0048 00000000`0000ffff 00000000`0000f800 <Reserved> 0 Nb By Np Nl 00000000
    15. 0050 ffffffff`fffe0000 00000000`00003c00 Data RW Ac 3 Bg By P  Nl 000004f3
    16. 0058 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    17. 0060 00000000`00000000 00000000`ffffffff Code RE    0 Bg Pg P  Nl 00000c9a
    18. 0068 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    19. 0070 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    20. 0078 00000000`00000000 00000000`00000000 <Reserved> 0 Nb By Np Nl 00000000
    21. 0080 Unable to get descriptor
    22. 0: kd>
     
    Mikl___ нравится это.
  5. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.582
    Да асм вставка плохо, что на х64 нельзя, и приходится добавлять асм файл, в этой [непечатное слово] студии.
    Поэтому, проще таки взять винапи, избыточно, ну да ладно.
     
  6. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    491
    значение CS разнится от ОС версии к ОС?
    или хардкод
     
  7. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.582
    Разнится от битности вроде как, 32 бит это 0x1b, wow64 = 0x23,64 native = 0x33
    за ОС не скажу.
     
    Mikl___ нравится это.
  8. Marylin

    Marylin Active Member

    Публикаций:
    0
    Регистрация:
    17 фев 2023
    Сообщения:
    223
    Хард только индекс дескрипторов в GDT,
    т.е. всегда идёт CS/DS ядра(0), и после них CS/DS юзера(3).
    на х32 селектор(0) в резерве, на х64 первые два селектора(0,8).
    вот лог от 32-битной ХР, где в столбце PL указано кольцо защиты - если в нём 3, то нужно добавить эту тройку к значению селектора.
    Код (Text):
    1. kd> dg 0 80
    2.                                       P  Si  Gr  Pr  Lo
    3. Sel     Base      Limit      Type     l  ze  an  es  ng   Flags
    4. ----  --------  -------- -----------  -  --  --  --  --  --------
    5. 0000  00000000  00000000  <Reserved>  0  Nb  By  Np  Nl  00000000
    6. 0008  00000000  ffffffff  Code RE Ac  0  Bg  Pg  P   Nl  00000c9b
    7. 0010  00000000  ffffffff  Data RW Ac  0  Bg  Pg  P   Nl  00000c93
    8. 0018  00000000  ffffffff  Code RE Ac  3  Bg  Pg  P   Nl  00000cfb
    9. 0020  00000000  ffffffff  Data RW Ac  3  Bg  Pg  P   Nl  00000cf3
    10. 0028  80042000  000020ab  TSS32 Busy  0  Nb  By  P   Nl  0000008b
    11. 0030  ffdff000  00001fff  Data RW Ac  0  Bg  Pg  P   Nl  00000c93
    12. 0038  7ffdf000  00000fff  Data RW Ac  3  Bg  By  P   Nl  000004f3
    13. 0040  00000400  0000ffff  Data RW     3  Nb  By  P   Nl  000000f2
    14. 0048  00000000  00000000  <Reserved>  0  Nb  By  Np  Nl  00000000
    15. 0050  80551380  00000068  TSS32 Avl   0  Nb  By  P   Nl  00000089
    16. 0058  805513e8  00000068  TSS32 Avl   0  Nb  By  P   Nl  00000089
    17. 0060  00022f40  0000ffff  Data RW Ac  0  Nb  By  P   Nl  00000093
    18. 0068  000b8000  00003fff  Data RW     0  Nb  By  P   Nl  00000092
    19. 0070  ffff7000  000003ff  Data RW     0  Nb  By  P   Nl  00000092
    20. 0078  80400000  0000ffff  Code RE     0  Nb  By  P   Nl  0000009a
    21. 0080  80400000  0000ffff  Data RW     0  Nb  By  P   Nl  00000092
    22. kd>
     
    Mikl___, M0rg0t и alex_dz нравится это.
  9. Ahimov

    Ahimov Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    71
    Можно сделать не на уровне ISA, тоесть не кодировать инструкции, нп call far, а из скрипта прокинуть фаулт и обработать средствами скрипта ловушку. В контексте будет состояние задачи на момент исключения. Это получится манипуляция только структурами, без всяких idt gdt etc.
     
  10. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    311
    ?

    Код (Text):
    1. #if defined(_M_X64) || defined(__x86_64__)
    2.     // 64-bit
    3.     #define CS_VALUE 0x33
    4. #elif defined(_M_IX86) || defined(__i386__)
    5.     // 32-bit
    6.     #define CS_VALUE 0x1b
    7. #else
    8.     #error "Architecture not supported"
    9. #endif
    10.  
    11. static inline unsigned short get_cs(void) {
    12.     #ifdef _MSC_VER
    13.         // Для Microsoft Visual C++
    14.         CONTEXT ctx = {0};
    15.         ctx.ContextFlags = CONTEXT_CONTROL;
    16.         GetThreadContext(GetCurrentThread(), &ctx);
    17.         return (unsigned short)ctx.SegCs;
    18.     #else
    19.         // Для GCC/Clang
    20.         unsigned short cs;
    21.         __asm__ __volatile__("mov %%cs, %0" : "=r"(cs));
    22.         return cs;
    23.     #endif
    24. }
     
  11. Ahimov

    Ahimov Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    71
    galenkane

    Очевидно задача определить режим(cpl), может быть среду(wow)/разрядность(архитектуру в общем), такое нужно только если окружение не известно; если определен мод и можно звать его апи, селекторы читать незачем :preved:
     
  12. galenkane

    galenkane Active Member

    Публикаций:
    0
    Регистрация:
    13 янв 2017
    Сообщения:
    311
    ?

    Код (Text):
    1. #include <windows.h>
    2.  
    3. static inline int get_execution_mode(void) {
    4.     // Определяем WOW64
    5.     BOOL is_wow64 = FALSE;
    6.     IsWow64Process(GetCurrentProcess(), &is_wow64);
    7.    
    8.     if (is_wow64) {
    9.         return 1;  // WOW64
    10.     }
    11.    
    12.     #ifdef _WIN64
    13.         return 2;  // Native 64-bit
    14.     #else
    15.         return 0;  // Native 32-bit
    16.     #endif
    17. }
    18.  
    19. // Получение CPL через проверку привилегий процесса
    20. static inline int get_privilege_level(void) {
    21.     HANDLE token;
    22.     if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
    23.         TOKEN_ELEVATION elevation;
    24.         DWORD size;
    25.         if (GetTokenInformation(token, TokenElevation, &elevation,
    26.                               sizeof(elevation), &size)) {
    27.             CloseHandle(token);
    28.             return elevation.TokenIsElevated ? 0 : 3;
    29.         }
    30.         CloseHandle(token);
    31.     }
    32.     return 3; // По умолчанию user mode
    33. }
    --- Сообщение объединено, 28 янв 2025 ---
    вообще https://wasm.in/threads/ischu-antidebag-indi.34964/page-2#post-443095 тут код для cpl был наскок помню
     
  13. Ahimov

    Ahimov Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    71
    Код (Text):
    1. // Получение CPL через проверку привилегий процесса
    2. static inline int get_privilege_level(void) {
    3.     HANDLE token;
    4.     if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
    cpl это хардверный уровень прав, не осевой. OpenProcessToken() это юзер апи и тащит импорт. В произвольный код такое не всунешь, если слинковать и скопировать дамп, выполнив в ядре к примеру это уронит ось.
    --- Сообщение объединено, 28 янв 2025 ---
    galenkane

    ТС нужно без асм вставок, средствами скрипта. Это врядле возможно, ловушки так нельзя использовать, защита не даст.

    CS регистр определяет машинный мод(ядерный cs/ss) и саму среду значение селектора.

    Вообще суть задачи какая ?
     
  14. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.477
    Адрес:
    Россия, Нижний Новгород
    Можно вообще их захардкодить, т.к. эти селекторы не меняются.
    Но если надо в коде и без ассемблера, то на MSVC можно просто набить байтами шелл и положить в исполняемую секцию:
    Код (C):
    1.  
    2. #include <stdio.h>
    3.  
    4. #pragma code_seg(".shell")
    5. __declspec(allocate(".shell"))
    6. static const unsigned char s_readCs[]
    7. {
    8.     0x66, 0x8C, 0xC8, // mov ax, cs
    9.     0xC3              // ret
    10. };
    11.  
    12. typedef unsigned short (*ReadCs)();
    13.  
    14. unsigned short _asm_read_cs()
    15. {
    16.     return ((ReadCs)&s_readCs[0])();
    17. }
    18.  
    19. int main()
    20. {
    21.     printf("0x%X\n", _asm_read_cs());
    22.     return 0;
    23. }
    24.  
    Код ( (Unknown Language)):
    1.  
    2. $ .\app.exe
    3. 0x33
    4.  
     
    M0rg0t, Treant, Mikl___ и ещё 1-му нравится это.
  15. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    491
    лютый кодес, годнота :)