首页
社区
课程
招聘
[原创]程序逆向技术之三流程控制
发表于: 2008-2-29 17:20 12552

[原创]程序逆向技术之三流程控制

2008-2-29 17:20
12552

很不容易,又来写字了,很不喜欢敲字,不知道为什么,今天就给大家说说逆向里的流程控制,说白了就是if和switch,

for和while之间的事,今天很想给大家说很多,但是苦于语言很差,就简单明了点,跟前一篇来讲,这一篇比较难点,但是对于曾经

的我来说已经是啃不动的骨头了,当10多天的耐心钻研后,我已经能在ASM和C++之间任意游走了,但是我现在只差的是耐心和经验。

当我看到ASM时,我就想到了C++,虽然不一定编译后的结果和所看到的一样,而我接近正确的代码是越来越近,准确率也比以前搞了

1个百分点,这对于我来说已经是进步了,毕竟做为一个典型的菜鸟,我无法解释我的智力为什么比平常人要少很多,但是我可以解

释的是在努力后,我的收获却比平常人多,那大概是我的努力比较多或者来说这叫???????。
        慢慢的苦傲总是一种痛苦,看着ASM的语句,突然发现一句变两句时,才记得自己已经需要休息了,虽然本本带给我的快乐

是那么的少,我已经很荣幸、很满足了。但是它送给我的辐射让我知道,面对它不只是要带眼镜的问题,还有退化细胞的强力功效,

如果想慢性自杀,那是最好的药了。今天精神状况不佳,没心思罗列条理,我就用一个例子说明吧~,大概是杀蚂蚁杀多了吧,电脑

渐渐表现的不稳定,让我觉得不能再懒了,需要动手了,大开杀戒。当然,我没心思手动搞了,那瑞星、金山、卡巴过了一遍。我很

荣幸的是基本上解决了,我不用在亲自动手了。或许依然在我的电脑里,我就不管了,随它去吧~~~~。实在没那么多的时间和精力去

做那么无聊的事。........
        对于学习是要有耐心的,我特意从茫茫代码中找了一段比较典型的代码,虽然比较多但是很容易说明问题的答案,我们来看

看:
//-------------------------------------------------------------------------------------
00411EF0  /$  55            push    ebp
00411EF1  |.  8BEC          mov     ebp, esp
00411EF3  |.  81EC B0000000 sub     esp, 0B0
00411EF9  |.  53            push    ebx
00411EFA  |.  56            push    esi
00411EFB  |.  57            push    edi
00411EFC  |.  C605 2845E600>mov     byte ptr [E64528], 0               ;这里表示有个全局变量被声明了
00411F03  |>  A1 9045E600   /mov     eax, dword ptr [E64590]           ;根据函数就可以知道
00411F08  |.  50            |push    eax                               ;
00411F09  |.  E8 A1980400   |call    0045B7AF                          ;call fgetc,根据函数我们就知道EAX为FILE指针
00411F0E  |.  83C4 04       |add     esp, 4
00411F11  |.  8845 FC       |mov     byte ptr [ebp-4], al              ;AL为读取到的字节,放入的是局部变量
00411F14  |.  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]             ;
//======================================================================
这里说明一下,在我逆的时候发现了一个很好玩的规律:
有符号类型转换为MOVSX,无符号类型转换为AND,怎么理解呢?
我来举个例子:
char cc=0x00;
int  ii=(int)cc;

//----------------------
mov     byte ptr [ebp-4], 0
movsx   eax, byte ptr [ebp-4]
mov     dword ptr[ebp-8],eax
//----------------------

BYTE byte=0x00;
int  ii=(int)byte;

//----------------------
mov     byte ptr [ebp-4], 0
mov     eax, byte ptr [ebp-4]
and     eax, 0xFF
mov     dword ptr[ebp-8],eax
//----------------------

看的明白了吧,在转换的时候方法是不一样的,所以BYTE和char是不完全一样的哦,以后别混淆了.
//======================================================================
00411F18  |.  83F9 FF       |cmp     ecx, -1                    ;这里一看就知道byte ptr [ebp-4]为char类型不是BYTE
00411F1B  |.  75 0A         |jnz     short 00411F27
00411F1D  |.  B8 02000000   |mov     eax, 2                     ;EAX在函数里通常被规定为返回值,也就是这个函数是有
00411F22  |.  E9 A2020000   |jmp     004121C9                   ;返回值2的,可以断定这个函数为int类型
00411F27  |>  0FBE55 FC     |movsx   edx, byte ptr [ebp-4]
00411F2B  |.  83FA 2F       |cmp     edx, 2F                    ;判断0x2F,判断为if(XX==XX)才会出现不等于.
00411F2E  |.  75 37         |jnz     short 00411F67
00411F30  |.  A1 9045E600   |mov     eax, dword ptr [E64590]
00411F35  |.  50            |push    eax
00411F36  |.  E8 74980400   |call    0045B7AF                    ;fgetc
00411F3B  |.  83C4 04       |add     esp, 4
00411F3E  |.  8845 FC       |mov     byte ptr [ebp-4], al
00411F41  |.  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]
00411F45  |.  83F9 2F       |cmp     ecx, 2F
00411F48  |.  75 1D         |jnz     short 00411F67
00411F4A  |>  8B15 9045E600 |/mov     edx, dword ptr [E64590]
00411F50  |.  52            ||push    edx
00411F51  |.  E8 59980400   ||call    0045B7AF                    ;fgetc
00411F56  |.  83C4 04       ||add     esp, 4
00411F59  |.  8845 FC       ||mov     byte ptr [ebp-4], al
00411F5C  |.  0FBE45 FC     ||movsx   eax, byte ptr [ebp-4]
00411F60  |.  83F8 0A       ||cmp     eax, 0A
00411F63  |.  74 02         ||je      short 00411F67
00411F65  |.^ EB E3         |\jmp     short 00411F4A
00411F67  |>  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]
00411F6B  |.  51            |push    ecx
00411F6C  |.  E8 56960400   |call    0045B5C7                    ;isspace
00411F71  |.  83C4 04       |add     esp, 4
00411F74  |.  85C0          |test    eax, eax
00411F76  |.^ 75 8B         \jnz     short 00411F03
//===================================================================
for和while的区别就是for在循环的时候都是jmp来跳转而while通常都是如jnz,je,jg,jl等等.
上面的汇编一看就是do..while循环,于是我把它的逻辑流程写出来:
////////////////////////////////////////////////////////////////////////
        do{
                XXXX=fgetc(XXXX);  //返回的值放入char类型变量
                if(XXXX==-1){return 2;}
                if(XXXX==0x2F)
                {
                        XXXX=fgetc(XXXX);
                        if(XXXX==0x2F)
                        {
                                for(;XXXX!=0x0A&&XXXX!=-1;){XXXX=fgetc(XXXX);}
                                if(XXXX==-1){return 2;}
                        }
                }

        }while(::isspace(XXXX)!=0);
/////////////////////////////////////////////////////////////////////
我编译后和原来汇编代码完全一样,不知道大家试了会不会有差别.
下面来说一点规律:
if(a==b)
//------------------------
JNZ XXXXXXXX
JMP XXXXXXXX
//------------------------

if(a!=b)
//-------------------------
JE  XXXXXXXX
JMP XXXXXXXX
//-------------------------

有符号:
jle:>
jge:<
jl :>=
jg :<=
...
(注:无符号类似)

在&&和||中的逻辑条件也是不一样的,大家可以试试.总的来说,只要是汇编里的和C++里的刚好是反的,碰到||又就是一样的.
//===================================================================

