欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]第七题

[原创]第七题

1、处理int3反调试,可以看到:

0040F2CA                             |> \68 E2DE4000   PUSH 7-不问少.0040DEE2                                ; /pTopLevelFilter = 7-不问少.0040DEE2
0040F2CF                             |.  FF15 F83C4500 CALL DWORD PTR DS:[<&KERNEL32.SetUnhandledExceptio>; \SetUnhandledExceptionFilter

0040DEE2 为程序处理异常的函数:

0040DEE2                             /.  55            PUSH EBP
0040DEE3                             |.  8BEC          MOV EBP,ESP
0040DEE5                             |.  56            PUSH ESI
0040DEE6                             |.  8B75 08       MOV ESI,DWORD PTR SS:[EBP+8]
0040DEE9                             |.  8B06          MOV EAX,DWORD PTR DS:[ESI]
0040DEEB                             |.  8138 03000080 CMP DWORD PTR DS:[EAX],80000003          比较是不是int3
0040DEF1                             |.  75 25         JNZ SHORT 7-不问少.0040DF18
0040DEF3                             |.  6A 00         PUSH 0                                             ; /lParam = 0
0040DEF5                             |.  6A 00         PUSH 0                                             ; |wParam = 0
0040DEF7                             |.  FF35 302C4000 PUSH DWORD PTR DS:[402C30]                         ; |Message = MSG(464)
0040DEFD                             |.  FF35 00264500 PUSH DWORD PTR DS:[452600]                         ; |hWnd = 9303D4
0040DF03                             |.  FF15 E03D4500 CALL DWORD PTR DS:[<&USER32.PostMessageW>]         ; \PostMessageW        //发送窗口消息,执行正常的流程
0040DF09                             |.  8B46 04       MOV EAX,DWORD PTR DS:[ESI+4]
0040DF0C                             |.  8380 B8000000>ADD DWORD PTR DS:[EAX+B8],9
0040DF13                             |.  83C8 FF       OR EAX,FFFFFFFF
0040DF16                             |.  EB 02         JMP SHORT 7-不问少.0040DF1A
0040DF18                             |>  33C0          XOR EAX,EAX
0040DF1A                             |>  5E            POP ESI
0040DF1B                             |.  5D            POP EBP
0040DF1C                             \.  C2 0400       RETN 4

通过PostMessageW发送消息,可以推断出,最终会执行到0040E3ED :

0040E3ED                             |.  8D45 1C       LEA EAX,DWORD PTR SS:[EBP+1C]
0040E3F0                             |.  C745 1C 01000>MOV DWORD PTR SS:[EBP+1C],1
0040E3F7                             |.  50            PUSH EAX
0040E3F8                             |.  FF75 14       PUSH DWORD PTR SS:[EBP+14]
0040E3FB                             |.  8BCB          MOV ECX,EBX
0040E3FD                             |.  56            PUSH ESI
0040E3FE                             |.  57            PUSH EDI
0040E3FF                             |.  E8 C9200000   CALL 7-不问少.004104CD         这里就是效验key的函数


然而每次按下按钮会执行到:

0040E478                             |.  8D45 1C       LEA EAX,DWORD PTR SS:[EBP+1C]
0040E47B                             |.  897D 1C       MOV DWORD PTR SS:[EBP+1C],EDI
0040E47E                             |.  50            PUSH EAX
0040E47F                             |.  FF75 14       PUSH DWORD PTR SS:[EBP+14]
0040E482                             |.  51            PUSH ECX
0040E483                             |.  6A 00         PUSH 0
0040E485                             |.  8BCB          MOV ECX,EBX
0040E487                             |.  E8 F91D0000   CALL 7-不问少.00410285              这个为执行int3反调试


00410285如下:

00410285                                 CC            INT3                                                  跳到0040DEE2                            

00410286                                 6A 01         PUSH 1                                             ; /ExitCode = 1
00410288                             |.  FF15 343E4500 CALL DWORD PTR DS:[<&USER32.PostQuitMessage>]      ; \PostQuitMessage
0041028E                             |.  33C0          XOR EAX,EAX
00410290                             \.  C2 1000       RETN 10
正常来说,在调试的情况,int3会被调试器接管,不会执行到0040DEE2,然后执行PostQuitMessage退出,达到反调试的目的;

下面说下我咋处理这个int3,不难发现0040E478和0040E3ED 是处于同一个函数下,所以只要是 执行到0040E478,改变eip到0040E3ED就可以简单pass    


2、具体key效验过程:

key经过一个算法得到一个buffer,然后在和 g_result比较,如果相等就用这个key和一个加密的call进行循环异或解密得到正常call,然后执行这个call

具体爆破key的算法如下:

#include "stdafx.h"

#include <vector>

#include <ctype.h>

#define  _DWORD unsigned int

#define _BYTE unsigned char

#define CROL(value, bits) ((value << bits) | (value >> (8 - bits)))

#define CROR(value, bits) ((value >> bits) | (value << (8 - bits)))

unsigned char g_table[64] = {

    0x89, 0xBC, 0x95, 0xFC, 0xFB, 0xBA, 0xED, 0x9A, 0xBB, 0xAE, 0xFE, 0x99, 0xA2, 0x98, 0xB9, 0xF9, 

    0x9F, 0x84, 0x9C, 0xFD, 0x83, 0xAD, 0xB6, 0xA9, 0xA5, 0xF5, 0x8C, 0xA7, 0x9E, 0x96, 0x8A, 0xF4, 

    0x85, 0xBE, 0xA8, 0x8F, 0x86, 0xAF, 0x88, 0x9D, 0x87, 0xBF, 0xFF, 0xA1, 0x8B, 0x81, 0xA0, 0xAB, 

    0x8E, 0xBD, 0xB5, 0xAA, 0x82, 0x94, 0xA4, 0x8D, 0xA3, 0xF8, 0xB4, 0xFA, 0x9B, 0xA6, 0xB8, 0x80

};

unsigned char g_result[80] = {

    0x02, 0x02, 0x00, 0x03, 0x00, 0x00, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x02, 0x00, 0x00, 0x02, 

    0x02, 0x00, 0x02, 0x02, 0x02, 0x03, 0x02, 0x03, 0x01, 0x00, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 

    0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x01, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 

    0x02, 0x02, 0x00, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 

    0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x02, 0x03, 0x00, 0x02, 0x01, 0x00, 0x00, 0x03

};

void encode(unsigned char *lpKey,unsigned char *lpOut,unsigned int len)

{

    unsigned int v8; // esi@1

    unsigned int v16; // ecx@13

    unsigned char *v17; // edi@14

    unsigned int v18; // eax@15

    unsigned int v19; // eax@17

    unsigned int v20; // ecx@17

    bool v21; // zf@18

    unsigned char v22; // al@18

    unsigned char v23; // bl@19

    bool v24; // sf@21

    unsigned int v25; // edi@23

    char v26; // al@27

    unsigned int v32; // [sp-Ch] [bp-Ch]@1

    unsigned char *t;

    unsigned int v34;

    unsigned int v35;

    v8 = (unsigned int)g_table;

    v16 = 0;

    v17 = lpOut;

    t = v17;

    v34 = 0;

    v35 = 0;

    while ( 1 )

    {

        v18 = (unsigned int)lpKey;

        v32 = v16 + v18;

        v19 = (unsigned int)memchr((void*)v8, *(unsigned char *)(v16 + v18),sizeof(g_table));

        v20 = v19;

        if ( v19 != 0 )

        {

            v22 = v19 - v8;

            v21 = (v20 == v8);

            *v17 = v22;

            if ( v21 )

                v23 = 1;

            else

                v23 = v22;

            v24 = (v16 < 0);

            *v17 = v23;

            if ( !v24 )

            {

                v35 = v35 + 1;

                v34 = v35;

                do

                {

                    v25 = 0;

                    do

                    {

                        if ( ++v20 == (v8 + sizeof(g_table)) )

                            v20 = v8;

                        ++v25;

                    }

                    while ( v25 != (signed int)v23 / 5 + 5 );

                    v17 = t;

                    v26 = v20 - v8;

                    v21 = (v20 == v8);

                    *v17 = v26;

                    if ( v21 )

                        v23 = 1;

                    else

                        v23 = v26;

                    v34--;

                    v21 = (v34 == 0);

                    *v17 = v23;

                }

                while ( !v21 );

            }

            *v17 = *(_BYTE *)(*v17 + v8);

        }

        v16 = v16 + 1;

        ++v17;        

        t = v17;

        if ( v16 >= len )

            break;

    }

}

void HexStrToByte(const char* source, unsigned char* dest, int sourceLen)  

{  

    short i;  

    unsigned char highByte, lowByte;  

    for (i = 0; i < sourceLen; i += 2)  

    {  

        highByte = toupper(source[i]);  

        lowByte  = toupper(source[i + 1]);  

        if (highByte > 0x39)  

            highByte -= 0x37;  

        else  

            highByte -= 0x30;  

        if (lowByte > 0x39)  

            lowByte -= 0x37;  

        else  

            lowByte -= 0x30;  

        dest[i / 2] = (highByte << 4) | lowByte;  

    }  

    return ;  

}  

void PrintKey(char keyTable[0x14][0x10],char *lpKey,unsigned int i,unsigned int j)

{

    if (i==0x14)

    {

    

        if (strstr(lpKey,"Pediy2017")&&strstr(lpKey,"Bwns"))   //加了这个限制,解缩减到200多个

        {

            printf("%s\n",lpKey);

        }

        

        //i=0;

    }

    else

    {

        for (int a=i;a<0x14;a++)

        {

            for (int b=0;b<0x10;b++ )

            {

                if (keyTable[a][b]!=0)

                {

                    lpKey[a] = keyTable[a][b];                    

                    PrintKey(keyTable,lpKey,a+1,0);

                }

                else

                {

                    //PrintKey(keyTable,lpKey,a+1,0);

                    return;

                }

            }            

        }

        

        

    }

}

int _tmain(int argc, _TCHAR* argv[])

{

    char szResult[260] = "";

    char szTable[] = "0123456789ABCDEF";

    int len = sizeof(g_result)/2;

    int i = 0,j=0,k=0,a=0,b=0;

    unsigned short index = 0;

    unsigned char szTemp[260] = {NULL};

    unsigned short t = 0;

    unsigned char szKey[260] = {NULL};

    unsigned char szOut[260] = {NULL};

    memset(szResult,0,sizeof(szResult));

    for (i=0;i<len;i++)

    {

        index = g_result[2*i]*4 + g_result[2*i+1];

        szResult[i] = szTable[index];        

    }

    HexStrToByte(szResult,szTemp,len);

    for (i=0;i<len/2;i++)

    {

        szTemp[i] = CROR(szTemp[i],3);

        szTemp[i] = szTemp[i] ^ 0xCC;

    }

    char  keyTable[0x14][0x10] = {NULL};

    memset(keyTable,0,sizeof(keyTable));

    for (i=0;i<len/2;i++)

    {

        printf("\n%d:",i);

        k=0;

        for (j=0;j<0x100;j++)

        {

            szKey[i] = j;

            encode(szKey,szOut,0x14);

            

            if (szOut[i] == szTemp[i])

            {

                t = szKey[i]^0xCC;

                if ((t >='0' && t <='9')||(t >='a' && t <='z')||(t >='A' && t <='Z'))

                {

                    keyTable[i][k++]=t;                    

                    printf("%c",t);

                }                

                //break;

            }

        }

        

    }

    printf("\n");

    char kk[0x20] = {NULL};

    PrintKey(keyTable,kk,0,0);

    

    return 0;

}

一打印,我的妈,有好多的解,是作者变态还是我哪里分析得不够,在这多个解找一个key,和最终加密call进行解密,然后执行,很是蛋疼,这里纠结很久,还好作者在key上面给了些提示最终在key里肉眼发现了一组可疑的key:

BwnsAtPediy2017KXIOF
BwnsAtPediy2017KXIOk
BwnsAtPediy2017KXDOF
BwnsAtPediy2017KXDOk
BwnsAtPediy2017KX9OF
BwnsAtPediy2017KX9Ok      //这个尝试了一下弹出 well done

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功