Bugku Mountain climbing

不得不说 这道题其实不算难  脱完壳 用ida查看很方便 但是感觉好久没有用过od 分析了 我就试着用了用od  分析  

这个程序被加了upx壳 用esp + 修复 就ok了 然后就可以愉快的用ida了

 

主函数的内容其实就已经够够分析了 但是我还是用了od分析 

00411B9A    6A 0C           push 0xC                                        ; 0xC
00411B9C    FF15 50214300   call dword ptr ds:[<&ucrtbased.srand>]          ; ucrtbase.srand
00411BA2    83C4 04         add esp,0x4                                     ; 上面的意思是 srand(0xC)
00411BA5    3BF4            cmp esi,esp
00411BA7    E8 7BF5FFFF     call 1__.00411127
00411BAC    68 409C0000     push 0x9C40
00411BB1    6A 00           push 0x0
00411BB3    68 803D4200     push 1__.00423D80
00411BB8    E8 06F5FFFF     call 1__.004110C3
00411BBD    83C4 0C         add esp,0xC
00411BC0    C745 88 0100000>mov dword ptr ss:[ebp-0x78],0x1                 ; 初始值是1
00411BC7    EB 09           jmp short 1__.00411BD2
00411BC9    8B45 88         mov eax,dword ptr ss:[ebp-0x78]
00411BCC    83C0 01         add eax,0x1                                     ; eax+1
00411BCF    8945 88         mov dword ptr ss:[ebp-0x78],eax                 ; ebp-0x78 +1
00411BD2    837D 88 14      cmp dword ptr ss:[ebp-0x78],0x14                ; 如果ebp-0x78 大于0x14 直接退出
00411BD6    7F 55           jg short 1__.00411C2D
00411BD8    C785 7CFFFFFF 0>mov dword ptr ss:[ebp-0x84],0x1                 ; ebp-0x84 赋值为1
00411BE2    EB 0F           jmp short 1__.00411BF3
00411BE4    8B85 7CFFFFFF   mov eax,dword ptr ss:[ebp-0x84]
00411BEA    83C0 01         add eax,0x1
00411BED    8985 7CFFFFFF   mov dword ptr ss:[ebp-0x84],eax
00411BF3    8B85 7CFFFFFF   mov eax,dword ptr ss:[ebp-0x84]                 ; 那么每次循环 就是eax初始化为1
00411BF9    3B45 88         cmp eax,dword ptr ss:[ebp-0x78]                 ; eax 大于ebp-0x78里面的值 退出
00411BFC    7F 2D           jg short 1__.00411C2B
00411BFE    8BF4            mov esi,esp
00411C00    FF15 4C214300   call dword ptr ds:[<&ucrtbased.rand>]           ; ucrtbase.rand
00411C06    3BF4            cmp esi,esp
00411C08    E8 1AF5FFFF     call 1__.00411127
00411C0D    99              cdq
00411C0E    B9 A0860100     mov ecx,0x186A0
00411C13    F7F9            idiv ecx
00411C15    6945 88 9001000>imul eax,dword ptr ss:[ebp-0x78],0x190
00411C1C    8B8D 7CFFFFFF   mov ecx,dword ptr ss:[ebp-0x84]
00411C22    899488 38A14100 mov dword ptr ds:[eax+ecx*4+0x41A138],edx       ; 从这其实就可以看出来是二位数组了 而且是int
00411C29  ^ EB B9           jmp short 1__.00411BE4
00411C2B  ^ EB 9C           jmp short 1__.00411BC9
00411C2D    68 307B4100     push 1__.00417B30                               ; input your key with your operation can get the maximum:
00411C32    E8 16F7FFFF     call 1__.0041134D
00411C37    83C4 04         add esp,0x4
00411C3A    8D45 94         lea eax,dword ptr ss:[ebp-0x6C]
00411C3D    50              push eax
00411C3E    68 747B4100     push 1__.00417B74                               ; %s
00411C43    E8 01F6FFFF     call 1__.00411249
00411C48    83C4 08         add esp,0x8
00411C4B    8D45 94         lea eax,dword ptr ss:[ebp-0x6C]
00411C4E    50              push eax
00411C4F    E8 79F4FFFF     call 1__.004110CD                               ; 求出输入的长度
00411C54    83C4 04         add esp,0x4
00411C57    83F8 13         cmp eax,0x13                                    ; 长度保存在了eax
00411C5A    74 2B           je short 1__.00411C87
00411C5C    68 787B4100     push 1__.00417B78                               ; error\n
00411C61    E8 E7F6FFFF     call 1__.0041134D
00411C66    83C4 04         add esp,0x4
00411C69    8BF4            mov esi,esp
00411C6B    68 807B4100     push 1__.00417B80                               ; pause
00411C70    FF15 48214300   call dword ptr ds:[<&ucrtbased.system>]         ; ucrtbase.system
00411C76    83C4 04         add esp,0x4
00411C79    3BF4            cmp esi,esp
00411C7B    E8 A7F4FFFF     call 1__.00411127
00411C80    33C0            xor eax,eax
00411C82    E9 41010000     jmp 1__.00411DC8
00411C87    8D45 94         lea eax,dword ptr ss:[ebp-0x6C]
00411C8A    50              push eax
00411C8B    E8 BFF4FFFF     call 1__.0041114F                               ; 改变
00411C90    83C4 04         add esp,0x4
00411C93    C785 70FFFFFF 0>mov dword ptr ss:[ebp-0x90],0x0
00411C9D    C785 7CFFFFFF 0>mov dword ptr ss:[ebp-0x84],0x1
00411CA7    8B85 7CFFFFFF   mov eax,dword ptr ss:[ebp-0x84]
00411CAD    8945 88         mov dword ptr ss:[ebp-0x78],eax
00411CB0    6945 88 9001000>imul eax,dword ptr ss:[ebp-0x78],0x190
00411CB7    8B8D 7CFFFFFF   mov ecx,dword ptr ss:[ebp-0x84]
00411CBD    8B15 783D4200   mov edx,dword ptr ds:[0x423D78]
00411CC3    039488 38A14100 add edx,dword ptr ds:[eax+ecx*4+0x41A138]
00411CCA    8915 783D4200   mov dword ptr ds:[0x423D78],edx
00411CD0    83BD 70FFFFFF 1>cmp dword ptr ss:[ebp-0x90],0x13                ; 循环 0x13
00411CD7    0F8D BF000000   jge 1__.00411D9C
00411CDD    8B85 70FFFFFF   mov eax,dword ptr ss:[ebp-0x90]
00411CE3    0FBE4C05 94     movsx ecx,byte ptr ss:[ebp+eax-0x6C]
00411CE8    83F9 4C         cmp ecx,0x4C                                    ; a0x4c ?? ascii码为 L
00411CEB    75 29           jnz short 1__.00411D16
00411CED    8B45 88         mov eax,dword ptr ss:[ebp-0x78]
00411CF0    83C0 01         add eax,0x1
00411CF3    8945 88         mov dword ptr ss:[ebp-0x78],eax                 ; ebp-0x78 值+1
00411CF6    694D 88 9001000>imul ecx,dword ptr ss:[ebp-0x78],0x190
00411CFD    8B95 7CFFFFFF   mov edx,dword ptr ss:[ebp-0x84]
00411D03    A1 783D4200     mov eax,dword ptr ds:[0x423D78]
00411D08    038491 38A14100 add eax,dword ptr ds:[ecx+edx*4+0x41A138]
00411D0F    A3 783D4200     mov dword ptr ds:[0x423D78],eax                 ; 0x423d78 应该是存储在我们值
00411D14    EB 72           jmp short 1__.00411D88
00411D16    8B85 70FFFFFF   mov eax,dword ptr ss:[ebp-0x90]
00411D1C    0FBE4C05 94     movsx ecx,byte ptr ss:[ebp+eax-0x6C]
00411D21    83F9 52         cmp ecx,0x52                                    ; 这里我并没有输入 0x52输入字符串却变化了
00411D24    75 3A           jnz short 1__.00411D60
00411D26    8B45 88         mov eax,dword ptr ss:[ebp-0x78]
00411D29    83C0 01         add eax,0x1
00411D2C    8945 88         mov dword ptr ss:[ebp-0x78],eax
00411D2F    8B8D 7CFFFFFF   mov ecx,dword ptr ss:[ebp-0x84]
00411D35    83C1 01         add ecx,0x1                                     ; 这里ebp-0x78 ebp-0x84 都+1
00411D38    898D 7CFFFFFF   mov dword ptr ss:[ebp-0x84],ecx
00411D3E    6955 88 9001000>imul edx,dword ptr ss:[ebp-0x78],0x190          ; edx=[ebp-0x78]*400
00411D45    8B85 7CFFFFFF   mov eax,dword ptr ss:[ebp-0x84]
00411D4B    8B0D 783D4200   mov ecx,dword ptr ds:[0x423D78]
00411D51    038C82 38A14100 add ecx,dword ptr ds:[edx+eax*4+0x41A138]       ; 4*(edx*100+eax)+41a138  4是字节的意思