00411F78  |.  0FBE55 FC     movsx   edx, byte ptr [ebp-4]
00411F7C  |.  8955 90       mov     dword ptr [ebp-70], edx
00411F7F  |.  8B45 90       mov     eax, dword ptr [ebp-70]
00411F82  |.  83E8 22       sub     eax, 22
00411F85  |.  8945 90       mov     dword ptr [ebp-70], eax
00411F88  |.  837D 90 5B    cmp     dword ptr [ebp-70], 5B
00411F8C  |.  0F87 80010000 ja      00412112
00411F92  |.  8B55 90       mov     edx, dword ptr [ebp-70]
00411F95  |.  33C9          xor     ecx, ecx
00411F97  |.  8A8A F0214100 mov     cl, byte ptr [edx+4121F0]
00411F9D  |.  FF248D D02141>jmp     dword ptr [ecx*4+4121D0]
//=====================================================================
看到这样的代码,大家觉得会是什么呢?C++怎么写才会是这样呢?实际很简单:
switch(XXX)
{
        case XXXX:
        ....
        default :
        {....}
}
这样的代码就是会被编译成上面的那种形式.
sub     eax, 22说明在这个判断里最小的值为0x22
cmp     dword ptr [ebp-70], 5B说明最大值为0x22+0x5B=0x7D
我们怎么知道有多少项呢?怎么知道每项应该多少呢??
实际我们可以看数组:
mov     cl, byte ptr [edx+4121F0]中的0x004121F0处为:
004121F0  00 01 07 07 07 07 07 07 07 07 02 03 03 07 03 03  .
00412200  03 03 03 03 03 03 03 03 07 04 07 07 07 07 07 07  
00412210  07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07  
00412220  07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07  
00412230  07 07 07 07 07 07 07 07 07 07 07 07 07 07 07 07  
00412240  07 07 07 07 07 07 07 07 07 05 07 06 CC CC CC CC  烫烫

根据上面的分析,我们知道总计处理了8项即0-7为8.
而0x004121D0处为8个地址
004121D0   9D 20 41 00 A4 1F 41 00 CC 1F 41 00 08 20 41 00  ?A.?A.?A. A.
004121E0   B8 1F 41 00 E0 1F 41 00 F4 1F 41 00 12 21 41 00  ?A.?A.?A.!A.

根据汇编代码不难看出来,上面的8个地址代表case处理的8处代码.我们可以很容易的知道
0x004121F0为对应case 0x22,我们依次找出对应为:
F0-22 F1-23 F2-24 F3-25 F4-26 F5-27 F6-28 F7-29 F8-2A F9-2B FA-2C FB-2D FC-2E FD-2F FE-30 FF-31
....
可以推断处理方式为22,23,2C,39,3B,7B,7D为处理不同,其它都是第7种处理也就是default,在对应排序的表中是按从小到大的排,在

