[Tutorial] DLL Injection menu

Shout-Out

User Tag List

Page 2 of 2 FirstFirst 12
Results 16 to 23 of 23
  1. #16
    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 jagged software View Post
    Okay everyone, it has come to my attention that this code is garbage. My bad, I apologize! To make this code acceptable C++, please change the following line:
    #define PROC_NAME "target.exe"
    to:
    static char const*const PROC_NAME = "target.exe";


    Because according to Cypher, it will f*** up your SYMBOL TABLES@! oh noes!

    You ever use NULL in your code Cypher? ((You use it frequently in your released sources.)) Because then you'd be doing the same f***ing thing as you're attacking. You'd be using a f***ing macro.
    #define NULL 0
    Just use 0 instead. Hypocrite.

    Macros are bad because they do not do native type checking. They're also messy when you have to use multiple lines, and if you're doing logical checking from within a macro (such as an IF statement) you would get much better performance out of doing it in a function, because of optimization. Also, macros can be bad because of token concatenation. But that is beyond the scope of this article. But those are the only reasons macros are bad. According to Bjarne Stroustrup, avoid them if you can: "I really hate macros. Yes they're useful sometimes, and yes I use them."

    Gone are the days of C, when macros were quicker, and faster. Now, there's a ton of C++ functionality that macros will just plain f*** up. That's why they're bad.

    Anyways, let me summarize this post into a readers digest version for newcomers:
    Jaggedsoft: Here's a spot for you guys to get started. It's acceptable.
    Cypher: THAT IS NOT ACCEPTABLE see it has a macroes@! YOU GO TO HELL AND DIE
    Jaggedsoft: ok


    Edit: Very mature of you to lower my reputation. Programmers are supposed to be objective, not subjective. Whatever fuels that ego of yours.
    I love how you pick out a single thing but ignore all the other points I raised. When doing Windows programming, using NULL is often the 'correct' thing to do, but obviously I wouldn't expect someone like yourself to realise that when working with C APIs you often have to make concessions in a trade-off for clarity. By your logic we should ban the use of the Windows API entirely.

    Code in a macro still gets optimised dipshit, the difference is negligible in 'extreme' cases and zero in most cases, but functions are not faster.

    The macro I pointed out doesn't use token concatenating, it doesn't use conditionals, etc. The only thing it really screws up is the use of symbol tables.

    If you wanted ALL the reasons not to use macros then say that. I was referring to the SINGLE macro I pointed out.

    How about you learn to read FIRST, complain SECOND.

    @Xarg0, in most cases yes you do.

    P.S. When attempting to use reductio ad absurdum it helps if you have a valid starting point, otherwise you just look retarded.

    [Tutorial] DLL Injection
  2. #17
    jagged software's Avatar Member
    Reputation
    -4
    Join Date
    Feb 2009
    Posts
    36
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Xarg0,
    SeDebugPrivilege is typically used when interfacing another application out of process. It gives your process the ability to read another process, by telling it that we're debugging it. With injection, it shouldn't be needed, because we are in the same process.
    I'm not sure, but you might need to call it before hooking kernel32's LoadLibraryA on Vista.
    kynox had given us some code for this:
    Code:
    // We need to do this to gain access to read out-of-process. Author: kynox
    int AddDebugPrivileges() {
    	HANDLE hToken;
    	TOKEN_PRIVILEGES tp;
    
    	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken);
    
    	if( !LookupPrivilegeValueA( NULL, "SeDebugPrivilege", &tp.Privileges[0].Luid ) ) {
    		CloseHandle(hToken);
    		return 1;
    	}
    
    	tp.PrivilegeCount = 1;
    	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    	if( !AdjustTokenPrivileges( hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0) ) {
    		CloseHandle(hToken);
    		return 1;
    	}
    
    	CloseHandle(hToken);
    	return 0;
    }

  3. #18
    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 jagged software View Post
    Xarg0,
    SeDebugPrivilege is typically used when interfacing another application out of process. It gives your process the ability to read another process, by telling it that we're debugging it. With injection, it shouldn't be needed, because we are in the same process.
    I'm not sure, but you might need to call it before hooking kernel32's LoadLibraryA on Vista.
    kynox had given us some code for this:
    Code:
    // We need to do this to gain access to read out-of-process. Author: kynox
    int AddDebugPrivileges() {
        HANDLE hToken;
        TOKEN_PRIVILEGES tp;
    
        OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken);
    
        if( !LookupPrivilegeValueA( NULL, "SeDebugPrivilege", &tp.Privileges[0].Luid ) ) {
            CloseHandle(hToken);
            return 1;
        }
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
        if( !AdjustTokenPrivileges( hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0) ) {
            CloseHandle(hToken);
            return 1;
        }
    
        CloseHandle(hToken);
        return 0;
    }
    Wtf.. You're allocating memory, writing to that memory, then creating a thread in a remote process (thats how DLL injection works). To do that you will often need SeDebugPrivilege otherwise the call to OpenProcess would fail.

    Code:
    // Gives the current process the SeDebugPrivelige
    // Note: Requires administrator rights
    void Injector::GetSeDebugPrivilege()
    {
        // Open current process token with adjust rights
    EnsureCloseHandle Token;
        BOOL RetVal = OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES
            | TOKEN_QUERY, Token.GetHandlePtr());
        if (!RetVal) 
            throw std::runtime_error("Could not open process token.");
    
        // Get the LUID for SE_DEBUG_NAME 
        LUID Luid = { NULL }; // Locally unique identifier
        if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid)) 
            throw std::runtime_error("Could not look up privilege value for SeDebugName.");
        if (Luid.LowPart == NULL && Luid.HighPart == NULL) 
            throw std::runtime_error("Could not get LUID for SeDebugName.");
    
        // Process privileges
        TOKEN_PRIVILEGES Privileges = { NULL };
        // Set the privileges we need
        Privileges.PrivilegeCount = 1;
        Privileges.Privileges[0].Luid = Luid;
        Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
        // Apply the adjusted privileges
        if (!AdjustTokenPrivileges(Token, FALSE, &Privileges,
            sizeof (Privileges), NULL, NULL)) 
            throw std::runtime_error("Could not adjust token privileges.");
    }
    EDIT:

    Also, calling it before hooking LoadLibrary? Wtf? You really have no idea what's going on do you.

    You give your LOADER the SeDebugPriv, so you can inject the DLL, the DLL then hooks LoadLibrary so any modules that are then delay loaded after yours can be IAT hooked on the fly too. You're already in the address space of the remote process at that point so you don't need to call SeDebugPriv because you're modifying LOCAL memory.
    Last edited by Cypher; 04-19-2009 at 11:20 AM.

  4. #19
    jagged software's Avatar Member
    Reputation
    -4
    Join Date
    Feb 2009
    Posts
    36
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This code is from a loader I used in the past, not in the DLL itself. It does just what I said above.
    Code:
    bool injectDLL(DWORD procID, std::string dll) {
        HMODULE hLocKernel32 = GetModuleHandle("Kernel32");
        FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryA");
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp;
        if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
            LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
        }
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
        dll += '\0';
        LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, dll.size(), MEM_COMMIT, PAGE_READWRITE);
        DWORD numBytesWritten;
        WriteProcessMemory(hProc, hRemoteMem, dll.c_str(), dll.size(), &numBytesWritten);
        HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL);
        std::cout << hRemoteThread << std::endl;
        bool res = false;
        if (hRemoteThread) { res = (bool)WaitForSingleObject(hRemoteThread, MAXWAIT) != WAIT_TIMEOUT; }
        VirtualFreeEx(hProc, hRemoteMem, dll.size(), MEM_RELEASE);
        CloseHandle(hProc);
        return res;
    }
    I guess it depends on which method of injection you're using. The thing I understand about setting debug privileges is that the remote process will (or can) receive notifications that you're debugging it. This could be a problem for detection in the future. There was a detailed write up on how to circumvent this but I can not seem to locate it at this moment. I'll post it on here if I can find it, it's really a good read.

  5. #20
    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 jagged software View Post
    This code is from a loader I used in the past, not in the DLL itself. It does just what I said above.
    Code:
    bool injectDLL(DWORD procID, std::string dll) {
        HMODULE hLocKernel32 = GetModuleHandle("Kernel32");
        FARPROC hLocLoadLibrary = GetProcAddress(hLocKernel32, "LoadLibraryA");
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp;
        if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
            LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
            tkp.PrivilegeCount = 1;
            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
            AdjustTokenPrivileges(hToken, 0, &tkp, sizeof(tkp), NULL, NULL);
        }
        HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, procID);
        dll += '\0';
        LPVOID hRemoteMem = VirtualAllocEx(hProc, NULL, dll.size(), MEM_COMMIT, PAGE_READWRITE);
        DWORD numBytesWritten;
        WriteProcessMemory(hProc, hRemoteMem, dll.c_str(), dll.size(), &numBytesWritten);
        HANDLE hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)hLocLoadLibrary, hRemoteMem, 0, NULL);
        std::cout << hRemoteThread << std::endl;
        bool res = false;
        if (hRemoteThread) { res = (bool)WaitForSingleObject(hRemoteThread, MAXWAIT) != WAIT_TIMEOUT; }
        VirtualFreeEx(hProc, hRemoteMem, dll.size(), MEM_RELEASE);
        CloseHandle(hProc);
        return res;
    }
    I guess it depends on which method of injection you're using. The thing I understand about setting debug privileges is that the remote process will (or can) receive notifications that you're debugging it. This could be a problem for detection in the future. There was a detailed write up on how to circumvent this but I can not seem to locate it at this moment. I'll post it on here if I can find it, it's really a good read.
    In other words, you didn't understand a word of what I said in my edit.

    Anyway, some better injection code:
    Code:
    // Injects a module (fully qualified path) via process id
    void Injector::InjectLib(DWORD ProcID, const std::wstring& Path)
    {
        // Get a handle for the target process.
        EnsureCloseHandle Process(OpenProcess(
            PROCESS_QUERY_INFORMATION |   // Required by Alpha
            PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
            PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
            PROCESS_VM_WRITE,             // For WriteProcessMemory
            FALSE, ProcID));
        if (!Process) 
            throw std::runtime_error("Could not get handle to process.");
    
        // Calculate the number of bytes needed for the DLL's pathname
        size_t Size  = (Path.length() + 1) * sizeof(wchar_t);
    
        // Allocate space in the remote process for the pathname
        EnsureReleaseRegionEx LibFileRemote(VirtualAllocEx(Process, NULL, Size, MEM_COMMIT, PAGE_READWRITE),
            Process);
        if (!LibFileRemote)
            throw std::runtime_error("Could not allocate memory in remote process.");
    
        // Copy the DLL's pathname to the remote process' address space
        if (!WriteProcessMemory(Process, LibFileRemote, 
            Path.c_str(), Size, NULL))
            throw std::runtime_error("Could not write to memory in remote process.");;
    
        // Get the real address of LoadLibraryW in Kernel32.dll
        HMODULE hKernel32 = GetModuleHandle(TEXT("Kernel32"));
        if (!hKernel32)
            throw std::runtime_error("Could not get handle to Kernel32.");
        PTHREAD_START_ROUTINE pfnThreadRtn = reinterpret_cast<PTHREAD_START_ROUTINE>
            (GetProcAddress(hKernel32, "LoadLibraryW"));
        if (!pfnThreadRtn)
            throw std::runtime_error("Could not get pointer to LoadLibraryW.");;
    
        // Create a remote thread that calls LoadLibraryW(DLLPathname)
        EnsureCloseHandle Thread(CreateRemoteThread(Process, NULL, 0, pfnThreadRtn, 
            LibFileRemote, 0, NULL));
        if (!Thread)
            throw std::runtime_error("Could not create thread in remote process.");
    
        // Wait for the remote thread to terminate
        WaitForSingleObject(Thread, INFINITE);
    }
    Reasons:

    Not only is the code you posted leaking at least one handle one every call, it has the potential to leak both extra handles and remote memory in the event that an exception is thrown by the STL.
    On top of that, it has the potential to fail across OS version because of the use of PROCESS_ALL_ACCESS. The flag is a different size on Vista than XP for example so it probably won't work properly. You should only use the flags you actually need.
    Also, its passing an object by value when a reference-to-const is much more appropriate.
    And of course, most of the handles and return values from the APIs go completely unchecked for errors.
    Oh, another one. Not Unicode compatible.

    Note:
    To use the code above grab the source code for "Programming Windows via C/C++" and use the "EnsureCleanup" header (slightly modified, all I did was remove the C and add a cleanup for VirtualAllocEx, very easy modifications).

    EDIT:

    And the ASCII version:
    Code:
    // MBCS version of InjectLib
    void Injector::InjectLib(DWORD ProcID, const std::string& Path)
    {
        // Convert path to unicode
        std::wstring UnicodePath(Path.begin(),Path.end());
    
        // Call the Unicode version of the function to actually do the work.
        InjectLib(ProcID, UnicodePath);
    }
    Last edited by Cypher; 04-19-2009 at 04:17 PM.

  6. #21
    jagged software's Avatar Member
    Reputation
    -4
    Join Date
    Feb 2009
    Posts
    36
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cypher, thanks for the detailed explanation in your reply. I'd +rep you if I could. I like how your code is simple and efficient, and you actually use comments which I tend to not do.
    Since I have only done development on the code within the injected DLL's from scratch, and not the loader, I used it from an 'it just works' methodology, never bothering to create my own. If I were to adopt your injection source, I would take solace in knowing that I was using the best.

  7. #22
    Xarg0's Avatar Member
    Reputation
    61
    Join Date
    Jan 2008
    Posts
    389
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by jagged software View Post
    Cypher, thanks for the detailed explanation in your reply. I'd +rep you if I could. I like how your code is simple and efficient, and you actually use comments which I tend to not do.
    Since I have only done development on the code within the injected DLL's from scratch, and not the loader, I used it from an 'it just works' methodology, never bothering to create my own. If I were to adopt your injection source, I would take solace in knowing that I was using the best.
    Why did you try to write a dll injection tutorial in the first place, if you don't even understand how it works?
    When writing tutorials it's important to know what you're doing, atleast you should've ensured that your code is working before posting it, as Cypher said OpenProcess would fail without SeDebugPrivilege, I just asked about it to point out this very important mistake so you could correct it.
    I hacked 127.0.0.1

  8. #23
    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)
    http://www.mmowned.com/forums/wow-memory-editing/227176-dll-injector-x86-x64-unicode-mbcs.html

    Better example.

Page 2 of 2 FirstFirst 12

Similar Threads

  1. [WoW] [C++] Hack Loader (DLL Injection Example)
    By Cypher in forum WoW Memory Editing
    Replies: 28
    Last Post: 07-06-2010, 11:41 PM
  2. Destructor's Tutorial: Managed .NET DLL Injection
    By ugkbunb in forum Programming
    Replies: 1
    Last Post: 07-30-2009, 05:15 PM
  3. Dll injection.. Failing bigtime
    By xzidez in forum WoW Memory Editing
    Replies: 4
    Last Post: 06-03-2009, 06:16 AM
  4. DLL injection with windows SP3
    By Therrm in forum World of Warcraft Bots and Programs
    Replies: 3
    Last Post: 12-06-2008, 03:03 PM
  5. What are the risks with DLL injection?
    By object in forum WoW Memory Editing
    Replies: 14
    Last Post: 08-22-2008, 09:23 PM
All times are GMT -5. The time now is 08:23 AM. 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