Position

看txt文件,是找到 Serial 是 76876-77776 时的 Name
用ida打开,全是乱码,没有看到有用的字符串
用od打开,找到了correct和wrong

01091CD0   .  56            push esi                                 ;  Position.<ModuleEntryPoint>
01091CD1   .  8BF1          mov esi,ecx                              ;  Position.<ModuleEntryPoint>
01091CD3   .  56            push esi                                 ;  Position.<ModuleEntryPoint>
01091CD4   .  E8 67FAFFFF   call Position.01091740
01091CD9   .  8D8E BC000000 lea ecx,dword ptr ds:[esi+0xBC]
01091CDF   .  85C0          test eax,eax
01091CE1   .  74 0D         je short Position.01091CF0
01091CE3   .  68 F4370901   push Position.010937F4                   ;  Correct!
01091CE8   .  FF15 70320901 call dword ptr ds:[<&mfc100u.#12951>]    ;  mfc100u.#12951
01091CEE   .  5E            pop esi                                  ;  kernel32.74F88484
01091CEF   .  C3            retn
01091CF0   >  68 08380901   push Position.01093808                   ;  Wrong
01091CF5   .  FF15 70320901 call dword ptr ds:[<&mfc100u.#12951>]    ;  mfc100u.#12951
01091CFB   .  5E            pop esi                                  ;  kernel32.74F88484

在ida中找到对应的函数

void __thiscall sub_401CD0(void *this)
{
  void *v1; // esi@1
  signed int v2; // eax@1
  CWnd *v3; // ecx@1

  v1 = this;
  v2 = sub_401740((int)this);
  v3 = (CWnd *)((char *)v1 + 188);
  if ( v2 )
    CWnd::SetWindowTextW(v3, L"Correct!");
  else
    CWnd::SetWindowTextW(v3, L"Wrong");
}

只要v2==1即correct,所以看v2,即看sub_401740,很长

 ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v61);// name
  v1 = 0;
  v64 = 0;
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v62);// serial
  ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t>>>(&v63);
  LOBYTE(v64) = 2;
  CWnd::GetWindowTextW(a1 + 304, &v61);         // 将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内
  if ( *(_DWORD *)(v61 - 12) == 4 )             // 长度为4
  {
    v4 = 0;
    while ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v4) >= 0x61u
         && (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v4) <= 0x7Au )// 把CString对象里的字符串中的第一个字符ASCII 值送返回来
    {
      if ( ++v4 >= 4 )                          // 四个都为字母
      {
LABEL_8:
        v5 = 0;
        while ( 1 )
        {
          if ( v1 != v5 )
          {
            v6 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v5);
            if ( (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, v1) == v6 )// 每个字母不相同
              goto LABEL_2;
          }
          if ( ++v5 >= 4 )
          {
            if ( ++v1 < 4 )
              goto LABEL_8;
            CWnd::GetWindowTextW(a1 + 420, &v62);
            if ( *(_DWORD *)(v62 - 12) != 11 || (unsigned __int16)ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 5) != 45 )// serial长度为11,第六个字符为-
              goto LABEL_2;
            v7 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, 0);// 第一个字母,第三个字母也是相同的操作
            v8 = (v7 & 1) + 5;
            v59 = ((v7 >> 4) & 1) + 5;
            v53 = ((v7 >> 1) & 1) + 5;
            v55 = ((v7 >> 2) & 1) + 5;
            v57 = ((v7 >> 3) & 1) + 5;          // 取前五位二进制。每一位加5
            v9 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v61, 1);// 第二个字母,第四个字母也是相同的操作
            v45 = (v9 & 1) + 1;
            v51 = ((v9 >> 4) & 1) + 1;
            v47 = ((v9 >> 1) & 1) + 1;
            v10 = ((v9 >> 2) & 1) + 1;
            v49 = ((v9 >> 3) & 1) + 1;          // 取前五位二进制,每一位加1
            v11 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
            itow_s(v8 + v10, v11, 0xAu, 10);    // v8+v10放到v11  第三位
            v12 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
            v13 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 0);
            v2 = &v63;
            if ( v13 == v12 )
            {
              ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
              v14 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
              itow_s(v57 + v49, v14, 0xAu, 10); // v57+v49放到v14中  第四位
              v15 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 1);
              v16 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
              v2 = &v63;
              if ( v15 == v16 )
              {
                ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
                v17 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
                itow_s(v53 + v51, v17, 0xAu, 10);// v53+v51放到v17 第五位
                v18 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 2);
                v19 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
                v2 = &v63;
                if ( v18 == v19 )
                {
                  ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
                  v20 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
                  itow_s(v55 + v45, v20, 0xAu, 10);// v55+v45放到v20中 第一位
                  v21 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v62, 3);
                  v22 = ATL::CSimpleStringT<wchar_t,1>::GetAt(&v63, 0);
                  v2 = &v63;
                  if ( v21 == v22 )
                  {
                    ATL::CSimpleStringT<wchar_t,1>::ReleaseBuffer(&v63, -1);
                    v23 = (wchar_t *)ATL::CSimpleStringT<wchar_t,1>::GetBuffer(&v63);
                    itow_s(v59 + v47, v23, 0xAu, 10);// v59+v47放到v23中 第二位

Name到Serial一共经过了3步变换:
1.取前五位ASCII并加常数5/1
2.改变顺序(逆序后将第五位放至第二位)
3.分别取两个字母的特定位置数相加逐步逆向: 0 4 2 3 1
3 4 1 0 2
每一位都经过+1和+5,所以和其实为10210-11110
提示中说了最后一个字母是’p’,处理后为00100
故第二位和是11010,位置变换后是01101,换成十进制是13,即m。

然后就看10210的可能情况有哪些,第二位为0,第三位为1,第五位为0。
所以第一位字母和第三个字母必然为x01y0
如果为第一个字符,则x01y0,x1y00,00y1x
如果为第三个字符,则y10x0,y0x01,10x0y
两个x和两个y,只能一个为1,一个为0
所以 00010 10101,00011 10100,00110 10001,00111 10000

bump
ctmp
gpmp
dqmp
不能重复所以第三个不可能。提交试一下bump正确

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值