Luigi Auriemma

aluigi.org (ARCHIVE-ONLY FORUM!)
It is currently 19 Jul 2012 19:08

All times are UTC [ DST ]





Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Windows hooking / DLL injection
PostPosted: 15 Oct 2007 10:31 

Joined: 13 Aug 2007 21:44
Posts: 4068
Location: http://aluigi.org
The following is an example of DLL injection which is ready to use for real of functions and, in my opinion, is really very very simple to read and understand.

I have used CreateRemoteThread since seems the most easy to use way (although doesn't work on the old Win9x/NT) but I will probably add also a SetWindowsHookEx example when I will find a good way to implement it.

What this code allows you to do?
It allows to run a program at your choice and controlling the MessageBox function, in this example any MessageBox will contain the message "hook success".
As already said the code is ready to use so modifying only 4 parameters (the name of the original function and its dll, its prototype and the function you want to use) you have done everything.

The hooker is composed by two usual parts:
- loader: it runs the executable you want to hook and loads the dll in it
- inject: the dll which will be placed in the process and will take the control of the desired function (or functions since you can add how much functions you want)

if you want to add arguments to the loaded file use: loader "file.exe arg1 arg2" file.dll
And remember that if you don't specify the full path of file.dll the file.exe's process will load or try to load the dll in its folder.

Hope it helps and let me know if you have comments, suggestions or ideas

Note: CREATE_SUSPENDED and ResumeThread() are probably not really useful, I have added them only because I think this solution gives to the dll more time for modifying the process, let me know what you think.
Note: I prefer to consider this example still experimental since it's still not stable as I desire (heavily tested yesterday)


EDIT: attachments removed since wrongs, a new version will be updated soon


Top
 Profile  
 
 
 Post subject: Re: Windows hooking / DLL injection
PostPosted: 05 Oct 2008 00:05 

Joined: 05 Oct 2008 00:04
Posts: 2
Well, the CreateRemoteThread() "method" is very good but
there is also a possibility to take control over particular
thread, playing with its CONTEXT structure...Basically this
is a simple structure (defined in winnt.h) that describes the
thread "state". Here are steps to redirect the thread execution to
our code.

1. Open thread using OpenThread()
2. Suspend the execution of opened thread using SuspendThread()
3. Get CONTEXT structure of the thread via GetThreadContext()
4. Set the 'ContextFlags' field of CONTEXT structure to 'CONTEXT_CONTROL'
5. Change the EIP registry of the thread (Eip field) to point to our code
5. Set all changes to the thread via SetThreadContext()
6. Resume the execution of the thread calling ResumeThread()

Cheers
suN8Hclf


Top
 Profile  
 
 Post subject: Re: Windows hooking / DLL injection
PostPosted: 01 May 2009 01:08 

Joined: 01 May 2009 00:43
Posts: 4
aluigi wrote:
The following is an example of DLL injection which is ready to use for real of functions and, in my opinion, is really very very simple to read and understand.

I have used CreateRemoteThread since seems the most easy to use way (although doesn't work on the old Win9x/NT) but I will probably add also a SetWindowsHookEx example when I will find a good way to implement it.

What this code allows you to do?
It allows to run a program at your choice and controlling the MessageBox function, in this example any MessageBox will contain the message "hook success".
As already said the code is ready to use so modifying only 4 parameters (the name of the original function and its dll, its prototype and the function you want to use) you have done everything.

The hooker is composed by two usual parts:
- loader: it runs the executable you want to hook and loads the dll in it
- inject: the dll which will be placed in the process and will take the control of the desired function (or functions since you can add how much functions you want)

if you want to add arguments to the loaded file use: loader "file.exe arg1 arg2" file.dll
And remember that if you don't specify the full path of file.dll the file.exe's process will load or try to load the dll in its folder.

Hope it helps and let me know if you have comments, suggestions or ideas

Note: CREATE_SUSPENDED and ResumeThread() are probably not really useful, I have added them only because I think this solution gives to the dll more time for modifying the process, let me know what you think.
Note: I prefer to consider this example still experimental since it's still not stable as I desire (heavily tested yesterday)


EDIT: attachments removed since wrongs, a new version will be updated soon



There's a simpler way (works on Windoze and Linux) to achieve this:

1. Run the target program
2. Get the PID of the running target programm
3. Use gdb to attach to said PID
4. Use the following gdb commands to load your code

call (int)dlopen("/path/to/MyPlugin.so", 2)
continue

Of course dlopen is LoadLibrary on Windoze.


To get the PID on Linux:
Code:
#ifndef __cplusplus
    #define _GNU_SOURCE
#endif

#include <unistd.h>
#include <dirent.h>
#include <sys/types.h> // for opendir(), readdir(), closedir()
#include <sys/stat.h> // for stat()

#ifdef __cplusplus
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdarg>
#else
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
#endif


#define PROC_DIRECTORY "/proc/"
#define CASE_SENSITIVE    1
#define CASE_INSENSITIVE  0
#define EXACT_MATCH       1
#define INEXACT_MATCH     0


int IsNumeric(const char* ccharptr_CharacterList)
{
    for ( ; *ccharptr_CharacterList; ccharptr_CharacterList++)
        if (*ccharptr_CharacterList < '0' || *ccharptr_CharacterList > '9')
            return 0; // false
    return 1; // true
}


int strcmp_Wrapper(const char *s1, const char *s2, int intCaseSensitive)
{
    if (intCaseSensitive)
        return !strcmp(s1, s2);
    else
        return !strcasecmp(s1, s2);
}

int strstr_Wrapper(const char* haystack, const char* needle, int intCaseSensitive)
{
    if (intCaseSensitive)
        return (int) strstr(haystack, needle);
    else
        return (int) strcasestr(haystack, needle);
}


#ifdef __cplusplus
pid_t GetPIDbyName(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#else
pid_t GetPIDbyName_implements(const char* cchrptr_ProcessName, int intCaseSensitiveness, int intExactMatch)
#endif
{
    char chrarry_CommandLinePath[100]  ;
    char chrarry_NameOfProcess[300]  ;
    char* chrptr_StringToCompare = NULL ;
    pid_t pid_ProcessIdentifier = (pid_t) -1 ;
    struct dirent* de_DirEntity = NULL ;
    DIR* dir_proc = NULL ;

    int (*CompareFunction) (const char*, const char*, int) ;

    if (intExactMatch)
        CompareFunction = &strcmp_Wrapper;
    else
        CompareFunction = &strstr_Wrapper;


    dir_proc = opendir(PROC_DIRECTORY) ;
    if (dir_proc == NULL)
    {
        perror("Couldn't open the " PROC_DIRECTORY " directory") ;
        return (pid_t) -2 ;
    }

    // Loop while not NULL
    while ( (de_DirEntity = readdir(dir_proc)) )
    {
        if (de_DirEntity->d_type == DT_DIR)
        {
            if (IsNumeric(de_DirEntity->d_name))
            {
                strcpy(chrarry_CommandLinePath, PROC_DIRECTORY) ;
                strcat(chrarry_CommandLinePath, de_DirEntity->d_name) ;
                strcat(chrarry_CommandLinePath, "/cmdline") ;
                FILE* fd_CmdLineFile = fopen (chrarry_CommandLinePath, "rt") ;  // open the file for reading text
                if (fd_CmdLineFile)
                {
                    fscanf(fd_CmdLineFile, "%s", chrarry_NameOfProcess) ; // read from /proc/<NR>/cmdline
                    fclose(fd_CmdLineFile);  // close the file prior to exiting the routine

                    if (strrchr(chrarry_NameOfProcess, '/'))
                        chrptr_StringToCompare = strrchr(chrarry_NameOfProcess, '/') +1 ;
                    else
                        chrptr_StringToCompare = chrarry_NameOfProcess ;

                    //printf("Process name: %s\n", chrarry_NameOfProcess);
                    //printf("Pure Process name: %s\n", chrptr_StringToCompare );

                    if ( CompareFunction(chrptr_StringToCompare, cchrptr_ProcessName, intCaseSensitiveness) )
                    {
                        pid_ProcessIdentifier = (pid_t) atoi(de_DirEntity->d_name) ;
                        closedir(dir_proc) ;
                        return pid_ProcessIdentifier ;
                    }
                }
            }
        }
    }
    closedir(dir_proc) ;
    return pid_ProcessIdentifier ;
}

#ifdef __cplusplus
    pid_t GetPIDbyName(const char* cchrptr_ProcessName)
    {
        return GetPIDbyName(cchrptr_ProcessName, CASE_INSENSITIVE, EXACT_MATCH) ;
    }
#else
    // C cannot overload functions - fixed
    pid_t GetPIDbyName_Wrapper(const char* cchrptr_ProcessName, ... )
    {
        int intTempArgument ;
        int intInputArguments[2] ;
        // intInputArguments[0] = 0 ;
        // intInputArguments[1] = 0 ;
        memset(intInputArguments, 0, sizeof(intInputArguments) ) ;
        int intInputIndex ;
        va_list argptr;

        va_start( argptr, cchrptr_ProcessName );
            for (intInputIndex = 0;  (intTempArgument = va_arg( argptr, int )) != 15; ++intInputIndex)
            {
                intInputArguments[intInputIndex] = intTempArgument ;
            }
        va_end( argptr );
        return GetPIDbyName_implements(cchrptr_ProcessName, intInputArguments[0], intInputArguments[1]);
    }

    #define GetPIDbyName(ProcessName,...) GetPIDbyName_Wrapper(ProcessName, ##__VA_ARGS__, (int) 15)

#endif

int main()
{
    pid_t pid = GetPIDbyName("bash") ; // If -1 = not found, if -2 = proc fs access error
    printf("PID %d\n", pid);
    return EXIT_SUCCESS ;
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for: