BUUCTF逆向刷题记录--crackMe、你好sao啊

发布时间 2023-07-03 12:00:07作者: zydt10

[安洵杯 2019]crackMe

 
程序异常处理的一题,刚开始还以为是双线程(),因为input和hook的弹窗这两个函数之间没有跳转的关系。
在动调的过程中,没发现是异常处理,就把跳转进异常处理的汇编给nop掉了,有点蠢哈哈哈哈哈
  跟踪main()函数无果的情况下,通过跟踪关键字符串,然后通过交叉引用的方法理清函数逻辑也是一种思路。
  
    
  有资料说可以通过Imports找到引用的库,一下就可以定位到,进去找X
  注册向量异常处理程序
  AddVectoredExceptionHandler 函数
  注册向量异常处理程序
  AddVectoredExceptionHandler(0, Handler);---->第一个参数0表示注册的Handler函数在出现异常后会优先触发,第二个参数表示触发执行的函数
  
  SetUnhandledExceptionFilter
  使应用程序能够取代进程的每个线程的顶级异常处理程序
  调用此函数后,如果在未调试的进程中发生异常,并且异常会将其设置为未处理的异常筛选器,该筛选器将调用 lpTopLevelExceptionFilter 参数指定的异常筛选器函数。
  SetUnhandledExceptionFilter(TopLevelExceptionFilter);--->TopLevelExceptionFilter指向顶级异常筛选器函数的指针,每当 UnhandledExceptionFilter 函数得到控制时,都会调用该函数,并且进程不会被调试。
  
  SM4:
  0xA3B1BAC6 是 SM4 的特征值
  密钥为传入的 v2 即 "where_are_u_now?"
  脚本解密
  
  base64:
  '!'--->'='
  这里是刚好24位,所以就不用补位
  以及表后移了24位,还大小写交换了
  

  [NPUCTF2020]你好sao啊

  
  单走一个6
    base64的加密解密:
  加密为3位变4位
  解密反过来
  这里是由4位变三位,不难猜出这个就是解密,那么逆向的话,就要用加密的脚本
  或者这样看:
  只有加密后的密文才有=号,所以输入进来的是密文,那么这个就是解密
  再或者这样看:
  
  
  左移6位再or上右边的两位,就是解密的过程
  
  字节最高八位
  6
  6
  这里的数据其实是超出8位的,然而按照base64加密的规则【我乱说的】,我们只能取后面高地址的八位【我也不知道是高地址还是低地址】。
  
  也有wp是用脚本转字节的
#include <iostream>
#include <cstring>
 
int main() {
    unsigned long long s[] = {
        0xFD370FEB59C9B9E,
        0xDEAB7F029C4FD1B2,
        0xFACD9D40E7636559,
        0x4,
        0x0
    };
 
 
    for (int i = 0; i < 25; i++) {
        int c = (int) * ((unsigned char *) (s) + i);
        std::cout << "\\x" << std::hex << c;
    }
    std::cout << std::endl;
 
    return 0;
}