хз в реверс или сюда, как по мне - проще наверное сюда, ибо просто отладка фактически. давно чёто ничего не писал, сейчас у самого к фоксу тёрки, поэтому параллельно напишу. файрфокс свежий, 64битный. если кто заморачивался - наверное заметили, инжект то сделан, код внедрён, а не запускается при помощи CreateRemoteThread. сразу оговорюсь - это может присекать и авер своей проактивкой, которая вообщем тоже обходится, но это несколько приватные разработки, такчто расскажу про голый фокс просто. с чем это может быть связано? а с тем что поток скорее всего ктото прихлопнул. или он грохнулся сам. плясать будем от конца. я использую windbg, имхо лучший дебаггер виндовый, умеет практически всё, кроме того чтобы ассемблировать x64 инструкции в х64 режиме, хотя х86ые в том же х64 - легко. это единственный минус. надеюсь когданибудь исправят. он не очень прост - но если осилить документацию, да потренироваться - лучшей альтернативы не сыскать. короче, вокруг да около ходить не буду, я сразу прикинул что поток попросту убивается гдето на пути следования от ntdll!RtlUserThreadStart и до указанной в CreateRemoteThread() LPTHREAD_START_ROUTINE. иного быть и не может т.к. результат отработки CreateRemoteThread успешен, а никаких сторонних шляп, которые бы могли вмешаться в процесс работы инжектора (а это сторонний процесс) попросту нет. дело в том что вообще любой юзермодный поток стартует именно с ntdll!RtlUserThreadStart, а выпиливается при вызове ntdll!NtTerminateThread. этим и воспользуемся. воспользуемся фильтрованием событий. запускаем виндбг, открываем из него файрфокс, даём команду: эта команда значит - брякаться когда какойто поток завершает исполнение. относится к разряду событий. есть кстати 2 вида причин: события отладки и программные исключения. писать долго о разнице - читайте мануалы. полный список можно посмотреть командой sx на данный момент будем часто брякаться, т.к. много потоков и одни запускаются, другие выходят итд, жмём ф5 пока не настанет относительное спокойствие. затем берем инжектор, который должен выполнить CreateRemoteThread, запускаем.. и тут мы должны брякнуться и увидеть примерно такое: ага. убился ктото. и скорее всего это наш поток, судя по тому что бряк произошёл сразу после инжекта. посмотрим его коллстек, чтобы разобраться как он сюда приполз: тут всё последовательно, RtlExitUserThread должна вызвать NtTerminateThread. а вот саму RtlExitUserThread какимто хером вызвала BaseThreadInitThunk. надо бы глянуть там. кстати вот еще. чтобы убедиться тот ли мы тред смотрим, посмотримка все командой ~ (покажу только конец списка) ... 53 Id: 5b4c.14c Suspend: 1 Teb: 000000df`7d474000 Unfrozen "URL Classifier" 54 Id: 5b4c.2444 Suspend: 1 Teb: 000000df`7d476000 Unfrozen "Classifier Update" 55 Id: 5b4c.249c Suspend: 1 Teb: 000000df`7d4ae000 Unfrozen 56 Id: 5b4c.43a4 Suspend: 1 Teb: 000000df`7d4b4000 Unfrozen "StreamTrans #13" 57 Id: 5b4c.1770 Suspend: 1 Teb: 000000df`7d47c000 Unfrozen "SaveScripts" 58 Id: 5b4c.828 Suspend: 1 Teb: 000000df`7d47e000 Unfrozen "Cache I/O" 59 Id: 5b4c.5a04 Suspend: 1 Teb: 000000df`7d480000 Unfrozen "mozStorage #1" 60 Id: 5b4c.5de8 Suspend: 1 Teb: 000000df`7d482000 Unfrozen "mozStorage #2" 61 Id: 5b4c.1c24 Suspend: 1 Teb: 000000df`7d484000 Unfrozen "mozStorage #3" 62 Id: 5b4c.5a30 Suspend: 1 Teb: 000000df`7d4a0000 Unfrozen 63 Id: 5b4c.5c28 Suspend: 1 Teb: 000000df`7d488000 Unfrozen "localStorage DB" 64 Id: 5b4c.5c7c Suspend: 1 Teb: 000000df`7d48a000 Unfrozen "QuotaManager IO" 65 Id: 5b4c.415c Suspend: 1 Teb: 000000df`7d4b6000 Unfrozen "Lazy Idle" . 66 Id: 5b4c.15f0 Suspend: 0 Teb: 000000df`7d4b8000 Unfrozen вот. практически все потоки фокса имеют тег, наш его иметь не должен, ибо не задавали. он помечен точкой, номер 66 (контекст которого сейчас смотрит отладчик, и по совместительству онже и вызвал событие, а если был бы не активным - напротив бы стояла # - означает поток вызвавший исключение) так вот, интересно нам с чего это BaseThreadInitThunk закинула нас самоубиваться. поэтому задеассемблим её: и тут невооружённым глазом видна какаято херня, джамп кудато в модули мозиллы. особо заморачиваться не стоит, т.к. уже понятно что в стандартном случае поток идёт так: ntdll!RtlUserThreadStart-> KERNEL32!BaseThreadInitThunk -> ...LPTHREAD_START_ROUTINE у нас же выходит что: ntdll!RtlUserThreadStart-> KERNEL32!BaseThreadInitThunk -> (offset mozglue!mozilla::Compression::LZ4::decompress+0x1b0) ->RtlExitUserThread->NtTerminateThread от этого можно фф отучить легко, просто поставить бряк на запись по адресу KERNEL32!BaseThreadInitThunk и выявить того кто пытается эту функу пропатчить. но решение на самом деле проще без всяких кряков: создаём замороженыйй поток (он стартует с RtlUserThreadStart но и там пока спит). берём его контекст, ставим RIP = LPTHREAD_START_ROUTINE, и пробуждаем. вуаля, заработало. Code: HANDLE thread = CreateRemoteThread(hndProc, NULL, 0, (LPTHREAD_START_ROUTINE) address_of_ep, NULL, CREATE_SUSPENDED, NULL); CONTEXT ctx; ctx.ContextFlags = CONTEXT_ALL; GetThreadContext(thread, &ctx); ctx.Rip = (DWORD64)address_of_ep; SetThreadContext(thread, &ctx); ResumeThread(thread); CloseHandle(thread); ну и всё. а можно попросту переписать KERNEL32!BaseThreadInitThunk в процессе фокса копией кода со своего процесса, тогда и без хитрости выше запашет. если конечно снова не перезапишет, не смотрел, лень. всем добра.
Всё это прошлый век. 1) Не работает инжект из 32 в 64 битные 2) Сомневаюсь что поможет в работе во всяких EDGE где строка следят за исполнением левого кода 3) Подобное можно засечь без проблем: в любой своей DLL в EntryPoint следить за DLL_THREAD_ATTACH и уничтожать все левые потоки. Если хочется универсальности и красоты, то 1) Получаем адрес NtWaitForSingleObject 2) Добавляем права на запись через NtProtectVirtualMemory или в случае 32->64 вызываем 64-х битный NtProtectVirtualMemory через heaven gate 3) Пишем свой шелкод и патчим NtWaitForSingleObject для прыжка на шелкод 4) 99% процессов в течении пару секунд вызовут шелкод и главное никакой мороки с кроссархитектурностью или любой защитой. Да и к тому же запись в память как бы менее паливное дело чем запуск удаленного потока.
Но это же вроде не совсем про фаерфокс И для прыжка на шеллкод кстати это овермайнд. Я как-то тоже думал что канонишный ядырный метод переключения на процесс будет палиться. Сколько лет прошло а он не палится. Хотя может это потому что всякий это подозревает и страхуется
Забыл. Гуглил щас... но забыл. Была функа типа "PsGetCurrentProcess" или типа того. Не помню. И такая же функа чтобы сменить контекст. Я всегда хук юзал Думаю палевно это менять контекст такой функой А зря. Никто внимания не обращает. Но кстате Огнелис выдержит. Он патчит системные dll-ки и чуть что вываливается не объясняя причин.
Ох чуйствую слеш щас как даст мне по жопе )) Но на самом деле есть такой факт. Если ты вздумаешь его дебажить - он фокусы выкидывает с завидной регулярностью. А по хорошему надо бы обновить RKU.
Интересно. А обязательно дизасмом заниматься? Я почему-то думал что Firefox это Open Source продукт и там можно глянуть исходники... думал так, не проверял
Глянь, чтож. И убедишься, что насыпано там немало всяких чудес, и в Windows, и в Linux и в Android версиях.
короче хуита эьто, учитывая чт о исходный код никто не скрывал оказывается, просто меня в гугле забанили
там покупать нечего, берешь читаешь LdrLoadDll и BaseThreadInitThunk в своём процессе и копируешь в процесс браузера. если конечно нет всяких проактивок аверских. хотя это тоже обходится со свистом, главное не шаблонить