人间何所以,观风|

逆世混沌

园龄:3年2个月粉丝:6关注:5

逆向-第四次实验-注册码分析升级

本次实验考虑使用到了ida

在使用ida时,用ida32而非64,否则无法查看伪代码。

打开后看到dialog,即对话框元素函数,很有可能是我们要考虑的地方,点击后F5得到伪代码。

 代码

复制代码
INT_PTR __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4)
{
  HICON IconA; // eax
  UINT DlgItemTextA; // eax
  UINT v7; // [esp-4h] [ebp-8h]

  if ( a2 == 272 )
  {
    IconA = LoadIconA(hInstance, (LPCSTR)0x1F4);
    SendMessageA(hWnd, 0x80u, 0, (LPARAM)IconA);
    return 0;
  }
  if ( a2 == 16 )
  {
LABEL_16:
    EndDialog(hWnd, 0);
    return 0;
  }
  if ( a2 != 273 )
    return 0;
  if ( a3 == 300 )
  {
    MessageBoxA(hWnd, Text, Caption, 0);
    return 0;
  }
  if ( a3 != 900 )
  {
    if ( a3 != 400 )
      return 0;
    goto LABEL_16;
  }
  DlgItemTextA = GetDlgItemTextA(hWnd, 100, String1, 300);
  if ( !DlgItemTextA )
    return MessageBoxA(0, aYourNamePlease, aOoohInputError, 0);
  v7 = DlgItemTextA;
  if ( !GetDlgItemTextA(hWnd, 200, byte_409CF8, 300) )
    return MessageBoxA(0, aWhereIsDaSeria, aOoohInputError, 0);
  lstrcatA(String1, String2);
  sub_401000(String1, v7, &unk_4056A8);
  sub_401B79();
  if ( lstrcmpA(byte_409CF8, byte_4079D0) )
  {
    MessageBoxA(0, aHmmmNotLikeThi, aFatalError, 0);
    return 0;
  }
  MessageBoxA(0, aGoodSerialNowS, aGoodWork, 0);
  return 0;
}
复制代码

 

我们解读一下,逆向的思路是从后面解读:

if ( lstrcmpA(byte_409CF8, byte_4079D0) )
  {
    MessageBoxA(0, aHmmmNotLikeThi, aFatalError, 0);
    return 0;
  }
  MessageBoxA(0, aGoodSerialNowS, aGoodWork, 0);
//这段代码指istrcmpA函数判断byte_409CF8, byte_4079D0是否相等,不相等就fail,相等在下一步就有goodserial

 

 接着来看全部的代码

复制代码
DlgItemTextA = GetDlgItemTextA(hWnd, 100, String1, 300);  
//此行从对话框hWnd的ID为100的控件中获取输入,并将其存储在String1中,最大长度为300个字符。GetDlgItemTextA()函数的返回值存储在DlgItemTextA中。
//我们大约可以猜测string1是用户名
if ( !DlgItemTextA ) return MessageBoxA(0, aYourNamePlease, aOoohInputError, 0); //如果GetDlgItemTextA()返回NULL,则显示错误消息框,提示输入名称。 v7 = DlgItemTextA; //将DlgItemTextA的值(刚获取的输入)存储到v7中。 if ( !GetDlgItemTextA(hWnd, 200, byte_409CF8, 300) ) return MessageBoxA(0, aWhereIsDaSeria, aOoohInputError, 0); //从ID为200的控件获取输入并存储在byte_409CF8中,最大长度300个字符。如果获取失败,显示另一个错误消息框。我们大约猜测byte是序列码 lstrcatA(String1, String2); //将String2中的字符串追加到String1的末尾。String1现在包含两个控件的输入值。string2可能是个额外变量不被输入 sub_401000(String1, v7, &dword_4056A8); sub_401B79(); //调用两个子例程sub_401000和sub_401B79,传入String1和v7的值,以及dword_4056A8的地址。我们不知道这两个子例程的功能。
复制代码
我们并不清楚这sub_401000和sub_401B79是什么,查询一下。

sub_401000:

 发现了四个常量,猜测为md5,

值应该运算在dword里了,因为函数没有输出,只有它有指针

sub_401B79:

复制代码
int v0; 

v0 = dword_4056A8[1]; 
//v0初始化为dword_4056A8数组的第二个元素的值。我们不知道dword_4056A8的值。

wsprintfA(byte_4079D0, "%.8X", v0 ^ dword_4056A8[0]);
//这将v0与dword_4056A8的第一个元素进行异或运算,并使用wsprintfA()将结果作为8个十六进制字符存储在byte_4079D0中。
v0 ^= 0xFBD0099u;
 
//v0与0xFBD0099u进行异或运算。这会修改v0的值。

wsprintfA(&byte_4079D0[8], "%.8X", v0); 
//然后,v0的值作为8个十六进制字符存储在byte_4079D0的第9-16个字符中。

wsprintfA(&byte_4079D0[16], "%.8X", v0 ^ dword_4056A8[2]);
//v0再与dword_4056A8的第三个元素进行异或运算,结果存储在byte_4079D0的第17-24个字符中。
 
wsprintfA(&byte_4079D0[24], "%.8X", dword_4056A8[3]); 
//最后,dword_4056A8的第四个元素的值存储在byte_4079D0的第25-32个字符中。
复制代码

 

这里也有dword也证实了我们的猜想

我们现在假设一个用户名“admin”

运行olldbg输入后找到lstrcatA,这里可以找到string2

 也就是总字符为“admin BytePtr[e!]”

然后进行

sub_401000(String1, v7, &dword_4056A8); 

sub_401B79();

然后:

我们只要找到这两个值,就可以直接拿到序列号了,因为最后的判断就这一步,前面都是计算

byte_409CF8, byte_4079D0

代码中是

lstrcmpA(byte_409CF8, byte_4079D0)

基本上找到这个函数,打个断点就好了

 

以admin和1填入之后,点击数据窗口跟随

下面的string1是我输入的数,上面是计算好的值

 

good serial

 

posted @   逆世混沌  阅读(78)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 狂迪 卢广仲
狂迪 - 卢广仲
00:00 / 00:00
An audio error has occurred.

作词 : 卢广仲/討海人/黄少雍

作曲 : 卢广仲

在我眼前消失不见

今天的什么都不对

楼下的店听见熟悉的音乐

谁离开我谁爱着我

剩下一半的小火锅

别乱牵拖直到你出现

满天星光月亮出来了

神魂颠倒这是真的吗

管不住我自己的步伐

戒不掉你致命的魔法

谁教我蜿蜒的弹跳

谁教我崎岖的舞蹈

我爱你你知不知道

OH Dónde estás Bongria

想要见面有点抱歉

下午才跟你晚上约

请放轻松看着公园的落叶

摇摇晃晃我的形状

一边海洋一边天堂

你拉着我这一步叫做永远

满天星光月亮出来了

神魂颠倒这是真的吗

管不住我自己的步伐

戒不掉你致命的魔法

谁教我蜿蜒的弹跳

谁教我崎岖的舞蹈

我爱你你知不知道

OH Dónde estás Bongria

我丢掉太多的不必要

朝着有你的方向跑

跑到你眼前逗你笑

听到电影里的配乐响起

全场只为了等你说一句

说欸你要不要跟我一起

去教堂

Yes I do希望你也一样

先说好一起永保安康

每一天蜿蜒的弹跳

每一天崎岖的舞蹈

我爱你你知不知道 OH

如果爱我让我看见你

的脚