Создание потока NtCreateThread

Тема в разделе "WASM.WIN32", создана пользователем Klayd, 5 авг 2007.

  1. Klayd

    Klayd Степан

    Публикаций:
    0
    Регистрация:
    7 апр 2006
    Сообщения:
    59
    Адрес:
    Киев
    Добрый день
    На днях решил разобраться с созданием потока используя NtCreateThread. Единственный найденый мною пример http://www.wasm.ru/forum/files/_1687450158__CreateThread.c оказался не рабочим :dntknw:. Я так понял что там неверно определяются стек или контекст потока, потому что обьект потока создается нормально но при попытке запуска все виснет. Буду очень признателен за любую инфу по теме или пример рабочего кода ;)
     
  2. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Klayd
    http://cygwin.com/ml/cygwin-developers/2001-02/msg00032.html - пример из книги Неббета. Хотя сам его не проверял.
     
  3. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    Klayd
    нестранно) нужно или уведомлять сервер подсистемы win32 о создании новго потока, или использовать в нём только апишки из ntdll
     
  4. Klayd

    Klayd Степан

    Публикаций:
    0
    Регистрация:
    7 апр 2006
    Сообщения:
    59
    Адрес:
    Киев
    asd
    чето не могу скомпилить, в ntdll.h почемуто находит множество ошибок..

    мож у когото есть пример проверенный?
     
  5. Klayd

    Klayd Степан

    Публикаций:
    0
    Регистрация:
    7 апр 2006
    Сообщения:
    59
    Адрес:
    Киев
    Проблема решена
    Написал свой вариант:
    Код (Text):
    1. function ROUND_UP(VALUE: ULONG;
    2.                   ROUND: ULONG): ULONG;
    3. begin
    4.   Result := (VALUE + (ROUND - 1)) and (not(ROUND - 1))
    5. end;
    6.  
    7. function RtlpCreateStack(Process: HANDLE;
    8.                          MaximumStackSize: ULONG;
    9.                          CommittedStackSize: ULONG;
    10.                          ZeroBits: ULONG;
    11.                          InitialTeb: PTHREAD_STACK): NTSTATUS;
    12. var
    13.   Status:     NTSTATUS;
    14.   Stack:      PCHAR;
    15.   SysInfo:    SYSTEM_BASIC_INFORMATION;
    16.   GuardPage:  BOOLEAN;
    17.   RegionSize: ULONG;
    18.   OldProtect: ULONG;
    19.   Peb:        PPEB;
    20.   NtHeaders:  PIMAGE_NT_HEADERS;
    21.  
    22. label
    23.   Exit;
    24.  
    25. begin
    26.   Status := NtQuerySystemInformation(SystemBasicInformation,
    27.                                      @SysInfo,
    28.                                      SizeOf(SysInfo),
    29.                                      nil);
    30.   if Status <> STATUS_SUCCESS then
    31.     goto Exit;
    32.   if Process = GetCurrentProcess() then
    33.     begin
    34.       Peb := RtlGetCurrentPeb();
    35.       NtHeaders := RtlImageNtHeader(Peb^.ImageBaseAddress);
    36.       if MaximumStackSize = 0 then
    37.         MaximumStackSize := NtHeaders^.OptionalHeader.SizeOfStackReserve;
    38.       if CommittedStackSize = 0 then
    39.           CommittedStackSize := NtHeaders^.OptionalHeader.SizeOfStackCommit
    40.     end
    41.   else
    42.     begin
    43.       if CommittedStackSize = 0 then
    44.           CommittedStackSize := SysInfo.PhysicalPageSize;
    45.  
    46.       if MaximumStackSize = 0 then
    47.           MaximumStackSize := SysInfo.AllocationGranularity
    48.     end;
    49.   if CommittedStackSize >= MaximumStackSize then
    50.       MaximumStackSize := ROUND_UP(CommittedStackSize, (1024*1024));
    51.   CommittedStackSize := ROUND_UP(CommittedStackSize, SysInfo.PhysicalPageSize);
    52.   MaximumStackSize := ROUND_UP(MaximumStackSize, SysInfo.AllocationGranularity);
    53.   Stack := nil;
    54.   Status := NtAllocateVirtualMemory(Process,
    55.                                     @Stack,
    56.                                     ZeroBits,
    57.                                     @MaximumStackSize,
    58.                                     MEM_RESERVE,
    59.                                     PAGE_READWRITE);
    60.   if Status <> STATUS_SUCCESS then
    61.     goto Exit;
    62.   InitialTeb^.OldStackBase := nil;
    63.   InitialTeb^.OldStackLimit := nil;
    64.   InitialTeb^.StackAllocationBase := Stack;
    65.   InitialTeb^.StackBase := Stack + MaximumStackSize;
    66.   Stack := Stack + MaximumStackSize - CommittedStackSize;
    67.   if MaximumStackSize > CommittedStackSize then
    68.     begin
    69.       Stack := Stack - SysInfo.PhysicalPageSize;
    70.       CommittedStackSize := CommittedStackSize + SysInfo.PhysicalPageSize;
    71.       GuardPage := TRUE
    72.     end
    73.   else
    74.     GuardPage := FALSE;
    75.   Status := NtAllocateVirtualMemory(Process,
    76.                                     @Stack,
    77.                                     0,
    78.                                     @CommittedStackSize,
    79.                                     MEM_COMMIT,
    80.                                     PAGE_READWRITE);
    81.   InitialTeb^.StackLimit := Stack;
    82.   if Status <> STATUS_SUCCESS then
    83.     goto Exit;
    84.   if GuardPage then
    85.     begin
    86.       RegionSize :=  SysInfo.PhysicalPageSize;
    87.       Status := NtProtectVirtualMemory(Process,
    88.                                        @Stack,
    89.                                        @RegionSize,
    90.                                        PAGE_GUARD or PAGE_READWRITE,
    91.                                        @OldProtect);
    92.  
    93.  
    94.       if Status <> STATUS_SUCCESS then
    95.         goto Exit;
    96.       InitialTeb^.StackLimit := PVOID(ULONG(InitialTeb^.StackLimit) - RegionSize);
    97.     end;
    98.   Status := STATUS_SUCCESS;
    99. Exit:
    100.   Result := Status
    101. end;
    102.  
    103. function RtlpFreeStack(Process: HANDLE;
    104.                        InitialTeb: PTHREAD_STACK): NTSTATUS;
    105. var
    106.   Status: NTSTATUS;
    107.   Zero: ULONG;
    108.  
    109. label
    110.   Exit;
    111.    
    112. begin
    113.   Zero := 0;
    114.   Status := NtFreeVirtualMemory(Process,
    115.                                 @InitialTeb^.StackAllocationBase,
    116.                                 @Zero,
    117.                                 MEM_RELEASE);
    118.   if Status <> STATUS_SUCCESS then
    119.     goto Exit;
    120.   RtlZeroMemory(InitialTeb, SizeOf(InitialTeb^) );
    121. Exit:
    122.   Result := Status;
    123. end;
    124.  
    125. function CreateUserThread(Process: HANDLE;
    126.                           ThreadSecurityDescriptor: PSECURITY_DESCRIPTOR;
    127.                           CreateSuspended: BOOLEAN;
    128.                           ZeroBits: ULONG;
    129.                           MaximumStackSize: ULONG;
    130.                           CommittedStackSize: ULONG;
    131.                           StartAddress: PVOID;
    132.                           Parameter: PVOID;
    133.                           Thread: PHANDLE;
    134.                           ClientId: PCLIENT_ID): NTSTATUS;
    135. var
    136.   InitialTeb:       THREAD_STACK;
    137.     ThreadHandle:     HANDLE;
    138.     ThreadContext:    CONTEXT;
    139.     ThreadClientId:   CLIENT_ID;
    140.   ObjectAttributes: OBJECT_ATTRIBUTES;
    141.     Status:           NTSTATUS;
    142.  
    143. label
    144.   Exit;
    145.  
    146. begin
    147.   Status := RtlpCreateStack(Process,
    148.                             MaximumStackSize,
    149.                             CommittedStackSize,
    150.                             ZeroBits,
    151.                             @InitialTeb);
    152.   if Status <> STATUS_SUCCESS then
    153.     goto Exit;
    154.   RtlInitializeContext(Process,
    155.                        @ThreadContext,
    156.                        Parameter,
    157.                        StartAddress,
    158.                        InitialTeb.StackBase);
    159.   InitializeObjectAttributes(@ObjectAttributes, nil, 0, 0,
    160.                              ThreadSecurityDescriptor );
    161.   Status := NtCreateThread(@ThreadHandle,
    162.                            THREAD_ALL_ACCESS,
    163.                            @ObjectAttributes,
    164.                            Process,
    165.                            @ThreadClientId,
    166.                            @ThreadContext,
    167.                            @InitialTeb,
    168.                            CreateSuspended);
    169.  
    170.     if Status <> STATUS_SUCCESS then
    171.       RtlpFreeStack(Process, @InitialTeb)
    172.     else
    173.       begin
    174.         if Thread <> nil then
    175.             Thread^ := ThreadHandle;
    176.         if ClientId <> nil then
    177.             ClientId^ := ThreadClientId
    178.       end;
    179. Exit:
    180.   Result := Status
    181. end;
    извините за паскаль :)
     
  6. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    на каких осях проверял?
     
  7. Klayd

    Klayd Степан

    Публикаций:
    0
    Регистрация:
    7 апр 2006
    Сообщения:
    59
    Адрес:
    Киев
    Проверял пока тока на своей: WinXP SP2
     
  8. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    я делал примерно так только на асме
    тред не регистрировал в crsss (ClientCallServer не вызывал)
    были какие-то косяки, ща не помню точно что, но что-то серьезное не работало
    вейт на хендле чтоли
     
  9. Klayd

    Klayd Степан

    Публикаций:
    0
    Регистрация:
    7 апр 2006
    Сообщения:
    59
    Адрес:
    Киев
    если не использовать в потоке, как сказал Cr4sh, ниче кроме ntdll, то работает нормально
    тока сомневаюсь что станет работать на 64 разрядной винде :\
     
  10. el-

    el- New Member

    Публикаций:
    0
    Регистрация:
    14 сен 2006
    Сообщения:
    89
    боян пробовал сам лично ... нифига не получилось, тред создается нормально только в простых приложения если попробовать создать удаленый тред в службе ... служба на пару с csrss занимают все процессорное время и начинают тупить по максимуму ... в обяз надо информировать csrss

    ап: причем стабильность даж в простых приложения не гарантирована ... мбо у меня тред был на нативах ... но тем неменее тупил ...
     
  11. Klayd

    Klayd Степан

    Публикаций:
    0
    Регистрация:
    7 апр 2006
    Сообщения:
    59
    Адрес:
    Киев
    тут CreateUserThread вопщемто является прототипом RtlCreateUserThread поэтому csrss надо информировать самому