代码中是按源代码的编写来排,于是整理为下面代码:
        switch((int)ibuf)
        {
        case 0x23:    //处理对应1
                {
                        ...
                }
        case 0x3B:    //处理对应4
                {
                        ...
                }
        case 0x2C:    //处理对应2
                {
                        ...
                }
        case 0x7B:    //处理对应5
                {
                        ...
                }
        case 0x7D:    //处理对应6
                {
                        ...
                }
        case 0x2D:
        case 0x2E:
        case 0x30:
        case 0x31:
        case 0x32:
        case 0x33:
        case 0x34:
        case 0x35:
        case 0x36:
        case 0x37:
        case 0x38:
        case 0x39:    //处理对应3
                {
                        ...
                }
        case 0x22:    //处理对应0
                {
                        ...
                }
        default:      //处理对应7
                {
                        ....
                }
}
//=====================================================================
00411FA4  |>  C705 2445E600>mov     dword ptr [E64524], 23      ;case 0x23
00411FAE  |.  A1 2445E600   mov     eax, dword ptr [E64524]
00411FB3  |.  E9 11020000   jmp     004121C9
00411FB8  |>  C705 2445E600>mov     dword ptr [E64524], 3B     ;case 0x3B
00411FC2  |.  A1 2445E600   mov     eax, dword ptr [E64524]
00411FC7  |.  E9 FD010000   jmp     004121C9
00411FCC  |>  C705 2445E600>mov     dword ptr [E64524], 2C      ;case 0x2C
00411FD6  |.  A1 2445E600   mov     eax, dword ptr [E64524]
00411FDB  |.  E9 E9010000   jmp     004121C9
00411FE0  |>  C705 2445E600>mov     dword ptr [E64524], 7B        ;case 0x7B
00411FEA  |.  A1 2445E600   mov     eax, dword ptr [E64524]
00411FEF  |.  E9 D5010000   jmp     004121C9
00411FF4  |>  C705 2445E600>mov     dword ptr [E64524], 7D         ;case  0x7D
00411FFE  |.  A1 2445E600   mov     eax, dword ptr [E64524]
00412003  |.  E9 C1010000   jmp     004121C9
00412008  |>  A1 9045E600   mov     eax, dword ptr [E64590]   ;case 0x39
0041200D  |.  50            push    eax
0041200E  |.  0FBE4D FC     movsx   ecx, byte ptr [ebp-4]
00412012  |.  51            push    ecx
00412013  |.  E8 D3970400   call    0045B7EB                  ;ungetc()
00412018  |.  83C4 08       add     esp, 8
0041201B  |.  8D55 94       lea     edx, dword ptr [ebp-6C]
0041201E  |.  8955 F8       mov     dword ptr [ebp-8], edx
00412021  |>  A1 9045E600   /mov     eax, dword ptr [E64590]
00412026  |.  50            |push    eax
00412027  |.  E8 B4970400   |call    0045B7E0                 ;fgetc()
0041202C  |.  83C4 04       |add     esp, 4
0041202F  |.  8845 FC       |mov     byte ptr [ebp-4], al
00412032  |.  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]
00412036  |.  83F9 FF       |cmp     ecx, -1
00412039  |.  74 36         |je      short 00412071
0041203B  |.  0FBE55 FC     |movsx   edx, byte ptr [ebp-4]
0041203F  |.  83FA 2E       |cmp     edx, 2E
00412042  |.  74 1A         |je      short 0041205E
00412044  |.  0FBE45 FC     |movsx   eax, byte ptr [ebp-4]
00412048  |.  50            |push    eax
00412049  |.  E8 24950400   |call    0045B572                    ;isdigit()
0041204E  |.  83C4 04       |add     esp, 4
00412051  |.  85C0          |test    eax, eax
00412053  |.  75 09         |jnz     short 0041205E
00412055  |.  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]
00412059  |.  83F9 2D       |cmp     ecx, 2D
0041205C  |.  75 13         |jnz     short 00412071
0041205E  |>  8B55 F8       |mov     edx, dword ptr [ebp-8]
00412061  |.  8A45 FC       |mov     al, byte ptr [ebp-4]
00412064  |.  8802          |mov     byte ptr [edx], al
00412066  |.  8B4D F8       |mov     ecx, dword ptr [ebp-8]
00412069  |.  83C1 01       |add     ecx, 1
0041206C  |.  894D F8       |mov     dword ptr [ebp-8], ecx
0041206F  |.^ EB B0         \jmp     short 00412021
00412071  |>  8B55 F8       mov     edx, dword ptr [ebp-8]
00412074  |.  C602 00       mov     byte ptr [edx], 0
00412077  |.  8D45 94       lea     eax, dword ptr [ebp-6C]
0041207A  |.  50            push    eax
0041207B  |.  E8 D8960400   call    0045B758                   ;atof()
00412080  |.  83C4 04       add     esp, 4
00412083  |.  D91D 8C45E600 fstp    dword ptr [E6458C]
//=================================================
TokenNumber=(float)atof((char*)&dwUnk);   //float为fstp    dword ptr [E6458C]
//double为fstp    qword ptr [E6458C]
//=================================================
00412089  |.  C705 2445E600>mov     dword ptr [E64524], 1
00412093  |.  A1 2445E600   mov     eax, dword ptr [E64524]
00412098  |.  E9 2C010000   jmp     004121C9
0041209D  |>  C745 F8 2845E>mov     dword ptr [ebp-8], 00E64528   ;case 0x22
004120A4  |>  8B0D 9045E600 /mov     ecx, dword ptr [E64590]
004120AA  |.  51            |push    ecx
004120AB  |.  E8 30970400   |call    0045B7E0                         ;fgetc()
004120B0  |.  83C4 04       |add     esp, 4
004120B3  |.  8845 FC       |mov     byte ptr [ebp-4], al
004120B6  |.  0FBE55 FC     |movsx   edx, byte ptr [ebp-4]
004120BA  |.  83FA FF       |cmp     edx, -1
004120BD  |.  74 1C         |je      short 004120DB
004120BF  |.  0FBE45 FC     |movsx   eax, byte ptr [ebp-4]
004120C3  |.  83F8 22       |cmp     eax, 22
004120C6  |.  74 13         |je      short 004120DB
004120C8  |.  8B4D F8       |mov     ecx, dword ptr [ebp-8]
004120CB  |.  8A55 FC       |mov     dl, byte ptr [ebp-4]
004120CE  |.  8811          |mov     byte ptr [ecx], dl
004120D0  |.  8B45 F8       |mov     eax, dword ptr [ebp-8]
004120D3  |.  83C0 01       |add     eax, 1
004120D6  |.  8945 F8       |mov     dword ptr [ebp-8], eax
004120D9  |.^ EB C9         \jmp     short 004120A4                       ;判断为for循环
004120DB  |>  0FBE4D FC     movsx   ecx, byte ptr [ebp-4]
004120DF  |.  83F9 22       cmp     ecx, 22
004120E2  |.  74 14         je      short 004120F8
004120E4  |.  8B15 9045E600 mov     edx, dword ptr [E64590]
004120EA  |.  52            push    edx
004120EB  |.  0FBE45 FC     movsx   eax, byte ptr [ebp-4]
004120EF  |.  50            push    eax
004120F0  |.  E8 F6960400   call    0045B7EB                        ;ungetc()
004120F5  |.  83C4 08       add     esp, 8
004120F8  |>  8B4D F8       mov     ecx, dword ptr [ebp-8]
004120FB  |.  C601 00       mov     byte ptr [ecx], 0
004120FE  |.  C705 2445E600>mov     dword ptr [E64524], 0    ;返回0
00412108  |.  A1 2445E600   mov     eax, dword ptr [E64524]
0041210D  |.  E9 B7000000   jmp     004121C9
00412112  |>  0FBE55 FC     movsx   edx, byte ptr [ebp-4]            ;default:
00412116  |.  52            push    edx
00412117  |.  E8 D8930400   call    0045B4F4                       ;isalpha()
0041211C  |.  83C4 04       add     esp, 4
0041211F  |.  85C0          test    eax, eax
00412121  |.  0F84 93000000 je      004121BA
00412127  |.  C745 F8 2845E>mov     dword ptr [ebp-8], 00E64528
0041212E  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
00412131  |.  8A4D FC       mov     cl, byte ptr [ebp-4]
00412134  |.  8808          mov     byte ptr [eax], cl
00412136  |.  8B55 F8       mov     edx, dword ptr [ebp-8]
00412139  |.  83C2 01       add     edx, 1
0041213C  |.  8955 F8       mov     dword ptr [ebp-8], edx
0041213F  |>  A1 9045E600   /mov     eax, dword ptr [E64590]
00412144  |.  50            |push    eax
00412145  |.  E8 96960400   |call    0045B7E0                       ;fgetc()
0041214A  |.  83C4 04       |add     esp, 4
0041214D  |.  8845 FC       |mov     byte ptr [ebp-4], al
00412150  |.  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]
00412154  |.  83F9 FF       |cmp     ecx, -1
00412157  |.  74 36         |je      short 0041218F
00412159  |.  0FBE55 FC     |movsx   edx, byte ptr [ebp-4]
0041215D  |.  83FA 2E       |cmp     edx, 2E
00412160  |.  74 1A         |je      short 0041217C
00412162  |.  0FBE45 FC     |movsx   eax, byte ptr [ebp-4]
00412166  |.  83F8 5F       |cmp     eax, 5F
00412169  |.  74 11         |je      short 0041217C
0041216B  |.  0FBE4D FC     |movsx   ecx, byte ptr [ebp-4]
0041216F  |.  51            |push    ecx
00412170  |.  E8 A2940400   |call    0045B617                  ;isalnum()
00412175  |.  83C4 04       |add     esp, 4
00412178  |.  85C0          |test    eax, eax
0041217A  |.  74 13         |je      short 0041218F
0041217C  |>  8B55 F8       |mov     edx, dword ptr [ebp-8]
0041217F  |.  8A45 FC       |mov     al, byte ptr [ebp-4]
00412182  |.  8802          |mov     byte ptr [edx], al
00412184  |.  8B4D F8       |mov     ecx, dword ptr [ebp-8]
00412187  |.  83C1 01       |add     ecx, 1
0041218A  |.  894D F8       |mov     dword ptr [ebp-8], ecx
0041218D  |.^ EB B0         \jmp     short 0041213F                          ;判断为for循环
0041218F  |>  8B15 9045E600 mov     edx, dword ptr [E64590]
00412195  |.  52            push    edx
00412196  |.  0FBE45 FC     movsx   eax, byte ptr [ebp-4]
0041219A  |.  50            push    eax
0041219B  |.  E8 4B960400   call    0045B7EB                      ;ungetc()
004121A0  |.  83C4 08       add     esp, 8
004121A3  |.  8B4D F8       mov     ecx, dword ptr [ebp-8]
004121A6  |.  C601 00       mov     byte ptr [ecx], 0
004121A9  |.  C705 2445E600>mov     dword ptr [E64524], 0
004121B3  |.  A1 2445E600   mov     eax, dword ptr [E64524]      ;返回0
004121B8  |.  EB 0F         jmp     short 004121C9
004121BA  |>  C705 2445E600>mov     dword ptr [E64524], 3C   ;返回3C
004121C4  |.  A1 2445E600   mov     eax, dword ptr [E64524]
004121C9  |>  5F            pop     edi
004121CA  |.  5E            pop     esi
004121CB  |.  5B            pop     ebx
004121CC  |.  8BE5          mov     esp, ebp
004121CE  |.  5D            pop     ebp
004121CF  \.  C3            retn

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

