JustAGuy Posted June 6, 2015 Posted June 6, 2015 (edited) It's possible to create suspended process, change for example entrypoint and when resumed it would start from changed EP? I have a non-working executable(wrong EP) idea is to modify PE header but only when it's loaded in memory. I used WriteProcessMemory api to write correct EP to header but when resumed, process crashes. WriteProcessMemory returns success, so problem must be somewhere else. Is it too late to modify header when the process is suspended? thanx in andvance Edited June 6, 2015 by JustAGuy
JustAGuy Posted June 6, 2015 Author Posted June 6, 2015 I had to google process hollowing to find out what it is, but no, I do not try to replace one process with another, but to create loader which modifies a few PE header values in memory in order for process to work
JustAGuy Posted June 6, 2015 Author Posted June 6, 2015 it works, you did something wrong It means you created suspended process changed EP in memory , resumed process and it started form new EP?
Aguila Posted June 6, 2015 Posted June 6, 2015 (edited) yes it works, sorry I got something wrong, you must set entrypoint with SetThreadContext Edited June 6, 2015 by Aguila
Gyrus Posted June 7, 2015 Posted June 7, 2015 You can debug any process right after its first APC delivery, using: windbg.exe -xe ld:ntdll.dll YourExeNameText below is result of debugging notepad on XP SP3 x86, 5 years ago :When process A creates a normal process B:After A called CreateProcess() and kernel did all the magic, kernel uses APC to call B's ntdll!LdrInitializeThunk and to transfer the execution to B.Windows uses ntdll!KiUserApcDispatcher (of process B) as the reciever of the APC. Kernel sets the KiUAD()'s stack contents.KiUserApcDispatcher( IN PVOID Unused1, IN PVOID Unused2, IN PVOID Unused3, IN PVOID ContextStart, IN PVOID ContextBody);Unused1 = 7C901166 -> ntdll!LdrInitializeThunk -> it's "Used" here Unused2 = 00000000Unused3 = 7c900000ContextStart = 00000000ContextBody = 17 00 01 00 -> Beginning of a context structure which is on the stack.ntdll!KiUserApcDispatcher() loads ContextBody's stack pointer into edi for using it after popping the ntdll!LdrInitializeThunk() address (Unused1) into eax and calling it for initialization.ntdll!KiUserApcDispatcher:lea edi,[esp+10h -> ContextBody]pop eax -> ntdll!LdrInitializeThunk() address = Unused1call eax -> Stepping over this will generate the debugger's first break-exception (int3). ntdll!LdrInitializeThunk() does not change the eip and eax of ContextBody structure.push 1push edicall ntdll!ZwContinueThen KiUAD() calls ntdll!ZwContinue(edi -> ContextBody, TRUE)NtContinue( IN PCONTEXT ThreadContext, IN BOOLEAN RaiseAlert );Inside the ContextBody structure:ntdll!_CONTEXT +0x000 ContextFlags : 0x10017 +0x09c Edi : 0xa4f6ee +0x0a0 Esi : 0xa4f718 +0x0a4 Ebx : 0x7ffdd000 +0x0a8 Edx : 0x30 +0x0ac Ecx : 0x20fa685 +0x0b0 Eax : 0x100739d -> the real entrypoint of the process +0x0b4 Ebp : 0 +0x0b8 Eip : 0x7c810735 -> This is where the execution resumes and is address of kernel32!BaseProcessStartThunk: +0x0bc SegCs : 0x1b +0x0c0 EFlags : 0x300 +0x0c4 Esp : 0x7fffc -> sets esp to top of the stackkernel32!BaseProcessStartThunk:xor ebp,ebppush eax -> pushes the real entrypoint of the processpush 0jmp kernel32!BaseProcessStartkernel32!BaseProcessStart:push 0Chpush offset kernel32!`string'+0x98call kernel32!_SEH_prologand dword ptr [ebp-4],0push 4lea eax,[ebp+8]push eaxpush 9 -> _THREAD_INFORMATION_CLASS->ThreadQuerySetWin32StartAddresspush 0FFFFFFFEhcall dword ptr [kernel32!_imp__NtSetInformationThread -> Sets the thread strart address (_ETHREAD->Win32StartAddress) to it's real onecall dword ptr [ebp+8] -> Calls the real entrypoint.push eax -> Real entrypoint returned..call kernel32!ExitThread -> .. exit this thread.Real entrypoint is inside the ContextBody->Eax and kernel fills the ContextBody before the APC call.For a suspended process B, kernel does not automatically call ntdll!LdrInitializeThunk() via APC. I guess you can remotely install a hook (without dll) on ntdll!ZwContinue to change the real EP (ContextBody->Eax) into any address you want. ******************************************************************************************** ******************************************************************************************** @ Aguila:On XP SP3 x86, Set/GetThreadContext doesn't work with a new suspended processes. (attachment) When I break on KiUAD() with Windbg, before ZwContinue, trying to set a hardware breakpoint shows this error: on ntdll!KiUserApcDispatcher+0x4 (pop eax): -ba ntdll!KiUserApcDispatcher ^ Unable to set breakpoint errorThe system resets thread contexts after the process breakpoint so hardware breakpoints cannot be set. Go to the executable's entry point and set it then. Please correct me if i'm wrong. Test.rar
Aguila Posted June 7, 2015 Posted June 7, 2015 works on all operating systems CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI);GetThreadContext(PI.hThread, &ctx);ctx->Eax = pImageBase + AddressOfEntryPoint;SetThreadContext(PI.hThread, &ctx);ResumeThread(PI.hThread); 2
Gyrus Posted June 7, 2015 Posted June 7, 2015 Thank you AguilaThat was my mistake. I didnt setctx.ContextFlags = CONTEXT_ALLbefore calling Set/GetThreadContext Actually i was lost in my dusty stuffs. this new attachment works well.test2.rar
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now