Сейчас на форуме: zds, _MBK_ (+6 невидимых)

 eXeL@B —› Основной форум —› Помогите разобраться с глюком в лоадере.
Посл.ответ Сообщение

Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 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



Ранг: 66.8 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 18 октября 2007 18:44
· Личное сообщение · #2

Потому что процесс на стадии CREATE_SUSPENDED еще не до конца проинициализирован, и если сменить regEIP, а потом сделать ResumeThread, могут возникнуть разные нехорошие глюки.
Под XP SP2 можно сменить regEAX, он в это время содержит entry point проги. Тогда должно нормально работать, но на других системах врядли =\



Ранг: 115.1 (ветеран), 3thx
Активность: 0.070
Статус: Участник

Создано: 18 октября 2007 18:52
· Личное сообщение · #3

посмотрите как запускает второй процесс армадилла, она пишет в точку входа EBFE(jmp $)
и потом делает resume процессу, в этот момент можно инжектить код, чтобы его запустить
используйте SetThreadContext, не забудьте учесть ньюансы ;)



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 18 октября 2007 19:01 · Поправил: SergX
· Личное сообщение · #4

Глюк бывает и без CREATE_SUSPENDED с ResumeThread.
Просто если запускать через CREATE_SUSPENDED и между InjectThisExe и ResumeThread поставить Sleep(1000), он будет гарантированно. Если без Sleep(1000) то бывает иногда.

В примере наглядно показано.

Я не могу понять причём тут паузы...



Ранг: 24.9 (новичок)
Активность: 0.010
Статус: Участник

Создано: 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;

З.ы. Ники у нас прикольные



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 18 октября 2007 21:38
· Личное сообщение · #6

Xserg пишет:
//Как только скончается код, скончается и хук.

Моя твоя не понимает.

Xserg пишет:
З.ы. Ники у нас прикольные

Ага, обхохочешься...



Ранг: 24.9 (новичок)
Активность: 0.010
Статус: Участник

Создано: 19 октября 2007 07:59
· Личное сообщение · #7

SergX пишет:
Моя твоя не понимает.

Скончаться – синоним слова умереть.
Код (англ. Code - кодировать, программировать) – программа.
Хук –(англ. Hook) – перехватывать.
Применительно к программированию переводится, приблизительно так:

//Как только скончается код, скончается и хук.
Как только, завершится программа (в данном случае Thread), освободится память которую она занимала. В следствии чего, установленный Hook, обратится к несуществующему участку памяти.

Почему умрет Thread?
Адрес возврата для функции созданной CreateRemoteThread, будет ExitTread.
Т.е. команда end; в функции Main , равносильна команде ExitTread.

SergX пишет:
Я не могу понять причём тут паузы...

Если запущенная тобой программа, успеет обратится, к похуканой(сленг) АPI, до того, как умрет твой Hook, все сработает без глюков.



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 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%

В чём проблема ? Причём тут паузы ?
Кто куда не успевает ???

Бред какой-то !



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 19 октября 2007 08:20 · Поправил: SergX
· Личное сообщение · #9

Xserg ты ошибаешься. Задача Main, только в том чтоб установить хук.

Xserg пишет:
освободится память которую она занимала

Вряд ли. Щаз олей гляну.

Xserg пишет:
установленный Hook, обратится к несуществующему участку памяти.

Это уж точно нет. Хук как раз работает нормально.


З.Ы.
Хотя хз. Может ты и прав. Поставил в конце Main:
repeat sleep(1000); until false;
и вроде работает. Но почему всё равно не догоняю...
По памяти смотрел, вроде после выполнения Main ниче не меняется.



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 20 октября 2007 10:36
· Личное сообщение · #10

Неужели никто не может сказать почему так происходит ?

Program Loader;
{$IMAGEBASE $15000000}

Uses Windows, AdvApiHook;
Var StartInf: TStartupInfo; ProcInf: TProcessInformation;

Function Main(dwEntryPoint: Pointer): dword; stdcall;
Begin
Sleep(100); // - если поставить этот слип, то вроде работает OK.
ExitThread(0);
End;

Begin
ZeroMemory(@StartInf, SizeOf(TStartupInfo));
StartInf.cb:=SizeOf(TStartupInfo);
CreateProcess(nil, 'ccalc.exe', nil, nil, false, CREATE_SUSPENDED, nil, nil, StartInf, ProcInf);
InjectThisExe(ProcInf.hProcess, @Main);
Sleep(1000); // - а если поставить этот, то глюк будет 100%.
ResumeThread(ProcInf.hThread);
End.





Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 20 октября 2007 12:22
· Личное сообщение · #11

выложи все исходники, где то у тя косяк в реализации...

-----
[nice coder and reverser]




Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 20 октября 2007 14:45
· Личное сообщение · #12

UsAr пишет:
на других системах врядли

По-моему, это в сорцах 2К есть.



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 20 октября 2007 15:46 · Поправил: SergX
· Личное сообщение · #13