上面的代码很是简单了,前面我已经把重要的说了,我想后面不用说也呢看懂了.
我自己对上面代码逆向为下:
//-------------------------------------------------------------------------------------

int  GetToken()
{
        char    ibuf;
        *TokenString=NULL;      //这样是和BYTE TokenString=0编译后是一样的代码,所以要看整体区分.

        do{
                ibuf=fgetc(SMDFile);
                if((int)ibuf==-1){return 2;}

                if((int)ibuf==0x2F)
                {
                        ibuf=fgetc(SMDFile);
                        if((int)ibuf==0x2F)
                        {
                                for(;(int)ibuf!=0x0A&&(int)ibuf!=-1;)
                                {
                                                ibuf=fgetc(SMDFile);
                                }
                                if((int)ibuf==-1){return 2;}
                        }
                }

        }while(::isspace(ibuf)!=0);

        BYTE    *pbyte;
        switch((int)ibuf)
        {
        case 0x23:
                {
                        CurrentToken=0x23;
                        return CurrentToken;
                }
        case 0x3B:
                {
                        CurrentToken=0x3B;
                        return CurrentToken;
                }
        case 0x2C:
                {
                        CurrentToken=0x2C;
                        return CurrentToken;
                }
        case 0x7B:
                {
                        CurrentToken=0x7B;
                        return CurrentToken;
                }
        case 0x7D:
                {
                        CurrentToken=0x7D;
                        return CurrentToken;
                }
        case 0x2D:
        case 0x2E:
        case 0x30:
        case 0x31:
        case 0x32:
        case 0x33:
        case 0x34:
        case 0x35:
        case 0x36:
        case 0x37:
        case 0x38:
        case 0x39:
                {
                        DWORD   dwUnk;    //不推荐变量不初始化,而根据汇编逆了以后发现源代码BUG
                        ::ungetc((int)ibuf,SMDFile);
                        pbyte=(PBYTE)&dwUnk;

                        for(;;)
                        {
                                ibuf=fgetc(SMDFile);
                                if((int)ibuf!=-1){
                                        if((int)ibuf!=0x2E){
                                                if(::isdigit((int)ibuf)==0&&(int)ibuf!=0x2D){break;}  //这里编译后多个JMP,想想取掉它,不难.
                                        }
                                        *pbyte=(BYTE)ibuf;
                                        pbyte++;
                                        continue;
                                }
                                break;
                        }
                        *pbyte=0;
                        TokenNumber=(float)atof((char*)&dwUnk);
                        CurrentToken=1;
                        return CurrentToken;
                }
        case 0x22:
                {
                        pbyte=(PBYTE)TokenString;   //TokenString为指针,不要处理成字节,字节和指针很容易分辨,第一次,不注意搞错了.

                        for(;;)
                        {
                                ibuf=fgetc(SMDFile);
                                if((int)ibuf!=-1&&(int)ibuf!=0x22)
                                {
                                        *pbyte=(BYTE)ibuf;
                                        pbyte++;
                                        continue;
                                }
                                break;
                        }
                        if((int)ibuf!=0x22)
                        {
                                ::ungetc((int)ibuf,SMDFile);
                        }
                        *pbyte=0;
                        CurrentToken=0;
                        return CurrentToken;
                }
        default:
                {
                        if(::isalpha(ibuf)!=0)
                        {
                                pbyte=(PBYTE)TokenString;
                                *pbyte=(BYTE)ibuf;
                                pbyte++;

                                for(;;)   
                                {
                                        ibuf=::fgetc(SMDFile);
                                        if((int)ibuf!=-1){
                                                if((int)ibuf!=0x2E&&(int)ibuf!=0x5F){
                                                        if(::isalnum((int)ibuf)==0){break;}
                                                }
                                                *pbyte=(BYTE)ibuf;
                                                pbyte++;
                                                continue;
                                        }
                                        break;
                                }
                                ungetc((int)ibuf,SMDFile);
                                *pbyte=0;
                                CurrentToken=0;
                                return CurrentToken;
                        }
                        CurrentToken=0x3C;
                        return CurrentToken;
                }
        }

        return 0;
}

