тащемта не стал ходить лесом а смапил нтдлл в процесс, затем перекопировал и ребазировал, всякие прямые стабы работают оккей, но вот с ЛДР уже траблы, споткнулся на первой же: ntdll!_LdrpResolveDllName ... .text:6B2D5EF5 mov eax, _NtdllBaseTag .text:6B2D5EFA push edi ; Size .text:6B2D5EFB add eax, 40000h .text:6B2D5F00 push eax ; Flags .text:6B2D5F01 push _LdrpHeap ; ; HeapHandle -- uninitialized after raw copy section .text:6B2D5F07 call _RtlAllocateHeap@12 ; RtlAllocateHeap(x,x,x) тут вроде пофиксил - нужен хендл был кучи, пофиксил, но опять ntdll!RtlpLowFragHeapAllocFromContext+0x20e: 77ec34f4 f646073f test byte ptr [esi+7],3Fh пока не вкуривал, ибо в говно - может есть у кого уже наработки, или проясните что я делаю не так? это всё касаемо LdrLoadDll
sn0w, Логгер включи и не дури мозги. GlobalFlag\ShowSnaps. Если косяк с хипом, то для этого есть целый набор системных тулз и механизмов, тогда включается страничная аллокация(PH), на каждом действии с кучей логгер, для этого есть набор штатных тулз. А есчо есть слой верификации. Кури матчасть.
это я уже курнул, мне надо шобы нтлоадер отрабатывал корректно, насчёт хипа и так понятно, просто я к тому что может ктото тоже такое делал и есть костыли об которые спотыкались
sn0w, Вы задачу не описали, только "смапил нтдлл в процесс, затем перекопировал и ребазировал". Когда смапил, что копировал и зачем релоцировал хз, откуда же мне знать. Нужно нормально описывать задачу, если конкретный ответ нужен. ntdll не релоцируется, так как там глобальные в системе указатели по фикс. адресам. Это значит что этот модуль релоцировать не нужно, если замапить на другую базу, то адресация останется исходного модуля. > LdrpHeap ; ; HeapHandle -- uninitialized after raw copy section Что это значит тоже не известно. Пусть потоки не стартовали, не прошла инициализация загрузчика. Но причём там копии проекции тоже хз. Опиши норм что делаешь и задачу, иначе это бессмысленный отрывок потока мыслей ваших.
Действительно, снег, ты не говори чо ты делаешь (в этих словах совсем потеряно, что именно хочешь добиться), скажи что хочешь сделать от ... и ... до, включительно
ок) возможно что разные экспорты нтдлл похуканы и периодически чекаются сторонними процессами, поэтому мне нужно просто сделать её дубль в этом ап чтобы не пилить оверхеда + пользоваться той же LdrLoadDll. для этого я решил смапить секцию, релоцировать и инициализировать вручную. надо чтобы LdrLoadDll корректно отрабатывала в этой новой памяти
Принципиально вручную мапить? Если нет, то может этот вариант подойдет: https://scorchsecurity.wordpress.com/2016/08/26/bypassing-user-mode-the-sneaky-way/ Два вызова и длл готова к использованию.
sn0w, Так наоборот ведь, релоцировать не нужно. Если ты релочил, то у тебя модуль окажется не инициализированным, отсюда видимо и ошибки. Без какого либо понятия решил релоцировать Нэйтив никогда не релоцируется, его база фиксед. Если спроецировать на другую базу, то адресация из копии останется в базовую проекцию. Если не понятно, то вот на цифрах: 7C97B178: _LdrpLoaderLock 7C97B1A0 ntdll._LoaderLockDebug Отображаем на другую базу, получится: (7C97B178 - 7C900000 + NEWBASE): _LdrpLoaderLock 7C97B1A0 ntdll._LoaderLockDebug Релок по 7C97B178 оригинальный и указатель тот же самый. 7C916633: push offset _LdrpLoaderLock(7C97B178) - Адресация в оригинальной проекции. (7C916633 - 7C900000 + NEWBASE): push offset _LdrpLoaderLock(7C97B178) - Адресация в копии. Тоесть все указатели останутся в оригинальную проекцию. Как частный случай останется адресация колбеков, тоесть обратный вызов будет происходить в оригинальную проекцию, тоесть управление выйдет из копии. Что бы это зафиксить необходимо релоцировать ссылки в кодовую секцию(там константы/процедуры). Так как адресация переменных абсолютная, а за пределы кодовой секции нет релатив ветвлений, то кодовая секция может перемещаться как строка в памяти. Так например восстанавливал кодовую секцию загрузчик из памяти(lwe). > инициализировать вручную. Повторную инициализацию нэйтив выполнить не получится. Трабла с серверным соеденением(csrss), подробности я давно на exploit.in описывал, там можно глянуть, если он есчо существует.
блин, да я не совсем идиот в отношении релокаций и статических символов, так вот что к чему подсоединить или пересоздать - вот в чём вопрос
не с той стороны зашел. находишь и сохраняешь нужный экспорт в загруженной нтдлл. мапишь нтдлл в память. восстанавливаешь из нее нужный экспорт в загруженную. пользуешься. возвращаешь обратно как было.
я же говорю что в .data там есть неинициализированные поинтеры, такие как ntdll!LdrpHeap, без которого не работает ничего кроме syscall стабов например, то что они не экспортируются - другое дело - но на это просто символьный подгруз можно запилить.
Заколхожено до неприличия, но для демонстрации сгодится. Код (ASM): format pe console 4.0 include 'win32ax.inc' entry main macro pushdata label,[data] { common __PUSHDATA_LAST equ label __PUSHDATA_LIST equ .len=0 .size=0 forward virtual data .len=.len+$-$$ end virtual common .tlen=((3+.len) and (not 3))-(.len) .part=0 reverse .ofst=0 .dlen=1 while .ofst<.dlen .ofst=.ofst+4 virtual rb 4 data if .tlen > 0 db (.part shr 24) and 0xFF end if if .tlen > 1 db (.part shr 16) and 0xFF end if if .tlen > 2 db (.part shr 8) and 0xFF end if .dlen=$-$$-4 load .part DWORD from $-.ofst end virtual if .ofst<=.dlen push .part .size=.size+4 end if end while .pad=0 .tlen=4-((3+.dlen) and (not 3))+(.dlen) if .tlen=4 .tlen=0 end if common locals label dd ? endl mov [label],esp pushdata.#label#.size=.size pushdata.#label#.length=.len __PUSHDATA_LAST_SIZE equ pushdata.#label#.size __PUSHDATA_LAST_LENGTH equ pushdata.#label#.length } macro pushdatanp d { local length,size,part virtual d length=$-$$ size=((length+3)and(not 3)) end virtual repeat size shr 2 virtual d rb size-length load part DWORD from $-%*4 end virtual push part end repeat __PUSHDATA_LAST_SIZE equ size __PUSHDATA_LAST_LENGTH equ length } macro popdata { add esp,__PUSHDATA_LAST_SIZE restore __PUSHDATA_LAST_SIZE restore __PUSHDATA_LAST_LENGTH } struct IMAGE_DOS_HEADER e_magic dw ? e_cblp dw ? e_cp dw ? e_crlc dw ? e_cparhdr dw ? e_minalloc dw ? e_maxalloc dw ? e_ss dw ? e_sp dw ? e_csum dw ? e_ip dw ? e_cs dw ? e_lfarlc dw ? e_ovno dw ? e_res rw 4 e_oemid dw ? e_oeminfo dw ? e_res2 rw 10 e_lfanew dd ? ends struct IMAGE_FILE_HEADER Machine dw ? NumberOfSections dw ? TimeDateStamp dd ? PointerToSymbolTable dd ? NumberOfSymbols dd ? SizeOfOptionalHeader dw ? Characteristics dw ? ends struct IMAGE_DATA_DIRECTORY VirtualAddress dd ? Size dd ? ends struct IMAGE_OPTIONAL_HEADER Magic dw ? MajorLinkerVersion db ? MinorLinkerVersion db ? SizeOfCode dd ? SizeOfInitializedData dd ? SizeOfUninitializedData dd ? AddressOfEntryPoint dd ? BaseOfCode dd ? BaseOfData dd ? ImageBase dd ? SectionAlignment dd ? FileAlignment dd ? MajorOperatingSystemVersion dw ? MinorOperatingSystemVersion dw ? MajorImageVersion dw ? MinorImageVersion dw ? MajorSubsystemVersion dw ? MinorSubsystemVersion dw ? Reserved1 dd ? SizeOfImage dd ? SizeOfHeaders dd ? CheckSum dd ? Subsystem dw ? DllCharacteristics dw ? SizeOfStackReserve dd ? SizeOfStackCommit dd ? SizeOfHeapReserve dd ? SizeOfHeapCommit dd ? LoaderFlags dd ? NumberOfRvaAndSizes dd ? DataDirectoryExport IMAGE_DATA_DIRECTORY DataDirectoryImport IMAGE_DATA_DIRECTORY DataDirectoryResource IMAGE_DATA_DIRECTORY DataDirectoryException IMAGE_DATA_DIRECTORY DataDirectorySecurity IMAGE_DATA_DIRECTORY DataDirectoryBaseRelocationTable IMAGE_DATA_DIRECTORY DataDirectoryDebugDirectory IMAGE_DATA_DIRECTORY DataDirectoryCopyrightOrArchitectureSpecificData IMAGE_DATA_DIRECTORY DataDirectoryGlobalPtr IMAGE_DATA_DIRECTORY DataDirectoryTLSDirectory IMAGE_DATA_DIRECTORY DataDirectoryLoadConfigurationDirectory IMAGE_DATA_DIRECTORY DataDirectoryBoundImportDirectory IMAGE_DATA_DIRECTORY DataDirectoryImportAddressTable IMAGE_DATA_DIRECTORY DataDirectoryDelayImportDescriptors IMAGE_DATA_DIRECTORY DataDirectoryComRuntimeDescriptor IMAGE_DATA_DIRECTORY DataDirectoryReserved IMAGE_DATA_DIRECTORY ends struct IMAGE_NT_HEADERS Signature dd ? FileHeader IMAGE_FILE_HEADER OptionalHeader IMAGE_OPTIONAL_HEADER ends struct IMAGE_SECTION_HEADER Name rb 8 union PhysicalAddress dd ? VirtualSize dd ? ends VirtualAddress dd ? SizeOfRawData dd ? PointerToRawData dd ? PointerToRelocations dd ? PointerToLinenumbers dd ? NumberOfRelocations dw ? NumberOfLinenumbers dw ? Characteristics dd ? ends section '.code' code data readable executable proc main locals hNtdllDll dd ? hNtdllCopyDll dd ? nNumberOfSections dd ? nBaserelocRva dd ? nBaserelocSize dd ? nCurrentSection dd ? nDataRvaLo dd ? nDataRvaHi dd ? nCurrentBaserelocHeaderOffset dd ? nBaserelocBlockRva dd ? nBaserelocBlockSize dd ? nCurrentBaserelocItemOffset dd ? nOldProtection dd ? nUnknown dd ? hLibrary dd ? endl pushdatanp db 'ntdll.dll'\,0 invoke GetModuleHandle,esp popdata mov [hNtdllDll],eax pushdatanp db 'ntdll_copy.dll'\,0 invoke GetModuleHandle,esp popdata mov [hNtdllCopyDll],eax mov ecx,[eax + IMAGE_DOS_HEADER.e_lfanew] movzx edx,[eax + ecx + IMAGE_NT_HEADERS.FileHeader.NumberOfSections] mov [nNumberOfSections],edx mov edx,[eax + ecx + IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryBaseRelocationTable.VirtualAddress] mov [nBaserelocRva],edx mov edx,[eax + ecx + IMAGE_NT_HEADERS.OptionalHeader.DataDirectoryBaseRelocationTable.Size] mov [nBaserelocSize],edx movzx edx,[eax + ecx + IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader] lea ecx,[ecx + IMAGE_NT_HEADERS.OptionalHeader + edx] lea ecx,[ecx + eax] mov [nCurrentSection],0 @@: mov edx,[nCurrentSection] .if edx < [nNumberOfSections] imul edx,edx,sizeof.IMAGE_SECTION_HEADER pushad mov eax,[ecx + edx + IMAGE_SECTION_HEADER.VirtualAddress] add eax,[hNtdllCopyDll] mov ecx,[ecx + edx + IMAGE_SECTION_HEADER.VirtualSize] invoke VirtualProtect,eax,ecx,PAGE_EXECUTE_READWRITE,addr nOldProtection popad inc [nCurrentSection] jmp @B .endif mov [nCurrentSection],0 @@: mov edx,[nCurrentSection] .if edx < [nNumberOfSections] imul edx,edx,sizeof.IMAGE_SECTION_HEADER .if DWORD[ecx + edx + IMAGE_SECTION_HEADER.Name + 00]<>'.dat' | DWORD[ecx + edx + IMAGE_SECTION_HEADER.Name + 04]<>'a' inc [nCurrentSection] jmp @B .endif mov eax,[ecx + edx + IMAGE_SECTION_HEADER.VirtualAddress] mov [nDataRvaLo],eax mov [nDataRvaHi],eax mov eax,[ecx + edx + IMAGE_SECTION_HEADER.VirtualSize] add [nDataRvaHi],eax mov esi,[hNtdllCopyDll] mov [nCurrentBaserelocHeaderOffset],0 .next_basereloc_header: mov edi,[nCurrentBaserelocHeaderOffset] .if edi < [nBaserelocSize] add edi,[nBaserelocRva] mov eax,DWORD[esi + edi + 00] mov [nBaserelocBlockRva],eax mov eax,DWORD[esi + edi + 04] mov [nBaserelocBlockSize],eax mov [nCurrentBaserelocItemOffset],8 @@: mov edx,[nCurrentBaserelocItemOffset] .if edx < [nBaserelocBlockSize] add edx,edi movzx ecx,WORD[esi + edx] .if ecx>=0x3000 & ecx<0x4000 and ecx,0xFFF add ecx,[nBaserelocBlockRva] mov eax,DWORD[esi + ecx] sub eax,esi .if eax>=[nDataRvaLo] & eax<[nDataRvaHi] add eax,[hNtdllDll] mov DWORD[esi + ecx],eax .endif .endif add [nCurrentBaserelocItemOffset],2 jmp @B .endif mov ecx,[nBaserelocBlockSize] add [nCurrentBaserelocHeaderOffset],ecx jmp .next_basereloc_header .endif .endif pushdatanp du 'advapi32.dll'\,0 mov [nUnknown],0 mov [hLibrary],0 invoke LdrLoadDll_copy,1,addr nUnknown,addr esp + 1*4,addr hLibrary,0x001A0018,esp pop ecx ecx popdata ret endp section '.data' data readable writable data import library kernel32,'kernel32.dll',user32,'user32.dll',ntdll_copy,'ntdll_copy.dll' include 'api\kernel32.inc' include 'api\user32.inc' import ntdll_copy,\ LdrLoadDll_copy,'LdrLoadDll' end data ntdll_copy.dll чтобы не возиться с остальным На 8.1 х64 работает.
f13nd, Статистика по косвенным ветвлениям из LdrLoadDll(), call: Код (Text): ICALL 0x7C915216 -> [0x12FA00]: 0x7C915454 ; bsearch(_RtlpCompareActivationContextStringSectionEntryByPseudoKey) ICALL 0x7C915216 -> [0x12F6B8]: 0x7C915454 ICALL 0x7C915216 -> [0x12F838]: 0x7C915454 ICALL 0x7C90D61A -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C910412 -> [0x12F544]: 0x7C901000 ; RtlAcquirePebLock() ICALL 0x7C910412 -> [0x12F480]: 0x7C901000 ICALL 0x7C91043D -> [0x7FFD8024]: 0x7C9010E0 ICALL 0x7C91043D -> [0x7FFD8024]: 0x7C9010E0 ICALL 0x7C90D6FA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C910412 -> [0x12F544]: 0x7C901000 ; RtlAcquirePebLock() ICALL 0x7C910412 -> [0x12F480]: 0x7C901000 ICALL 0x7C91043D -> [0x7FFD8024]: 0x7C9010E0 ; RtlReleasePebLock() ICALL 0x7C91043D -> [0x7FFD8024]: 0x7C9010E0 ICALL 0x7C90D16A -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D8BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90CFDA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D50A -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90CFDA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C91C12F -> [0x7C97C30C]: 0x7C8112A0 ; _LdrpManifestProberRoutine ICALL 0x7C915216 -> [0x12F410]: 0x7C915454 ICALL 0x7C915216 -> [0x12F410]: 0x7C915454 ICALL 0x7C915216 -> [0x12F410]: 0x7C915454 ICALL 0x7C915216 -> [0x12F464]: 0x7C915454 ICALL 0x7C915216 -> [0x12F3AC]: 0x7C915454 ICALL 0x7C90EAB8 -> [0x7C916B10]: 0x7C916B79 ; __local_unwind2 ICALL 0x7C915216 -> [0x12F464]: 0x7C915454 ICALL 0x7C90EAB8 -> [0x7C916B10]: 0x7C916B79 ICALL 0x7C915216 -> [0x12F464]: 0x7C915454 ICALL 0x7C90EAB8 -> [0x7C916B10]: 0x7C916B79 ICALL 0x7C90EAB8 -> [0x7C916B10]: 0x7C916B79 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C901187 -> [0x12F948]: 0x76BE10F1 ; _LdrpCallInitRoutine ICALL 0x76BE1109 -> [0x76BE103C]: 0x7C811326 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 ICALL 0x7C90D5BA -> [0x7FFE0300]: 0x7C90E4F0 - XP 32 Код (Text): ICALL 0x77D18348 -> [0x77DD31D0]: 0x77D14700 ; bsearch(RtlDebugPrintTimes) ICALL 0x77D18372 -> [0x18FA04]: 0x77D182E0 ICALL 0x77D18372 -> [0x18FA04]: 0x77D182E0 ICALL 0x77D0C9A5 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0C8B5 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0CB45 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0C725 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0C945 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0CB35 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0CB35 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D29755 -> [0x77DD31D0]: 0x77D14700 ICALL 0x77D2975B -> [0x76EC7190]: 0x8B55FF8B ICALL 0x76EC71C6 -> [0x76F300D8]: 0x77540280 ICALL 0x76EC71E1 -> [0x76F30CB4]: 0x77D2A840 ICALL 0x77D0CB35 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0CB35 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D0CAF5 -> [0x7FFDD0C0]: 0x77CC1218 ICALL 0x77D19B5B -> [0x18FC50]: 0x77AD10E0 ; LdrpCallInit ICALL 0x77AD10EE -> [0x77AD3040]: 0x775445F0 ICALL 0x775445FC -> [0x775F6584]: 0x77D2B0D0 - 8 wow Видим пару вызовов интернал колбеков, за исключением сервисов. Так же вызов загружаемого модуля. По JMP статистика - их много, все в интернал функциях, это примитивы копирования памяти и тп. Из всех интернал ветвлений происходит возврат в вызывающий код, за исключением вызова загружаемой длл. В таком случае какой смысл в релокации кодовых секций ?
Задачка была про хукнутые экспорты ntdll, экспорты из длл вынесены. Надо только вычитывать оригинал из файла, проставить все релоки, кроме указателей в секцию .data на свой образ, указатели на .data в оригинальную длл. Если по-тупому скопировать содержимое .data, будет затыкаться на сравнении указателей в ней, если пофиксить их, будет затыкаться на указатели в .data в хипе. Это единственный более-менее простой способ обойти перехват.
ну во, а говорил что я не я и жопа не моя)) а у индия всё время закос на предел того, что маглам, вроде меня, не понять))) борщит чувак не по теме специями) я конечно понимаю желание сверкнуть своими знаниями, - но не так уж чрезмерно --- Сообщение объединено, 22 авг 2019 --- исчо раз, повторюсь - как заставить работать клонированный нтдлл, после его маппинга с секции KnownDlls?
f13nd, Директория экспорта расположена в кодовой секции. Фиксапить ссылки можно(те не имеет смысла) на колбеки, я же говорил. Ничего не нужно релоцировать, n-й раз уже сказал что можно использовать образ как строку. Так восстанавливалась кодовая секция в lwe: MemoryMappedFilenameInformation(*ntdll) -> NtOpenFile -> NtCreateSection -> NtMapViewOfSection -> deprotect_code_sect -> mmcopy. Хотя можно смапить и вызвать, но при этом нужно править указатели в апп на дельту баз, что не удобно. sn0w, Тебе всё подробно сказали. Не можешь пару апи вызвать или отладить - закрой тему и займись чем то другим, коденг не твоё дело судя по всему.