小菜鸟一枚 发表于 2020-7-4 16:13

学破解第111天,《攻防世界reverse练习区ReverseMe-120》分析

# 学破解第111天,《攻防世界reverse练习区ReverseMe-120》分析
前言:
  一直对黑客充满了好奇,觉得黑客神秘,强大,无所不能,来论坛两年多了,天天看各位大佬发帖,自己只能做一个伸手党。也看了官方的入门视频教程,奈何自己基础太差,看不懂。自我反思之下,决定从今天(2019年6月17日)开始定下心来,从简单的基础教程开始学习,希望能从照抄照搬,到能独立分析,能独立破解。
不知不觉学习了好几个月,发现自己离了教程什么都不会,不懂算法,不懂编程。随着破解学习的深入,楼主这个半吊子迷失了自我,日渐沉迷水贴装X,不能自拔。
==========申明:从第71天楼主开始水贴装X,帖子不再具有连续性,仅供参考,后续帖子为楼主YY专用贴!!!==========

立帖为证!--------记录学习的点点滴滴

## 0x1下载程序
  1.首先查壳,显示Microsoft Visual C++ v.12 - 2013 ( E8 ),无壳。

  2.运行程序看看,随便输入信息,然后提示错误!


## 0x2调试分析
  1.丢进吾爱的OD跑起来,搜索字符串,看到提示信息
```
00401190/$55            push ebp
00401191|.8BEC          mov ebp,esp
00401193|.81EC CC000000 sub esp,0xCC
00401199|.68 C04E4100   push ReverseM.00414EC0                   ;please input your flah:
0040119E|.E8 24010000   call ReverseM.004012C7
004011A3|.6A 63         push 0x63
004011A5|.8D85 35FFFFFF lea eax,dword ptr ss:
004011AB|.C685 34FFFFFF>mov byte ptr ss:,0x0
004011B2|.6A 00         push 0x0
004011B4|.50            push eax
004011B5|.E8 E6460000   call ReverseM.004058A0
004011BA|.8D85 34FFFFFF lea eax,
004011C0|.50            push eax
004011C1|.68 D84E4100   push ReverseM.00414ED8                   ;%s
```

  2.很好,定位到关键函数00401190了,去IDA中F5一下
```
int sub_401190()
{
unsigned int v0; // edx@1
unsigned int v1; // ecx@1
__m128i v2; // xmm1@3
unsigned int v3; // esi@3
const __m128i *v4; // eax@3
__m128i v5; // xmm0@4
int v6; // eax@7
char v8; // @1
char v9; // @1
char v10; // @1
char v11; // @1
unsigned int v12; // @1

sub_4012C7("please input your flah:", v8);
v8 = 0;
memset(&v9, 0, 0x63u);
sub_401376("%s", (unsigned int)&v8);
v10 = 0;
memset(&v11, 0, 0x63u);
sub_401000(&v8, strlen(&v8));
v0 = v12;
v1 = 0;
if ( v12 )
{
    if ( v12 >= 0x10 )
    {
      v2 = _mm_load_si128((const __m128i *)&xmmword_414F20);
      v3 = v12 - (v12 & 0xF);
      v4 = (const __m128i *)&v10;
      do
      {
      v5 = _mm_loadu_si128(v4);
      v1 += 16;
      ++v4;
      _mm_storeu_si128((__m128i *)&v4[-1], _mm_xor_si128(v5, v2));
      }
      while ( v1 < v3 );
    }
    for ( ; v1 < v0; ++v1 )
      *(&v10 + v1) ^= 0x25u;
}
v6 = strcmp(&v10, "you_know_how_to_remove_junk_code");
if ( v6 )
    v6 = -(v6 < 0) | 1;
if ( v6 )
    sub_4012C7("wrong\n", v8);
else
    sub_4012C7("correct\n", v8);
sub_401416("pause");
return 0;
}
```

