zoukankan      html  css  js  c++  java
  • 一次VB汇编中看-溢出计算

     图文记录

     一.观察程序特点和运行逻辑

    • 带弹窗

    • 是VB开发的

    • 需要用户名和注册码

    • 有弹框 

    具备了很简单的特点……

    错误弹框,如图

     

    二.定位

    弹窗内容入手,搜索关键字定位到关键跳,nop掉或者je改jne就可以实现,即怎么输入都是正确,但不是我们的重点,直接略过

     

    三、研究算法

    1.找块入口

    从关键跳【0040258B】开始往上浏览,找到push ebp ,上面又是retn的地方(这个找多了下下断试试就有经验了),即【00402310】下断点,运行程序,输入用户名''123456",伪码"654321",程序如期断在断点处

    2.F8步过分析反汇编代码

    F8步过,关注寄存器,堆栈,注释等的变化,找到敏感函数和信息,这里找到了取字串输入内容的相关函数

    004023B6   call dword ptr ds:[eax+0xA0]             ;  msvbvm50.7407A5B6

    F8步过这个call后堆栈变化为输入的用户名"123456"

    做个标签,这里需要注意的是:对于VB的反汇编,ollydbg就会出现丢失标签的情况,所以比较操蛋,敏感的入口地址自己还是记录一下,否则重载一次标签就没了,但是注释不丢,可以注释,但是毕竟没标签类似于重命名函数来的方便、直观!

    继续F8继续走

    3.发现算法

    再继续F8发现算法部分,算法是:输入用户名长度*0x17cfb+用户名第一个字符ascii码,再转换10进制,再转字符串

    如下图

     这里深挖一下jo溢出跳转,增强一下基本功

    • imul是有符号乘法(即要考虑正负号)

    • edi是32位寄存器,即最大取址范围是FFFFFFFFF,考虑到符号,则正数是0-7FFFFFFF,负数是80000000-FFFFFFFF

    • 换成十进制就是正数0到20亿多一些,负数是从-1到负20亿左右

    • 我们输入的字符串长度取值乘以常量0x17CFB,所以只用考虑正数即可

    • 自己算一下字符串长度上限应该是多少呢?

    • 答案是0x5602也就是十进制的22018

    • 也就是说你的用户名最长是22018位,再多程序就崩了个球了

    • 有兴趣的可以自己写个Fuzzer来测试一下是不是,当然下断后修改寄存器数值也可以达到效果

    • 题外话,这也是为什么早期的xp系统下的网络游戏端游游戏玩家经验值总是被限制到20亿,再多对于早期的开发就很烦了,当然我妄测一下,这也是早期出现游戏角色转生的技术诱因之一

     

    回到正题,最后拼接”AKA-“给计算好的字符串组成完整激活码,来给输入的激活码比较,最后根据比较结果弹框。

     

     三、写getkey

    既然知道了算法开始写注册机,由于XP也想兼容的原因,就用“千年老妖” vc6来写吧,因为笔者vs2017出的程序xp死活是不行的(2015通过xp支持还是可以的,2017似乎全世界已经没人想管他到底xp是否可以搞了),废话不多说核心代码如下图

     1 void CCM002Dlg::OnOK() 
     2 {
     3     // TODO: Add extra validation here
     4     
     5     //CDialog::OnOK();
     6 
     7    char szName[100]={0};
     8    int nKey = 0;
     9    char szkey [100] = {0};
    10    GetDlgItemText(IDC_EDIT1,szName,100);
    11    if (strlen(szName)>0)
    12    {
    13           nKey = strlen(szName) * 0x17CFB + szName[0];
    14           sprintf(szkey,"AKA-%d",nKey);
    15           SetDlgItemText(IDC_EDIT2,szkey);
    16    } 
    17    else
    18    {
    19        const char * szTitle="逆向驿站提示您";
    20        const char * szText="用户名不能为空!";
    21        MessageBoxA(szText,szTitle);
    22    }
    23 
    24 
    25    
    26 }

     

  • 相关阅读:
    我爱java系列之---【微服务间的认证—Feign拦截器】
    我爱java系列之---【设置权限的三种解决方案】
    581. Shortest Unsorted Continuous Subarray
    129. Sum Root to Leaf Numbers
    513. Find Bottom Left Tree Value
    515. Find Largest Value in Each Tree Row
    155. Min Stack max stack Maxpop O(1) 操作
    painting house
    Minimum Adjustment Cost
    k Sum
  • 原文地址:https://www.cnblogs.com/nxyz/p/10299089.html
Copyright © 2011-2022 走看看