![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поток без длл или самодостаточный код
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.
Меня интересует - всё ли в этом примере правильно - нет ли негде "подводных камней" ?
И, что будет, если в созданном потоке возникнет исключение - "процесс-носитель" в этом случае завершится ? - как в таком случае можно обрабатывать исключения ?
n0name (2004-11-25 11:35:00) [21]Digitman мне кажется что Win9X это анахроизм.
У меня его нет, и я не могу программировать под него.
Digitman (2004-11-24 17:41:00) [22]
> -SeM- (24.11.04 16:43) [88]
ХАкать я бы не посоветовал.
Xaker (2004-11-24 17:40:00) [23]n0name (24.11.04 12:06) [86]
> Что насчёт загрузки кернела, то измени ImageBase в
> PE-заголовке при компиляции на предпологаемый адрес
> кернела.
Ошибка: Недопустимое перемещение системной DLL
- не хочет запускаться ..
самое интересное, что можно больше сделать и меньше - будет работать ...
-SeM- (2004-11-24 16:43:00) [24]Digitman © (24.11.04 13:16) [87]
И на маздай то же - ха! Но для этого надо как-то узнать адрес загрузки кернел. Что и пытаюсь определить http://www.delphimaster.ru/cgi-bin/forum.pl?id=1101201473&n=5&web=1
Digitman (2004-11-24 13:16:00) [25]
> n0name (24.11.04 12:06) [86]
> Никаких извращений - NtTerminateProcess
это ты - про НТ... а про маздайную линейку ?
> Причём обязательно вторым по счету
опять же - а для маздая кто будет первым ?
n0name (2004-11-24 12:06:00) [26]>Digitman © (24.11.04 10:37) [82]
На это (ExitProcess) я отвечу : ха!
Никаких извращений - NtTerminateProcess(DWORD(-1), 0).
Что насчёт загрузки кернела, то измени ImageBase в PE-заголовке при компиляции на предпологаемый адрес кернела.
Загрузчик PE ВСЕГДА для Win32-приложений грузит kernel32.dll. Причём обязательно вторым по счету.
Игорь Шевченко (2004-11-24 11:30:00) [27]Digitman © (24.11.04 11:04) [84]
Нет, исходный текст тут не причем, такая связь при импорте символов устанавливается, насколько мне известно. Опытным путем было установлено, что при попытке залезть в область адресов kernel32.dll программа не запускается из-за того, что kernel32.dll не может быть перемещена.
Digitman (2004-11-24 11:04:00) [28]
> Игорь Шевченко © (24.11.04 10:59) [83]
да, точно, перепутал.
строго наоборот.
> Про попытке запустить программу, которая в адресном пространстве
> занимает область kernel32.dll такая программа просто не
> запускается
и анализ исх.текста это также подтверждает ?
Игорь Шевченко (2004-11-24 10:59:00) [29]Digitman © (24.11.04 10:37) [82]
> Особенно это касается НТ-платформы, где kernel32 грузится
> в верхние (системные) 2Гб АП процесса, куда при всем желании
> пользовательские модули загрузить (дабы вынудить систему
> "подвинуть" kernel32) не удастся
Это ты с Win9x перепутал, извини.
> Так что вероятность изменения факт.адреска загрузки kernel32
> по отношения к предпочтительному в НТ практически равна
> нулю
Теоретически она тоже равна нулю, так как на фиксированные адреса в kernel32 ссылаются другие системные библиотеки. Про попытке запустить программу, которая в адресном пространстве занимает область kernel32.dll такая программа просто не запускается.
Digitman (2004-11-24 10:37:00) [30]
> n0name (24.11.04 09:36) [81]
> Win32-приложение может и не импортировать никаких функций
> из kernel32.dll
Нормальное (без выкрутасов с RET) win32-приложение импортирует из kernel32.dll как минимум одну ф-цию - ExitProcess(), поскольку в соответствии с док-цией Майкрософт вызов этой ф-ции есть предпочтительный способ нормального завершения процесса.
> будет грузиться вторым(после ntdll.dll)
ну и что ? предпочтительный адрес загрузки kernel32 выбран разработчиком ОС таким образом, что вынужденное изменение его системой в подавляющем большинстве не требуется. Особенно это касается НТ-платформы, где kernel32 грузится в верхние (системные) 2Гб АП процесса, куда при всем желании пользовательские модули загрузить (дабы вынудить систему "подвинуть" kernel32) не удастся. К тому же докум.загрузка пользов. PE-модулей осуществляется с пом. LoadLibrary(), которая опять же требует уже загруженной kernel32.
Так что вероятность изменения факт.адреска загрузки kernel32 по отношения к предпочтительному в НТ практически равна нулю. Она (такая вероятность), конечно же, больше нуля в Маздае, но с учетом того, что нормальныеприложения грузят kernel32 первым модулем в цепочке требуемых к импорту, этой вероятностью опять же можно пренебречь.
В конечном итоге, ДАЖЕ если сомнения существуют, можно просканировать АП целевого процесса на предмет обнаружения какой-либо сигнатуры, идентифицирующей kernel32, и найдя таковую с учетом ее смещения отн-но начала образа получить фактический базовый адрес.
n0name (2004-11-24 09:36:00) [31]>Игорь Шевченко © (24.11.04 00:13) [79]
Спасибо за информацию, обязательно напишу.
>Digitman © (24.11.04 08:18) [80]
Вот именно, как правило :)
Win32-приложение может и не импортировать никаких функций из kernel32.dll, но он будет грузиться вторым(после ntdll.dll).
Digitman (2004-11-24 08:18:00) [32]
> Piter © (23.11.04 23:26) [78]
имелся ввиду не какой-то конкретный адрес, а то что в рамках одной и той же сессии ОС образ модуля kernel32 в АП всех использующих его приложениях будет находиться по одному и тому же адресу, поскольку как правило статически загружается одним из первых системных модулей, импортируемых win32-приложениями.
Игорь Шевченко (2004-11-24 00:13:00) [33]n0name (23.11.04 19:32) [77]
Из отладчика WinDbg и символов Windows.
Есть предложение - если тебя интересуют знания потрохов, структур и так далее - пиши на whitefranz@hotmail.com
Piter (2004-11-23 23:26:00) [34]>Kernel32.dll не всегда грузится по одному адресу
понятно. Просто я почитал:
Digitman © (12.11.04 12:46) [9]
основываясь на достаточно устойчивом факте загрузки kernel32 по фикс.адресу
и понял, что на это фактически можно полагаться...
n0name (2004-11-23 19:32:00) [35]Игорь Шевченко © (22.11.04 15:04) [75]
Спасибо, можешь подсказать, откуда у тебя эти сведения?
Piter © (22.11.04 15:41) [76]
Kernel32.dll не всегда грузится по одному адресу. Если ImageBase программы равен адресу ImageBase kernel32.dll, то используются релоки и длл грузится по другому адресу.
Piter (2004-11-22 15:41:00) [36]Извините, а можно вопрос? Зачем вы пишете свой GetModuleHandle? Ведь он находится в kernel, который грузится по одному и тому же адресу. Сори, если я чего-то не понял...
Игорь Шевченко (2004-11-22 15:04:00) [37]n0name (22.11.04 13:30) [74]
b003: byte;
d004: DWORD;
--------------
SpareBool : UChar;
Mutant : Ptr32;
==============
d028: DWORD;
--------------
EnvironmentUpdateCount : Uint4B;
==============
d030: DWORD;
do34: DWORD;
d038: DWORD;
-------------
SystemReserved : Uint4B;
ExecuteOptions : Uint4B; {Pos 0, 2 Bits, SpareBits : Pos 2, 30 Bits }
FreeList : Ptr32; { _PEB_FREE_BLOCK }
=============
p04C: Pointer;
p050: Pointer;
TextInfo: Pointer;
-----------
ReadOnlySharedMemoryBase : Ptr32;
ReadOnlySharedMemoryHeap : Ptr32;
ReadOnlyStaticServerData : Ptr32;
===========
И так далее.
n0name (2004-11-22 13:30:00) [38]Xaker © (22.11.04 12:17) [73]
TPEB=packed record
InheritedAddressSpace: boolean;
ReadImageFileExecOptions: boolean;
BeingDebugged: boolean;
b003: byte;
d004: DWORD;
SectionBaseAddress: Pointer;
Ldr: PPebLdrData;
ProcessParameters: PPROCESS_PARAMETERS;
SubSystemData: DWORD;
ProcessHeap: THandle;
FastPebLock: PCRITICAL_SECTION;
AcquireFastPebLock: Pointer;
ReleaseFastPebLock: Pointer;
d028: DWORD;
User32Dispatch: PPointer;
d030: DWORD;
do34: DWORD;
d038: DWORD;
TlsBitMapSize: DWORD;
TlsBitMap: PRTL_BITMAP;
TlsBitMapData: array [0..1] of DWORD;
p04C: Pointer;
p050: Pointer;
TextInfo: Pointer;
InitAnsiCodePageData: Pointer;
InitOemCodePageData: Pointer;
InitUnicodeCaseTableData: Pointer;
KeNumberProcessors: DWORD;
NtGlobalFlag: DWORD;
d6C: DWORD;
MmCriticalSectionTimeout: LARGE_INTEGER;
MmHeapSegmentReserve: DWORD;
MmHeapSegmentCommit: DWORD;
MmHeapDeCommitTotalFreeThreshold: DWORD;
MmHeapDeCommitFreeBlockThreshold: DWORD;
NumberOfHeaps: DWORD;
AvailableHeaps: DWORD;
ProcessHeapsListBuffer: PHandle;
d094: DWORD;
d098: DWORD;
d09C: DWORD;
LoaderLock: PCRITICAL_SECTION;
NtMajorVersion: DWORD;
NtMinorVersion: DWORD;
NtBuildNumber: WORD;
CmNtCSDVersion: WORD;
PlatformId: DWORD;
Subsystem: DWORD;
MajorSubsystemVersion: DWORD;
MinorSubsystemVersion: DWORD;
AffinityMask: KAFFINITY;
ad0C4: array [0..34] of DWORD;
p150: Pointer;
ad154: array [0..31] of DWORD;
Win32WindowStation: THandle;
d1D8: DWORD;
d1DC: DWORD;
CSDVersion: PWORD;
d1E4: DWORD;
end;
Xaker (2004-11-22 12:17:00) [39]n0name (22.11.04 11:57) [72]
big thanks ещё проблема с FirstMod:=GetCurrentPEB.Ldr.InLoadOrderModuleList.FLink;- где тамLdrиInLoadOrderModuleList?
(интересует PPEB)
n0name (2004-11-22 11:57:00) [40]Xaker © (22.11.04 11:26) [71]
TLdrDataTableEntry=packed record
InLoadOrderLinks: TListEntry; //+0
InMemoryOrderLinks: TListEntry; //+8
InInitializationOrderLinks: TListEntry; //+16
DllBase: Pointer; //+24
EntryPoint: Pointer; //+28
SizeOfImage: Cardinal; //+32
FullDllName: UNICODE_STRING; //+36
BaseDllName: UNICODE_STRING; //+44
Flags: cardinal; //+52
LoadCount: word; //+56
TlsIndex: word; //+58
HashLinks: TListEntry; //+60
SectionPointer: Pointer; //+68
CheckSum: Cardinal; //+72
TimeDateStamp: Cardinal; //+76
LoadedImports: Pointer; //+80
end; //Size: 84
PLdrDataTableEntry=^TLdrDataTableEntry;
TLdrListEntry=packed record
ListEntry: TListEntry;
LdrDataTableEntry: TLdrDataTableEntry;
end;
PLdrListEntry=^TLdrListEntry;
TPebLdrData=packed record
length: Cardinal;
initialized: Cardinal;
SsHandle: Pointer;
InLoadOrderModuleList: TListEntry;
InMemoryOrderModuleList: TListEntry;
InInitializationOrderModuleList: TListEntry;
end;
PPebLdrData=^TPebLdrData;
Игорь Шевченко © (22.11.04 11:17) [70]
Я так и думал :)