&emsp;&emsp;3.看看跳向失败的代码
```
if ( v6 )
    sub_4012C7("wrong\n", v8);
else
    sub_4012C7("correct\n", v8);
sub_401416("pause");
return 0;
```

也就是说v6为0,才会成功,在上面是
```
v6 = strcmp(&v10, "you_know_how_to_remove_junk_code");
if ( v6 )
    v6 = -(v6 < 0) | 1;
```

也就说v10等于you_know_how_to_remove_junk_code,v6就会等于0,然后下面两行明显是垃圾代码,而v10定义为0。

&emsp;&emsp;4.那么就只剩下下面这些代码了
```
if ( v12 )
{
    if ( v12 >= 0x10 )
    {
      v2 = _mm_load_si128((const __m128i *)&xmmword_414F20);
      v3 = v12 - (v12 & 0xF);
      v4 = (const __m128i *)&v10;
      do
      {
      v5 = _mm_loadu_si128(v4);
      v1 += 16;
      ++v4;
      _mm_storeu_si128((__m128i *)&v4[-1], _mm_xor_si128(v5, v2));
      }
      while ( v1 < v3 );
    }
    for ( ; v1 < v0; ++v1 )
      *(&v10 + v1) ^= 0x25u;
}
```
改变v10的里面内容的地方在for循环里面,不断将自身异或0x25,得到加密后的字符串,上面那段算法我还不能一下子看出来,接下来换成OD继续调试。

&emsp;&emsp;5.随便输入01234567890进行调试
```
004011C1|.68 D84E4100   push ReverseM.00414ED8                   ;%s
004011C6|.E8 AB010000   call ReverseM.00401376                   ;输入01234567890
004011CB|.6A 63         push 0x63
004011CD|.8D45 99       lea eax,dword ptr ss:
004011D0|.C645 98 00    mov byte ptr ss:,0x0
004011D4|.6A 00         push 0x0
004011D6|.50            push eax
004011D7|.E8 C4460000   call ReverseM.004058A0
004011DC|.8D8D 34FFFFFF lea ecx,                     ;取出输入的字符串存入ecx
004011E2|.83C4 24       add esp,0x24                           ;平衡堆栈
004011E5|.8D51 01       lea edx,dword ptr ds:         ;存入到edx
004011E8|>8A01          /mov al,byte ptr ds:                ;计算字符串长度
004011EA|.41            |inc ecx                                 ;ReverseM.00414EDC
004011EB|.84C0          |test al,al
004011ED|.^ 75 F9         \jnz short ReverseM.004011E8
004011EF|.2BCA          sub ecx,edx                              ;将字符串长度0xB存入ecx
004011F1|.8D85 34FFFFFF lea eax,                     ;将字符串存入eax
004011F7|.51            push ecx                                 ;ReverseM.00414EDC
004011F8|.50            push eax
004011F9|.8D55 FC       lea edx,
004011FC|.8D4D 98       lea ecx,
004011FF|.E8 FCFDFFFF   call ReverseM.00401000                   ;这个call就是加密函数
00401204|.8B55 FC       mov edx,                        ;edx的值为6
00401207|.83C4 08       add esp,0x8                              ;平衡堆栈
0040120A|.33C9          xor ecx,ecx                              ;清空ecx
0040120C|.85D2          test edx,edx                           ;判断edx是否为0
0040120E|.74 4A         je short ReverseM.0040125A
00401210|.83FA 10       cmp edx,0x10                           ;判断edx是不是小于10
00401213|.72 33         jb short ReverseM.00401248               ;这里手动改下C标志,让跳转不实现,方便我下一步分析
00401215|.66:0F6F0D 204>movq mm1,qword ptr ds:         ;%%%%%%%%%%%%%%%%H
0040121D|.8BC2          mov eax,edx                              ;将edx的值6给了ecx
0040121F|.56            push esi
00401220|.83E0 0F       and eax,0xF                              ;将edx与00001111进行与运算
00401223|.8BF2          mov esi,edx
00401225|.2BF0          sub esi,eax                              ;edx,ecx都为6,这样减esi肯定为0
00401227|.8D45 98       lea eax,
0040122A|.8D9B 00000000 lea ebx,dword ptr ds:
00401230|>f30f6f00      /movdqu xmm0,dqword ptr ds:
00401234|.83C1 10       |add ecx,0x10
00401237|.8D40 10       |lea eax,dword ptr ds:
0040123A|.66:0FEFC1   |pxor mm0,mm1
0040123E|.f30f7f40 f0   |movdqu dqword ptr ds:,xmm0
00401243|.3BCE          |cmp ecx,esi
00401245|.^ 72 E9         \jb short ReverseM.00401230
00401247|.5E            pop esi
00401248|>3BCA          cmp ecx,edx                              ;这里ecx是0x10也就是16,与6相比,大于等于跳转
0040124A|.73 0E         jnb short ReverseM.0040125A
0040124C|.8D6424 00   lea esp,dword ptr ss:
00401250|>80740D 98 25/xor byte ptr ss:,0x25
00401255|.41            |inc ecx                                 ;ReverseM.00414EDC
00401256|.3BCA          |cmp ecx,edx
00401258|.^ 72 F6         \jb short ReverseM.00401250
0040125A|>B9 DC4E4100   mov ecx,ReverseM.00414EDC                ;you_know_how_to_remove_junk_code
0040125F|.8D45 98       lea eax,                     ;典型的strcmp函数
00401262|>8A10          /mov dl,byte ptr ds:
00401264|.3A11          |cmp dl,byte ptr ds:
00401266|.75 1A         |jnz short ReverseM.00401282
00401268|.84D2          |test dl,dl
0040126A|.74 12         |je short ReverseM.0040127E
0040126C|.8A50 01       |mov dl,byte ptr ds:
0040126F|.3A51 01       |cmp dl,byte ptr ds:
00401272|.75 0E         |jnz short ReverseM.00401282
00401274|.83C0 02       |add eax,0x2
00401277|.83C1 02       |add ecx,0x2
0040127A|.84D2          |test dl,dl
0040127C|.^ 75 E4         \jnz short ReverseM.00401262
0040127E|>33C0          xor eax,eax
00401280|.EB 05         jmp short ReverseM.00401287
```
通过以上分析和IDA的最照,除了加密call以外,基本都了解了。

