Вернуться   CoderX :: Forums > Основные форумы > Программинг
Войти через OpenID

Программинг Форум для тем связанных с программированием

Чат (Новых сообщений с момента вашего последнего визита нет)
Загрузка...
Задавайте ваши вопросы на форуме. Чат предназначен для небольших разговоров.
 
Ответ
 
Опции темы Опции просмотра
Старый 28.12.2024, 14:32   #1
Рыцарь
 
Аватар для VORON
 
Регистрация: 06.08.2007
Сообщений: 223
Сказал Спасибо: 6
Имеет 67 спасибок в 34 сообщенях
VORON пока неопределено
По умолчанию

Delphi Код:
{Устанавливаем отладочные привилегии для своего(этого) процесса САР, т.к. без данных привилегий код внедрения работать не будет. я не смогу это прокоментировать так как нихрена это не понимаю ну смысл понятен там и так. код самодостаточен и вродебы переносим копипастом. пусть работает главное не трогать руками} szPrivilege:='SeDebugPrivilege'; fEnable:=true;//вкл или выкл отладочные привы, это если в функцию собрать этот код удобно OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken); LookupPrivilegeValue(nil, szPrivilege, luid); NewState.PrivilegeCount := 1; NewState.Privileges[0].Luid := luid; if (fEnable) then   begin     NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED   end   else   begin     NewState.Privileges[0].Attributes := 0;   end; AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength); CloseHandle(hToken); // Открываем процесс жертвы. чтобы это не значило... но знайте что это не то что вы знаете или подумали.. {цель получить хэндл на процесс с помощью которого можно манипулировать процессом} hProc := OpenProcess(PROCESS_ALL_ACCESS, false, ProcPID); {сохраним в глобальную переменную этот хэндл, потом он пригодится чтобы создать локальную копию Хэндла для чтения из пайпа} g_DllHandle:=hProc; memo1.Lines.Add('открываем процесс получаем его ХЭНДЛ=' + inttostr(cardinal(hProc))); {Выделяем память внутри чужого процесса, в которую запишем какие-либо данные. в нашем случае мы запишем туда строку- путь к длл. которую потом будем использовать в качестве аргумента для запуска LoadLibraryA(путь к длл) } pMyMemAdr := VirtualAllocEx(hProc, nil, Length(DllNamePAnsiChar), MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); memo1.Lines.Add('выделяем память в чужом процессе, получаем pointer=' + inttostr(cardinal(pMyMemAdr))); //Пишем данные в выделенную память WriteProcessMemory(hProc,  pMyMemAdr, DllNamePAnsiChar, Length(DllNamePAnsiChar), BytesWriten); memo1.Lines.Add('пишем данные в выделенную память, записано байт=' + inttostr(cardinal(BytesWriten))); {когда нам эта память не нужна то надо ее освободить! а мы этого тут не делаем! протекли. если мы так бездумно будем выделять память и писать туда чтото каждый раз то ничем хорошим это не закончится. вопщем за памятью следить надо. чтото создали- если лишнее то освободить.} {ищем адрес функции LoadLybraryA в памяти текущего (этого, нашего) процесса. логика такая, КЕРНЕЛ32.ДЛЛ загружается ко всем вапще процессам и к чужому и к нашему(этому) и располагает свои функции по одним и темже адресам, поэтому узнав адрес функции в нашем приложении он будет таким же как и в чужом приложении. LoadLibraryA и LoadLibraryW отличаются кодировкой Ansi и Юникод для аргумента. в какойто статье прочел что версии функций с индексом А на конце возвращают адрес ,а с индексом W возвращают хендл} {про память и адреса скажу так.. загружаясь процесс погружается в виртуальный мир адресного пространства, который любезно предоставляет ему система. большой мир адресов 4х байтный (32 бит) . и там и живет какбудто он один во всем мире. но этот мир памяти процесса виртуален. т.е. например 2 процесса могут по одному адресу внутри себя иметь совершенно разные данные. потому что их виртальные адресные пространства не пересекаются никак. у каждого процесса свой персональный виртуальный адресный мир-адресное пространство. длл туда подселяется располагает свои функции внутри этого виртуального мира. и по какойто причине КЕРНЕЛ32.ДЛЛ всегда располагает свои функции по одним и темже виртуальным адресам внутри виртуального адресного пространства приложения. взаимодействие приложухи с внешним миром (за пределами виртуального адресного пространства) происходит через апи. мы просим систему чегото сделать за пределами нашего виртуального мира с помощью апи.} pLoadLibAdr := GetProcAddress(GetModuleHandle('KERNEL32.DLL'), PAnsiChar('LoadLibraryA')); memo1.Lines.Add('ищем адрес функции LoadLybraryA, pointer=' + inttostr(cardinal(pLoadLibAdr))); // Запускаем удаленный поток {CreateRemoteThread может завершиться успешно даже если начальный адрес старта- белеберда тем не менее это наверняка приведет к краху чужого приложения, запускать удаленный поток нужно с какогото работоспособного кода (его адреса) который может выполниться. часто таким началом старта является начало какойто функции, процедуры, подпрограммы. но это может быть и иначе. мы можем и сами в какуюто область памяти что угодно понаписать байты, и запустить эти байты на выполнение начиная например с 5-го байта от начала области памяти.. ну это к примеру. нам удобно указывать в качестве начала выполнения кода(потока) адрес какойто функции. вот функция LoadLibraryA которую предоставила (загрузила в адресное пространство процесса) дллка КЕРНЕЛ32.ДЛЛ это подходящее место для старта потока в чужом процессе. аргумент для этой функции в виде строки (путь к длл) мы уже записали в выделенную память в виртуальное адресное пространство чужого процесса. осталось запустить поток. эта апи CreateRemoteThread ,зная о поводках пользователей в том что они любят стартовать с начала какойто функции, любезно предоставляет нам сервис чтобы еще и аргумент подсунуть для этой стартовой функции. без такой фишечки поток мы бы стартонули с начала какойто функции но как туда аргумент подсунуть была бы проблема. однако если мы захотим стартонуть функцию которая требует например 2 аргумента для своей работы. вот так вот нельзя. прототип стартовой функции потока должен быть таким чтоб тока 1 аргумент был и этот аргумент есть указатель на чтото. хотя он может быть весьма длинным аргументом. строкой. мне тут самому не ясно вот мы указатель на область памяти указываем которую нужно воспринимать как аргумент для стартовой функции, а где окончание области памяти этой, размер? видимо используется ноль терминатор #0 для окончания.} hRemoteThread  := CreateRemoteThread(hProc, nil, 0, pLoadLibAdr, pMyMemAdr, 0, pRemoteThread); memo1.Lines.Add('запуск удаленного потока, Хэндл=' + inttostr(cardinal(hRemoteThread)) + ' Pointer=' + inttostr(cardinal(pRemoteThread))); {можно конечно подождать завершения инъекции.. но тогда код отправки сообщений из главной функции длл отправит данные а тут они не обработаются.. потомучто мы ждем.. получатся взаимождущие петли происходящие. и поэтому я код оставлю но закоменчу. типа вот так можно ожидать когда удаленный поток завершит свою работу и можно сразу получить какойто результат его работы, в виде кода возврата. который сюда както вернет отработавший удаленный поток.} // Ждем пока удаленный поток отработает... //WaitForSingleObject(hRemoteThread, INFINITE); //получаем код возврата удаленного потока. который по задумке должен содержать адрес загрузки длл //RemoteThreadResult := 0; //GetExitCodeThread(hRemoteThread, &RemoteThreadResult); //memo1.Lines.Add('код возврата =' + inttostr(cardinal(RemoteThreadResult)));} Closehandle(hRemoteThread); //освобождаем хэндл открытого процесса //Closehandle(hProc);//подержим хэндл открытым он нам нужен чтобы дубликат хэндла для пайпа сделать. закроем при выходе. end;
__________________
Цитата:
Сообщение от pybukon
прежде чета попросить я немнога раскажу чтоб вы понили как мне плоха
Цитата:
Сообщение от Byrger
А как сделать мой скрипт бесконечным?
Цитата:
Сообщение от XKOR
.. каждый день ионизированной ногой протирает больную)
Цитата:
Сообщение от PsyR
Вылоджите пожалуйста скрипт на рыбалку желательно что бы сам в ВХ клал адаптированый под шоки и так же скрипт на ТТ рец, тоже с диалогами

Последний раз редактировалось VORON, 29.01.2025 в 15:14.
VORON вне форума   Ответить с цитированием
Старый 28.12.2024, 14:34   #2
Рыцарь
 
Аватар для VORON
 
Регистрация: 06.08.2007
Сообщений: 223
Сказал Спасибо: 6
Имеет 67 спасибок в 34 сообщенях
VORON пока неопределено
По умолчанию

Delphi Код:
procedure TForm1.Button3Click(Sender: TObject); var ProcPID: Cardinal; hProc: THandle; hRemoteThread: THandle; pRemoteThread: Cardinal; begin {пробуем запустить нужную нам функцию удаленным потоком внутри жертвы} ProcPID := GetRemotePID('calc1.exe'); memo1.Lines.Add('PID=' + inttostr(cardinal(ProcPID))); //вот мы какбы тут еще один хэндл делаем на жертву. хотя он открыт в кнопке2. ну пофиг. открыли закрыли. хуже не будет. hProc := OpenProcess(PROCESS_ALL_ACCESS, false, ProcPID); hRemoteThread  := CreateRemoteThread(hProc, nil, 0, pAdrFunc2, nil, 0, pRemoteThread); //если функция в чужом процессе отработала(Func2 мы тестим) то создастся лог файл c:\Log\Func2.txt CloseHandle(hProc); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin CloseHandle(g_DllHandle); end; function GetRemotePID(ProcName:string):Cardinal; var hSnapshoot: THandle;//дескриптор объекта- созданного снимка всех процессов. ProcSnapshot:TProcessEntry32;//структура описывает один процесс. сюда записывается описание одного процесса из снимка для анализа tempBOOL:Boolean; begin {Ищем ProcessID (PID) интересующего нас процесса, для этого делается снимок всех процессов в системе, он перебирается и сравнивается имя процесса с заданным как тока путем перебора нашли нужный нам процесс (по имени) мы запомним его PID. входной аргумент функции с именем процесса чувствителен к регистру Calc1.exe или calc1.exe} Result:=0; hSnapshoot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if hSnapshoot = INVALID_HANDLE_VALUE then Exit; if hSnapshoot <> INVALID_HANDLE_VALUE then   begin     try     ProcSnapshot.dwSize := SizeOf(ProcSnapshot);     tempBOOL := Process32First(hSnapshoot, ProcSnapshot);//получаем первый процесс в снимке     if tempBOOL = false then Exit;     while tempBOOL do       begin       if (ProcSnapshot.szExeFile = ProcName) then Result:=ProcSnapshot.th32ProcessID;       tempBOOL := Process32Next(hSnapshoot, ProcSnapshot);//получаем следующий процесс       end;     finally     CloseHandle(hSnapshoot);//я думаю что это выгружает обьект с указанным ИД     end;   end; end; function SetDebugPrivilege(boolOnOff:boolean):Boolean; var hToken:THandle;//Хэндл токена безопасности. szPrivilege: PChar;//название уровня безопасности. в системе уже существуют                    //имена мы будем использовать szPrivilege:='SeDebugPrivilege' luid: TLargeInteger; NewState: TTokenPrivileges; ReturnLength: DWord; begin {Устанавливаем отладочные привилегии для своего(этого) процесса, т.к. без данных привилегий код внедрения работать не будет} szPrivilege:='SeDebugPrivilege'; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken); LookupPrivilegeValue(nil, szPrivilege, luid); NewState.PrivilegeCount := 1; NewState.Privileges[0].Luid := luid; if (boolOnOff) then   begin     NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED   end   else   begin     NewState.Privileges[0].Attributes := 0;   end; result:=AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength); CloseHandle(hToken); end; end.