//-------------------------------------------------------------------------------------
        大家一边逆一边对对....有个问题让大家去试,当然按我逆的运行是正确的,可原版下面没JMP,而按我的代码编译后就有JMP
有心思的可以试试~~~~~~~~~~ ^_^ !
004120C6  |.  74 13         |je      short 004120DB   

                                                                           - By EasyStudy For PhantomNet


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 7
支持
分享
最新回复 (15)
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
2
占座学习。。。
2008-2-29 17:31
0
雪    币: 144
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习学习 MC大狭的文章
2008-2-29 17:58
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
4
"
实在没那么多的时间和精力去

做那么无聊的事。因为做病毒的都是为钱而做的,没要道德水准的人,怎么会有高超的水平,那些人是被我BS的对象。反来复去的前

人的技术,并没有太多的变化和进步。只是危害做的强点,让人更讨厌点,那才被荣作“高手”。也引来了一群追捧,也有羡慕的眼

光,但是靠谋害别人来得到的东西,永远只属于别人,只不过是借来用用,等到归还时,还有高昂的利息,或许那个时候,才会明白

知识是来做好事的,不是用来谋害他人的。
"

以十步笑百步罢了.
2008-2-29 20:25
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
5
嗯,学习,不过楼主研究的是debug版的程序,并非release版的程序。
例如下面这段代码