&emsp;&emsp;6.接下来就要去里面瞧一瞧我们输入的字符串到底怎么被处理的。
```
00401000/$55            push ebp
00401001|.8BEC          mov ebp,esp
00401003|.83EC 0C       sub esp,0xC                              ;分配3个局部变量
00401006|.53            push ebx
00401007|.56            push esi
00401008|.8B75 0C       mov esi,                        ;arg2保存的是字符串到长度0xB,也就是11
0040100B|.33DB          xor ebx,ebx                              ;清空ebx,后面是花指令
0040100D|.894D F4       mov ,ecx
00401010|.33C0          xor eax,eax
00401012|.33C9          xor ecx,ecx
00401014|.8955 F8       mov ,edx
00401017|.894D FC       mov ,ecx
0040101A|.57            push edi                                 ;上面这些是花指令???
0040101B|.85F6          test esi,esi                           ;esi为0就跳转
0040101D|.0F84 3F010000 je ReverseM.00401162
00401023|.8B7D 08       mov edi,                        ;arg1使我们输入到字符串
00401026|>33D2          /xor edx,edx                           ;清空edx
00401028|.3BC6          |cmp eax,esi                           ;比较eax和esi的值
0040102A|.73 12         |jnb short ReverseM.0040103E             ;不小于0跳转
0040102C|.8D6424 00   |lea esp,dword ptr ss:            ;取出esp寄存器中的值给esp
00401030|>803C38 20   |/cmp byte ptr ds:,0x20         ;判断edx+edi等不等于0x20,也就是32
00401034|.75 06         ||jnz short ReverseM.0040103C
00401036|.40            ||inc eax
00401037|.42            ||inc edx
00401038|.3BC6          ||cmp eax,esi
0040103A|.^ 72 F4         |\jb short ReverseM.00401030
0040103C|>3BC6          |cmp eax,esi
0040103E|>74 72         |je short ReverseM.004010B2
00401040|.8BCE          |mov ecx,esi                           ;ecx获得字符串长度
00401042|.2BC8          |sub ecx,eax                           ;ecx减去eax
00401044|.83F9 02       |cmp ecx,0x2                           ;eax和2比较
00401047|.72 0D         |jb short ReverseM.00401056            ;小于就跳走
00401049|.803C38 0D   |cmp byte ptr ds:,0xD         ;不相等就跳走
0040104D|.75 07         |jnz short ReverseM.00401056
0040104F|.807C38 01 0A|cmp byte ptr ds:,0xA
00401054|.74 50         |je short ReverseM.004010A6
00401056|>8A0C38      |mov cl,byte ptr ds:            ;再将字符串第一个字符给ecx的低8位
00401059|.80F9 0A       |cmp cl,0xA
0040105C|.74 48         |je short ReverseM.004010A6
0040105E|.85D2          |test edx,edx                            ;edx是0,不跳走
00401060|.0F85 05010000 |jnz ReverseM.0040116B
00401066|.80F9 3D       |cmp cl,0x3D                           ;0x3d是=
00401069|.75 0A         |jnz short ReverseM.00401075             ;不相等跳走
0040106B|.43            |inc ebx
0040106C|.83FB 02       |cmp ebx,0x2
0040106F|.0F87 F6000000 |ja ReverseM.0040116B
00401075|>80F9 7F       |cmp cl,0x7F                           ;0x7F是127
00401078|.0F87 ED000000 |ja ReverseM.0040116B                  ;大于就跳走
0040107E|.0FB6C9      |movzx ecx,cl                            ;将cl给ecx,字符0
00401081|.8A89 404E4100 |mov cl,byte ptr ds:       ;将0x34赋值给cl
00401087|.80F9 7F       |cmp cl,0x7F
0040108A|.0F84 DB000000 |je ReverseM.0040116B                  ;同样的比较
00401090|.80F9 40       |cmp cl,0x40
00401093|.73 08         |jnb short ReverseM.0040109D             ;不小于0跳转
00401095|.85DB          |test ebx,ebx                            ;ebx之前被清空了,这还是0
00401097|.0F85 CE000000 |jnz ReverseM.0040116B
0040109D|>8B4D FC       |mov ecx,
004010A0|.41            |inc ecx                                 ;ecx+1
004010A1|.894D FC       |mov ,ecx                     ;再将ecx给local1,也就是说ecx每次加1
004010A4|.EB 03         |jmp short ReverseM.004010A9
004010A6|>8B4D FC       |mov ecx,
004010A9|>40            |inc eax                                 ;eax每次也是加1
004010AA|.3BC6          |cmp eax,esi                           ;eax此时为1,还是小于0
004010AC|.^ 0F82 74FFFFFF \jb ReverseM.00401026                  ;这里小于0跳转
004010B2|>85C9          test ecx,ecx
004010B4|.0F84 A8000000 je ReverseM.00401162                     ;相等,这里不会跳走
004010BA|.8B75 F4       mov esi,
004010BD|.8D0C49      lea ecx,dword ptr ds:
004010C0|.8D0C4D 070000>lea ecx,dword ptr ds:         ;这是在干嘛,ecx的值为0x49
004010C7|.C1E9 03       shr ecx,0x3                              ;右移3位,值为9
004010CA|.2BCB          sub ecx,ebx
004010CC|.85F6          test esi,esi
004010CE|.0F84 A3000000 je ReverseM.00401177
004010D4|.8B55 F8       mov edx,
004010D7|.390A          cmp dword ptr ds:,ecx
004010D9|.0F82 98000000 jb ReverseM.00401177                     ;不跳走
004010DF|.33C9          xor ecx,ecx
004010E1|.C745 FC 03000>mov ,0x3                        ;将0x3给回去
004010E8|.33DB          xor ebx,ebx
004010EA|.894D 0C       mov ,ecx                        ;ecx清0
004010ED|.85C0          test eax,eax
004010EF|.74 69         je short ReverseM.0040115A
004010F1|>8A0F          /mov cl,byte ptr ds:                ;下面这一段就是在for循环处理输入的字符串了
004010F3|.80F9 0D       |cmp cl,0xD
004010F6|.74 5E         |je short ReverseM.00401156
004010F8|.80F9 0A       |cmp cl,0xA
004010FB|.74 59         |je short ReverseM.00401156
004010FD|.80F9 20       |cmp cl,0x20
00401100|.74 54         |je short ReverseM.00401156
00401102|.0FB6C9      |movzx ecx,cl
00401105|.8A91 404E4100 |mov dl,byte ptr ds:       ;读取4给dl
0040110B|.33C9          |xor ecx,ecx                           ;清空ecx
0040110D|.80FA 40       |cmp dl,0x40
00401110|.0F94C1      |sete cl                                 ;设置为false
00401113|.C1E3 06       |shl ebx,0x6                           ;将ebx左移6位
00401116|.294D FC       |sub ,ecx
00401119|.0FB6CA      |movzx ecx,dl                            ;将dl的值4给ecx
0040111C|.8B55 0C       |mov edx,                         ;arg2此时是0
0040111F|.83E1 3F       |and ecx,0x3F                            ;0x3F是?
00401122|.42            |inc edx                                 ;edx+1
00401123|.0BD9          |or ebx,ecx                              ;ebx和ecx或运算
00401125|.8955 0C       |mov ,edx
00401128|.83FA 04       |cmp edx,0x4
0040112B|.75 29         |jnz short ReverseM.00401156             ;跳走
0040112D|.8B55 FC       |mov edx,
00401130|.33C9          |xor ecx,ecx
00401132|.894D 0C       |mov ,ecx
00401135|.85D2          |test edx,edx
00401137|.74 08         |je short ReverseM.00401141
00401139|.8BCB          |mov ecx,ebx
0040113B|.C1E9 10       |shr ecx,0x10
0040113E|.880E          |mov byte ptr ds:,cl
00401140|.46            |inc esi
00401141|>83FA 01       |cmp edx,0x1
00401144|.76 08         |jbe short ReverseM.0040114E
00401146|.8BCB          |mov ecx,ebx
00401148|.C1E9 08       |shr ecx,0x8
0040114B|.880E          |mov byte ptr ds:,cl
0040114D|.46            |inc esi
0040114E|>83FA 02       |cmp edx,0x2
00401151|.76 03         |jbe short ReverseM.00401156
00401153|.881E          |mov byte ptr ds:,bl
00401155|.46            |inc esi
00401156|>47            |inc edi                                 ;edi的值+1
00401157|.48            |dec eax
00401158|.^ 75 97         \jnz short ReverseM.004010F1             ;eax的值减1
0040115A|>8B45 F8       mov eax,
0040115D|.2B75 F4       sub esi,
00401160|.8930          mov dword ptr ds:,esi
00401162|>5F            pop edi
00401163|.5E            pop esi
00401164|.33C0          xor eax,eax
00401166|.5B            pop ebx
00401167|.8BE5          mov esp,ebp
00401169|.5D            pop ebp
0040116A|.C3            retn
```

