![]() |
|
[C#] [Tutorial] [C#] Inject PE From Resources - Printable Version +- Hack Forums (https://hackforums.net) +-- Forum: Tech (https://hackforums.net/forumdisplay.php?fid=444) +--- Forum: Coding (https://hackforums.net/forumdisplay.php?fid=151) +---- Forum: Software Development (https://hackforums.net/forumdisplay.php?fid=118) +---- Thread: [C#] [Tutorial] [C#] Inject PE From Resources (/showthread.php?tid=2667490) |
[Tutorial] [C#] Inject PE From Resources - Tsukuyomi - Jul 11, 2012 VB.Net Version of this tutorial Hello. In this tutorial we will...
For this tutorial you need...
The C++ Part ( Creating the PE DLL ) If you for some reason want to skip this(C++) part, here's a precompiled version of the DLL we will be creating: ThePE.dll ( Direct Link ) It's a 28,5kb native DLL named "ThePE.dll" that pops up a MessageBox "Injected!" on attach. Even if you decided not to compile the DLL yourself, I suggest you still read this part so you get a basic idea of what's going on. Fire up your C++ IDE and create a new Windows DLL project. (How to? VS 2008) Spoiler (Click to View) Regardless of your compiler of choice, you should end up with compiler generated DLL entry point, which looks somewhat like this: Code BOOL APIENTRY DllMain( HMODULE hModule,When we get to the part of injecting the DLL into another process, this is the function that gets called, and the "case DLL_PROCESS_ATTACH:" part of the switch statement will be executed. This is where we would normally create a thread/threads which our server, hack, extension, whatever would run on. For the sake of simplicity however, we are just going to display a messagebox. Add this code after DLL_PROCESS_ATTACH: Code MessageBox(NULL, L"Injected!", L"Success", MB_OK);Your code should now look more or less like this: Code #include "stdafx.h"Compile the DLL(or download from the link above). And rename it to PE.Dat: [img]http://i.minus.com/1342008029/mlIRlvw4DFdA9Rd3W8IM3Q/ibnH0Lj5uPI9CR.png[/img] You should now have a compiled DLL file renamed to PE.DAT. The C# Part ( Injector ) Create a new C# Console Application. Select Properties and open the Resources tab: [img]http://i.minus.com/1342009422/Pwo0sfTmHDrs-jqdFyGa9A/ibcS99tlZZIChN.png[/img] Select Add Resource -> Add Existing file, find and select your PE.Dat. [img]http://i.minus.com/1342009518/lTbXMZ2O-4MdwXhN-1O7yA/ibkRShwGU9wQl0.png[/img] Now tap open program.cs. To keep things as simple as possible, we'll do everything from the main function. Start by adding these two imports in the top of your code: Code using System.Diagnostics;Then we need some declarations for calling windows API. Copy these flag structures right after Code class Program {Code [Flags]And right after them, put these API call declarations: Code [DllImport("kernel32.dll")]Right. Now our program is capable enough of calling windows API functions for our needs, so we can start writing the main function. What we're going to do(in a nutshell) is something like this: Pseudo code: Code Find Notepad Window < Exit If Not Exists >First thing to do is finding the notepad window. For this we'll use the managed System.Diagnostics.Process class to enumerate through processes named "notepad", check if the enumeration returned more than 0 results and if so, save the process ID of the "first notepad" in variable pidNotepad and proceed, otherwise exit("Couldn't find notepad window"). Code Process[] p = Process.GetProcessesByName("notepad");Then we will use the OpenProcess API to return a handle with full read/write/execute access to the notepad process, and save it to variable hProc. If opening process fails(OpenProcess returns 0), exit("Couldn't open process"). Code IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, pidNotepad);Now we're going to extract our resource PE.Dat and save it to our application data folder with the name "TempPE.dat": Code string pathTempPE = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\TempPE.dat";Okay. Now we need to allocate some memory inside notepad process and get a handle to where that memory begins, so we know where to create our thread. Sounds scary right? Luckily there's an API for that too, called VirtualAllocEx which makes it very easy for us. We'll just call VirtualAllocEx(Opened Process, 0, our dll path's length, Commit memory, Feel free to wreak havoc) and save the return value into ptrMem, which is a pointer to the start of our brand new allocated memory. If something fails, the return value will be 0 in which case we'll exit("Couldn't allocate memory"). Code IntPtr ptrMem = VirtualAllocEx(hProc, (IntPtr)0, (uint)pathTempPE.Length, AllocationType.COMMIT, MemoryProtection.EXECUTE_READ);Almost there. A bit later we will force notepad to call LoadLibrary with path to our temp PE as it's parameter, but first we have to store that path somewhere into notepad's own memory, and for that we will use the WriteProcessMemory API. WriteProcessMemory takes the following parameters: Process ( our hProc ) Address to write ( our ptrMem we just allocated ) Bytes to write ( path to our temp PE converted to bytes ) Bytes count ( count of bytes in ^ ) [out] Bytes written ( returns the bytes written into this variable, our ipTmp ) So we create a managed ASCIIEncoding object and convert our pathTempPE into bytes and save those bytes into variable pathTempPEBytes, then call WriteProcessMemory and check its return value. If it returns true, proceed. If false, exit("Couldn't write memory"). Code ASCIIEncoding ae = new ASCIIEncoding();The final part! To call CreateRemoteThread with LoadLibrary as it's parameter we will first need to know the address of the LoadLibrary function. So we will first call the GetProcAddress API with "KERNEL32.DLL" and "LoadLibraryA" as it's parameters. This means we are trying to find the entry point "LoadLibraryA" in "KERNEL32.DLL" and save it's address to variable ptrLoadLib. Then(finally!) we call the main function, CreateRemoteThread, which takes the following parameters: Process ( our hProc ) SecurityAttributes( don't mind this for now, we'll just pass 0 here ) Stack Size ( don't mind this either, we'll pass 0 again ) Start Address ( where to start the thread. we want the thread to call LoadLibrary, so we pass ptrLoadLib here. ) Parameter ( pointer to the parameter we created, path to temp PE. we'll pass ptrMem here. Creation flags ( don't mind, pass 0 ) [out] Thread ID ( if you want to track the thread or something, you can give a variable here and the thread ID will be saved to it. I will however pass 0. ) We save the thread handle instead, by using IntPtr hThread = CreateRemoteThread... After which, we will use the WaitForSingleObject API to wait for the thread to complete, AKA the DLL to be injected. Finally, report("Injection complete"). Code IntPtr ptrLoadLib = GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "LoadLibraryA");It's ready, open notepad and run the program. You should see notepad display a MessageBox "Injected!", "Success". [img]http://i.minus.com/1342021561/aM3w2OM-gn4ewqikpYxsXg/iCdIz8TV3c2Rw.png[/img] In case of compile errors / laziness, here's the whole project for download: Download Project Files ( Direct ) NOTE: It is very much recommended to actually read through the tutorial and try to understand the essence of Win API, instead of just copy & pasting the code. Conclusion: You can accomplish almost anything on windows by using the windows API, and you can use it in almost any programming language. In C++, however, you can just include "windows.h" and you're good to go. If you're on a x64 system, you will have to do slight modifications, but I will not go there. Note that once injected, the DLL file will become unavailable to any other process(you can't delete it, write to it, etc) until notepad decides to unload it. In other words, you will have to write your own unload routines, or just close notepad and start over. You can use this method to create a crypter, for instance. Guess that's it. Any questions about anything I'm more than happy to answer them. * - Penfold - Jul 11, 2012 Detailed tutorial, thanks very much. Bookmarked for future reference. * - hackpet - Jul 11, 2012 Very nice tutorial, really THX! :) 35 char -.- * - Сlassy - Jul 11, 2012 Pictures are broken, but this seems like a detailed HQ tutorial. :) I don't know shit about injecting in C#, but I hope other people learn from this. :D * - JeromeMarshall - Jul 12, 2012 I was going to write a tutorial the other day about injecting a managed dll (with a c++ wrapper) into an unmanged process, but I noticed theres a few tutorials out there already. This is a little bit different, but a way more details tut than I would have wrote. Nice one pal, HF needs more of these posts, it will really help them understand the deep inner workings of the framework. Also for anyone trying to expand on OP's idea, just make sure if youre doing something other than msgbox, that you make sure to create a seperate thread, and dont use the dllmain. Lots and lots of room for a deadlock if you don't do that. * - Tsukuyomi - Jul 12, 2012 (Jul 12, 2012 02:15 AM)JeromeMarshall Wrote: I was going to write a tutorial the other day about injecting a managed dll (with a c++ wrapper) into an unmanged process, but I noticed theres a few tutorials out there already. This is a little bit different, but a way more details tut than I would have wrote. Nice one pal, HF needs more of these posts, it will really help them understand the deep inner workings of the framework. About managed DLL injection, you can actually start the CLR runtime in a process after which you can inject .Net 4.0 modules into that process. Lots of fun, you can even do hooks with managed code. Quite useless though. If you're already injecting a native DLL, why not just use unmanaged code for whatever it is you're doing. I wanted this tutorial to be detailed, as the purpose was not just to show people how to inject a DLL, but to demonstrate the capabilities of the windows API altogether. (Jul 11, 2012 04:11 PM)BlankHat Wrote: Pictures are broken, but this seems like a detailed HQ tutorial. :) The pictures are back. I have no idea why they were off, maybe i.minus was down for a while. * - unnamednoob - Jul 12, 2012 great tutorial i've been looking for stuff like this for a while in the hacking section and never found something good. Thanks a lot, hope you don't mind if i PM you with some questions when i try to apply this tutorial and extend it. * - Washi - Jul 12, 2012 Nice tutorial. I'd suggest to create a new instance of a Win32Exception with the Error Code you can get at Marshal.GetLastWin32Error() to get the last native error with an error message and stuff like that when an IntPtr.Zero is returned. Otherwise you'll have a message saying Couldn't open process and you've no idea why it failed. * - Tsukuyomi - Jul 12, 2012 (Jul 12, 2012 11:44 AM)TheUnknownProgrammer Wrote: Nice tutorial. I'd suggest to create a new instance of a Win32Exception with the Error Code you can get at Marshal.GetLastWin32Error() to get the last native error with an error message and stuff like that when an IntPtr.Zero is returned. Otherwise you'll have a message saying Couldn't open process and you've no idea why it failed. There was a plenty of things left out of this tutorial for the sake of simplicity, advanced error handling being one of them. But you're right though, using native errors is generally good practice when calling Win API. |