Win32 API功能封装
+ -

远程的DLL注入进程的实现

2021-08-30 68 0

进程注入的原理就是让目标进程执行一段自己的代码,而这个实现的前提是

1.让目标进程可以访问我们自己写的代码
2.让目标进程跳到我们的代码入口执行
3.执行完成后可以正常退出,不引发进程的crash。

这里采用的是DLL远程注入方式.
大概原理是基本上所有的进程都会依赖kernel32.dll,而这个DLL中有2个导出函数LoadLibraryA和LoadLibraryW,其实这2个函数没啥 区别,一个是多字节的接口,一个是宽字节的接口,而多字节的会在内部对多字节进行转换成宽字节,再调用宽字节继续执行。

而windows为了节省内存,所有的动态库都会加载到同一物理内存地址,同时为了便于内存管理,这些物量内存也会引映射到不同进程的内一虚执地址空间。所以A进程中的某个API函数和另一个进程的地址的样同。

而为了让这个目标进程能正常调用我们的代码,可以采用开线程的方式来实现,这样不影响进程原有的运行。

这样我们可以采用API函数CreateRemoteThread来产生远程线程,而线程的入口函数使用LoadLibraryA(W),参数为DLL的路径。

所以为了实现以上功能,需要解决2个问题,CreateRemoteThread的入口地址LoadLibraryA(W)和LoadLibraryA(W)的存储路径,且这个路径地址必须为目标进程的地址。

第一个问题可按上面说的,用协注入进程来获取LoadLibraryA(W)的地址。

第二个问题可以采用打开目标进程,使用API函数VirtualAllocEx来申请一段目标进程内存地址,然后将LoadLibraryA(W)的存储路径复制进去,然后将这个地址传给CreateRemoteThread远程线程函数即可。

BOOL InjectProcessByPID(DWORD dwPId, TCHAR *szDllName)
{
    HANDLE hProcess = NULL;
    LPVOID pRemoteBuf = NULL;
    FARPROC pThreadProc = NULL;
    DWORD dwBufSize = (DWORD)(_tcslen(szDllName) + 1) * sizeof(TCHAR);

    if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPId)))
    {
        printf("[ERROR] OpenProcess(%d) failed!!! [%d]", dwPId, GetLastError());
        return FALSE;
    }

    TCHAR path[MAX_PATH] = {0};
    GetModuleFileNameEx(hProcess, NULL, path, MAX_PATH + 1);
    for (unsigned int i = 0; i < m_WhiteList.size(); i++)
    {
        if (_tcsstr(path, m_WhiteList[i].c_str()))
        {
            _tprintf(TEXT("white list :%s"), m_WhiteList[i].c_str());
            return FALSE;
        }
    }

    pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);

    WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL);

#ifdef UNICODE
    pThreadProc = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryW");
#else
    pThreadProc = GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
#endif

    if (!ExecuteRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf))
    {
        printf("[ERROR] ExecuteRemoteThread() failed!!!");
    }

    VirtualFreeEx(hProcess, pRemoteBuf, 0, MEM_RELEASE);

    CloseHandle(hProcess);

    return TRUE;
}
BOOL ExecuteRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
{
    HANDLE      hThread = NULL;
    FARPROC     pFunc = NULL;

    if (IsVistaOrLater())    // Vista, 7, Server2008
    {
        #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF)
        pFunc = GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "NtCreateThreadEx");
        if (pFunc == NULL)
        {
            printf(" MyCreateRemoteThread() : GetProcAddress("NtCreateThreadEx") failed!!!  [%d]
", GetLastError());
            return FALSE;
        }

        INT_PTR rtn = ((_NtCreateThreadEx)pFunc)(&hThread, THREAD_ALL_ACCESS, NULL, hProcess, pThreadProc, pRemoteBuf, FALSE, NULL, NULL, NULL, NULL);

        if (hThread == NULL)
        {
            printf("win7 MyCreateRemoteThread() : NtCreateThreadEx() failed!!! [%d]", GetLastError());
            return FALSE;
        }
    }
    else
    {
        hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, pRemoteBuf, 0, NULL);
        if (hThread == NULL)
        {
            printf("xp MyCreateRemoteThread() : CreateRemoteThread() failed!!! [%d]", GetLastError());
            return FALSE;
        }
    }

    if (WAIT_FAILED == WaitForSingleObject(hThread, INFINITE))
    {
        printf("MyCreateRemoteThread() : WaitForSingleObject() failed!!! [%d]", GetLastError());
        return FALSE;
    }

    return TRUE;
}

0 篇笔记 写笔记

ApiSetSchema.dll的apiset节
api-ms系列动态库函数其实还在在另外一种映射,即api-ms部分dll不存在系统中函数映射分发。也就是说某个exe文件依赖于某个api-ms的dll,但这个dll并不存在系统中,但实际上这个exe文件运行时并不报错。这是为什么呢?api-ms- 系列的 DLL 确实起的是转发作用,但其本身可以......
WDDM 模型架构
WDDM驱动模型架构从Windows Vista开始支持,由内核模块和应用模块组成。微软图形显示子系统架构如下所示:根据上图可知,我们开发WDDM驱动并不是从头开始全部,而是配合Windows已经提供的现有的显示驱动架构的基础上开发内核态的显示MiniPort驱动、用户模式的显示驱动和用于支持O......
远程的DLL注入进程的实现
进程注入的原理就是让目标进程执行一段自己的代码,而这个实现的前提是1.让目标进程可以访问我们自己写的代码2.让目标进程跳到我们的代码入口执行3.执行完成后可以正常退出,不引发进程的crash。这里采用的是DLL远程注入方式.大概原理是基本上所有的进程都会依赖kernel32.dll,而这个DLL......
ASIO asiosample.dll注册及注册表信息变化
在Windows下注册ASIO一节中,是需要对COM进入注册的。故我们使用Regsvr32命令注册。如:K:usbzhasioasiosdk_2.3.3_2019-06-14driverasiosampleasiosampleDebug>REGSVR32 asiosample.......
ASIO 示例代码调试准备
ASIO提供的示例代码在进行调试前,需要做以下几个步骤:第一,就是按上节的要求将编译好的asiosample.dll通过命令行进行注册,这里使用的命令是REGSVR32 asiosample.dll当然,这个注册分为32位和DLL和64位的DLL,所以会有差别。本人在现有的机器使用的是32位编程......
COM组件注册信息
根据COM规范,客户程序通过COM库完成COM对象的创建,COM库则通过注册表所提供的信息进行组件的创建。注册表中包含了所有COM组件的必要信息。组件程序和客户程序都可访问注册表。组件程序把它所实现的COM对象的信息及接口信息保存到注册表中,称之为组件的注册。COM组件在HKEY_CLASSES_......
COM 类厂和DllGetObjectClass函数
类厂是COM对象的生产基地,COM库通过类厂创建COM对象;对应每一个COM类,都有一个类厂,用于该COM类的对象创建操作。类厂本身也是一个COM对象,它支持一个特殊接口(IClassFactory):class IClassFactory:public IUnknown{ virtua......
COM组件的安装与卸载
(1)进程内组件的安装客户调用COM库的CoCreateInstance或CoGetClassObject创建COM对象时,在CoGetClassObject中,COM库根据注册表中的信息,找到类标识符CLSID对应的组件程序(DLL)的全路径并调用CoLoadLibrary,再调用组件程序的Dll......
APO动态库DLL文件的路径问题
APO DLL注册路径APO的DLL文件是通过regsvr32注册表的。比如:regsvr32.exe xxAPO.dll这样在注册表HKEY_LOCAL_MACHINESOFTWAREClassesCLSID就会记录该文件的GUID的路径。该GUIDPKEY_FX_*EffectCls......
vs2019编写dll并导出函数
下面是一个使用Visual Studio 2019的示例,演示如何通过.def文件修改DLL导出函数名称:在Visual Studio 2019中创建一个新的Win32 DLL项目。选择“DLL”项目类型,并在“导出符号”选项中选择“Yes”。在项目中创建一个源文件(例如,YourSource......
CreateRemoteThread远程汪入DLL
注入DLLBOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!