Добавлено через 59 секунд
это было САР (control application)

теперь код ДЛЛ...
__________________
Цитата:
Сообщение от pybukon
прежде чета попросить я немнога раскажу чтоб вы понили как мне плоха
Цитата:
Сообщение от Byrger
А как сделать мой скрипт бесконечным?
Цитата:
Сообщение от XKOR
.. каждый день ионизированной ногой протирает больную)
Цитата:
Сообщение от PsyR
Вылоджите пожалуйста скрипт на рыбалку желательно что бы сам в ВХ клал адаптированый под шоки и так же скрипт на ТТ рец, тоже с диалогами

Последний раз редактировалось VORON, 29.01.2025 в 15:15. Причина: Добавлено сообщение
VORON вне форума   Ответить с цитированием
Старый 28.12.2024, 14:36   #3
Рыцарь
 
Аватар для VORON
 
Регистрация: 06.08.2007
Сообщений: 223
Сказал Спасибо: 6
Имеет 67 спасибок в 34 сообщенях
VORON пока неопределено
По умолчанию

Delphi Код:
library Pi; uses   System.SysUtils,   Messages,//для SendMessage, PostMessage   Windows,   System.Classes,   TlHelp32;//для работы CreateToolhelp32Snapshot-сделать снимок процессов, узнать PID type TMyRec = Record   Age     :Cardinal;   Name    :String[20];   Fam     :String[20];   End;{интересный факт, что такая структура (string[20] , string[20] , Cardinal) взвешивается SizeOF(MyRec) в 48 байт} type //хлам    TCopyDataStruct = packed record     dwData: DWORD; // до 32 бит, которые нужно передать                    // приложению-получателю     cbData: DWORD; // размер, в байтах данных, указателя lpData     lpData: Pointer; // Указатель на данные, которые нужно передать                      // приложению-получателю. Может быть NIL.    end; var   LogFile: TextFile;//файл который будет сохраняться на диск   pFunc1: pointer;//адрес функции Func1   pFunc2: pointer;//адрес функции Func2   g_MyRec: TMyRec;//структура с данными которую попробуем отправить в САР //  g_CopyDataStruct: TCopyDataStruct;   g_String: string[40];   g_PipeRead: THandle;   g_PipeWrite: THandle;   g_tempCardinal:cardinal;   g_s: string[40];   g_car: cardinal; {$R *.res} //это ваши функции //их нужно объявить после $R *.res {Обратите внимание: все функции нашей DLL используют соглашение stdcall, которое обеспечивает совместимость новых функций с функциями API Windows 32. Мы могли бы не указывать это соглашение; в этом случае компилятор использовал бы более эффективное соглашение register, но обращение к нашей DLL из программ, написанных на других языках программирования, в общем случае стало бы невозможным. Если вы создали DLL для "внешнего" исользования (внеDelphi), объявляйте подпрограммы с директивой stdcall или safecall!} function Func1(a:integer):integer;stdcall; begin   Result:=a+1; end; function Func2(a: Cardinal):Cardinal;stdcall; begin   //пишем лог файл.   AssignFile (LogFile, 'C:\log\Func2.txt');//инициализация   ReWrite (LogFile);//если файла нет то создаст его. если есть то перезапишет   WriteLn (LogFile, 'Log Func2.dll'); //содержимое   CloseFile (LogFile);//закрыть работу с файлом   Result := 0; end; {//здесь вы можете указать, какие из ваших функций будут видны для внешнего вызова из DLL Раздел Exports помогает компилятору и компоновщику создать специальный заголовок DLL-модуля, в котором перечисляются имена подпрограмм и адреса их точек входа. перечисляемые в Exports подпрограммы должны быть описаны где-то выше по тексту библиотеки. Для использования подпрограмм из DLL необходимо описать их как внешние, добавив за словом External имя библиотеки в апострофах: procedure MyProc; External 'MyDLL'; функцию можно будет вызвать по имени или по индексу. Если нужно сослаться на индекс функции, за именем библиотеки указывается слово index и индекс: procedure MyProc; External 'MyDLL' index 2;} Exports   {plus index 1 name 'plus' resident;   экспортировать функцию plus, присвоить ей индекс 1, и внешнее имя plus. resident- это тайна   а мы експортируем по умолчанию просто указав имя функции}   Func1,   Func2; begin   //здесь пишется код, который выполняется при инициализации DLL   {полагаю поток повиснет на выводе этого окошка до тех пор пока ОК не нажать}   //MessageBox(0, 'DLL LOADED', 'Pi', 0);   {при загрузке ДЛЛ в чужой процесс- выполнится автоматически эта основная процедура.   узнаю сразу адреса всех своих функций внутри длл в чужом процессе и отошлю их   в CAP(control aplication). адреса можно передать с помощью SendMessage.   его достаточно чтобы передать 4+4 байта информации(WParam и LParam) (или там по 8 байт поля хз) плюс еще   сам заголовок(название) сообщения- несет в себе полезную информацию о том что именно мы передаем в WParam и LParam.   однако большой обьем информации так передать неполучится. Передавать любые данные можно   записывая их в буфер в CAP а с помощью SendMessage передавать адрес буфера. тогда можно передать любой   объем информации. но это требует отладочных привелегий для жертвы. чего делать не хочу.   Именно так мы писали путь к ДЛЛ в память чужого процесса а потом использовали эти данные для вызова ДЛЛ.   но мы это делали имея отладочные привы у приложения САР (писателя данных в чужой процесс).   вначале CAP должна узнать адреса всех нужных функций (областей памяти с данными возможно).   DLL должна уведомить CAP об адресах всех своих функций.   CAP должна запомнить где находятся адреса нужных функций внутри ДЛЛ инжектированой.   SendMessage может быть полезной для какойто синхронизации работы. для асинхронной работы PostMessage.   так как для тестов я использую всплывающее сообщение MessageBox(0, 'DLL LOADED', 'Pi', 0); то   оно останавливает поток который выполняет эту главную процедуру ДЛЛ а это тот жэ самый поток что   и инжектирует ДЛЛ. Для тестов я использовал PostMessage(FindWindow(nil , 'Form1'), WM_USER+1, 123, 456);   принимающая сторона должна прописать обработчик сообщений в классе формы   type   TForm1 = class(TForm)     ...   private      (Private declarations)      Procedure MesGet(var Msg:TMessage); message MyMes1;   а потом описать его тело   Procedure TForm1.MesGet(var Msg:TMessage);     begin     end;   также следует прописать константы перед type   const   MyMes1=WM_USER+1; }   {попробуем отправить что-нибудь в CAP. Отправлять будем адреса функций. Так как в данный момент   выполняется основная процедура ДЛЛ это значит что ДЛЛ уже разместилась в памяти чужого процесса.   мы узнаем адреса интересующих нас функций и отправляем эти адреса в САР. таким образом САР узнает   по каким адресам расселись разные функции инжектированной ДЛЛ, и сможет их вызвать удаленным потоком.   конечно для того чтобы была возможность вызвать функцию удаленным потоком из САР нужно чтоб функция имела   совместимый прототип. function Func2(a: Cardinal):Cardinal;stdcall; такой. 4байта аргумент. 4 байта результат.   аргументом и результатом обычно выступают указатели. можно использовать PVOID или (возможно)Pointer.}   pFunc1 := GetProcAddress(GetModuleHandle('pi.dll'), PAnsiChar('Func1'));   pFunc2 := GetProcAddress(GetModuleHandle('pi.dll'), PAnsiChar('Func2'));   SendMessage(FindWindow(nil , 'Form1'), WM_USER+1, cardinal(pFunc1), 0);   PostMessage(FindWindow(nil , 'Form1'), WM_USER+2, cardinal(pFunc2), 0); //  PostMessage(FindWindow(nil , 'Form1'), WM_USER+3, 123, 456);   {теперь усложним задачу. нужно переслать в САР данные произвольной длинны, аля массив байтов=буфер.}   //подготовим структуру для отправки.   g_MyRec.Name:='Lex';   g_MyRec.Fam:='Lexov';   g_MyRec.Age:=23;   g_String:='123456';  CreatePipe(g_PipeRead , g_PipeWrite, NIL , 40);  g_tempCardinal:=0;  WriteFile(g_PipeWrite , g_string , length(g_string)+1 , g_tempCardinal , NIL);  {чтобы работать с безымянным пайпом из другого процесса(САР) нужно создать дубликат, копию хендлов  с помощью DuplicateHandle апи. это можно сделать тут в длл и выслать в САР дубликат хендла  специально настроенного для работы в процессе САР либо можно это сделать внутри САР процесса а отослать  оригинал. безразницы. мы отошлем оригинал хэндла в САР, и в САР продублируем его.  второй вариант работать с именнованным пайпом. тогда обращиться к пайпу можно будет по его имени,  как к файлу, без хэндлов. типа //./MyPipeName.pip хотя насчет расширения я не уверен нужно ли оно и не заглючит ли с ним.  настроить (создать) именнованный пайп на мой взгляд сложновато, параметров много непонятных. поэтому я выбрал  безымянный пайп.}  SendMessage(FindWindow(nil , 'Form1'), WM_USER+3, cardinal(g_PipeRead), length(g_string));  {в процессе САР данные из пайпа будут прочитаны. прочитанные данные из пайпа удаляются.  это отличие пайпа от файла. в файл можно записать данные и читать их потом много раз передвигая курсор указатель.  а в пайпе данные типа одноразовые прочел- и они стерлись. поэтому и называется труба(PIPE) .  типа одна и таже вода на выходе из трубы не может быть выпита дважды. пожтому никакие апи по установке  позиции курсора чтения/записи в пайпе не работают. я в этом убедился. однако пайп можно читать  частями по несколько байт, в несколько операций. то что прочли то и удалится остальное прочесть такимже  способом можно указав сколько байт читать.} {тут я хочу опять прочесть чтото из пайпа теперь на стороне ДЛЛ. если пайп пустой (САР оттуда все прочел) а мы попытаемся его повторно тут прочесть то это приведет к подвисанию потока. Подвиснет поток не критично. поток будет ждать когда в пайп кто-то, откуда-то запишет какие-то данные и их можно будет прочесть. тогда апи чтения прочтет пайп и поток продолжит свою работу. мыже предварительно запишем новую порцию информации в пайп и прочтем его уже на стороне ДЛЛ и выведем отчет об этом в логфайл}  g_string := 'qwerty';  WriteFile(g_PipeWrite , g_string , length(g_string)+1 , g_tempCardinal , NIL);  ReadFile(g_PipeRead , g_s , length(g_string)+1 , g_car, nil);  //g_car := FileRead(g_PipeRead , g_s , length(g_string)+1);//и так тоже можно  closeHandle(g_PipeRead);  closeHandle(g_PipeWrite);   //пишем лог файл.   AssignFile (LogFile, 'C:\log\PiLog.txt');//инициализация   ReWrite (LogFile);//если файла нет то создаст его. если есть то перезапишет   writeln (LogFile, 'Log Pi.dll'); //пишем строку в файл   writeln (LogFile, 'Func1=' + inttostr(cardinal(pFunc1)));   writeln (LogFile, 'Func2=' + inttostr(cardinal(pFunc2)));   writeln (LogFile, 'длинна строки length(g_string)=' + inttostr(length(g_string)));   writeln (LogFile, 'записали байт в пайп=' + inttostr(g_tempCardinal));   writeln (LogFile, 'прочли байт из пайпа=' + inttostr(g_car));   writeln (LogFile, 'прочли строку из пайпа=' + g_s);   CloseFile (LogFile);//закрыть работу с файлом end.

Добавлено через 44 секунды
впринципе и все. что я смог сделать.

Последний раз редактировалось VORON, 29.01.2025 в 15:18. Причина: Добавлено сообщение
VORON вне форума   Ответить с цитированием
Ответ

  CoderX :: Forums > Основные форумы > Программинг



Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 11:34.

vBulletin style designed by MSC Team.
Powered by vBulletin® Version 3.6.11
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd. Перевод: zCarot
Locations of visitors to this page
Rambler's Top100

Вы хотите чувствовать себя в безопасности? чоп Белган обеспечит её!