![]() |
| ||
|
|
Новости |
Поиск |
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.
Меня интересует - всё ли в этом примере правильно - нет ли негде "подводных камней" ?
И, что будет, если в созданном потоке возникнет исключение - "процесс-носитель" в этом случае завершится ? - как в таком случае можно обрабатывать исключения ?
Xaker (2004-12-05 02:21:00) [1]Удалено модератором
Примечание: Создание пустых сообщений. Предупреждение тебе
Игорь Шевченко (2004-12-01 23:08:00) [2]n0name (01.12.04 13:47) [109]
Я бы тебе посоветовал переделать функции LdrLockLoaderLock и LdrUnlockLoaderLock
на
type
TLdrLockLoaderLock: function (Flags: DWORD; Aresult, Magic: PDWORD): NTSTATUS; stdcall;
TLdrUnlockLoaderLock: function (Flags, Magic: DWORD): NTSTATUS; stdcall;
var
_LdrLockLoaderLock: TLdrLockLoaderLock;
_LdrUnlockLoaderLock: TLdrUnlockLoaderLock;
procedure InitAPI;
var
NtDLLHandle: THandle;
begin
NtDLLHandle:=GetNtDLLHandle;
@_LdrLockLoaderLock:=xGetProcAddress(NtDLLHandle, 'LdrLockLoaderLock');
@_LdrUnlockLoaderLock:=xGetProcAddress(NtDLLHandle, 'LdrUnlockLoaderLock');
end;
function LdrLockLoaderLock (Flags: DWORD; Aresult, Magic: PDWORD): NTSTATUS; stdcall;
begin
if Assigned(_LdrLockLoaderLock) then
Result := _LdrLockLoaderLock (Flags, Aresult, Magic)
else begin
Result := NT_SUCCESS;
EnterCriticalSection(CurrentPEB.LoaderLock);
end;
end;
function LdrUnlockLoaderLock (Flags, Magic: DWORD): NTSTATUS; stdcall;
begin
if Assigned(_LdrUnlockLoaderLock) then
Result := _LdrUnlockLoaderLock (Flags, Magic)
else begin
Result := NT_SUCCESS;
LeaveCriticalSection(CurrentPEB.LoaderLock);
end;
end;
Причина в том, что функции блокировки загрузчика экспортируются из NTDLL только в WinXP, Win2003 и в LongHorn.
n0name (2004-12-01 13:47:00) [3]
unit xFuncs;
interface
uses
CommonTypes,
StrFuncs,
PETypes,
xTypes;
function xGetModuleHandle(ModuleName: PChar): HMODULE;
function xGetProcAddress(hMod: HMODULE; ProcName: PChar): Pointer;
implementation
var
LdrLockLoaderLock: function (Flags: DWORD; result, Magic: PDWORD): NTSTATUS; stdcall;
LdrUnlockLoaderLock: function (Flags, Magic: DWORD): NTSTATUS; stdcall;
function GetCurrentPEB: PPEB;
asm
mov eax, fs:[30h]
mov result, eax
end;
function xGetProcAddress(hMod: HMODULE; ProcName: PChar): Pointer;
var
ExportDir: PImageExportDirectory;
i, IndInAddr: DWORD;
begin
result:=nil;
ExportDir:=PImageExportDirectory(PImageNtHeaders(hMod+DWORD(PImageDosHeader(hMod).e_lfanew)).OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress+hMod);
for i:=0 to ExportDir.NumberOfNames-1 do
begin
if ComparePCharStrings(PChar(PDWORD(DWORD(ExportDir.AddressOfNames)+hMod+i*4)^+hMod), ProcName) then
begin
IndInAddr:=PWORD(DWORD(ExportDir.AddressOfNameOrdinals)+hMod+i*2)^;
result:=Pointer(PDWORD(DWORD(ExportDir.AddressOfFunctions)+hMod+IndInAddr*4)^+hMod);
end;
end;
end;
function GetNtDLLHandle: HModule;
begin
result:=DWORD(PLdrDataTableEntry(PLdrDataTableEntry(GetCurrentPEB.Ldr.InLoadOrderModuleList.FLink)^.
InLoadOrderLinks.Flink)^.DllBase);
end;
procedure InitAPI;
var
NtDLLHandle: THandle;
begin
NtDLLHandle:=GetNtDLLHandle;
@LdrLockLoaderLock:=xGetProcAddress(NtDLLHandle, 'LdrLockLoaderLock');
@LdrUnlockLoaderLock:=xGetProcAddress(NtDLLHandle, 'LdrUnlockLoaderLock');
end;
function xGetModuleHandle(ModuleName: PChar): HMODULE;
var
FirstMod: Pointer;
CurrentMod: TLdrDataTableEntry;
LdrLockMagic: DWORD;
begin
InitAPI;
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;
end.
Xaker (2004-12-01 13:14:00) [4]n0name (01.12.04 10:52) [107]
выкладывай :))
потестим :)
n0name (2004-12-01 10:52:00) [5]Если ты про xGetModuleHandle и xGetProcAddress. Я сделал новую версию. В прошлых было несколько багов, теперь их нет.
Xaker (2004-11-30 23:14:00) [6]TankMan © (30.11.04 15:01) [102]
код работает .. улучшаем . :)
Piter © (30.11.04 21:01) [105]
я сам пока точноне выяснил...
Piter (2004-11-30 21:01:00) [7]Xaker © (30.11.04 13:24) [99]
а чем выделяется стек потока трояна? Колись...
TankMan (2004-11-30 20:58:00) [8]>>n0name
:)) Самый самый верхний :)
n0name (2004-11-30 15:08:00) [9]//TankMan © (30.11.04 15:01) [102]
Какой код?
TankMan (2004-11-30 15:01:00) [10]Прочитал я эту ветку...и у меня вопрос возник, вы всетаки хотите довести этот код до ~100% вероятности работоспособности или просто так спорите?
Xaker (2004-11-30 14:24:00) [11]Digitman © (30.11.04 13:29) [100]
ок, спасибо, постараюсь сделать его более "нормальным" :))
- а что там лучше указывать ? - какое значение ?
- чтобя вообще не выделялся ?
Digitman (2004-11-30 13:29:00) [12]
> Xaker © (30.11.04 13:24) [99]
размер стека трэда задается 2-м параметром при вызове ф-ций CreateThread/CreateRemoteThread
Xaker (2004-11-30 13:24:00) [13]n0name (30.11.04 10:33) [98]
чтобы не выделялся ;))
n0name (2004-11-30 10:33:00) [14]Для чего тебе "подправлять" стек?
Xaker (2004-11-28 23:25:00) [15]Остался вопрос, а как можно подправить стёа потока, чтобы он был "нормальным" ?
n0name (2004-11-25 14:03:00) [16]Digitman © (25.11.04 12:09) [93]
-SeM- (25.11.04 12:21) [94]
Как программист я должен учитывать эту возможность(есть же слабые компы). А как юзер давно простился с линейкой Win9X.
Но еа каждый хитрый болт есть своя хитрая гайка.
Что можно сделать в WinNT+ можно сделать и в Win9X. Вопрос в другом сколько займёт реализация...
Например в Win9X нет NativeAPI. Если хочешь реализуй нужную функцию сам.
n0name (2004-11-25 14:03:00) [17]Удалено модератором
Примечание: Дубль
-SeM- (2004-11-25 12:21:00) [18]Digitman © (25.11.04 12:03) [92]
Да нет, ты не правильно понял. Ответ там же.
n0name (25.11.04 11:35) [91]
А ты, как программист, разве не должен учитывать то, что твоя прога может быть запущена на другой линейке ОС. Или ты предпочитаешь писать в реадми, что прога работает только на NT линейке?
Digitman (2004-11-25 12:09:00) [19]
> мне кажется что Win9X это анахроизм
ну наверно она, эта линейка ОС, потому маздайной и зовется, что изначально рождалась под флагом "Должна умереть") ... что ж, для тебя она уже умерла ... аминь)
Digitman (2004-11-25 12:03:00) [20]
> -SeM- (24.11.04 16:43) [88]
> для этого надо как-то узнать
> адрес загрузки кернел. Что и пытаюсь определить http://www.delphimaster.ru/cgi-bin/forum.pl?id=1101201473&n=5&web=1
в той ветке ты поехал в совершенно иной огород - создание KMD ..
никак не вяжется что-то поднятая тобой проблема определения адреса загрузки модуля kernel32 как модуля режима пользователя с программированием KMD, использующего модули и ф-ции именно режима ядра, но никак не режима пользователя ..