CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Feb 2012
    Posts
    7

    Unhappy [Help/Advice needed]Program crashes when code is injected

    Hi,

    I have been trying awhile for weeks to do dll injection. Found several ways such as CreateRemoteThread(), SetWindowsHookEx() and Code Cave method. Currently working on CreateRemoteThread(), I have read up A LOT on it. Finally i managed to grab hold of it quite abit. But I'm still left with one last problem. I'm sure the code is injected into the remoteprocess, but the remote process crashes immediately after the code is injected.

    Attached is the main highlights that the error should reside in.

    Code:
    typedef void (WINAPI *_GetModuleHandle)(LPCTSTR);
    
    typedef struct MyData {
        TCHAR dll_data_name[128];
        HANDLE (WINAPI * _GetModuleHandle)(LPCTSTR);
    } MYDATA, *PMYDATA;
    
    DWORD WINAPI MyThreadFunction( LPVOID lpParam )
    {
        PMYDATA prd = (PMYDATA)lpParam;
        prd->_GetModuleHandle(prd->dll_data_name);
        return 0;
    }
    
    BOOL Inject(DWORD pID, char * DLL_N)
    {
       HANDLE Proc, hThread;LPVOID RemoteString;MYDATA * VirtualAllooo;HMODULE hModule;
    
       DWORD dwNumBytesXferred = 0, dwThreadId = 0;
    
       hModule = LoadLibrary("Project1");
    
       MYDATA *dataLocal = {(PMYDATA)GetProcAddress(hModule, "Function")};
    
       Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    
       VirtualAllooo = (MYDATA*)VirtualAllocEx(Proc, NULL, sizeof(MYDATA), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
       WriteProcessMemory(Proc, VirtualAllooo, &dataLocal, sizeof(MYDATA), &dwNumBytesXferred);
    
       RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_N), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
       WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_N), NULL);
    
       hThread = CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)RemoteString, VirtualAllooo, 0, &dwThreadId);
       return true;
    }

    What went wrong here?

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: [Help/Advice needed]Program crashes when code is injected

    Quote Originally Posted by WoodyWool View Post
    What went wrong here?
    I cannot say what went wrong.
    However, I can say what looks wrong:
    1. Allocating only 128 TCHAR for the DLL full path name. Why not MAX_PATH?
    2. Why do you mix TCHARs with chars? Is your build a UNICODE or ANSI, BTW?
    3. Why are you passing NOT the full path name to your LoadLibrary call?
    4. Why don't you check the return values of all the API calls?
    Victor Nijegorodov

  3. #3
    Join Date
    Feb 2012
    Posts
    7

    Re: [Help/Advice needed]Program crashes when code is injected

    Allocating only 128 TCHAR for the DLL full path name. Why not MAX_PATH?
    I tried changing to

    char dll_data_name[MAX_PATH];

    But the remote process still crashes. Btw i'm running it in xp and win7. Either OS will still crash the process.

    Why do you mix TCHARs with chars? Is your build a UNICODE or ANSI, BTW?
    I'm not quite sure either. Truth is that I read that much to be able to extract codes from many different sources and try to fix the puzzle myself. I'm quite new to C++ too, took me quite awhile to figure out all the data structures/functions and API.

    Why are you passing NOT the full path name to your LoadLibrary call?
    Code:
    DWORD pID = GetTargetProcessIdFromProcname(PROCESS_NAME);
    
    char buf[MAX_PATH];
    GetFullPathName(DLL_NAME, MAX_PATH, buf, NULL);
       
    if(!Inject(pID, buf)){
        printf("DLL Not Loaded!");
    }else{
            printf("DLL Loaded!");
    }
    I corrected that mistake to full path now.

    Why don't you check the return values of all the API calls?
    Do you mean checking the values of each function such as VirtualAllocEx() by printing out to the console? There may need to be some format conversion right?

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: [Help/Advice needed]Program crashes when code is injected

    Quote Originally Posted by WoodyWool View Post
    Truth is that I read that much to be able to extract codes from many different sources and try to fix the puzzle myself. I'm quite new to C++ too, took me quite awhile to figure out all the data structures/functions and API.
    Well, "extract codes from many different sources" to use in your own project is not a bad idea. But you must do it properly!
    And since you are "quite new to C++" I doubt you understand what you do and how you have to...
    Perhaps, you should begin with some more simple and trivial things like learning about project types, build types, UNICODE and MBCS (ANSI), ... before developing such a non-trivial program like doing the "dll injecting".

    Quote Originally Posted by WoodyWool View Post
    Do you mean checking the values of each function such as VirtualAllocEx() by printing out to the console? There may need to be some format conversion right?
    What I meant is:
    1. You must read (carefully!) documentation about every API you are going to use.
    2. You have to plan what your code will perform in the case of any of the APIs failed. Example: what will happen if LoadLibrary returns NULL? If GetProcAddress returns NULL? If OpenProcess retun NULL?... And so on.
    3. You have to obtain the reason of the failure if API failed. Some APIs just return the error code, others set the last error, so you have to call GetLastError to get extended error information.
    Victor Nijegorodov

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [Help/Advice needed]Program crashes when code is injected

    What went wrong here?
    Well, almost everything. You allocate remote memory for DLL_NAME (which I literally take for dll name ) and instruct CreateRemoteThread to run what? DLL_NAME? Don't you find this weird a bit? Did you ever read a documentation on CreateRemoteThread? It needs thread function address, not string or something. And I don't see in your snippet anything like copying thread function code.
    Best regards,
    Igor

  6. #6
    Join Date
    Feb 2012
    Posts
    7

    Re: [Help/Advice needed]Program crashes when code is injected

    Thanks for the reply and pardon me for the late reply, been away for 2days.

    You allocate remote memory for DLL_NAME (which I literally take for dll name ) and instruct CreateRemoteThread to run what? DLL_NAME? Don't you find this weird a bit? Did you ever read a documentation on CreateRemoteThread? It needs thread function address, not string or something.
    Are you referring to the method VirtualAllocEx or WriteProcessMemory?

    If its VirtualAllocEx, I thought I'm suppose to put the size of the DLL?

    Oh wait..

    I think I see this here. I inserted the size of the string name of the DLL filename. So I need to insert the size of the DLL function instead? MyThreadFunction() or dataLocal?

    If it's WriteProcessMemory, I totally see my mistake here. It's totally wrong, i pointed the third parameter to the filename of my DLL. I'm suppose to point it to the address space that data can be written? Second parameter is the base address, third parameter is the pointer to the buffer. Where do I find these parameters from my code?

    Pardon me for saying that I read A LOT. Although I did went through all those msdn websites to view the APIs, I guess I didn't understand it thoroughly enough yet.

    And I don't see in your snippet anything like copying thread function code.
    Sorry, I thought I did that in WriteProcessMemory? Please do guide me here.

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [Help/Advice needed]Program crashes when code is injected

    I inserted the size of the string name of the DLL filename. So I need to insert the size of the DLL function instead? MyThreadFunction() or dataLocal?
    Seems I have to repeat my question. Did you ever read a documentation on CreateRemoteThread?

    lpStartAddress [in]

    A pointer to the application-defined function of type LPTHREAD_START_ROUTINE to be executed by the thread and represents the starting address of the thread in the remote process. The function must exist in the remote process. For more information, see ThreadProc.

    lpParameter [in]

    A pointer to a variable to be passed to the thread function.
    'The function must exist in the remote process' actually means you need to write the function body to the remote process.
    Last edited by Igor Vartanov; February 6th, 2012 at 12:10 PM.
    Best regards,
    Igor

  8. #8
    Join Date
    Feb 2012
    Posts
    7

    Re: [Help/Advice needed]Program crashes when code is injected

    Code:
    typedef struct MyData {
    
    } MYDATA, *PMYDATA;
    
    int main(int argc, char * argv[])
    {
        // enable debugging privileges
       enableDebugPriv();
       // Retrieve process ID
       //DWORD pID = GetTargetProcessIdFromProcname(PROCESS_NAME);
    
       // Get the dll's full path name
       char buf[MAX_PATH];
       GetFullPathName(DLL_NAME, MAX_PATH, buf, NULL);
       // Inject our main dll
       if(!Inject(buf))
       {
    
            printf("DLL Not Loaded!");
        }else{
            printf("DLL Loaded!");
        }
    
        _getch();
       return 0;
    }
    
    DWORD WINAPI MyThread(void *pData)
    {
        Sleep(3000);
        return (DWORD)pData;
    }
    
    BOOL Inject(char * DLL_N)
    {
       HANDLE Proc, hThread;
       LPVOID RemoteString;
       HMODULE hModule;
       BYTE Buffer = 0x55;
       int nSuccess = -1;
    
       DWORD TID = 0, newPID, error;
    
       PROCESS_INFORMATION pi;
       STARTUPINFO si;
    
       hModule = LoadLibrary(DLL_N);
    
       MYDATA *dataLocal = {(PMYDATA)GetProcAddress(hModule, "Function")};
    
       //Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    
       // Zero these structs
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
    
        // Start the child process
        if (!CreateProcess(NULL,    // No module name (use command line).
                           PROCESS_NAME,  // Command line.
                           NULL,    // Process handle not inheritable.
                           NULL,    // Thread handle not inheritable.
                           FALSE,   // Set handle inheritance to FALSE.
                           0,       // No creation flags.
                           NULL,    // Use parent's environment block.
                           NULL,    // Use parent's starting directory.
                           &si,     // Pointer to STARTUPINFO structure.
                           &pi))    // Pointer to PROCESS_INFORMATION structure.
        {
    		printf("CreateProcess(): failed");
    		getch();
    		return -1;
        }
    
        Proc = pi.hProcess;
        newPID = pi.dwProcessId;
        hThread = pi.hThread;
        TID = pi.dwThreadId;
        printf("CreateProcess(\"%s\"):hProcess=%X, PID=%X, hThread=%X, TID=%X\n\n",
    		   PROCESS_NAME, Proc, newPID, hThread, TID);
    
        PostThreadMessage(TID, WM_NCACTIVATE, TRUE, 0);
        Sleep(1000);
    
       RemoteString = VirtualAllocEx(Proc, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    
       printf("Writing memory... ");
       for (int i=0; i < 0x1000; i++)
    		{
    			if (!WriteProcessMemory(Proc, (PBYTE)RemoteString+i, &Buffer, 1, NULL))
    			{
    				printf("\nWriteProcessMemory(): failed");
    				getch();
    				return -1;
    			}
    		}
    
       printf("OK\n");
    
       // Free the allocated memory
    	if (!VirtualFreeEx(Proc,
    		                RemoteString,
    					    0,
    					    MEM_RELEASE))
    	{
    		printf("VirtualFreeEx(): failed");
    		getch();
    		return -1;
    	}
    	printf("VirtualFreeEx(Proc=%X): OK\n\n", Proc);
    
    	// Create remote thread
        hThread = CreateRemoteThread(Proc,
                                      NULL,
    				                  0,
    				                  (LPTHREAD_START_ROUTINE)MyThread,
    				                  (PVOID)123,
    				                  0,
    				                  &TID);
        if (!hThread)
    	{
    		printf("CreateRemoteThread(): failed");
    		getch();
    		return -1;
    	}
        printf("CreateRemoteThread(Proc=%X): hThread=%X, dwThreadId=%X\n", Proc, hThread, TID);
    
        // Wait for thread to finish
       	WaitForSingleObject(hThread, INFINITE);
    	GetExitCodeThread(hThread, (PDWORD)&nSuccess);
    
    	LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
    	error = GetLastError();
    
    	FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            error,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
    
        MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);
    
        CloseHandle(hThread);
        printf("Thread terminated with code: %d\n\n", nSuccess);
    
        // Close thread handle
        CloseHandle(pi.hThread);
    
       return true;
    }
    I have changed the way I wrote the codes. Have I done it right this time round? I received the error. It says Invalid Thread Identifier.

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [Help/Advice needed]Program crashes when code is injected

    What you do in the code makes no sense. You write 0x1000 of 0x55 bytes to a remote PAGE_EXECUTE allocated memory. What's that? Then you immediately free it. What's that? Then you run remote thread, but as a thread routine you provide your local address of MyThread. What's that?

    I tell you what that is: you have no plan, and you do random something that you hope would magically succeed. This is not the way how real program would be done. Please start with explaining your plan in verbal form, and we'll discuss it.
    Last edited by Igor Vartanov; February 7th, 2012 at 03:41 AM.
    Best regards,
    Igor

  10. #10
    Join Date
    Feb 2012
    Posts
    7

    Re: [Help/Advice needed]Program crashes when code is injected

    What I really want is a really simple DLL injector that injects a DLL into a remote process(any process, notepad.exe, explorer.exe, cmd.exe), using CreateRemoteThread(). In other words, copying the DLL codes into the remote process and executing it there. Nothing else. The DLL that I use is one that I created, just pops up a message box when it's attached and detached. It's a really simple one.

    I made some changes according to the websites that I used.

    http://www.codeproject.com/Articles/...Remote-Library
    http://www.codeproject.com/Articles/...Another-Proces

    Following all these, I still failed in making this a complete simple DLL injector.

  11. #11
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [Help/Advice needed]Program crashes when code is injected

    What I really want is a really simple DLL injector
    It is pretty obvious what you want. The real question is what your injection plan is. Step by step, doesn't matter whether you based it on what you have read in the articles or not.
    Best regards,
    Igor

  12. #12
    Join Date
    Feb 2012
    Posts
    7

    Re: [Help/Advice needed]Program crashes when code is injected

    Well, okay.

    1. Initialize the DLL function via LoadLibrary & GetProcAddress.
    2. Get the handle of the remote process.
    3. Allocate memory space for the DLL codes to be executed in there via VirtualAllocEx.
    4. Write the code to be executed into the memory space allocated via WriteProcessMemory.
    5. Start the code execution via CreateRemoteThread.
    6. End.

  13. #13
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [Help/Advice needed]Program crashes when code is injected

    Great. Now we can start a discussion.

    1. Initialize the DLL function via LoadLibrary & GetProcAddress.
    I'd like to understand what 'initialize' actually means. And what 'the DLL function' is.

    3. Allocate memory space for the DLL codes to be executed in there via VirtualAllocEx.
    4. Write the code to be executed into the memory space allocated via WriteProcessMemory.
    This won't work. You need to load the dll to the target process. Loading dll is much more than just copying code.

    Okay, here's an alternative plan:

    1. Implement thread procedure that would be copied to target process:
    • The thread initially loads the dll to target process by calling LoadLibrary.
    • !! LoadLibrary needs dll full path be copied to target process address space
    • Optionally, thread locates initialization function in the dll in context of target process by GetProcAddress
    • !! GetProcAddress needs initialization function name be copied to target process address space
    • Call the located initialization function
    • Optionally, unload the dll if required
    • Quit

    2. Allocate memory enough for keeping dll path and initialization function name. These data may comprise a struct type.
    3. Fill the sample data structure on injector side
    4. Copy the data structure to target process
    5. Locate the bounds of implemented thread function in injector process
    6. Allocate space for thread function in target process (here PAGE_EXECUTE is needed)
    7. Copy thread function bytes to target process
    8. Create remote thread providing remote thread function address as a thread routine, and remote data structure address as a thread parameter
    9. Wait on thread handle until the thread quits
    10. Free remote memory, both data struct and thread code
    Last edited by Igor Vartanov; February 8th, 2012 at 03:32 AM.
    Best regards,
    Igor

  14. #14
    Join Date
    Feb 2012
    Posts
    7

    Unhappy Re: [Help/Advice needed]Program crashes when code is injected

    I'd like to understand what 'initialize' actually means. And what 'the DLL function' is.
    From what I've learnt so far, I guess it is to start the preparation of the DLL execution by loading the CALLBACK function declared in my DLL.

    I took a few days break to try and understand what you wrote. So far I'm still unsuccessful.

    This won't work. You need to load the dll to the target process. Loading dll is much more than just copying code.
    I don't understand what it means by load the dll to the target process. So it isn't something like writing the codes over and then start the routine from there?

    1. Implement thread procedure that would be copied to target process:
    The thread initially loads the dll to target process by calling LoadLibrary.
    !! LoadLibrary needs dll full path be copied to target process address space
    Optionally, thread locates initialization function in the dll in context of target process by GetProcAddress
    !! GetProcAddress needs initialization function name be copied to target process address space
    Call the located initialization function
    Optionally, unload the dll if required
    Quit
    I've re-wrote my thread procedure, data structure and inject function. the DLL_NAME is defined as "Project1.dll". Hopefully I did improved on it a little? But I still get this error "Attempt to access invalid address.". As well as the remote application crashed. Which part did I go wrong?

    Code:
    struct StructSample {
    
        char dll_path;
        char function_name;
    
    } MyData;
    
    DWORD WINAPI MyThread()
    {
        // Get the dll's full path name
        char buf[MAX_PATH];
        GetFullPathName(DLL_NAME, MAX_PATH, buf, NULL);
    
        //Load the DLL
        HMODULE hModule = LoadLibrary(buf);
        FARPROC abcdef = GetProcAddress(hModule, "Function");
    
        return 0;
    }
    
    BOOL Inject()
    {
       HANDLE Proc, hThread;
       LPVOID RemoteString, ThreadFunc;
       HMODULE hModule;
       BYTE Buffer = 0x55;
       int nSuccess = 0;
    
       DWORD TID = 0, newPID, error;
    
       PROCESS_INFORMATION pi;
       STARTUPINFO si;
    
       //Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    
       // Zero these structs
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));
    
        // Start the child process
        if (!CreateProcess(NULL,    // No module name (use command line).
                           PROCESS_NAME,  // Command line.
                           NULL,    // Process handle not inheritable.
                           NULL,    // Thread handle not inheritable.
                           FALSE,   // Set handle inheritance to FALSE.
                           0,       // No creation flags.
                           NULL,    // Use parent's environment block.
                           NULL,    // Use parent's starting directory.
                           &si,     // Pointer to STARTUPINFO structure.
                           &pi))    // Pointer to PROCESS_INFORMATION structure.
        {
    		printf("CreateProcess(): failed");
    		getch();
    		return -1;
        }
    
        Proc = pi.hProcess;
        newPID = pi.dwProcessId;
        hThread = pi.hThread;
        TID = pi.dwThreadId;
        printf("CreateProcess(\"%s\"):hProcess=%X, PID=%X, hThread=%X, TID=%X\n\n",
    		   PROCESS_NAME, Proc, newPID, hThread, TID);
    
        PostThreadMessage(TID, WM_NCACTIVATE, TRUE, 0);
        Sleep(1000);
    
    
        // Get the dll's full path name
        char buf[MAX_PATH];
        GetFullPathName(DLL_NAME, MAX_PATH, buf, NULL);
    
        int totalSize = sizeof(buf) + sizeof("Function");
    
       //Virtual Allocate Memory
       RemoteString = VirtualAllocEx(Proc, NULL, totalSize, MEM_COMMIT, PAGE_READWRITE);
    
       char * fn = "Function";
    
        StructSample sampleABC;
        sampleABC.dll_path = *buf;
        sampleABC.function_name = *fn;
    
       //WriteProcessMemory
       printf("Writing memory... ");
       WriteProcessMemory(Proc, (LPVOID)RemoteString, &RemoteString, 1, NULL);
    
       ThreadFunc = VirtualAllocEx(Proc, NULL, MyThread(), MEM_COMMIT, PAGE_EXECUTE);
    
       WriteProcessMemory(Proc, (LPBYTE)ThreadFunc, &ThreadFunc, 1, NULL);
    
    	// Create remote thread
        hThread = CreateRemoteThread(Proc,NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, RemoteString, 0, &TID);
    
        if (!hThread)
    	{
    		printf("CreateRemoteThread(): failed");
    		getch();
    		return -1;
    	}
        printf("CreateRemoteThread(Proc=%X): hThread=%X, dwThreadId=%X\n", Proc, hThread, TID);
    
        // Wait for thread to finish
       	WaitForSingleObject(hThread, INFINITE);
    	GetExitCodeThread(hThread, (PDWORD)&nSuccess);
    
    	LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
    	error = GetLastError();
    
    	FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            error,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &lpMsgBuf,
            0, NULL );
    
        MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK);
    
        CloseHandle(hThread);
        printf("Thread terminated with code: %d\n\n", nSuccess);
    
        // Close thread handle
        CloseHandle(pi.hThread);
       WaitForSingleObject(hThread, INFINITE);
    
       return true;
    }

  15. #15
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [Help/Advice needed]Program crashes when code is injected

    Code:
    struct StructSample {
    
        char dll_path;
        char function_name;
    
    } MyData;
    Just a single char?

    Code:
        StructSample sampleABC;
        sampleABC.dll_path = *buf;
        sampleABC.function_name = *fn;
    What do you think this code does?

    Now, seriously. The plan I provided is a good starting point for an experienced developer. What you do in your code unambiguously indicates you're not one.

    What you need is to go on with programming something you really can handle. This is the only way for gaining experience.
    Best regards,
    Igor

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured