reverse之第三更

reverse第三更

程序打开,对话框上的确定按钮一直是隐藏的,输入16个字符之后按钮会显示出来。

使用OD打开程序,搜索字符串,找到了你赢啦,“Flag就是你的口令”。

这段代码的主要作用是判断0x00571458内存里字符串的长度,如果是8就跳转到成功,所以只要使0x00571458字符串长度为8就成功了。

接下来在0x00571458处下硬件断点,废了好大功夫下好这个断点,羞愧欲死啊!!!

首先在数据窗口跟随

接下来转到表达式,00571458,选中地址的数据段,在该位置下硬件写入断点。
再次运行会出现在如下位置:

输入的16个字符经过004017C0()函数每两个字符组合为一组,例如ABCDEF1234567890变成了AB,CD,EF,12,34,56,78,90

接下来就是找关键的加密算法:

找到sub_401B80()函数

int __stdcall sub_401B80(int a1)
{
  sub_401970();
  if ( (unsigned __int8)(flag_3_ + flag_2_ + flag_1_ + flag_0_) == 71
    && (unsigned __int8)(flag_7_ + flag_6_ + flag_5_) == 3
    && (unsigned __int8)flag_0_ == flag_1_ + 68
    && flag_1_ == (unsigned __int8)flag_2_ + 2
    && (unsigned __int8)flag_2_ == (unsigned __int8)flag_3_ - 59
    && (unsigned __int8)flag_6_ == (unsigned __int8)flag_4_ + 10
    && (unsigned __int8)flag_6_ == (unsigned __int8)flag_7_ + 9
    && (unsigned __int8)flag_4_ == flag_5_ + 52 )
  {
    JUMPOUT(__CS__, 0x1947 + 0x400000);
  }
  return 0;
}

sub_401970()函数是加密过程之后就是判断输入是否正确。

首先将上面的方程组解出来,方程组分成两个部分解,flag0,1,2,3一起,flag4,5,6,7一起解。需要注意的是int8类型

flag4~flag7只有一个解

flag4=100,flag5=48,flag6=110,flag7=101

flag0~flag4有三个解

flag0=183,flag1=115,flag2=113,flag3=172
flag0=119,flag1=51,flag2=49,flag3=108
flag0=247,flag1=179,flag2=177,flag3=236

sub_401970()函数里是一个置换表,每一个输入的字符都会经过四次置换,最终进行判断。

还有一个需要注意的是在没输入之前和输入之后置换表是不一样的,运行之后是正确的置换表:

0056B0D0  63 7C 77 7B F2 6B 6F C5 30 01 67 2B FE D7 AB 76  
0056B0E0  CA 82 C9 7D FA 59 47 F0 AD D4 A2 AF 9C A4 72 C0 
0056B0F0  B7 FD 93 26 36 3F F7 CC 34 A5 E5 F1 71 D8 31 15  
0056B100  04 C7 23 C3 18 96 05 9A 07 12 80 E2 EB 27 B2 75  
0056B110  09 83 2C 1A 1B 6E 5A A0 52 3B D6 B3 29 E3 2F 84  
0056B120  53 D1 00 ED 20 FC B1 5B 6A CB BE 39 4A 4C 58 CF 
0056B130  D0 EF AA FB 43 4D 33 85 45 F9 02 7F 50 3C 9F A8  
0056B140  51 A3 40 8F 92 9D 38 F5 BC B6 DA 21 10 FF F3 D2  
0056B150  CD 0C 13 EC 5F 97 44 17 C4 A7 7E 3D 64 5D 19 73  
0056B160  60 81 4F DC 22 2A 90 88 46 EE B8 14 DE 5E 0B DB  
0056B170  E0 32 3A 0A 49 06 24 5C C2 D3 AC 62 91 95 E4 79  
0056B180  E7 C8 37 6D 8D D5 4E A9 6C 56 F4 EA 65 7A AE 08 
0056B190  BA 78 25 2E 1C A6 B4 C6 E8 DD 74 1F 4B BD 8B 8A  
0056B1A0  70 3E B5 66 48 03 F6 0E 61 35 57 B9 86 C1 1D 9E 
0056B1B0  E1 F8 98 11 69 D9 8E 94 9B 1E 87 E9 CE 55 28 DF
0056B1C0  8C A1 89 0D BF E6 42 68 41 99 2D 0F B0 54 BB 16  

通过置换表逆推flag

buf=[0x63,0x7C,0x77,0x7B,0xF2,0x6B,0x6F,0xC5,0x30,0x01,0x67,0x2B,0xFE,0xD7,0xAB,0x76,
        0xCA,0x82,0xC9,0x7D,0xFA,0x59,0x47,0xF0,0xAD,0xD4,0xA2,0xAF,0x9C,0xA4,0x72,0xC0,
        0xB7,0xFD,0x93,0x26,0x36,0x3F,0xF7,0xCC,0x34,0xA5,0xE5,0xF1,0x71,0xD8,0x31,0x15,
        0x04,0xC7,0x23,0xC3,0x18,0x96,0x05,0x9A,0x07,0x12,0x80,0xE2,0xEB,0x27,0xB2,0x75,
        0x09,0x83,0x2C,0x1A,0x1B,0x6E,0x5A,0xA0,0x52,0x3B,0xD6,0xB3,0x29,0xE3,0x2F,0x84,
        0x53,0xD1,0x00,0xED,0x20,0xFC,0xB1,0x5B,0x6A,0xCB,0xBE,0x39,0x4A,0x4C,0x58,0xCF,
        0xD0,0xEF,0xAA,0xFB,0x43,0x4D,0x33,0x85,0x45,0xF9,0x02,0x7F,0x50,0x3C,0x9F,0xA8,
        0x51,0xA3,0x40,0x8F,0x92,0x9D,0x38,0xF5,0xBC,0xB6,0xDA,0x21,0x10,0xFF,0xF3,0xD2,
        0xCD,0x0C,0x13,0xEC,0x5F,0x97,0x44,0x17,0xC4,0xA7,0x7E,0x3D,0x64,0x5D,0x19,0x73,
        0x60,0x81,0x4F,0xDC,0x22,0x2A,0x90,0x88,0x46,0xEE,0xB8,0x14,0xDE,0x5E,0x0B,0xDB,
        0xE0,0x32,0x3A,0x0A,0x49,0x06,0x24,0x5C,0xC2,0xD3,0xAC,0x62,0x91,0x95,0xE4,0x79,
        0xE7,0xC8,0x37,0x6D,0x8D,0xD5,0x4E,0xA9,0x6C,0x56,0xF4,0xEA,0x65,0x7A,0xAE,0x08,
        0xBA,0x78,0x25,0x2E,0x1C,0xA6,0xB4,0xC6,0xE8,0xDD,0x74,0x1F,0x4B,0xBD,0x8B,0x8A,
        0x70,0x3E,0xB5,0x66,0x48,0x03,0xF6,0x0E,0x61,0x35,0x57,0xB9,0x86,0xC1,0x1D,0x9E,
        0xE1,0xF8,0x98,0x11,0x69,0xD9,0x8E,0x94,0x9B,0x1E,0x87,0xE9,0xCE,0x55,0x28,0xDF,
        0x8C,0xA1,0x89,0x0D,0xBF,0xE6,0x42,0x68,0x41,0x99,0x2D,0x0F,0xB0,0x54,0xBB,0x16]
d={}
for n,item in enumerate(buf):
    d[item]=n
#buf1=[183,115,113,172,100,48,110,101]
#buf1=[247,179,177,236,100,48,110,101]
buf1=[119,51,49,108,100,48,110,101]

flag=''
for i in buf1:
    nCurrent=i
    for j in range(0,64*4):
        nCurrent=d[nCurrent]
    flag+="%02X"%nCurrent
print(flag)
有钱的捧个钱场
0%