[General] CLR hosting without the dll? menu

Shout-Out

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 15 of 35
  1. #1
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [General] CLR hosting without the dll?

    Hello, I'm currently writing a injector in C# for a hobby project and i know the rough outlines of injection:

    1. retrive handle with OpenProcess
    2. retrive pointerToMemory with VirtualAllocEx
    3. write function into pointerToMemory with WriteProcessMemory
    4. start a thread with CreatRemoteThread
    5. wait for exit of created thread (WaitForSingleObject)
    6. free up memory and close handle

    I've run into trouble at step 3 though, because i'd really like to omit the c++ dll that stands for the CLR hosting.
    After looking into doing this on google i found this article: Dynamically Writing and Executing Native Assembly in C# - Devin Jenson's WebLog - Site Home - MSDN Blogs which mentions writing and compiling the native function and then storing it in a byte array, however this is only with a simple function that adds two args and return the result so i was wondering if my much larger function that includes the clr hosting API isn't gonna try to acces something outside of the function and thus crash because it hasn't been copied over to the remote process?
    (the second problem with above approach and the reason for me not trying it out is that i was unable to find when a function starts and stop in byte code and then get the bytes inbetween)

    My first idea to solve this was to store the whole dll in a byte array (Resharper hates that file and have crashed visual studio once or twice btw ) and then just set the remote threads entry point to the beginning of the injected array...
    That however doesn't work which i could have told myself so once again i'm back to finding the offset for the beginning of the function, any hints on how todo this? Or am i just being really dumb for injecting the whole dll in that way because it must be mapped by LoadLibrary or something similar?


    (The whole loadLibrary comes from me reading the source for the c++ injector i'm using at the moment):

    Code:
    bool InjectLibrary(DWORD dwProcessId, char* lpDll)
    {
        HMODULE hMod;
        FARPROC fpLoad = 0;
        HANDLE hThread = 0, hProcess = 0;
        LPVOID lpRemoteAddress = 0;
        int ret;
    
        try{
            hMod = GetModuleHandle("Kernel32");
            if(hMod == 0)
                throw MException("GetModuleHandle()");
    
            fpLoad = GetProcAddress(hMod, "LoadLibraryA");
            if(fpLoad == 0)
                throw MException("GetProcAddress()");
    
            hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, dwProcessId);
            if(hProcess == 0)
                throw MException("OpenProcess()");
    
            lpRemoteAddress = VirtualAllocEx(hProcess, 0, strlen(lpDll), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
            if(lpRemoteAddress == 0)
                throw MException("VirtualAllocEx()");
    
            ret = WriteProcessMemory(hProcess, lpRemoteAddress, (LPVOID)lpDll, strlen(lpDll), 0);
            if(ret == 0)
                throw MException("WriteProcessMemory()");
    
            hThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)fpLoad, lpRemoteAddress, 0, 0);
            if(hThread == 0)
                throw MException("CreateRemoteThread()");
    
            WaitForSingleObject(hThread, INFINITE);
    
            ret = VirtualFreeEx(hProcess, lpRemoteAddress, 0, MEM_RELEASE);
            if(ret == 0)
                throw MException("VirtualFreeEx()");
    
            ret = CloseHandle(hProcess);
            if(ret == 0)
                throw MException("CloseHandle()");
    
        }catch(MException& ex){
            if(lpRemoteAddress != 0)
                VirtualFreeEx(hProcess, lpRemoteAddress, 0, MEM_RELEASE);
            if(hProcess != 0)
                CloseHandle(hProcess);
            GetError(GetLastError(), ex.ErrorMessage);
            return false;
        }
        return true;
    }
    But since i suck at c++ i'm not sure what this does "(LPTHREAD_START_ROUTINE)fpLoad" but i think it essentially tells the spawned thread to call LoadLibrary with the parameter which is our dll, correct? however that's still using a dll to launch the CLR which i kinda want to avoid...

    Thanks in advance for any help and comments
    “Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning.” - Rich Cook

    [General] CLR hosting without the dll?
  2. #2
    jayswag's Avatar Sergeant
    Reputation
    15
    Join Date
    Mar 2011
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    awesome work so far mate, wish I could help on this one. but keep it up seems like your on the right track

  3. #3
    serock1's Avatar Member
    Reputation
    2
    Join Date
    Feb 2009
    Posts
    17
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    We shall think it as that remote thread. We know, the LPTHREAD_START_ROUTINE is just like:

    Code:
    int __stdcall routine_name(void *parameter);
    The 'LoadLibraryA' is this kind of function: int __stdcall LoadLibraryA(char *dllpath). So, if you create a thread and use LoadLibraryA as thread function, the LoadLibraryA will use 'parameter' as a dll file path, and load it if it can.

    But, you must know, after the LoadLibraryA finished its job, it will return, then that thread will return to system, and the thread will be terminated.

    So, we usually process DLL_PROCESS_ATTACH in DllMain function of dll and create our working thread, or hook something.

    The whole code you pasted is just loading a dll in target process. That will work fine. You just need to do something in your dll when it is loaded (create thread or hook something).

    ---------- Post added at 11:56 PM ---------- Previous post was at 11:52 PM ----------

    BTW: The code need to be modified a little. We must copy the dll path and the '\0' into target process, so:

    Code:
    .....
            lpRemoteAddress = VirtualAllocEx(hProcess, 0, strlen(lpDll) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
            if(lpRemoteAddress == 0)
                throw MException("VirtualAllocEx()");
    
            ret = WriteProcessMemory(hProcess, lpRemoteAddress, (LPVOID)lpDll, strlen(lpDll) + 1, 0);
    .....

  4. #4
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You're way better off using a JIT assembler or compiler than to statically compile a loader function and copying it to the target.
    See http://www.mmowned.com/forums/world-...-injector.html for reference.
    It has it's flaws, but it should get you started at least.

  5. #5
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by jayswag View Post
    awesome work so far mate, wish I could help on this one. but keep it up seems like your on the right track
    What the ****? Are you just here to bump your post count or something?

    Originally Posted by _Mike View Post
    You're way better off using a JIT assembler or compiler than to statically compile a loader function and copying it to the target.
    See http://www.mmowned.com/forums/world-...-injector.html for reference.
    It has it's flaws, but it should get you started at least.
    ^ This.

    AsmJit is awesome.

  6. #6
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @serock1 I'm not a code guru but isn't creating threads in dllmain one of the big "no go"s? and the c++ code doesn't need anything because it actually works fine also there's another dll in that project that gets injected and launches the CLR

    @_Mike THANK YOU!! I saw you mentioning asmJit in a thread a long time ago and how you could omit the extra dll and that's actually where i first got the desire to do that myself however i couldn't find any examples of it so i forgot about it again...
    Anyway you've actually created the exact type of injector i wanted to make myself so now i'm tempted to just leech it... however i'll probably have a quick look at the c# code and then steal the c++/cli dll because i'm a retard and as such have failed multiply times to learn c++ as the learning curve was a bit too step ><

    Also Cypher, just to troll you a bit: Your post is only marginably more usefull and longer than jayswag's comment
    “Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning.” - Rich Cook

  7. #7
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by !@^^@! View Post
    @serock1 I'm not a code guru but isn't creating threads in dllmain one of the big "no go"s? and the c++ code doesn't need anything because it actually works fine also there's another dll in that project that gets injected and launches the CLR

    @_Mike THANK YOU!! I saw you mentioning asmJit in a thread a long time ago and how you could omit the extra dll and that's actually where i first got the desire to do that myself however i couldn't find any examples of it so i forgot about it again...
    Anyway you've actually created the exact type of injector i wanted to make myself so now i'm tempted to just leech it... however i'll probably have a quick look at the c# code and then steal the c++/cli dll because i'm a retard and as such have failed multiply times to learn c++ as the learning curve was a bit too step ><

    Also Cypher, just to troll you a bit: Your post is only marginably more usefull and longer than jayswag's comment

    @The comments on DllMain:
    Correct, creating threads in your DLL's entry point is generally bad as it can cause loader locks.

    Just to troll you back a bit: _Mike beat me to a response, so I had nothing else to add regarding your post. I've earned the privilege to make useless posts. Jayswag has not.

  8. #8
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So you've earned the right to make useless posts by posting useless stuff?

    Also: You must spread some Reputation around before giving it to _Mike (and Cypher) again. ._.
    “Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning.” - Rich Cook

  9. #9
    _Mike's Avatar Contributor
    Reputation
    310
    Join Date
    Apr 2008
    Posts
    531
    Thanks G/R
    0/2
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by !@^^@! View Post
    @_Mike THANK YOU!! I saw you mentioning asmJit in a thread a long time ago and how you could omit the extra dll and that's actually where i first got the desire to do that myself however i couldn't find any examples of it so i forgot about it again...
    Anyway you've actually created the exact type of injector i wanted to make myself so now i'm tempted to just leech it... however i'll probably have a quick look at the c# code and then steal the c++/cli dll because i'm a retard and as such have failed multiply times to learn c++ as the learning curve was a bit too step ><
    Just be aware of Cypher's comment on zombie processes. I never got around to fixing it because I only inject into already running processes, and I can never focus my attention on a single project for very long

  10. #10
    serock1's Avatar Member
    Reputation
    2
    Join Date
    Feb 2009
    Posts
    17
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah, I understand it now, after read the post of _Mike. So sorry I am not working on .net. (to be frank, I dislike .net framework for 5 years, not about programming language: c#, vb.net, etc. I know nobody care. And sorry for off-topic. )

    The problem is .net dll has no the 'entry point' like DllMain. So, just load dll has no logical effect. _Mike's injector is awesome, it will load the .net dll and launch one function by clr metainfo apis.

    I tried to find a way to imitate the 'entry point', such as static constructor, set attribute... I failed and give up. _Mike's method is good enough.

  11. #11
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'll also only be injecting into running processes so that's not an issue for me either however if you could get around fixing the 64 bit thing it would be nice because i've already run into the first problems with it also i'm really bad at focusing on one project too because i lose interest quickly when i get stuck and can't fix it after having spent +5 hours on it so i know how you feel

    Also yes i know there's no entry point in .net dlls serock1 but the dll i planned to inject was a native one that launched the CLR and then called my managed dll's static function i specified in the arguments
    However thanks to _Mike i don't even need any magic strings :

    Code:
    class Injection
        {
            private static Injector.InjectorLib lib = new InjectorLib();
            public static uint Inject(uint pid, Type type, string args)
            {
                uint ret = 0;
    
                MethodInfo startMethod = null;
    
                foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
                {
                    var attributes = method.GetCustomAttributes(false);
    
                    if (attributes.OfType<EntryPointAttribute>().Any())
                    {
                        startMethod = method;
                    }
    
                    if (startMethod != null)
                    {
                        break;
                    }
                }
    
                if (startMethod == null)
                {
                    throw new InvalidOperationException(
                        "Please make sure the [EntryPoint] attribute is set on a static function in the class");
                }
    
                var path = (new System.Uri(type.Module.Assembly.CodeBase)).AbsolutePath;
    
    
                if (!lib.InjectAndRun(pid, path, startMethod.DeclaringType.FullName + "." + startMethod.Name, args, ref ret))
                {
                    throw new InvalidOperationException("Injection failed, exit code: " + ret);
                }
    
                return ret;
            }
        }
    Gotta love reflection <3

    edit: yes i know it's butt ugly code but i just mocked it together quickly to make some progress
    “Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning.” - Rich Cook

  12. #12
    sitnspinlock's Avatar Elite User CoreCoins Purchaser
    Reputation
    398
    Join Date
    Sep 2010
    Posts
    439
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Generally what I do (not that any of you care ;p) but I used to spawn threads from dllmain, which as Cypher said, is generally a bad practice and in most cases you can end up with a program deadlock. In case you also were not already aware you should not use any 'wait' functions in dllmain (waitforsingleobject, sleep) etc.

    After learning more, its just a bad idea in general to do work any work in dllmain. So what I do is write the functions inside of the dll I plan to inject, and then export them. Then once injected I call my own functions with CreateRemoteThread in the same sense that you just got said program to load your module by forcing it to call LoadLibrary.

    I know my rant probably dosent pertain to anything in your post, I'm just bored.

  13. #13
    !@^^@!'s Avatar Active Member
    Reputation
    23
    Join Date
    Feb 2007
    Posts
    155
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well that's basically what my old code did but it felt waaaay to ghetto because it was a c++ console program taking parameters for which c# dll to inject and a PID, then injecting a secondary dll which launched the CLR and then running a third dll with Apoc's domain manager and THEN finally launching my own dll
    It was one heck of an abomenation but thanks to _Mike it's finally dead and i've thus gone from a total of 5 dll's and exes down to 1 exe and 2 dll's
    “Programmers are in a race with the Universe to create bigger and better idiot-proof programs, while the Universe is trying to create bigger and better idiots. So far the Universe is winning.” - Rich Cook

  14. #14
    serock1's Avatar Member
    Reputation
    2
    Join Date
    Feb 2009
    Posts
    17
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why blame DllMain for programmer's mistake? Also, no need to be afraid of something before nothing happens. I think we can learn more from the trouble.

    About 'deadlock in DllMain', everdox is right

    should not use any 'wait' functions in dllmain (waitforsingleobject, sleep) etc
    This problem maybe occurs anywhere with similar mechanism as 'deadlock in dllmain'. I think we need to know why and how to solve it. Instead of obeying the rules only.

    ---------- Post added at 11:43 PM ---------- Previous post was at 10:12 PM ----------

    Oh, I recall Raymond Chen said before: Does creating a thread from DllMain deadlock or doesn't it?. Very good article.

  15. #15
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by serock1 View Post
    Why blame DllMain for programmer's mistake? Also, no need to be afraid of something before nothing happens. I think we can learn more from the trouble.

    About 'deadlock in DllMain', everdox is right



    This problem maybe occurs anywhere with similar mechanism as 'deadlock in dllmain'. I think we need to know why and how to solve it. Instead of obeying the rules only.

    ---------- Post added at 11:43 PM ---------- Previous post was at 10:12 PM ----------

    Oh, I recall Raymond Chen said before: Does creating a thread from DllMain deadlock or doesn't it?. Very good article.
    Huh? The first two sentences in your post make zero sense.

    Anyway... It's explained why it's dangerous (loader locks), and the solution is given to you (in the DLL best practices document). Wanna know the solution? Follow the rules and don't use APIs in DllMain which you are recommended not to!

    Just export a function from your DLL and do your work there. It's not hard...

    P.S. Read the first sentence of the article you linked:
    "Let me get this out of the way up front: Creating a thread from DllMain is not recommended. "

    That should be enough for you to NOT DO IT.
    Last edited by Cypher; 05-02-2011 at 03:06 AM.

Page 1 of 3 123 LastLast

Similar Threads

  1. Replies: 1
    Last Post: 01-19-2012, 03:14 AM
  2. Flying Mount - Fly without the animation
    By User in forum World of Warcraft Exploits
    Replies: 11
    Last Post: 06-22-2007, 09:38 PM
  3. Undead > BloodElf without the UD facial features!
    By drewdo in forum World of Warcraft Model Editing
    Replies: 9
    Last Post: 05-30-2007, 12:35 PM
  4. Start WoW without the News
    By shattered.ice in forum World of Warcraft Guides
    Replies: 7
    Last Post: 10-27-2006, 04:42 PM
All times are GMT -5. The time now is 12:05 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search