Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как пользоваться Zw/NtCreateProcess? 
:(
    Опции темы
Акакий
Дата 5.9.2011, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Если кто может, пожалуйста, покажите пример на Delphi использования Nt(Zw)CreateProcess. Особенно интересует запись параметров(ком.строка, текущий каталог и т.п.) в РЕВ. Заранее спасибо  smile 
PM MAIL   Вверх
Riply
Дата 5.9.2011, 21:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Акакий @  5.9.2011,  10:46 Найти цитируемый пост)
Если кто может, пожалуйста, покажите пример на Delphi использования Nt(Zw)CreateProcess. Особенно интересует запись параметров(ком.строка, текущий каталог и т.п.) в РЕВ. Заранее спасибо    


У Nebbet`а в книге "Windows NT/2000: Native API Reference"
есть примеры исходного кода с подробным описанием происходящего ( Example 6.1,  Example 6.2 )

Книжку можно найти у Rouse_`а на http://rouse.drkb.ru/books.php

Это сообщение отредактировал(а) Riply - 5.9.2011, 21:24
PM MAIL   Вверх
Акакий
Дата 6.9.2011, 10:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Riply, спасибо конечно, но все это я видел еще в 200-лохматом годе, когда Клерк давал ссылки на исходники мелкомягких(на paste.org.ru по моему), да и у Зомби есть куча примеров на асме(правда там tls не обрабатывается)....вообще теории выше крыши  smile   Процесс и поток я создаю(через Int 2E), пишу секции, делаю контекст и все такое и процесс спокойненько себе создается....но не получается записать параметры. Замучался уже с сишными исходниками. К слову сказать, совершенно не обязательно уведомлять csrss.  И товарищи, я не халявщик, но я smile !!!!!!!

ЗЗЗЗЫ!!!!
И таки везде только одни обсуждения за боянистую тему про перехват NtCreateProcess и нигде нет как эту фукн-ю пользовать. И даже здесь http://forum.sources.ru/index.php?showtopi...p;#entry2741053, ув. Riply, Вы не приводите исходники самой интересной Вашей процедуры Proc_AllocAndWriteParameters(какая досада...) 

Это сообщение отредактировал(а) Акакий - 6.9.2011, 20:07
PM MAIL   Вверх
Riply
Дата 7.9.2011, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Акакий @  6.9.2011,  10:51 Найти цитируемый пост)
ув. Riply, Вы не приводите исходники самой интересной Вашей процедуры Proc_AllocAndWriteParameters(какая досада...) 


Чудом раскопала исходники. В этой процедуре ничего особенного нет. Выделяем память в целевом, да пишем туда, что нужно smile
Очень сложно выдергивать из проекта, бо она использует другие самодельные ф-ии, но вдруг поможет ?

Код

function Proc_AllocAndWriteParameters(const hProcess: THANDLE; const pProcPeb: PPEB; const pProcParams: PRTL_USER_PROCESS_PARAMETERS; const pEnv: PWCHAR; const BytesPerEnv: ULONG): NTSTATUS; stdcall;
var
 pTmp: PVOID;
 EnvSize: ULONG;
 StatusOK: NTSTATUS;
begin
 StatusOK := STATUS_ACCESS_VIOLATION;
 Result := Proc_AllocAndWriteEnvironmentEx(hProcess, pEnv, BytesPerEnv, @pProcParams.Environment);
 if NT_SUCCESS(Result) then
  try
   Result := ZwAllocVirtualMemoryAndWrite(hProcess, @pTmp, pProcParams, pProcParams.Length, MEM_COMMIT, PAGE_READWRITE);
   if NT_SUCCESS(Result) then
    begin
     Result := NtWriteVirtualMemory(hProcess, INC_PVOID(pProcPeb, PEB_OffsetToProcessParameters(pProcPeb)), @pTmp, SizeOf(PVOID), nil);
     if not NT_SUCCESS(Result) then
      begin
       EnvSize := 0;
       ZwFreeVirtualMemory(hProcess, @pTmp, @EnvSize, MEM_RELEASE);
      end
     else StatusOK := Result;
    end;
  finally
   if not NT_SUCCESS(StatusOK) then
    begin
     EnvSize := 0;
     ZwFreeVirtualMemory(hProcess, @pProcParams.Environment, @EnvSize, MEM_RELEASE);
    end;
  end;
