欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]高手飘过。。。菜鸟第一次逆向一个小算法,留记号

[原创]高手飘过。。。菜鸟第一次逆向一个小算法,留记号

下了加密里面的一本书的光盘里面有个TraceMe.exe,也没去看书上怎么弄的,就因为刚看完了《C++逆向与反汇编技术解密》这本书,感觉想拿个东西练下手,就它了。很菜的,第一次分析算法,高手不笑,菜鸟学习不容易啊。
软件没加壳,OD载入后直接,查找字串。

在CPU窗口查看
在头部下断。
运行程序,发现无法运行,程序会不断调用此函数。
去掉断点,重新来过。运行程序发现输入用户名的框框。
于是用BP GetDlgitemtextA试下。
程序断在这里。单步走,查看堆栈,发现此处为取用户名和密码。


分析结果如下。以下用户名和注册码入栈后进入一个Call初步怀疑是算法Call,Call后一个跳转,测试跳转后,发现修改跳转结果,程序提示注册成功。
此时可确定些Call为算法Call。
重点分析这个Call的实现。
代码如下:


通过分析得出如下结论。
函数通过取用户输入的用户名,从第四个字符开始取,用取出字符的ASC码与依次取出的一个全局定义的整型数组项相乘,将依次的结果累加到一个局部变量中,将些作为注册码。
逆向的C代码如下。
int g_szBuffer[8]={0C,0A,13,09,0C,0B,0A,08};
int reav(char *userName,char *pass,int len)
{
  int userNameLen=len,intFlag=0,intA=0,intB=0,intC=0;
  char outBuffer[20]={0};
  if(userNameLen>=3)
  {
    
    for(int i=3;i<userNameLen;i++)
    {
      if(intFlag>7)
      {
        intFlag=0;
      }
      intA=0;
      intB=0;
      intA=userName[i];
      intB=g_szBuffer[intFlag];
      intA*=intB;
      intC+=intA;
      
      intFlag++;
      
    }  
  }
  
  wsprintf(outBuffer,"%ld",intC);  
  if(lstrcmp(outBuffer,pass)==0);
  {
    return 1;
  }
  else
  {
    return 0;
  }
  
}
顺手写出注册机
void reav(char *userName)
{
  int userNameLen=strlen(userName),intFlag=0,intA=0,intB=0,intC=0;
  char outBuffer[20]={0};
  if(userNameLen>=3||userNameLen<20)
  {
    
    for(int i=3;i<userNameLen;i++)
    {
      if(intFlag>7)
      {
        intFlag=0;
      }
      intA=0;
      intB=0;
      intA=userName[i];
      intB=g_szBuffer[intFlag];
      intA*=intB;
      intC+=intA;
      
      intFlag++;
      
    }  
  }
  else
  {
    printf("用户名不能长长度不能小于3或大于20,请重新输入");
    return;
  }
  wsprintf(outBuffer,"%ld",intC);  
  printf("正确注册码为:%d\n",intC);
}
分析完毕,第一次分析,加油!!

上传的附件 QQ截图20130805154832.jpg
CALL内部.jpg
CALL内部HOU.jpg
JE.jpg
算法CALL.jpg
GetText.jpg
字串CPU.jpg

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功