垃圾代码太多,分析的是不是有点晕头转向。

&emsp;&emsp;7.再来IDA,看看401000函数
```
signed int __usercall sub_401000@<eax>(unsigned int *a1@<edx>, _BYTE *a2@<ecx>, char *a3, unsigned int a4)
{
int v4; // ebx@1
unsigned int v5; // eax@1
int v6; // ecx@1
char *v7; // edi@2
int v8; // edx@3
bool v9; // zf@3
unsigned __int8 v10; // cl@11
char v11; // cl@16
_BYTE *v12; // esi@23
unsigned int v13; // ecx@23
unsigned int v14; // ebx@25
unsigned __int8 v15; // cl@26
char v16; // dl@29
_BYTE *v18; // @1
unsigned int *v19; // @1
int v20; // @1
unsigned int v21; // @25
int i; // @25

v4 = 0;
v18 = a2;
v5 = 0;
v6 = 0;
v19 = a1;
v20 = 0;
if ( !a4 )
    return 0;
v7 = a3;
do
{
    v8 = 0;
    v9 = v5 == a4;
    if ( v5 < a4 )
    {
      do
      {
      if ( a3 != 32 )
          break;
      ++v5;
      ++v8;
      }
      while ( v5 < a4 );
      v9 = v5 == a4;
    }
    if ( v9 )
      break;
    if ( a4 - v5 >= 2 && a3 == 13 && a3 == 10 || (v10 = a3, v10 == 10) )
    {
      v6 = v20;
    }
    else
    {
      if ( v8 )
      return -44;
      if ( v10 == 61 && (unsigned int)++v4 > 2 )
      return -44;
      if ( v10 > 0x7Fu )
      return -44;
      v11 = byte_414E40;
      if ( v11 == 127 || (unsigned __int8)v11 < 0x40u && v4 )
      return -44;
      v6 = v20++ + 1;
    }
    ++v5;
}
while ( v5 < a4 );
if ( !v6 )
    return 0;
v12 = v18;
v13 = ((unsigned int)(6 * v6 + 7) >> 3) - v4;
if ( v18 && *v19 >= v13 )
{
    v21 = 3;
    v14 = 0;
    for ( i = 0; v5; --v5 )
    {
      v15 = *v7;
      if ( *v7 != 13 && v15 != 10 && v15 != 32 )
      {
      v16 = byte_414E40;
      v21 -= v16 == 64;
      v14 = v16 & 0x3F | (v14 << 6);
      if ( ++i == 4 )
      {
          i = 0;
          if ( v21 )
            *v12++ = v14 >> 16;
          if ( v21 > 1 )
            *v12++ = BYTE1(v14);
          if ( v21 > 2 )
            *v12++ = v14;
      }
      }
      ++v7;
    }
    *v19 = v12 - v18;
    return 0;
}
*v19 = v13;
return -42;
}
```
传递了四个参数,结合前面OD的分析可知a3是我们输入的字符串,a4是字符串的长度,a2是0012FF78-0x4,a1是0012FF78-0x68,v18 = a2;v19 = a1;v7 = a3。

