Всем Доброго Времени Суток!! Пишу программу которая должна запустить некоторый ехе-код внутри другого процесса, но проблема в том что программа просто вылетает на CreateRemoteThread. Да ещё проблема в том, что я понятия не имею как должен быть устроен код, внедряемый в процесс. Сам запускающий код выглядит следующим образом: Code (Text): format pe gui 4.0 include 'win32ax.inc' .data p_info PROCESS_INFORMATION s_info STARTUPINFO hFile rd 1 _out rb 30 NumOfB rb 100 mem rd 1 size rd 1 buff rb 1536 .code start: mov [s_info.cb],sizeof.STARTUPINFO mov [s_info.hStdError],0 mov [s_info.hStdOutput],0 mov [s_info.hStdInput],0 mov [s_info.dwFlags],100h ; STARTF_USESTDHANDLES invoke CreateProcess,"C:\Windows\notepad.exe",NULL,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL, s_info, p_info invoke CreateFile,"InjectProg.EXE",GENERIC_READ,FILE_SHARE_WRITE+FILE_SHARE_READ,0,\ OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 cmp eax,-1 je _err mov [hFile],eax invoke GetFileSize,[hFile],NULL mov [size],eax invoke wsprintfA,_out,"Размер файла %d",[size] invoke VirtualAllocEx,[p_info.hProcess],0,[size],MEM_COMMIT,PAGE_EXECUTE_READWRITE mov [mem],eax ;invoke wsprintfA,_out,"Освобождено по адр. %d",[mem] ;invoke MessageBox,0,_out,"ProgDLL0.DLL",0 invoke ReadFile,[hFile],buff,[size],NumOfB,0 cmp eax,0 je _err invoke CloseHandle,[hFile] invoke WriteProcessMemory,[p_info.hProcess],[mem],buff,1536,0 ;invoke CreateRemoteThread,[p_info.hProcess],0,0,[mem],0,0,0 ;invoke CloseHandle,eax exit: invoke ExitProcess,0 _err: invoke MessageBox,HWND_DESKTOP,"error",invoke GetCommandLine,MB_ICONERROR jmp exit .end start А так выглядит вводимый код, на счет которого у меня большие сомнения: Code (Text): format PE GUI 4.0 include 'win32a.inc' section '.code' code readable executable proc Inj invoke MessageBox,0,"stop","stop",MB_OK ;--------помещаем текст-------------------------- invoke MessageBox,HWND_DESKTOP," После нажатия ОК откроется шрифт по настройкам меню",0,MB_OK invoke FindWindowExA,<invoke FindWindow,'notepad',0>,0,'edit',0 mov [hw],eax invoke SendMessageA,[hw],WM_SETTEXT,0,msg ;--------первый вариант шрифта--------------------- invoke MessageBox,HWND_DESKTOP,"После нажатия ОК откроется изменённый шрифт(первый вариант)",0,MB_OK invoke CreateFontIndirectA,lf1 invoke SendMessageA,[hw],WM_SETFONT,eax,TRUE invoke DeleteObject,lf1 ;-------второй вариант шрифта----------------------------- invoke MessageBox,HWND_DESKTOP,"После нажатия ОК откроется изменённый шрифт(второй вариант)",0,MB_OK invoke CreateFontIndirectA,lf2 invoke SendMessageA,[hw],WM_SETFONT,eax,TRUE invoke DeleteObject,lf2 ret endp section '.data' data readable writeable lf1 LOGFONT \ 12,7,\ ;lfHeight & lfWidth 0,0,\ ;lfEscapement(наклон отн. Х в 10х градуса) & lfOrientation FW_NORMAL,0,0,0,\ ;lfWeight & lfItalic & lfUnderline & lfStrikeOut RUSSIAN_CHARSET,\ ;lfCharSet OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ ;lfOutPrecision & lfClipPrecision & lfQuality FF_MODERN+FIXED_PITCH,\ ;lpPitchAndFamily ;FIXED_PITCH=моноширинный=красивосорцен Ж) <"Tw Cen MT",0> ;lfFaceName lf2 LOGFONT \ 12,7,\ ;lfHeight & lfWidth 0,0,\ ;lfEscapement(наклон отн. Х в 10х градуса) & lfOrientation FW_NORMAL,0,TRUE,0,\ ;lfWeight & lfItalic & lfUnderline & lfStrikeOut RUSSIAN_CHARSET,\ ;lfCharSet OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\ ;lfOutPrecision & lfClipPrecision & lfQuality FF_MODERN+FIXED_PITCH,\ ;lpPitchAndFamily ;FIXED_PITCH=моноширинный=красивосорцен Ж) <"courier new",0> msg db 'fedcb9870',0 hw rd 1 section '.idata' import data readable writeable library kernel,'KERNEL32.DLL',\ user,'USER32.DLL',\ shell,'SHELL32.DLL',\ gdi,'GDI32.DLL' import user,\ MessageBox,'MessageBoxA',\ FindWindowExA,'FindWindowExA',\ FindWindow,'FindWindowA',\ SendMessageA,'SendMessageA' import gdi,\ CreateFontIndirectA,'CreateFontIndirectA',\ DeleteObject,'DeleteObject'
'invoke WriteProcessMemory,[p_info.hProcess],[mem],buff,1536,0' завершается корректно? P.S. Для внедрения библиотеки в адресное пространство процесса лучше создавать удаленный поток с точкой входа в LoadLibrary и параметром-путем к загружаемой библиотеке. Тогда загрузчик сам разрешит все зависимости библиотеки.
Во-первых, оно криво компилится в fasm. Во-вторых, если вы делаете базонезависимый код, то вся адресация должна быть относительно начала кода. Начало кода вычисляется через дельта смещение (call $ + 5 / pop reg). Адреса апи должны вычисляться динамически (обычно через peb находят адрес загрузки kernel32.dll и пляшут от него). Фактически у вас сейчас три секции, а должна быть одна.
Flint_ta Способ, который я описал, не требует базонезависимости, можно загружать динамическую библиотеку, главное, чтобы в ней были релокации.
Ну, видимо, написать длл с релоками и пройтись по ним один раз во временном буффере до записи через WriteProcessMemory - это что-то из области фантастики ) Вообще, релокнуть образ для перемещения совершенно ничего экстраординарного не представляет. Завершаться она может и нормально, но ничего не писать. Сколько конкретно она возвращает dwBytesWritten - столько же, сколько было передано?
о_0 а как же пишете тогда? Короче, основной момент: нужно переносить образ длл целиком (не обязательно, но так удобнее; да и не будут спрашивать тогда "а почему данные и импорт не работают?") во-первых, нужно применить релоки для адреса назначения во-вторых. иначе в другой процесс уйдет код, который настроен для работы по одному базовому адресу, а запущенный по другому базовому адресу. Во-вторых, 1536 - это размер ВСЕГО модуля? Если да - ты потом передаешь управление куда, на ImageBase? Опять же, тогда управление надо передавать не на начало, а на точку входа. Не, чувак, так не пойдет - грузить с диска файл и сразу его отправлять. Нужно выполнить _вручную_ всю работу Windows загрузчика. Будет проще, если переносить уже загруженный модуль, например, текущий. Размести код для переноса и переносящий код в одной длл и переноси ее уже из памяти в память, тогда останется только применить релоки. А вообще, как уже сказали, будет гораздо проще вызвать в процессе назначения LoadLibrary с именем длл, чем сейчас объяснять все тонкости. И всю работу тогда выполнит системный загрузчик, потому что в ином случае придется ручками все фиксить. PS. Как пример кода для применения релокаций: http://www.rsdn.ru/forum/src/3202881.flat.aspx Тебе нужны LdrProcessRelocationBlock и LdrProcessRelocations. Пример вызова: Code (Text): PVOID ImageBase = VirtualAlloc (...); // make temporary buffer memcpy (ImageBase, GetModuleHandle(..), ..); // make copy of the image to be transferred PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER) ImageBase; PIMAGE_NT_HEADERS NtHeaders = (PIMAGE_NT_HEADERS) ((PUCHAR)ImageBase + DosHeader->e_lfanew); PIMAGE_BASE_RELOCATION BaseRelocs = (PIMAGE_BASE_RELOCATION) ((PUCHAR)ImageBase + NtHeaders->OptionalHeader.DataDirectory [IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); LONG_PTR lImageBaseDelta = (LONG_PTR)mem - (LONG_PTR)ImageBase; // image base delta LdrProcessRelocations (ImageBase, lImageBaseDelta, NtHeaders, BaseRelocs); PS2. Ну а про базонезависимый код и ручной поиск апи - смешно, смешно) Если нифига не знаете, зачем отвечать?
Flint_ta Ну да, конечно. Code (Text): ;invoke MessageBox,0,_out,"ProgDLL0.DLL",0 У него длл читается из файла. Иди спать дальше ) Ручной поиск, блин Да и даже если был бы exe, все равно я описал как _нужно_ делать. Писать в ехе тучу говнокода, чтобы потом перенести весь этот говнокод по парсингу импорта через peb в другой процесс - так точно делать не нужно. (ТС не знает даже как код переносить, о каком peb вообще идет речь?)
А к чему такие сложности -- руками проходиться по релокациям и т.д? Гораздно проще выделить в адресном пространстве целевого процесса кусочек памяти, записать туда путь к библиотеке и вызвать CreateRemoteThread, передав в него адрес LoadLibrary как start routine и адрес выделенной памяти с путем к библиотеке? Получится, что мы вызываем LoadLibrary(pathname) в целевом процессе. Тогда загрузчик все сделает сам, а нам лишь останется получить управление в DllMain.
Mika0x65 Да, как я уже сказал, если лень это все делать, то Меня никто не читает, да?) К тому же, разве это сложности? Сложности - это как выше предлагали вручную искать апи через peb А корректная обработка релоков - это сотня-полторы строчек, не больше. Просто этот способ не пойдет, если нет отдельной длл. Например, запускается ехе и копирует свое тело в чужое ап. Тогда никакими лоад либрари ты не подгрузишь его в чужое АП, и чтобы корректно обработались импорты (через LoadLibraryEx можно подгрузить ехе, но на то он и DONT_RESOLVE_DLL_REFERENCES - референсы (импорты) не будут обработаны). Тогда единственный вариант - собрать ехе с релоками и вручную переносить.
Great Я еще во втором сообщении это написал, хотя и не очень подробно, так что это меня никто не читает . Другое дело, что я не смотрел как дела обстоят с ASLR. Кажется, там библиотеки грузятся по одному и тому же адресу во всех процессах и адрес меняется каждый раз после перезагрузки, но точно не уверен.
Mika0x65 Да нет, я тебя прочитал и ответил тебе еще в первом своем посте) И написал, в каких случаях твой метод подходит, а в каких нет) Да, верно. Но я тебе уже написал, почему твой метод не годится: для этого нужно иметь на диске отдельную длл. Что является большим и безоговорочным минусом. Хотя, безусловно, для ТС это будет куда проще, чем вручную парсить релоки, я согласен. Тут уже ему выбирать в зависимости от его задач.
вот на,данный код запустит мессадж в explorer.exe. только твоему аверу это врятли понравится. Code (Text): format PE GUI 4.0 entry start include 'win32a.inc' struc PROCESSENTRY32 { .dwSize dd ? .cntUsage dd ? .th32ProcessID dd ? .th32DefaultHeapID dd ? .th32ModuleID dd ? .cntThreads dd ? .th32ParentProcessID dd ? .pcPriClassBase dd ? .dwFlags dd ? .szExeFile db 260 dup(?) } struc _LUID_AND_ATTRIBUTES { .Luid dq ? .Attributes dd ? } struc _TOKEN_PRIVILEGES { .PrivilegeCount dd ? .Privileges _LUID_AND_ATTRIBUTES } TH32CS_SNAPPROCESS = $00000002; TOKEN_QUERY = $0008; TOKEN_ADJUST_PRIVILEGES = $0020; SE_PRIVILEGE_ENABLED= $00000002; section '.code' code executable readable writeable RemoteCodeStart: call .delta .delta: pop ebp sub ebp, .delta ;------------------------------------------------------- www1: push 0 lea eax, [ebp+szCapt] push eax lea eax, [ebp+www] push eax push 0 call [ebp+pMessageBoxA] .thrend: push 0 call [ebp+pExitThread] ;---------------------------------------------------------------------------------- szCapt db 'Hacker',0 www db 'Hello Hacker',0 pMessageBoxA dd 0 pExitThread dd 0 RemoteCodeEnd: RemoteCodeSize equ RemoteCodeEnd-RemoteCodeStart section '.code' code executable readable writeable TokenPrivs _TOKEN_PRIVILEGES SeDeugPriv db 'SeDebugPrivilege',0 winlogon_procname db 'explorer.exe',0 proc_entry PROCESSENTRY32 pe_size: PROCESSENTRY32_structsize equ pe_size-proc_entry ProcessSnapshotHandle dd 0 WinlogonProcHandle dd 0 RemoteThreadBaseAddress dd 0 RemoteThreadID dd 0 TokenHandle dd 0 Writed dd 0 start: invoke GetCurrentProcess invoke OpenProcessToken, eax, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, TokenHandle invoke LookupPrivilegeValue, 0, SeDeugPriv, TokenPrivs.Privileges.Luid mov [TokenPrivs.PrivilegeCount], 1 mov [TokenPrivs.Privileges.Attributes], SE_PRIVILEGE_ENABLED; invoke AdjustTokenPrivileges, [TokenHandle], FALSE, TokenPrivs, 0, 0, 0 test eax, eax jnz @f jmp .exit @@: ;debug privilege is enabled invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0 mov [ProcessSnapshotHandle], eax mov [proc_entry.dwSize], PROCESSENTRY32_structsize invoke Process32First, eax, proc_entry .rep: invoke lstrcmpi, winlogon_procname, proc_entry.szExeFile cmp eax, 0 jz .endrep invoke Process32Next, [ProcessSnapshotHandle], proc_entry jmp .rep .endrep: invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, FALSE, [proc_entry.th32ProcessID] mov [WinlogonProcHandle], eax test eax, eax jnz @f jmp .exit @@: mov eax, [MessageBoxA] mov [pMessageBoxA], eax mov eax, [ExitThread] mov [pExitThread], eax invoke VirtualAllocEx, [WinlogonProcHandle], 0, RemoteCodeSize, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE mov [RemoteThreadBaseAddress], eax invoke WriteProcessMemory, [WinlogonProcHandle], eax, RemoteCodeStart, RemoteCodeSize, Writed invoke CreateRemoteThread, [WinlogonProcHandle], 0, 0, [RemoteThreadBaseAddress], 0, 0, RemoteThreadID .exit: invoke ExitProcess, 0 section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ gdi32,'GDI32.DLL',\ advapi32,'ADVAPI32.DLL',\ comctl32,'COMCTL32.DLL',\ comdlg32,'COMDLG32.DLL',\ shell32,'SHELL32.DLL',\ wsock32,'WSOCK32.DLL' include 'api/kernel32.inc' include 'api/user32.inc' include 'api/gdi32.inc' include 'api/advapi32.inc' include 'api/comctl32.inc' include 'api/comdlg32.inc' include 'api/shell32.inc' include 'api/wsock32.inc'
Всем привет! У меня похожая ситуация, и не много не понятная. 1. Отдельно от всего отладил код который будет инжектитьса, работает без збоев. 2. Програма-носитель успешно инжектит код (ну например в експлорер.ехе) и вызывает CreateRemoteThread() после чего завершаетса. Удаленный поток получив управление рушит експлорер наповал. (старнно, потому-что пикод отлажен и работает). Короче открываю Ольку, ставлю бряк на создание нового потока аттачусь к експлореру и вот тут-то начинается самое интересное. В внедренный поток я то попадаю, толко отлаживать уже нихера не могу, в статусе Ольки уже стоит access violation. ни с F8 ни с F7 ни с F9 я продвинутьса ни на шаг уже не могу. Вопрос: Что это за явление??? Тестировал на win 7 32bit и на win xp sp3, везде одно и тоже... Подведем итоги: 1. инжектируемый код работает (100%). 2. код инжектится корректно. 3. CreateRemoteThread() завершаетса успешно. 4. Поток получив управление в експлорере рушит его. 5. Отлаживать внедренный поток не удаетса. Ваши идеи господа???
файл вылаживайте, скорее всего поток начинает исполняться не оттуда где запланировано, т е адрес расчитываете неверно