然后改变那个函数的分析就是 

00411960    c405 8d41b887   les eax,fword ptr ds:[0x87b8418d]
00411966  ^ 79 B8           jns short 1__.00411920
00411968    17              pop ss
00411969    79 2D           jns short 1__.00411998
0041196B    8F41 B8         pop dword ptr ds:[ecx-0x48]                     ; 1__.<ModuleEntryPoint>
0041196E    2105 0404847D   and dword ptr ds:[0x7D840404],eax               ; 是每隔一位 异或一次0x4
00411974    014C87 CC       add dword ptr ds:[edi+eax*4-0x34],ecx
00411978    FA              cli
00411979    44              inc esp
0041197A    81C4 70108F41   add esp,0x418F1070
00411980    0C 07           or al,0x7

emmm  这里有个知识点 就是 如果随机种子固定的话  随机数 也是固定的 (计算机做不到真正的随机)  有时候我们会把时间作为种子 就是为了 让随机更加随机  emmm 那我们先把 随机数打印出来

77
5628 6232
29052 1558 26150
12947 29926 11981 22371
4078 28629 4665 2229 24699
27370 3081 18012 24965 2064 26890
21054 5225 11777 29853 2956 22439 3341
31337 14755 5689 24855 4173 32304 292 5344
15512 12952 1868 10888 19581 13463 32652 3409 28353
26151 14598 12455 26295 25763 26040 8285 27502 15148 4945
26170 1833 5196 9794 26804 2831 11993 2839 9979 27428 6684
4616 30265 5752 32051 10443 9240 8095 28084 26285 8838 18784 6547
7905 8373 19377 18502 27928 13669 25828 30502 28754 32357 2843 5401 10227
22871 20993 8558 10009 6581 22716 12808 4653 24593 21533 9407 6840 30369 2330
3 28024 22266 19327 18114 18100 15644 21728 17292 8396 27567 2002 3830 12564 1420
29531 21820 9954 8319 10918 7978 24806 30027 17659 8764 3258 20719 6639 23556 25786 11048
3544 31948 22 1591 644 25981 26918 31716 16427 15551 28157 7107 27297 24418 24384 32438 22224
12285 12601 13235 21606 2516 13095 27080 16331 23295 20696 31580 28758 10697 4730 16055 22208 2391 20143
16325 24537 16778 17119 18198 28537 11813 1490 21034 1978 6451 2174 24812 28772 5283 6429 15484 29353 5942
7299 6961 32019 24731 29103 17887 17338 26840 13216 8789 12474 24299 19818 18218 14564 31409 5256 31930 26804 9736

 然后到这一步 我就不知道要干什么了 参考了一下大牛们的博客 我才明白  这是让求和的   

然后注意上面还有会变化我们说的那个值 异或0x4 所以我们先求出最大和吧。。

然后最大和 的 是 RRRRRLLRRRLRLRRRLRL 下面是 c语言代码

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <fstream>
#include <climits>
#include <bitset>
#define digui 19
int ans[100000];
int as=0;
char s[20];
char ss[20];
void slove(int i,int j,int sum)
{
    if(i>digui||i<j)
    {
        return;
    }
     if(i==digui)
     {
        if(as<sum)
        {
          ss[i+1]='\0';
          as=sum;
          strcpy(s,ss);
        }
        return;
     }
     sum+=ans[i*100+j];
     ss[i]='L';
     slove(i+1,j,sum);
     ss[i]='R';
     slove(i+1,j+1,sum);
     sum-=ans[i*100+j];
}
int main()
{
    srand(0xCu);
    for(int i=0;i<20;i++)
    {
        for(int j=0;j<=i;j++)
        {
            ans[i*100 + j] = rand() % 100000;
        }
    }
    slove(0,0,0);
    printf("%s\n",s);
    return 0;
}

那么 这还没有完  因为还有一个异或 所以我们要把异或处理一下  最后结果是 

结果跑出来是 RVRVRHLVRVLVLVRVLVL

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值