00401000  /$  51             push    ecx
00401001  |.  8D4424 00     lea     eax, dword ptr [esp]
00401005  |.  B9 A89B4000   mov     ecx, 00409BA8
0040100A  |.  50            push    eax                              ; /Arg1
0040100B  |.  E8 6F3E0000   call    00404E7F                         ; \testtst.00404E7F
00401010  |.  8B4424 00     mov     eax, dword ptr [esp]
00401014  |.  83F8 14       cmp     eax, 14
00401017  |.  74 27         je      short 00401040
00401019  |.  83F8 1E       cmp     eax, 1E
0040101C  |.  74 11         je      short 0040102F
0040101E  |.  68 58904000   push    00409058                         ;  ASCII "jiang",LF
00401023  |.  E8 38000000   call    00401060
00401028  |.  83C4 04       add     esp, 4
0040102B  |.  33C0          xor     eax, eax
0040102D  |.  59            pop     ecx
0040102E  |.  C3            retn
0040102F  |>  68 54904000   push    00409054                         ;  ASCII "30",LF
00401034  |.  E8 27000000   call    00401060
00401039  |.  83C4 04       add     esp, 4
0040103C  |.  33C0          xor     eax, eax
0040103E  |.  59            pop     ecx
0040103F  |.  C3            retn
00401040  |>  68 50904000   push    00409050                         ;  ASCII "20",LF
00401045  |.  E8 16000000   call    00401060
0040104A  |.  83C4 04       add     esp, 4
0040104D  |.  33C0          xor     eax, eax
0040104F  |.  59            pop     ecx
00401050  \.  C3            retn

