首页
社区
课程
招聘
[原创]关于穷举的一些思路(附源码和TOOL)
发表于: 2009-9-23 14:01 6656

[原创]关于穷举的一些思路(附源码和TOOL)

2009-9-23 14:01
6656

初次见穷举的表演是jackozoo 的帖子《小试金枪: jackozoo 2009热身版 !! 》
http://bbs.pediy.com/showthread.php?t=97046&page=1
里面ccfer兄和海风兄的思路是我以往从未见过的(接触加解密快三个月了,请不要笑我孤陋寡闻,呵呵~),特别是ccfer兄的方法更是让我觉得匪夷所思,对比海风兄的dll注入方法,他的效率提高很多,但是我个人还是觉得海风兄的dll注入方法实现还是较为方便,至少不用手动去更改或将出现的某些偏移地址,有一定的通用性,呵呵,个人拙见。

http://bbs.pediy.com/showthread.php?t=97307,这个帖子是天易兄的详细解释说明和实例应用,

上面的例子是算法在一个fuction中计算对比序列号的穷举方法,最好的适用范围如下:
{
     getitemdlgtext();
      ……
    ……
   bool  result = check_nameserial();
      ……
    ……
     
}
在穷举的时候,只要构筑好环境,直接call check_nameserial,然后比较返回结果eax就可以了。

但是还有很多情况是这样子的:
{
     getitemdlgtext(); 或者  updatedata(true);
      ……
    switchname();
      ……
    switchserial();
    ……
    checkname();
      ……
    checkserial();
      ……
    ……
     
}
或者
{
     getitemdlgtext(); 或者  updatedata(true);
      ……
    ……
      ……
    ……
     
}

出现上述情况的话(这种情况也是比较多见的),直接call 算法函数 可能就有点不太适用了,因此我考虑直接call整个片段,即把需要call的内容开始到结束作为一个函数即可以了(只要注意堆栈平衡)。 依然以jackozoo 的帖子《小试金枪: jackozoo 2009热身版 !! 》中的CM为实例,具体实现步骤如下:

const char injectionwindow[MAX_CHAR] = "ACG TRIAL Membership Crackme v1.0";

BOOL callFullFucResult(char *name, char *key,DWORD wnd)
{
        BOOL bResult = 0;
        __asm
        {
                pushad;//把所有寄存器保存起来,即保存现场
                xor eax, eax; //以下的寄存器数据都是根据程序的实际情况来写的。即模拟调用函数时的状态
                xor ecx, ecx; //特别注意ecx,在类函数中,往往为this指针
                mov edx, 0x00000022;
                xor ebx, ebx;
;//                mov esp, 0x0013FA50; //这两个由函数自动分配,无需更改
;//                mov ebp, 0x0013FAA0;
                mov esi, wnd; //dlg窗口句柄 bb0cbe
                mov edi, 0x0013FADC;
                push offset _returnResult; //算法调用函数的返回值,先放到offset这边
                push 0x00401020; //算法调用的函数地址
                retn;
        _returnResult:
                mov bResult, eax;
                popad;//恢复所有寄存器,即恢复现场
        }

        return bResult;
}

__declspec(dllexport) void checkresult(void)
{

        HWND pWnd = NULL;

        int len = strlen(wantname);
        int i;
        char cc;

        memset(name, 0, MAX_CHAR);
        memset(key, 0, MAX_CHAR);
        strcpy(name, "feng");
        strcpy(key, "ujkt");

#if _ENABLE_MSG_
        char strWnd[MAX_CHAR] = _TEXT("NULL");
#endif

        pWnd =::FindWindow(NULL,injectionwindow);
        if(pWnd == NULL)   //先找到输入name和serial的dlg窗口
        {   
                MessageBoxEx(NULL,_TEXT("没有找到注入的窗口句柄"),_TEXT("测试结果"),MB_OK,0);
                return;
        }

#if 1
        for(i = 0; i < len; i++)        //name
        {
                name[i] = wantname[i];
                           SetDlgItemText(pWnd,0x3e9,name);//写入name,0x3e9为name输入框的ID

                for(cc = 'a'; cc < 'z'; cc++)       
                {
                        key[i] = cc;
                        SetDlgItemText(pWnd,0x3ea,key);//写入name,0x3ea为serial输入框的ID
#if _ENABLE_MSG_
                        sprintf(strWnd,"测试次数 == %d",cc);     
                        MessageBoxEx(NULL,strWnd,_TEXT("测试次数结果"),MB_OK,0);
#endif
                        if(callFullFucResult(name, key,(DWORD)pWnd))
                        {
                                MessageBox(NULL, name, key, NULL);
                                return;//break; //找到一个就返回好了
                        }
                }
        }
#endif

        MessageBox(NULL, name, key, NULL);
        return;
}

//---------------------------------------------------------------------

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                                         )
{
        switch (ul_reason_for_call)
     {
           case DLL_PROCESS_ATTACH:
                myTestFun();
               checkresult();
         break;

           case DLL_THREAD_ATTACH:
           case DLL_THREAD_DETACH:
           case DLL_PROCESS_DETACH:
         break;

     }

    return TRUE;
}

上面对CM的算法还是依据海风兄的源代码(所有的思路都是建立在对海风兄的那个源码的理解上,谢谢海风兄的共享! 听说他快结婚了,在此先恭喜他 :))

以上思路的主要注意点:
1,对注入环境的模拟,用ollydbg多跟踪应该就可得出。
2,穷举算法的选择,应该对CM的流程和算法(包括CM的一些限制)有一定的了解,然后选择最快的算法,这是穷举最关键的地方!
3,对CM需要做部分更改,以使堆栈平衡。

附件为此dll源码和我自己编写的dll注入工具,只要对dll进行相应修改就可以实现对有可能穷举实现的CM实现穷举了,呵呵~~我用2007年的CM做过实验,有很多可以穷举实现。。:)


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (9)
雪    币: 164
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
从来没抢过沙发
2009-9-23 14:46
0
雪    币: 418
活跃值: (63)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
3
ccfer兄有空请指导一下,如何能快速堆栈平衡之类的注意点。
2009-9-23 18:49
0
雪    币: 388
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
好好学习 天天进步~
2009-9-23 19:55
0
雪    币: 244
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
进来学习一下,正在学习DLL注入!
2009-9-23 21:05
0
雪    币: 433
活跃值: (1870)
能力值: ( LV17,RANK:1820 )
在线值:
发帖
回帖
粉丝
6
Support
2009-9-23 21:42
0
雪    币: 418
活跃值: (63)
能力值: ( LV12,RANK:260 )
在线值:
发帖
回帖
粉丝
7
上传了一个通用版的dll源码,有兴趣的可根据实际情况更改条件。
2009-9-23 23:51
0
雪    币: 517
活跃值: (64)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
谢谢,留个记号
2009-9-24 09:36
0
雪    币: 318
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
占位学习!!!!!!!!
2009-9-26 07:55
0
雪    币: 194
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
顶一顶..顺一顺...
2009-9-30 12:51
0
游客
登录 | 注册 方可回帖
返回
//