end;


P.S. 
  В том топике говорила, еще раз повторю: отнюдь не факт, что здесь ошибок меньше чем строчек smile
PM MAIL   Вверх
Акакий
Дата 7.9.2011, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Цитата(Riply)
...но вдруг поможет?
помогло, но немножко в другом плане, а именно - взяться за анализ сишных исходников Гарри Потт..., пардон - Неббетта  smile 

итого мы делаем:

1) Var  pp :RTL_USER_PROCESS_PARAMETERS;
           ImageFile :PUNICODE_STRING; //путь к ехе-шнику
   RtlCreateProcessParameters(@pp,ImageFile,Nil,CurrentDirectory,CommandLine,Nil,Nil,Nil,Nil,Nil);

2) формируем "блок окружения процесса", 
Код

var
  pEnv :Pointer = Nil;
  Env1, Env2 :PChar;
  EnvSize :Integer = 0;
begin
   Env1:=GetEnvironmentStrings; Env2:=Env1;
   If Env2<>nil then
     repeat
       Inc(EnvSize,Length(Env2));
       Inc(Env2,Length(Env2)+1);
     until Env2^=#0;
   Env2:=nil;
// выделяем память в новом процессе под блок окружения:
   ZwAllocateVirtualMemory(hProcess,pEnv,0,EnvSize,...) 
//и пишем туда его
   ZwWriteVirtualMemory(hProcess,pEnv,Env1,EnvSize,...)
   FreeEnvironmentStrings(Env1);
end;
   устанавливаем указатель на блок окружения нового процесса в структуре RTL_USER_PROCESS_PARAMETERS:
   pp.Environment:=pEnv; 

3) пишем в процесс структуру RTL_USER_PROCESS_PARAMETERS:
   Var  p2 :Pointer = Nil;
   ZwAllocateVirtualMemory(hProcess,p2,0,SizeOf(pp),...) 
   ZwWriteVirtualMemory(hProcess,p2,pp,...)

4) получаем адрес РЕВ созданного процесса:
   Var  pbi :PROCESS_BASIC_INFORMATION;
   ZwQueryInformationProcess(...,@pbi,...);
   и пишем в РЕВ(согласно его структуре) по смещению $10 адрес, по которому мы записали RTL_USER_PROCESS_PARAMETERS(т.е. указатель p2):
   ZwWriteVirtualMemory(hProcess,pbi.PebBaseAddress+$10,p2,4,...)

ЗЫ
ну и теперь дело остается за малым - в очередной раз убедиться, что все это не работает...(3 раза тьфу чтоб не сглазить)

Это сообщение отредактировал(а) Акакий - 7.9.2011, 14:39
PM MAIL   Вверх
Riply
Дата 7.9.2011, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Акакий,  с первого взгляда, вроде, похоже на правду.

PM MAIL   Вверх
Акакий
Дата 7.9.2011, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



небольшая неточность - неверно определяется размер окружения - не учитываются нули в конце строк, нужно так:
Код

Var
  pEnv :Pointer = Nil;
  Env1, Env2 :PChar;