对应的源码是:
int main(int argc, char* argv[])
{
        int x;
        cin >>x;
        switch(x)
        {
        case 20:
                printf("20\n");
                break;
        case 30:
                printf("30\n");
                break;
        default:
                printf("jiang\n");
        }
        return 0;
}
2008-2-29 22:17
0
雪    币: 244
活跃值: (105)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
啊?menting是MC?
出来膜拜一下,真的是MC?
2008-2-29 22:24
0
雪    币: 250
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这个精华加的好快,确实是好文章,学习了
2008-2-29 22:32
0
雪    币: 144
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
看到那什么壳的总揽篇,就想到MC了
2008-2-29 23:09
0
雪    币: 1657
活跃值: (291)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
9
[QUOTE=combojiang;422523]嗯,学习,不过楼主研究的是debug版的程序,并非release版的程序。
例如下面这段代码

00401000  /$  51             push    ecx
00401001  |.  8D4424 00     lea     eax, dword ptr [esp]
0040...[/QUOTE]

不对~~~~~~
我说的是典型,如果是2个case和多个不一样的
例如
switch(XXX)
case 1:
....
case 2:
...
case 3:
...
...
这样的和我举的例子是不一样的
我的例子是比较大众的,一般不会为2-3个去case,而不一定每个case都是顺序而来
我分析的是release版本,随着case不同代码会有变化...
2008-3-1 00:22
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
10
楼上各位都不用f5吗
2008-3-1 01:27
0
雪    币: 134
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
不错的东西,我学习了,谢谢楼主。
2008-3-1 16:11
0
雪    币: 370
活跃值: (57)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
好好学习,谢谢楼主的文章
2008-3-1 19:25
0
雪    币: 615
活跃值: (1212)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
  精品
2008-3-1 21:38
0
雪    币: 223
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
14
F5虽然好用,但是有时候出来的代码也很搞笑,流程都错了
2008-3-1 21:45
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
好文.......
2008-3-2 17:01
0
雪    币: 414
活跃值: (29)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
受教了,学习了
2008-3-11 22:40
0
游客
登录 | 注册 方可回帖
返回
//