首页
社区
课程
招聘
[求助]DLL注入后HOOK的奇怪问题!
发表于: 2010-4-8 17:43 8637

[求助]DLL注入后HOOK的奇怪问题!

2010-4-8 17:43
8637

RT:新手不明白,请高手解答下!

--------------------------------------注入程序-------------------------------------------
#include <Windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

void debug(const char * name);
BOOL inDLL(const char *path,const HANDLE hnd);

int WINAPI WinMain(
                 HINSTANCE hInstance,
                 HINSTANCE hprevInstance,
                LPSTR lpCmdLine,
                 int nShowCmd)
{
        char mzpath[MAX_PATH]={0};

        STARTUPINFO si; //一些必备参数设置

        memset(&si, 0, sizeof(STARTUPINFO)); //memset函数常用于内存空间初始化

        si.cb = sizeof(STARTUPINFO);

        si.dwFlags = STARTF_USESHOWWINDOW;

        si.cb = sizeof(STARTUPINFO);

        si.dwFlags = STARTF_USESHOWWINDOW;

        PROCESS_INFORMATION pi;

        GetCurrentDirectoryA(MAX_PATH,mzpath);//获取程序运行目录

        char mzfilename[]="\\a.exe";

        strcat(mzpath,mzfilename);//组合程序路径
                                                                                                                                                                                                      
        //以CREATE_SUSPENDED模式启动进程
        CreateProcess(NULL, mzpath, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si ,&pi);

        //返回线程执行流程
        ResumeThread(pi.hThread);

        //等待主进程启动
        WaitForInputIdle(pi.hProcess, 1000);
               
               //写入进程
        inDLL("F:\\windows开发\\regdll\\release\\regdll.dll",pi.hProcess);
        //退出
        exit(0);
        return 0;
}

/****************************************************************/
/*                                   权限提升                                           */
/****************************************************************/

void debug(const char * name)
{
        HANDLE hToken;//句柄

        TOKEN_PRIVILEGES tp;//特权令牌

        LUID luid;

        OpenProcessToken(
                GetCurrentProcess(),//获取当前进程的一个伪句柄
                TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
                &hToken);

        //获得进程本地唯一ID
        LookupPrivilegeValueA(NULL,name,&luid);

        tp.PrivilegeCount=1;
        tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;//特权使能
        tp.Privileges[0].Luid=luid;

        //调整权限
        AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL);

        CloseHandle(hToken);
        return ;
}

/****************************************************************/
/*                                插入DLL                                                   */
/****************************************************************/
BOOL inDLL(const char *path,const HANDLE hnd)
{
        debug(SE_DEBUG_NAME);
        //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区
        char *dllLib=(char *)VirtualAllocEx(hnd,NULL,lstrlenA(path)+1,MEM_COMMIT,PAGE_READWRITE);

        //写入远程线程
        WriteProcessMemory(hnd,dllLib,(void *) path,lstrlenA(path)+1,NULL);

        //计算LoadLibraryA的入口地址
        PTHREAD_START_ROUTINE mstat=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"),"LoadLibraryA");
        //启动远程线程

        CreateRemoteThread(hnd,NULL,0,mstat,dllLib,0,NULL);
        return TRUE;
}
--------------------------------------------------------------------------------------------------
主程序主要是启动一个本地程序,并将DLL注入进去!

---------------------------------------dll程序---------------------------------------------------
#include <Windows.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

void WINAPI HOOK();

LRESULT CALLBACK HOOKCL(int a,WPARAM wp,LPARAM lp);

HINSTANCE hmodule;//所模块句柄

static HHOOK myhook=NULL;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
                hmodule=hModule;
                CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)HOOK,NULL,NULL,NULL);
                //启动HOOK主程序;
                break;
        case DLL_THREAD_ATTACH:                                                                        
                break;
        case DLL_THREAD_DETACH:
                break;
        case DLL_PROCESS_DETACH:                                       
                break;
        }
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

void WINAPI HOOK()
{           
        myhook=SetWindowsHookEx(
                WH_KEYBOARD,//钩子类型
                (HOOKPROC)HOOKCL,//钩子函数地址
                hmodule,//钩子函数所在DLL的实例句柄
                0);//安装钩子后想监控的线程的ID号
        //返回参数为钩子句柄
        //UnhookWindowsHookEx 参数只有一个,为要卸载的钩子句柄
        //WaitForInputIdle(myhook, 1000);
        Sleep(1000);//等待1000秒
       
}

LRESULT CALLBACK HOOKCL(int a,WPARAM wp,LPARAM lp)
{

        //钩子函数(名称任意), 三个参数, 具体意义与钩子类型有关
        if(((DWORD)lp&0x40000000)&&(HC_ACTION==a))
        {
                switch(wp)
                {
                case '1':
                        MessageBoxA(NULL,"1","HOOK",0);
                        break;
                case '2':
                        MessageBoxA(NULL,"2","HOOK",0);
                        break;
                }
        }
       
        return CallNextHookEx(myhook, a, wp, lp );
}
----------------------------------------------------------------------------------------------
程序非常简单!调试也通过了!不过问题来了!
HOOK()函数中SetWindowsHookEx如果不等待1000毫秒,那就啥也HOOK不到!
可是就算sleep(1000)后,也只能获取到一次键盘输入,第二次敲击键盘就没反应了!
不明白这是为什么?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 242
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
case DLL_PROCESS_ATTACH:
    hmodule=hModule;
    CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)HOOK,NULL,NULL,NULL);
    //启动HOOK主程序;
    break;

这个地方会不会陷入死循环?因为设置钩子的时候会自动的把Dll注入到进程产生DLL_PROCESS_ATTACH消息,同时又创建线程安装钩子.
2010-4-8 18:10
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
的确是调用了两次!但是程序并没有死循环!
我开始一直不明白为什么会调用了两次HOOK,现在明白了!

不过。。我的问题还是没有解决!
2010-4-8 19:33
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
4
记得卸载钩子,不然会有不必要的麻烦

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
           )
{
  switch (ul_reason_for_call)
  {
  case DLL_PROCESS_ATTACH:
    hmodule=hModule;
    myhook = SetWindowsHookEx(WH_KEYBOARD, HOOKCL, hmodule, 0);//安装钩子后想监控的线程的ID号
    break;
  case DLL_THREAD_ATTACH:
    break;
  case DLL_THREAD_DETACH:
    break;
  case DLL_PROCESS_DETACH:
    break;
  }
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

void WINAPI HOOK()// 把这个函数去掉
{           
  myhook=SetWindowsHookEx(
    WH_KEYBOARD,//钩子类型
    (HOOKPROC)HOOKCL,//钩子函数地址
    hmodule,//钩子函数所在DLL的实例句柄
    0);//安装钩子后想监控的线程的ID号
  //返回参数为钩子句柄
  //UnhookWindowsHookEx 参数只有一个,为要卸载的钩子句柄
  //WaitForInputIdle(myhook, 1000);
  Sleep(1000);//等待1000秒  
}

我自己写了一个小程序测试了一下:
EXE代码:

#include <Windows.h>
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
        HMODULE        hMod = LoadLibrary( _T("dll.dll") );
        printf( "%08x", (DWORD)hMod );
        system("pause");
        return 0;
}

DLL代码:

#include <Windows.h>
#include <tchar.h>

LRESULT        CALLBACK        KeyBordProc( int nCode, WPARAM wParam, LPARAM lParam )
{
        if ( ( (DWORD)lParam & 0x40000000 ) && ( HC_ACTION == nCode ) )
        {
                switch( wParam )
                {
                        case '1':
                                MessageBox( NULL, _T("fuck 1"), NULL, 0 );
                                break;
                        case '2':
                                MessageBox( NULL, _T("fuck 2"), NULL, 0 );
                                break;
                }
        }
        return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                                          DWORD  ul_reason_for_call,
                                          LPVOID lpReserved
                                          )
{
        HHOOK        hHook = NULL;
        switch( ul_reason_for_call )
        {
                case DLL_PROCESS_ATTACH:
                        {
                                hHook = SetWindowsHookEx( WH_KEYBOARD, KeyBordProc, hModule, 0 );

                        }
                        break;
                case DLL_PROCESS_DETACH:
                        break;
        }
        return TRUE;
}
2010-4-8 22:26
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
等你!老兄!
2010-4-8 22:50
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
太晚了!明天再试试!
谢谢你哈!
2楼那位兄弟说。。使用HOOK。。DLL会被加载两次。是怎么回事?
2010-4-8 23:06
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
本进程。。是没有问题的!
但是把DLL注入到远程进程里去就不行了!
HOOK不到!
2010-4-9 10:18
0
雪    币: 242
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
把HOOK函数和安装函数写到DLL里面,然后在客户进程调用就行了,处理DllMain的时候就可以取得Dll的句柄,调用安装钩子函数后会直接插入到需要挂钩的进程,为什么还要开远程线程这么马烦?
前面我的理解是,开远程线程的时候加载一次,安装钩子的时候再加载一次(PS:我也是新手)
2010-4-9 11:44
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
因为。。写的是内存注册机!
要将本身的DLL注入到远端!
前天。试了试无DLL注入。。更是头痛!老出错!
汇编不会。。所以很麻烦!
2010-4-9 12:10
0
雪    币: 97
活跃值: (141)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
不应该用SetWindowsHookEx,最好用inline hook。就是修改函数内存前5个字节的方法挂钩。
2010-8-1 22:00
0
游客
登录 | 注册 方可回帖
返回
//