Hellspawn пишет:
выложи все исходники, где то у тя косяк в реализации...

Тебе смешно, а мне не очень.
Оно мне в принципе и не нужно, но не даёт спокойно спать...
Потратил уже кучу времени, но пока без результатов.
Не хватает знаний и практики.

З.Ы. Если ты серьёзно, то все файлы в первом посте.




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 20 октября 2007 15:50
· Личное сообщение · #14

SergX
Возможно проблема действительно в том,что создаваемый процесс ещё не успел инициализироваться,а ты уже пихаешь в него всякие процедуры.
Попробуй после создания процесса зациклить точку входа(вписать туда слово 0FEEBh) и запустить следующую функцию:


WAIT_PAUSE equ 02

; ########################################## SleepRoutine ########################################
SleepRoutine proc USES esi hThread:HANDLE, HookedAddr:DWORD

local pContext:CONTEXT

mov pContext.ContextFlags, CONTEXT_FULL

mov esi, HookedAddr

@@sleeping_loop:
lea eax, pContext
push eax
push hThread
call GetThreadContext

cmp dword ptr pContext.regEip, esi
jz @F

push hThread
call ResumeThread

push WAIT_PAUSE
call Sleep

push hThread
call SuspendThread

jmp @@sleeping_loop

@@:
ret

SleepRoutine endp


...параметры: описатель потока созданного процесса и адрес,который зациклен(в нашем случае это будет EP).
После того,как функция вернёт управление,пробуй внедрять код.

-----
the Power of Reversing team




Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 20 октября 2007 16:23 · Поправил: SergX
· Личное сообщение · #15

[del]



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 20 октября 2007 16:23 · Поправил: SergX
· Личное сообщение · #16

[del]



Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 20 октября 2007 16:24 · Поправил: SergX
· Личное сообщение · #17

[del]




Ранг: 283.6 (наставник), 56thx
Активность: 0.130
Статус: Участник
Author of GeTaOEP

Создано: 20 октября 2007 17:31
· Личное сообщение · #18

SergX
Дык,ты сначала проверь,а потом мы уже будем гипотезы строить,почему же он выдаёт глюк.Кстати,что именно делает эта функция InjectThisExe??

-----
the Power of Reversing team




Ранг: 66.8 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 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 в контексте главного треда.



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 21 октября 2007 07:49 · Поправил: S_T_A_S_
· Личное сообщение · #20

VOID
BaseInitializeContext(
OUT PCONTEXT Context,
IN PVOID Parameter OPTIONAL,
IN PVOID InitialPc OPTIONAL,
IN PVOID InitialSp OPTIONAL,
IN BASE_CONTEXT_TYPE ContextType
)

/*++

Routine Description:

This function initializes a context structure so that it can
be used in a subsequent call to NtCreateThread.

Arguments:

Context - Supplies a context buffer to be initialized by this routine.

Parameter - Supplies the thread's parameter.

InitialPc - Supplies an initial program counter value.

InitialSp - Supplies an initial stack pointer value.

NewThread - Supplies a flag that specifies that this is a new
thread, or a new process.

Return Value:

Raises STATUS_BAD_INITIAL_STACK if the value of InitialSp is not properly
aligned.

Raises STATUS_BAD_INITIAL_PC if the value of InitialPc is not properly
aligned.

--*/

{

Context->Eax = (ULONG)InitialPc;
Context->Ebx = (ULONG)Parameter;

//...





Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 21 октября 2007 13:14
· Личное сообщение · #21

SergX

я с рапиды не могу качать) вообще я аналогичным образом внедряю длл и всё ок,
никаких косяков нету... Поэтому я и предположил... =)

з.ы. так ли нужно те внедрять ехе?

-----
[nice coder and reverser]




Ранг: 226.0 (наставник), 67thx
Активность: 0.160
Статус: Участник

Создано: 22 октября 2007 13:37 · Поправил: SergX
· Личное сообщение · #22

DillerInc
Спасибо, попробую это себе на голову натянуть.
Пока не могу, углы мешают...
Мне на днях стукнуло 18h, до сих пор хожу как после CreateProcess(..,CREATE_SUSPENDED,…) без ResumeThread.

Hellspawn пишет:
я с рапиды не могу качать

Loader_BUG.ZIP http://ifolder.ru/3832219 Размер: 1.24 Мб

Hellspawn пишет:
вообще я аналогичным образом внедряю длл и всё ок, никаких косяков нету...

Я и DLL пробовал разными способами внедрять, та же хрень. Этот глюк не всюду, а только с этой прогой, и ещё на нескольких было нечто подобное.



Ранг: 163.7 (ветеран)
Активность: 0.070
Статус: Участник

Создано: 22 октября 2007 15:29
· Личное сообщение · #23

Eax пробовал?


 eXeL@B —› Основной форум —› Помогите разобраться с глюком в лоадере.
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати