![]() |
eXeL@B —› Основной форум —› Помогите разобраться с глюком в лоадере. |
Посл.ответ | Сообщение |
|
Создано: 18 октября 2007 17:47 · Поправил: SergX · Личное сообщение · #1 Пишу лоадер на Delphi 7, использую advApiHook by Ms-Rem. Столкнулся с непонятным для меня глюком. Процесс создается через CreateProcess с параметром CREATE_SUSPENDED. Насколько я понимаю, он создается но не запускается до вызова ResumeThread. Скорее всего здесь как раз моя ошибка… В память загружаемого процесса внедряется образ лоадера через InjectThisExe. И опять же если я правильно понял то сразу после внедрения исполняется Main. Тогда всё должно выглядеть так: 1. CreateProcess(…,CREATE_SUSPENDED,..) // Загружаем замороженный процесс. 2. InjectThisExe(..) // Внедряем образ своего EXE, и запускаем в нём процедуру Main. 3. ResumeThread(..) // Запускаем замороженный процесс. Подобный глюк встречал несколько раз. Приведу в пример прогу CCALC. Если между InjectThisExe и ResumeThread поставить Sleep(1000), то прога запуститься, но на окнах все кнопи, едиты и т.д. не перерисовываются, хотя вроде работают. Глюк иногда бывает и без Sleep, заметил что зависит от компа но не ясно от чего именно. А если поставить Sleep(100) в начале Main то работает нормально. Подскажите почему так ? В чём я туплю ? ПРИМЕР: Loader_BUG.zip http://rapidshare.com/files/63452072/Loader_BUG.zip.html 1.2 Mb ![]() |
|
Создано: 18 октября 2007 18:44 · Личное сообщение · #2 Потому что процесс на стадии CREATE_SUSPENDED еще не до конца проинициализирован, и если сменить regEIP, а потом сделать ResumeThread, могут возникнуть разные нехорошие глюки. Под XP SP2 можно сменить regEAX, он в это время содержит entry point проги. Тогда должно нормально работать, но на других системах врядли =\ ![]() |
|
Создано: 18 октября 2007 18:52 · Личное сообщение · #3 |
|
Создано: 18 октября 2007 19:01 · Поправил: SergX · Личное сообщение · #4 |
|
Создано: 18 октября 2007 19:44 · Поправил: Xserg · Личное сообщение · #5 Function Main(dwEntryPoint: Pointer): dword; stdcall; Begin HookProc('kernel32.dll','GetVolumeInformationA', @NewGetVolumeInformationA, @TrueGetVolumeInformationA); //Как только скончается код, скончается и хук. loadlibrary('user32.dll'); // На всякий случай. Sleep($ffffffff); // - если поставить этот слип, то вроде работает. End; З.ы. Ники у нас прикольные ![]() ![]() |
|
Создано: 18 октября 2007 21:38 · Личное сообщение · #6 |
|
Создано: 19 октября 2007 07:59 · Личное сообщение · #7 SergX пишет: Моя твоя не понимает. Скончаться – синоним слова умереть. Код (англ. Code - кодировать, программировать) – программа. Хук –(англ. Hook) – перехватывать. Применительно к программированию переводится, приблизительно так: //Как только скончается код, скончается и хук. Как только, завершится программа (в данном случае Thread), освободится память которую она занимала. В следствии чего, установленный Hook, обратится к несуществующему участку памяти. Почему умрет Thread? Адрес возврата для функции созданной CreateRemoteThread, будет ExitTread. Т.е. команда end; в функции Main , равносильна команде ExitTread. SergX пишет: Я не могу понять причём тут паузы... Если запущенная тобой программа, успеет обратится, к похуканой(сленг) АPI, до того, как умрет твой Hook, все сработает без глюков. ![]() |
|
Создано: 19 октября 2007 08:13 · Личное сообщение · #8 Глюк есть даже если из Main вообще ничё не делать… Так что трабл не в установке хука, и не в CREATE_SUSPENDED. Но если в Main поставить Sleep(100) то глюка нет… Function Main(dwEntryPoint: Pointer): dword; stdcall; Begin Sleep(100); End; Если в Main нет паузы, и запустить зразу штук 5-7 лоадеров, то на большинстве копий будет глюк. Если поставить в Main паузу все копии запускаются нормально… А если поставить паузу между InjectThisExe и ResumeThread, глюк будет 100% В чём проблема ? Причём тут паузы ? Кто куда не успевает ??? ![]() ![]() |
|
Создано: 19 октября 2007 08:20 · Поправил: SergX · Личное сообщение · #9 Xserg ты ошибаешься. Задача Main, только в том чтоб установить хук. Xserg пишет: освободится память которую она занимала Вряд ли. Щаз олей гляну. Xserg пишет: установленный Hook, обратится к несуществующему участку памяти. Это уж точно нет. Хук как раз работает нормально. З.Ы. Хотя хз. Может ты и прав. Поставил в конце Main: repeat sleep(1000); until false;
и вроде работает. Но почему всё равно не догоняю... По памяти смотрел, вроде после выполнения Main ниче не меняется. ![]() |
|
Создано: 20 октября 2007 10:36 · Личное сообщение · #10 Неужели никто не может сказать почему так происходит ? Program Loader;
![]() |
|
Создано: 20 октября 2007 12:22 · Личное сообщение · #11 |
|
Создано: 20 октября 2007 14:45 · Личное сообщение · #12 |
|
Создано: 20 октября 2007 15:46 · Поправил: SergX · Личное сообщение · #13 |
|
Создано: 20 октября 2007 15:50 · Личное сообщение · #14 SergX Возможно проблема действительно в том,что создаваемый процесс ещё не успел инициализироваться,а ты уже пихаешь в него всякие процедуры. Попробуй после создания процесса зациклить точку входа(вписать туда слово 0FEEBh) и запустить следующую функцию:
...параметры: описатель потока созданного процесса и адрес,который зациклен(в нашем случае это будет EP). После того,как функция вернёт управление,пробуй внедрять код. ----- the Power of Reversing team ![]() |
|
Создано: 20 октября 2007 16:23 · Поправил: SergX · Личное сообщение · #15 |
|
Создано: 20 октября 2007 16:23 · Поправил: SergX · Личное сообщение · #16 |
|
Создано: 20 октября 2007 16:24 · Поправил: SergX · Личное сообщение · #17 |
|
Создано: 20 октября 2007 17:31 · Личное сообщение · #18 |
|
Создано: 20 октября 2007 18:35 · Поправил: UsAr · Личное сообщение · #19 S_T_A_S_ пишет: По-моему, это в сорцах 2К есть. сорцы 2k к сожалению сейчас не могу посмотреть, но судя по исходникам функции BaseProcessStart( PVOID lpfnEntryPoint ) именно в её начале прерывается програмка с флагом CREATE_SUSPENDED. Как я понял это fastcall, хотя в сорцах реактоса она объявлена как stdcall. SergX Похоже глюк идет из-за того что второй тред стартует раньше главного и kernel32 еще не доступен (во всяком случае из другого процесса) Вообще там практически никакой инициализации не происходит, можно попробовать заменить CreateRemoteThread из InjectThisEx на NtSetInformationThread(ProcInf.hThread,ThreadQuerySetWin32StartAddress ,@Main,4); а в конец Main вставить прыжок на старый EntryPoint. а можно вместо NtSetInformationThread сменить regEax в контексте главного треда. ![]() |
|
Создано: 21 октября 2007 07:49 · Поправил: S_T_A_S_ · Личное сообщение · #20 VOID
![]() |
|
Создано: 21 октября 2007 13:14 · Личное сообщение · #21 |
|
Создано: 22 октября 2007 13:37 · Поправил: SergX · Личное сообщение · #22 DillerInc Спасибо, попробую это себе на голову натянуть. Пока не могу, углы мешают... Мне на днях стукнуло 18h, до сих пор хожу как после CreateProcess(..,CREATE_SUSPENDED,…) без ResumeThread. Hellspawn пишет: я с рапиды не могу качать Loader_BUG.ZIP http://ifolder.ru/3832219 Размер: 1.24 Мб Hellspawn пишет: вообще я аналогичным образом внедряю длл и всё ок, никаких косяков нету... Я и DLL пробовал разными способами внедрять, та же хрень. Этот глюк не всюду, а только с этой прогой, и ещё на нескольких было нечто подобное. ![]() |
|
Создано: 22 октября 2007 15:29 · Личное сообщение · #23 |
![]() |
eXeL@B —› Основной форум —› Помогите разобраться с глюком в лоадере. |