begin
   Env1:=GetEnvironmentStrings; Env2:=Env1;
   If Env2=Nil then  Exit;
   While (Env2^<>#0) or (PChar(DWord(Env2)+1)^<>#0) do  Inc(Env2);
   ZwAllocateVirtualMemory(hProcess,pEnv,0,Env2-Env1+2,...);
end;

PM MAIL   Вверх
Riply
Дата 8.9.2011, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Акакий @  7.9.2011,  23:40 Найти цитируемый пост)
While (Env2^<>#0) or (PChar(DWord(Env2)+1)^<>#0) do  Inc(Env2);

1. Почему or ? Вроде надо and.
2. Почему +1, а не SizeOf(CHAR) ?    (и здесь аналогично:  "Env1+2")
PM MAIL   Вверх
Акакий
Дата 8.9.2011, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Цитата(Riply @  8.9.2011,  08:50 Найти цитируемый пост)
1. Почему or ? Вроде надо and.
2. Почему +1, а не SizeOf(CHAR) ?    (и здесь аналогично:  "Env1+2") 

Мы ищем в последовательности байтов(на начало которой указывает Env1) два нуля подряд. Поэтому пока какой-нибудь из 2-х соседних байтов не ноль((Env2^<>#0) or (PChar(DWord(Env2)+1)^<>#0)) делаем Inc. В итоге получаем размер окружения, равный Env2-Env1+2(+2, т.к. в самом конце оставляем 2 нуля).

PM MAIL   Вверх
Акакий
Дата 11.9.2011, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Цитата

ну и теперь дело остается за малым - в очередной раз убедиться, что все это не работает...(3 раза тьфу чтоб не сглазить)
убедился, таки сглазил наверное(надо было еще постучать 3 раза по голо...в смысле - по дереву), натурально ничего не работает.
Код

Var
  pp :RTL_USER_PROCESS_PARAMETERS;
  stDllU, stExeFileU, stCurDirU, stCmdLineU :TUnicodeString;
  stDllW, stExeFileW, stCurDirW, stCmdLineW :WideString;
  pEnv, p2 :Pointer;
  Env1, Env2 :PChar;
  pbi :PROCESS_BASIC_INFORMATION;

Procedure InitUnicodeString(Var  stU :TUnicodeString; Var  stBufW :WideString; Const  stInit :String);
  Begin
    stBufW:=stInit+#0;
    With stU do
      begin
        MaxLen:=Length(stBufW)*2; Len:=MaxLen-2; Buf:=@stBufW[1];
      end;
  end;

Begin
  ZwCreateProcess(@ProcessInfo.hProcess,PROCESS_ALL_ACCESS,Nil{@oa},$FFFFFFFF,False,0{hsection},0,0);
  ProcessInfo.hThread:=HiddenCreateRemoteThread(ProcessInfo.hProcess,RealEntryPoint,True,@ProcessInfo.dwThreadId);
  If GetThreadContextInt2E(ProcessInfo.hThread,Context) then
    begin
  //  If ZwUnmapViewOfSection(ProcessInfo.hProcess,Pointer(SelfNTHeaders.OptionalHeader.ImageBase))>=0 then
        begin
          BaseAddress:=VirtualAllocInt2E(ProcessInfo.hProcess,NTHeaders.OptionalHeader.ImageBase,RealSizeOfImage,MEM_COMMIT or MEM_RESERVE);
          HeaderSize:=NTHeaders.OptionalHeader.SizeOfHeaders;
          If Assigned(BaseAddress) then
            begin
              //пишем заголовок
              WriteOrReadProcessMemoryInt2E(True,ProcessInfo.hProcess,DWord(BaseAddress),ExeBuf,HeaderSize);
              For i:=0 to RealNumberOfSections-1 do  With RealSections[i] do
                begin
                  //пишем секции
                  WriteOrReadProcessMemoryInt2E(True,ProcessInfo.hProcess,DWord(BaseAddress)+VirtualAddress,
                                                Pointer(DWord(ExeBuf)+PointerToRawData),SizeOfRawData);
                  //на всяк случай контроль размера заголовка
                  If PointerToRawData<HeaderSize then  HeaderSize:=PointerToRawData;
                end;
              WriteOrReadProcessMemoryInt2E(True,ProcessInfo.hProcess,Context.Ebx+8,@BaseAddress,4);
              Context.Eax:=DWord(BaseAddress)+RealEntryPoint;
              If not SetThreadContextInt2E(ProcessInfo.hThread,Context) then
                begin
                  TerminateProcessInt2E(ProcessInfo.hProcess); Exit;
                end;
            end;
         end;
    end;
  InitUnicodeString(stExeFileU,stExeFileW,ParamStr(0));
  InitUnicodeString(stCurDirU,stCurDirW,ExtractFileDir(ParamStr(0)));
  InitUnicodeString(stCmdLineU,stCmdLineW,CommandLine);
  InitUnicodeString(stDllU,stDllW,'C:\WINDOWS\system32');
  RtlCreateProcessParameters(@pp,@stExeFileU,@stDllU,@stCurDirU,@stCmdLineU,0,Nil,Nil,Nil,Nil);
  Env1:=GetEnvironmentStrings; Env2:=Env1;
  If Env2=Nil then  Exit;
  While (Env2^<>#0) or (PChar(DWord(Env2)+1)^<>#0) do  Inc(Env2);
  pEnv:=VirtualAllocInt2E(ProcessInfo.hProcess,0,Env2-Env1+2,MEM_COMMIT or MEM_RESERVE);
  WriteOrReadProcessMemoryInt2E(True,ProcessInfo.hProcess,DWord(pEnv),Env1,Env2-Env1+2);
  pp.Environment:=pEnv;
  p2:=VirtualAllocInt2E(ProcessInfo.hProcess,0,SizeOf(pp),MEM_COMMIT or MEM_RESERVE);
  WriteOrReadProcessMemoryInt2E(True,ProcessInfo.hProcess,DWord(p2),@pp,SizeOf(pp));
  ZwQueryInformationProcess(ProcessInfo.hProcess,ProcessBasicInformation,@pbi,SizeOf(pbi),Nil);
  WriteOrReadProcessMemoryInt2E(True,ProcessInfo.hProcess,DWord(pbi.PebBaseAddress)+$10,@p2,4);
  RtlDestroyProcessParameters(@pp);
  If _ResumeThread(ProcessInfo.hThread)=0 then  Exit;
end;

все создается, процесс, поток и т.д., проходит примерно секунда и за сим процесс уходит в мир иной...

Это сообщение отредактировал(а) Акакий - 11.9.2011, 19:00
PM MAIL   Вверх
Акакий
Дата 13.9.2011, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Иго-го!!!! Оказывается, приложение можно запустить, вообще не вызывая Nt/ZwCreateProcess/Int $2E/call fs:[$C0]. И притом сделать это из ring3!!!! Проверено на WinXP32/64bit и Win7 32/64bit. Иго-го!!!!  smile 
PM MAIL   Вверх
kami
Дата 19.9.2011, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 15
Всего: 72



Цитата(Акакий @  13.9.2011,  21:12 Найти цитируемый пост)
Оказывается, приложение можно запустить, вообще не вызывая Nt/ZwCreateProcess/Int $2E/call fs:[$C0]

"Народ требует опровержения" (с) чье-то. В смысле - каким путем для этого нужно пойти? (понятно, что верным путем, но тем не более).
PM MAIL WWW   Вверх
Акакий
Дата 20.9.2011, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 6.7.2009

Репутация: нет
Всего: нет



Цитата(kami @  19.9.2011,  12:48 Найти цитируемый пост)
"Народ требует опровержения" (с) чье-то. В смысле - каким путем для этого нужно пойти? (понятно, что верным путем, но тем не более).

Натурально ничего сверхъестественного, мне до Воланда и его свиты, как Акакию до собора парижской богоматери и даже дальше... вообщем - далеко очень  smile  
Берем сисер и смотрим, что происходит по адресу, записанному в IDT по смещению $170 при eax=$2F  smile  Думаем, бросаем думать, снова думаем, вспоминаем про CloseHandle, DuplicateHandle и SetInformationThread, и догадываемся, как можно сделать почти то же самое в р3.

Только не все так гладко, как сладко... Созданный таким образом процесс имеет ограничения:
 - в процессе не будут работь следующие API: CreateProcess, Sleep/NtDelayExecution/WaitForSingleObject, WaitForDebugEvent,  ContinueDebugEvent;
 - из предыдущего, в числе прочего, следует, что такой процесс будет полностью съедать ресурсы 1 ядра CPU. Но выход из  ситуации все же есть - вызывать для потоков нашего процесса SuspendThread/ResumeThread из другого процесса, кроме того, то же самое можно делать из потоков, внедренных в процесс извне(но не из созданных самим процессом)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1526 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.