tempnode Posted August 5, 2008 Share Posted August 5, 2008 Does anyone here know how to inject an executable into a suspended process? Basically, by doing so, you can run the executable from the current process's domain instead of running it from disk. i know the basics, but i'm having a bit of difficulty with the implementation Quote Link to comment Share on other sites More sharing options...
tempnode Posted August 7, 2008 Author Share Posted August 7, 2008 just for reference: it's possible to inject an EXE into a suspended process, but there is a program called RAMDisk that will create a virtual HDD (it will even show up under my computer) of variable size which you can set in the .inf file. RAMDisk allocates areas of blank memory for storage of anything you want: games, pics, vids, etc... and since the files exist on RAM instead of a physical HDD, access times are boosted by up to 50x normal speeds. ** However, this is important: THE FILES ON THE RAMDISK WILL BE DELETED UPON COMPUTER SHUTDOWN. The RAMDisk drive will still exist, but the files will be toasted (there are some RAMDisk applications with built-in backups that write to your HDD and rewrite to the RAMDisk on startup, though). Just thought I would post this in case anyone else ran into this problem. Quote Link to comment Share on other sites More sharing options...
Sparda Posted August 7, 2008 Share Posted August 7, 2008 just for reference: it's possible to inject an EXE into a suspended process, but there is a program called RAMDisk that will create a virtual HDD (it will even show up under my computer) of variable size which you can set in the .inf file. RAMDisk allocates areas of blank memory for storage of anything you want: games, pics, vids, etc... and since the files exist on RAM instead of a physical HDD, access times are boosted by up to 50x normal speeds. ** However, this is important: THE FILES ON THE RAMDISK WILL BE DELETED UPON COMPUTER SHUTDOWN. The RAMDisk drive will still exist, but the files will be toasted (there are some RAMDisk applications with built-in backups that write to your HDD and rewrite to the RAMDisk on startup, though). You can also get these as physical devices that don't requirer drivers to emulate a drive, this is good as they can have features such as the ability to retain the memory on power loss (using batteries). This is bad because it costs much much more. Note: Linux has had this functionality since 2.4(?). Quote Link to comment Share on other sites More sharing options...
moonlit Posted August 7, 2008 Share Posted August 7, 2008 AmigaOS had this functionality 15 years ago, and it even had a RAD disk which was essentially the same but would survive a soft reboot. Trumps you, sir! Quote Link to comment Share on other sites More sharing options...
Steve8x Posted August 8, 2008 Share Posted August 8, 2008 just for reference: it's possible to inject an EXE into a suspended process, but there is a program called RAMDisk that will create a virtual HDD (it will even show up under my computer) of variable size which you can set in the .inf file. RAMDisk allocates areas of blank memory for storage of anything you want: games, pics, vids, etc... and since the files exist on RAM instead of a physical HDD, access times are boosted by up to 50x normal speeds. ** However, this is important: THE FILES ON THE RAMDISK WILL BE DELETED UPON COMPUTER SHUTDOWN. The RAMDisk drive will still exist, but the files will be toasted (there are some RAMDisk applications with built-in backups that write to your HDD and rewrite to the RAMDisk on startup, though). Just thought I would post this in case anyone else ran into this problem. What does a RAMdisk have to do with injecting code into a process? I don't see the similarity there! Anyways what I think you mean is you want to inject executable code into a process! you can't exactly inject a .EXE into a process but you can inject some code or a DLL which will run your code from within the process! Injecting a .dll is closer to injecting an .exe than pure code injection! because you can create your DLL just like creating an EXE and inject it into the process and have it run the code either by having the dll create a thread upon injection or you could create the thread yourself with createremotethread... I would go with dll injection because its much simpler than pure code injection! because you can just code it like an exe compile it and inject it and everything will work right! doing just code injection without the dll, is more difficult because you pretty much have to code in assembly and since your inside another process you cannot access variables like you could in your own process, you'll understand in a bit, I'll show an example of both methods... First DLL Injection, I recommend using C++ to make things easier!, MASM if your feeling up to it. ::: here is the basic DLL skeleton: #include <windows.h> BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) {     switch (reason)     {         case DLL_PROCESS_ATTACH:             break;         case DLL_PROCESS_DETACH:             break;     }         return TRUE; } Its very simple "DllMain" is called immediately after the dll is loaded into a process (via LoadLibrary API) since its loading and not being free'd the reason is "DLL_PROCESS_ATTACH" usually a dll doesn't do anything in DLL_PROCESS_ATTACH, and it just exports functions which are to be called by the process that loads it! But for executing this code in a process I like to just not export anything and just Create a thread instead! Once you have a running thread in your target process you can do anything you want inside it! Including create more threads! :) Here is a some code of a dll which creates a thread, which waits indefinitely for a keypress!(F12) when the key is pressed it creates a message box (you can really make it do anything you want so whatever code you want to put here is fine, you don't need the infinite loop if its not desired or the waiting for a keypress I just made it as an example. I haven't had any luck getting it to work in dev cpp, for some reason dllmain is not being called upon. So instead I compiled it in visual studio 2008. So it may be dependent on the 2008 package http://www.microsoft.com/downloads/details...;displaylang=en So i've also made the same thing in assembly that for sure isn't dependent on any package like that! Visual C++ 2008 version: #include <windows.h> void MyThread() {     for(;; Sleep(10))     {         if(GetAsyncKeyState(VK_F12))         {             MessageBoxA(0, "Hello World! From A DLL!", "FROM DLL THREAD!", 0);         }     } } BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved) {     switch(reason)     {         case DLL_PROCESS_ATTACH:             CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&MyThread, 0, 0, 0);             break;         case DLL_PROCESS_DETACH:             break;     }         return TRUE; } http://www.popeax.com/download/TestDllCPP.rar MASM32 version: ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««       .486                    ; create 32 bit code       .model flat, stdcall    ; 32 bit memory model       option casemap :none    ; case sensitive ;    include files ;    ~~~~~~~~~~~~~       include \masm32\include\windows.inc       include \masm32\include\masm32.inc       include \masm32\include\gdi32.inc       include \masm32\include\user32.inc       include \masm32\include\kernel32.inc       include \masm32\include\Comctl32.inc       include \masm32\include\comdlg32.inc       include \masm32\include\shell32.inc       include \masm32\include\oleaut32.inc       include \masm32\include\dialogs.inc       include \masm32\macros\macros.asm    ; the macro file ;    libraries ;    ~~~~~~~~~       includelib \masm32\lib\masm32.lib       includelib \masm32\lib\gdi32.lib       includelib \masm32\lib\user32.lib       includelib \masm32\lib\kernel32.lib       includelib \masm32\lib\Comctl32.lib       includelib \masm32\lib\comdlg32.lib       includelib \masm32\lib\shell32.lib       includelib \masm32\lib\oleaut32.lib   ; ----------------------------------------   ; prototypes for local procedures go here   ; ----------------------------------------     MyThread PROTO       .data         Msg db 'Hello World! From A Dll!',0         MsgTitle db 'FROM DLL THREAD',0       .data?         hInstance dd ?       .code ; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« LibMain proc instance:DWORD,reason:DWORD,unused:DWORD     .if reason == DLL_PROCESS_ATTACH     m2m hInstance, instance     invoke CreateThread, 0, 0, addr MyThread, 0, 0, 0     .elseif reason == DLL_PROCESS_DETACH     .endif     ret LibMain endp MyThread proc     InfiniteLoop:     invoke Sleep, 10     invoke GetAsyncKeyState, VK_F12     test eax, eax     jz InfiniteLoop; if eax == 0 key was not pressed   ;If the execution makes it here, then F12 was pressed!     invoke MessageBox, 0, addr Msg, addr MsgTitle, 0     jmp InfiniteLoop MyThread endp     end LibMain http://www.popeax.com/download/TestDllASM.rar You can inject this into any process at all, and when F12 is pressed the messagebox will be created! and after you click ok the thread will still continue to run! How do you inject this dll into a process? Well the simplest method that I use most of the time is the CreateRemoteThread method... basically you allocate some memory in the target process, copy the path to the dll you want to inject into the allocated memory, then use CreateRemoteThread on the LoadLibrary address passing the pointer to the DLL string allocated in the process as the parameter... What will happen is a thread will begin at loadlibrary which will attempt to load the dll, if the path is correct the dll will be "injected" and your DllMain will be called with "DLL_PROCESS_ATTACH" reason, which will create your thread! Simple enough eh? here's a simple DLL injector I coded up in dev c++! download source here: http://www.popeax.com/download/DLLinjectorSRC.rar a clip from the source, which does the injecting bit... void InjectDll() {      void* remoteDLLstring = 0;     HANDLE processhandle = 0;     DWORD processID = 0;     DWORD BytesWritten = 0;         GetWindowText(pnameBox, ProcessName, 100);     if(ProcessName[0] == 0)     {         MessageBox(hwnd, "Enter A Process Name!", 0, 0);         ExitThread(0);     }     if(DllPath[0] == 0)     {         MessageBox(hwnd, "Type Or Browse For A Dll To Inject!", 0, 0);         ExitThread(0);     }         processID = GetPID(ProcessName);         if(!processID)     {         MessageBox(hwnd, "Failed to get process ID! \n make sure its running and try again", 0, 0);         ExitThread(0);     }         processhandle = OpenProcess(PROCESS_ALL_ACCESS, 0, processID);         if(!processhandle)     {         MessageBox(hwnd, "Failed to open process!! should not happen!", 0, 0);         ExitThread(0);     }         remoteDLLstring = VirtualAllocEx(processhandle, 0, strlen(DllPath)+1, MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(processhandle, remoteDLLstring, DllPath, strlen(DllPath), &BytesWritten);         DWORD loadLibraryAddress = (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");         // final step! :)         CreateRemoteThread(processhandle, 0, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddress, remoteDLLstring, 0, 0);         MessageBox(hwnd, "DLL INJECTED", "SUCCESS!", 0); } Now for the pure code injection! ::::: Basically we are going to do similar like injecting a dll, except we wont create a thread at loadlibrary, we will copy our code over into the executable directly and create our thread at the address the code was copied to! Its a little more difficult! Every variable or string or API address that we want to use in the target process must be copied over to it before executing the thread! for example if you had this code in your code to copy over "invoke MessageBox, 0, addr String, addr TitleString, 0" copying it over and running the thread would make the program crash! why? because the address in your application of "MessageBox" isnt the real address, it is instead from your programs IAT, so since your programs IAT is different from the target process, it will be an invalid address and the program will crash! So we have to use GetProcAddress, for all the API's we want to use, then copy them over, normally I would copy all the API's and addresses I needed into an array on the target process, then use any address by knowing the correct offset from the array! but to make things simpler for this example we aren't going to use an array, we are only going to use two api's! MessageBoxA(to display a message so we know it worked), and ExitThread(so the thread can exit peacefully without crashing the program) as you can see from the image, after I clicked inject code, the messagebox was called from inside of "calc.exe" notice the icon in the taskbar which is the calculator icon! try it with any running executable, and the messagebox will have the same icon as it! download here MASM32 project: http://popeax.com/download/CodeInjectionASM.zip here I will explain the code: CodeToInject proc     push 0DEADBEEFh; place holder for exit thread address         push 0; MB_OK     push 0BAADF00Dh; place holder for remote title address     push 0BAADBABEh; place holder for remote string address     push 0; no window handle provided     push 0BAADF00Dh; place holder for MessageBoxA address     pop eax; pop the messageboxa address off of the stack into eax     call eax; invoke MessageBoxA, 0, [addressofstring], [addressoftitle], 0     pop eax; pop the exit thread address into eax     push 0     call eax; invoke ExitThread, 0   CodeToInject endp that block of code is what will be copied into the target process! by place holder I mean it is just temporarily taking up the right amount of space, so that when we copy our addresses over this; the number of bytes stays the same except the values change, the invokes are there just to show you what the actual code is doing... INVOKE in MASM is just a nice way of doing push push call normally in ASM you push the parameters of the API/Function your trying to use in backwards into the stack, then you call the function address... MASM has the nice INVOKE feature where it will do that for you and you can just write invoke and write the params in the correct order! ;) InjectCode proc     LOCAL processname:DWORD     LOCAL processhandle:DWORD     LOCAL oldProtect:DWORD     stralloc 100     mov [processname], eax     mov [pID], 0     invoke GetWindowText, [ProcessNameBox], [processname], 100     invoke GetPID, [processname]     .if [pID] == 0     invoke MessageBox, 0, SADD("Process Not Found, Make Sure Its Running And Try Again"), 0, 0     invoke ExitThread, 0     .endif     invoke OpenProcess, PROCESS_ALL_ACCESS, 0, [pID]     mov [processhandle], eax LOCAL whatever:DWORD those just declare local stack variables so that we can use them temporarily stralloc allocates 100 bytes for a string then we move the address of that allocated string into [processname] we reset pID to zero incase we are going the second time around to make sure its null before calling GetPID GetWindowText grabs the process name from the editbox GetPID is exactly like the C++ function that was in the DLL injector! it does the same thing. Get the process ID from the process name, needed so we can call open process to get a handle to the process     invoke lstrlen, addr RemoteString     inc eax     mov [strlen1], eax     invoke lstrlen, addr RemoteTitle     inc eax     mov [strlen2], eax that just gets the length of the two strings and stores them into dword values, we need the lengths so we can know how much memory to allocate and how many bytes of the string to copy over   ;allocate memory to copy the code, and strings to     invoke VirtualAllocEx, [processhandle], 0, 1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE     mov [RemoteCode], eax     invoke VirtualAllocEx, [processhandle], 0, [strlen1], MEM_COMMIT, PAGE_READWRITE     mov [RemoteStringAddy], eax     invoke VirtualAllocEx, [processhandle], 0, [strlen2], MEM_COMMIT, PAGE_READWRITE     mov [RemoteTitleAddy], eax pretty self explanitory, note for the RemoteCode we make the protection PAGE_EXECUTE_READWRITE because we are not only going to be reading and writing to it but also EXECUTING A THREAD THERE! the addresses of the allocated memory are stored in the dword values, the addresses are not in our process but the target one!   ;get needed API addresses     invoke GetProcAddress, FUNC(GetModuleHandle, addr krnl32), SADD("ExitThread")     mov [ExitThreadAddy], eax     invoke GetProcAddress, FUNC(GetModuleHandle, addr usr32), SADD("MessageBoxA")     mov [MessageBoxAddy], eax   ;move real addresses into place holders   ;i figured out the offsets using a disassembler on this program         invoke VirtualProtect, addr CodeToInject, 24, PAGE_EXECUTE_READWRITE, addr oldProtect; so we can write over our code to inject     mov eax, offset CodeToInject   ; we need the real addresses so we have a flawless working code in the remote process     mov ecx, [ExitThreadAddy]     mov [eax+1], ecx     mov ecx, [RemoteTitleAddy]     mov [eax+8], ecx     mov ecx, [RemoteStringAddy]     mov [eax+13], ecx     mov ecx, [MessageBoxAddy]     mov [eax+20], ecx     mov ecx, offset EndOfCode     sub ecx, eax; ecx now equals size of code to inject;)   ;Write CodeToInject + Strings into the process at the memory we already allocated     invoke WriteProcessMemory, [processhandle], [RemoteCode], addr CodeToInject, ecx, addr byteswritten     invoke WriteProcessMemory, [processhandle], [RemoteStringAddy], addr RemoteString, [strlen1], addr byteswritten     invoke WriteProcessMemory, [processhandle], [RemoteTitleAddy], addr RemoteTitle, [strlen2], addr byteswritten   ;finally create the remote thread which will create a messagebox from the remote process and then exit the thread     invoke CreateRemoteThread, [processhandle], 0, 0, [RemoteCode], 0, 0, 0     strfree processname     invoke ExitThread, 0 InjectCode endp So thats basically it! You should now have a better understanding of injecting executable code into processes in windows! You probably will want to make a DLL as its much simpler and closer to what you described! I like to think of DLL's as EXE's in a way, except they cannot run on their own, they must have an exe to load them! So injecting a dll is almost like injecting an exe :) NOTE* you need winrar to unzip/unrar the files here's the link to download MASM32, ITS FREE! http://www.masm32.com/ also here's a free version of vc++ 2008 http://www.microsoft.com/express/vc/ Quote Link to comment Share on other sites More sharing options...
digip Posted August 8, 2008 Share Posted August 8, 2008 First DLL Injection, I recommend using C++ to make things easier!, MASM if your feeling up to it. Wow dude, your really up on your stuff. Question, with somehting like this, would you then be able to elevate privledges of an executable to run as admin, or system? What I mean is, lets say you wanted to install a program that needs admin access, or approval, and your account can't install programs. Could you attach the process to an authorized running process, such as lsass and then trick the system into running the exe and installing it? If so, you could pretty much run anything then, and add users, change passwords, etc, just because it would be running as a system process which has full authority over the entire system. Scary stuff. :) How would anti-virus programs handle the injection, and would they evne pick it up? I know ZoneAlarm checks for programs tyring to change data in memory, or modify physical memory, so it might block it or alert the user, but I don't know how many programs even would catch this. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.