Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Поток без длл или самодостаточный код


Страницы:   1 2 3 4 5 6

kaZaNoVa ©   (2004-11-10 18:01:00) 

Идея: создать программу, которая могла бы "создавать самодостаточный код" - в плане того, чтобы возможно внедриться в другой процесс, и при этом НЕ подгружать дополнительных DLL ;)
Я давно интересовался этой темой, и только недавно нащёл реализацию:
(использованы материалы с сайта   http://www.iamaphex.cjb.net)
код:
program Project1;

{$IMAGEBASE $13140000}

uses
 Windows;

function Main(dwEntryPoint: Pointer): longword; stdcall;
begin
 LoadLibrary('kernel32.dll');
 LoadLibrary('user32.dll');
    MessageBox(0, 'Ok', 'Hijacked Process', 0);
// ExitProcess(0);
 Result := 0;
end;

procedure Inject(ProcessHandle: longword; EntryPoint: pointer);
var
 Module, NewModule: Pointer;
 Size, BytesWritten, TID: longword;
begin
 Module := Pointer(GetModuleHandle(nil));
 Size := PImageOptionalHeader(Pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;
 VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE);
 NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
 WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten);
 CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID);
end;

var
 ProcessHandle, PID: longword;
begin
 GetWindowThreadProcessId(FindWindow('Progman', nil), @PID);
 ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
 Inject(ProcessHandle, @Main);
 CloseHandle(ProcessHandle);
end.


Меня интересует - всё ли в этом примере правильно - нет ли негде "подводных камней" ?

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


Xaker   (2004-11-22 11:26:00) [41]

n0name   (20.11.04 18:14) [63]
ловко ты придумал
а что такое TLdrDataTableEntry?


Игорь Шевченко   (2004-11-22 11:17:00) [42]

n0name   (22.11.04 11:11) [69]

Всегда. Там же находится загрузчик, который загружает все-все остальное.


n0name   (2004-11-22 11:11:00) [43]

Не знаешь, всегда ли ntdll.dll загружается первым?(не в драйверах). Мне просто лучше использовать дин. загрузку.


Игорь Шевченко   (2004-11-21 20:01:00) [44]


> Не знаю почему он тебе кажется знакомым.


Где-то видел, может, аналогичный. Что-то сам писал пару лет назад, только идентификаторы брались из WinDbg, а они там несколько иные в структуре LDR_DATA_TABLE_ENTRY


n0name   (2004-11-21 19:21:00) [45]

n0name   (21.11.04 18:27) [66]

Я не вытерпел и дизасмил всё-таки GetModuleHandle :)
Нашёл эти функции - LdrLockLoaderLock и LdrUnlockLoaderLock.
Пока искал их прототипы нашёл для себя много интересного. Например предпологаемый код некоторых фунций, используемых загрузчиком(т.е. LdrLoadDll, LdrUnloadDll, etc).

Если интересно, вот ковая версия xGetModuleHandle(greet Игорь Шевченко):

function LdrLockLoaderLock(Flags: DWORD; result, Magic: PDWORD): NTSTATUS; stdcall; external 'ntdll.dll';
function LdrUnlockLoaderLock(Flags, Magic: DWORD): NTSTATUS; stdcall; external 'ntdll.dll';
....
function xGetModuleHandle(ModuleName: PChar): HMODULE;
var
FirstMod: Pointer;
CurrentMod: TLdrDataTableEntry;
LdrLockMagic: DWORD;
begin
result:=0;

LdrLockLoaderLock(0, nil, @LdrLockMagic);

FirstMod:=GetCurrentPEB.Ldr.InLoadOrderModuleList.FLink;
CurrentMod:=PLdrDataTableEntry(FirstMod)^;
repeat
 if FirstMod=CurrentMod.InLoadOrderLinks.FLink then
  exit;
 if CompareMultibyteWithAnsi(CurrentMod.BaseDllName.Buffer, ModuleName) then
  begin
   result:=DWORD(CurrentMod.DllBase);
   exit;
  end;
 CurrentMod:=PLdrDataTableEntry(CurrentMod.InLoadOrderLinks.Flink)^;
until (not true);

LdrUnlockLoaderLock(0, LdrLockMagic);
end;


n0name   (2004-11-21 18:27:00) [46]

Игорь Шевченко ©   (20.11.04 18:39) [65]    
Не знаю почему он тебе кажется знакомым.
Писал полностью я. Без привлечения сторонних исходников и документации. Корме ,пожалуй, описания PE-формата.

Про какой загрузчик ты говоришь?
Если ты насчёт того, что во время перебора TLdrDataTableEntry могут загрузиться новые модули, то я не знаю какой функцией это выполняется. Можешь подсказать? (Мне неохота заниматься дизасмингом GetModuleHandle).

kaZaNoVa ©   (20.11.04 18:27) [64]
Весь DrvTypes я выкладывать не буду(47,7 KB   1831 строк кода).
Скажи нужные тебе типы и константы.


Игорь Шевченко   (2004-11-20 18:39:00) [47]


> PS: Весь код написан мною.


А кажется таким знакомым...отдельные места.

Кстати, совет - в процедуре GetModuleHandle блокируй загрузчик, а по выходе разблокируй.


kaZaNoVa   (2004-11-20 18:27:00) [48]

n0name   (20.11.04 18:14) [63]
огромное спасибо :)

можно ещё

>unit xFuncs;
>
>interface
>
>uses
> DrvTypes;

- можно ещё на юнит DrvTypesпосмотреть  ?


n0name   (2004-11-20 18:14:00) [49]

Я со своей стороны считаю что позиционно-независимый(так как я понимаю) создать в Delphi возможно. Основная трабла с определением API. Так вот алт. код GetProcAddress и GetModuleHandle.


unit xFuncs;

interface

uses
DrvTypes;

function xGetModuleHandle(ModuleName: PChar): HMODULE;
function xGetProcAddress(hMod: HMODULE; ProcName: PChar): Pointer;

implementation

function GetCurrentPEB: PPEB;
asm
mov eax, fs:[30h]
mov result, eax
end;

function CompareMultibyteWithAnsi(str1: PWChar; str2: PChar): boolean;
var
i: DWORD;
begin
result:=false;
i:=0;
while (PChar(DWORD(str1)+i*2)^<>#0) and (str2[i]<>#0) do
 begin
  if PChar(DWORD(str1)+i*2)^<>str2[i] then
   exit;
  inc(i);
 end;
result:=true;
end;

function GetPCharLength(str1: PChar): DWORD;
begin
result:=0;
while (str1[result]<>#0) do
 inc(result);
end;

function ComparePCharStrings(str1, str2: PChar): boolean;
var
i: DWORD;
begin
result:=false;
i:=0;
if GetPCharLength(str1)<>GetPCharLength(str2) then
 exit;
while (str1[i]<>#0) do
 begin
  if str1[i]<>str2[i] then
   exit;
  inc(i);
 end;
result:=true;
end;

function xGetModuleHandle(ModuleName: PChar): HMODULE;
var
FirstMod: Pointer;
CurrentMod: TLdrDataTableEntry;
begin
result:=0;

FirstMod:=GetCurrentPEB.Ldr.InLoadOrderModuleList.FLink;
CurrentMod:=PLdrDataTableEntry(FirstMod)^;
repeat
 if FirstMod=CurrentMod.InLoadOrderLinks.FLink then
  exit;
 if CompareMultibyteWithAnsi(CurrentMod.BaseDllName.Buffer, ModuleName) then
  begin
   result:=DWORD(CurrentMod.DllBase);
   exit;
  end;
 CurrentMod:=PLdrDataTableEntry(CurrentMod.InLoadOrderLinks.Flink)^;
until (not true);
end;

function xGetProcAddress(hMod: HMODULE; ProcName: PChar): Pointer;
var
ExportDir: PImageExportDirectory;
dwAddressOfNames: DWORD;
dwAddressOfFunctions: DWORD;
i: DWORD;
begin
result:=nil;
ExportDir:=PImageExportDirectory(PImageNtHeaders(hMod+DWORD(PImageDosHeader(hMod)._lfanew)).OptionalHeader.
 DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+hMod);
dwAddressOfNames:=DWORD(ExportDir.AddressOfNames);
dwAddressOfFunctions:=DWORD(ExportDir.AddressOfFunctions);
for i:=0 to ExportDir.NumberOfNames-1 do
 if ComparePCharStrings(PChar(PDWORD(dwAddressOfNames+hMod+i*4)^+hMod), ProcName) then
  result:=Pointer(PDWORD(dwAddressOfFunctions+hMod+i*4)^+hMod);
end;

end.


PS: Весь код написан мною.


kaZaNoVa   (2004-11-20 15:40:00) [50]

Я проанализировал работу кода в "целевом" процессе и пришёл к выводу что "позиционно-независимый" код стандартными средствами Delphi создать крайне сложно и практически неприемлимо (как и драйвер).

После многочисленных экспериментов я пришёл к выводу , что единственный способ _достаточно простой и работоспособный_ - это способ с ImageBase.

Мой "финальный демонстрационный код" (итог моих "изысканий") :

program loader;
{$IMAGEBASE $70000000}
uses
 Windows;

Var
hProcess, hTh: THandle;
MemPtr: Pointer;
PID,ExitCode,Size,BytesWritten,ThreadID: Cardinal;

function Main(dwEntryPoint: Pointer): longword; stdcall;
begin
LoadLibrary('kernel32.dll');
LoadLibrary('user32.dll');
MessageBox(0,'Fantastika !!!', 'Hijacked Process', 0);
Result:=0;
end;

begin
GetWindowThreadProcessId(FindWindow('Progman', nil), @PID);
if PID = 0 then Exit;

MemPtr:= Pointer(GetModuleHandle(nil));

Size := PImageOptionalHeader(Pointer(integer(MemPtr) + PImageDosHeader(MemPtr)._lfanew + SizeOf(dword) + SizeOf(TImageFileHeader))).SizeOfImage;

hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,true,PID);

if hProcess = 0 then Exit;

BytesWritten:=0;
VirtualFreeEx(hProcess,MemPtr, 0, MEM_RELEASE);
 MemPtr := VirtualAllocEx(hProcess,MemPtr, Size , MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE );

 if MemPtr <> nil then
 begin
   if WriteProcessMemory(hProcess, MemPtr,MemPtr, Size, BytesWritten) then
   begin
   hTh := CreateRemoteThread(hProcess, nil, 0,@Main,MemPtr, 0, ThreadID);
     if hTh <> 0 then
     begin
       if (WaitForSingleObject(hTh,INFINITE) = WAIT_OBJECT_0) and
         GetExitCodeThread(hTh, ExitCode) then CloseHandle(hTh);
     end;
   end ;
   VirtualFreeEx(hProcess, MemPtr, 0, MEM_RELEASE);  //?
 end;
 CloseHandle(hProcess);
end.


Игорь Шевченко ©   (19.11.04 16:23) [61]
Со своей стороны считаю тему "закрытой" ;)


Игорь Шевченко   (2004-11-19 16:23:00) [51]

Если пустые сообщения не прекратятся ветка будет закрыта.

С уважением,
Ко-модератор


kaZaNoVa   (2004-11-19 16:09:00) [52]

а так я понял, что полностью грамотно пока сделать не могу ..  ;(


kaZaNoVa   (2004-11-19 16:08:00) [53]

Digitman ©   (19.11.04 15:56) [57]

> готовых нет, не будет и быть не может по определению.

я нашёл одно (оно в самом первом посте .. ) но оно, как я уже убедился в общем случае неверное ....

п.с. буду ждать примеры %)))