&emsp;&emsp;8.再来看这些值用在哪里,做了什么。
```
v13 = ((unsigned int)(6 * v6 + 7) >> 3) - v4;
if ( v18 && *v19 >= v13 )
{
    v21 = 3;
    v14 = 0;
    for ( i = 0; v5; --v5 )//v5是字符串的长度,一直-1操作
    {
      v15 = *v7;//注意了v7这个字符串的第一个字符给了v15
      if ( *v7 != 13 && v15 != 10 && v15 != 32 )//这是在干啥?
      {
      v16 = byte_414E40;//一串类似密码表的东西,以0x7F开头,字符不可见>?456789:;<=@',0
      v21 -= v16 == 64;//v16是密码表中第v15+1个字符,64是@符号
      v14 = v16 & 0x3F | (v14 << 6);取v16后六位,v14的前两位给v14
      if ( ++i == 4 )//判断i等不等于4,同时i++,每次取4个字符,然后依次赋值给v12的三个字符
      {
          i = 0;//每循环4次,i的值清零
          if ( v21 )//如果v21 = 1
            *v12++ = v14 >> 16;//将v14右移16位赋值给*v12,同时v12指针右移一位
          if ( v21 > 1 )//如果v21 > 1
            *v12++ = BYTE1(v14);//直接将V14给*v12,同时v12指针右移一位
          if ( v21 > 2 )//如果v21 > 2
            *v12++ = v14;直接将v14的值给*v12,同时v12指针右移一位
      }
      }
      ++v7;//字符串指针右移一位
    }
    *v19 = v12 - v18;
    return 0;
}
```

