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 }

     

  • 相关阅读:
    多线程面试题
    Tcpdump MySQL Query
    Gossip和Redis集群原理
    mysql-table_open_cache_file_limits/
    introducing-backup-locks-percona-server-2/
    MySQL 一致性读 深入研究
    how-to-configure-mysql-masterslave-replication-with-mha-automatic-failover/
    mysqlOOM
    mysql 线程池
    Linux performance monitor tool
  • 原文地址:https://www.cnblogs.com/nxyz/p/10299089.html
Copyright © 2011-2022 走看看