kaZaNoVa   (2004-11-19 16:05:00) [54]

Digitman ©   (19.11.04 15:56) [57]
ок ;))
спасибо за совет .. :))

> внедрение ДЛЛ

эх .. старое решение ..  но надёжное :))


Digitman   (2004-11-19 15:56:00) [55]


> мне просто некогда щас более заниматься этой идее


а это твои проблемы.


> хотел спросить - может кто уже пробовал .. - поучиться на
> примерах .. (так хочется "готовое решение" найти


готовых нет, не будет и быть не может по определению.
хочешь быстрое и беспроблемное решение ?
его ты уже знаешь - внедрение ДЛЛ ... и это решение - далеко не самое худшее.


kaZaNoVa   (2004-11-19 15:48:00) [56]

Digitman ©   (19.11.04 13:03) [54]
мне просто некогда щас более заниматься этой идеей ..

- и хотел спросить - может кто уже пробовал .. - поучиться на примерах .. (так хочется "готовое решение" найти ..)

:)


Cobalt   (2004-11-19 15:43:00) [57]

> по кр.мере на первых порах
Я бы сказал "на первых годах" :)


Digitman   (2004-11-19 13:03:00) [58]


> kaZaNoVa ©   (19.11.04 12:18) [53]
> Кто-нить пробовал реализовать сабж ?


ты о чем ?


kaZaNoVa   (2004-11-19 12:18:00) [59]

Кто-нить пробовал реализовать сабж ?
- постите, плиз ..


kaZaNoVa   (2004-11-17 18:42:00) [60]

Digitman ©   (17.11.04 8:09) [51]
ок, спасибо огромное, попробую под отладчиком всесторонне изучить :)


Страницы:   1 2 3 4 5 6

Наверх

Титульная страница Поиск, карта сайта Написать письмо