&emsp;&emsp;9.这怎么特别的像base64解密的过程呢?

## 0x3尝试编写算法
&emsp;&emsp;1.思路,我输入的字符串通过base64解密,然后异或0x25等于"you_know_how_to_remove_junk_code"这个字符串,就说明我输入的字符串是正确的flag,那么我可以反其道而行之,输入这个比较的字符串,然后异或25,接着进行base64加密不就可以得到flag了吗?

&emsp;&emsp;2.编写程序,成功得到flag:XEpQek5LSlJ6TUpSelFKeldASEpTQHpPUEtOekZKQUA=,具体base64编码解码实现函数:(https://www.52pojie.cn/thread-1212431-1-1.html)。
```
int main()
{
        char str1 = "you_know_how_to_remove_junk_code";
        char str2;

        for (int i = 0; i < strlen(str1); i++)
        {
                *(str1 + i) ^= 0x25;
        }

        encodeBase64(str1, strlen(str1), str2, strlen(str2));
        cout << str2 << endl;
       
        system("pause");
        return 0;
}
```

&emsp;&emsp;3.IDA F5的效果不太好,差点错过了401000函数,最后还是贴一张成功图,高兴一下。


## 0x4总结
&emsp;&emsp;1.论坛编辑器会自动把识别成斜体,还好我用的是c++有指针可以用*操作。

&emsp;&emsp;2.调试果然不能全靠IDA的F5,压根就没识别到在哪调用的401000函数,结合OD,到了调用这个函数,然后再去IDA分析。

&emsp;&emsp;3.听说IDA也能动态调试,我不会,只能碰到入栈参数和函数调用去OD中调试看,然后再回IDA分析。

&emsp;&emsp;4.不懂汇编,完全不能区分哪些是垃圾指令,只能靠猜。

&emsp;&emsp;5.只有了解算法的实现原理,最好能体验一把算法的实现,结合反汇编代码,才能更好的分析算法。


总结:楼主是个小菜鸟,离了教程啥都不会!

小菜鸟一枚 发表于 2020-7-5 12:18

1933420530 发表于 2020-7-5 12:14
膜拜大佬,能不能教我,

https://www.52pojie.cn/thread-1208234-1-1.html来,跟着我从第一天学,或者你自己搜索论坛零基础教程,选择合适自己的入门。:lol

vrvree 发表于 2020-7-5 11:17



问一下楼主学破解的话   一般多少时间之内才有起色{:301_1003:}

guide 发表于 2020-7-4 16:35

大佬大佬

ミм謌 发表于 2020-7-4 16:55

只要努力肯专一定会成功的加油!

volcanocan 发表于 2020-7-4 17:59

加油加油!!!

liu5653250 发表于 2020-7-4 19:05

厉害厉害,比我强!哈哈

小马驾到 发表于 2020-7-4 19:06

{:1_921:}加油加油

nut1999 发表于 2020-7-4 21:05

加油,奥里给

0319yang 发表于 2020-7-4 21:34

坚持,一定胜利✌

wangxd 发表于 2020-7-4 21:53

坚持,一定胜利✌

liehuo2012 发表于 2020-7-4 22:08

楼主的毅力不错,继续努力吧,一定会胜利的,加油!
页: [1] 2 3 4 5
查看完整版本: 学破解第111天,《攻防世界reverse练习区ReverseMe-120》分析