zoukankan      html  css  js  c++  java
  • BUUCTF-RE-Youngter-drive

    一、查壳

     UPX壳

    二、脱壳

    可以直接构造命令脱壳

    (你没安装【UPX】是不能直接upx -d 的哈)

    也可以使用工具

    三、IDA分析

     1 int main_0()
     2 {
     3   HANDLE v1; // [esp+D0h] [ebp-14h]  //HANDLE等价于void*
     4   HANDLE hObject; // [esp+DCh] [ebp-8h]
     5 
     6   sub_4110FF();  //输入字符串的函数,下展开①
     7   ::hObject = CreateMutexW(0, 0, 0);
     8   j_strcpy(Dest, Source);  //把输入的字符串,复制给Dest
     9   hObject = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)StartAddress, 0, 0, 0);//加密函数②
    10   v1 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)sub_41119F, 0, 0, 0);//CreateThread就是创建线程,所以推测这是多线程运行。sub_41119F③
    11   CloseHandle(hObject);                                                 //②和③的两个进程会交替执行
    12   CloseHandle(v1);
    13   while ( dword_418008 != -1 )
    14     ;
    15   sub_411190();//④
    16   CloseHandle(::hObject);
    17   return 0;
    18 }

    进入  ①sub_4110FF()  函数

    进入  ②StartAddress  函数  先进入该函数加密,然后通过sleep()函数暂停线程,切到另一个线程执行函数③...循环到flag完整输出,也就是说对字符串的奇数位加密,偶数位不加密

     1 void __stdcall StartAddress_0(int a1)
     2 {
     3   while ( 1 )
     4   {
     5     WaitForSingleObject(hObject, 0xFFFFFFFF);
     6     if ( dword_418008 > -1 )
     7     {
     8       sub_41112C((int)Source, dword_418008);  //这个函数进不去
     9       --dword_418008;
    10       Sleep(0x64u);
    11     }
    12     ReleaseMutex(hObject);
    13   }
    14 }

    sub_41112C()  提示如下图   参考资料1参考资料2

    不能F5的原因  可能有两个

    1、是在于跳转,一个函数里面的一个跳转在未知的情况下会出现不能F5

    2、函数的堆栈是不平衡

     解决方法:

     在菜单栏的Options→General,然后勾选stack pointer

    然后找到出问题的部分 

    在View里查看他的汇编代码

    解决方法(1)这个是野路子,我也不大明白原理,但可以试试

    从跳转的角度

     跳到下一个函数时,是用的条件跳转,将jz改为jmp(无条件跳转)也可以解决问题

    解决方法(2)参考

    IDA中Options->General选中Stack pointer可以查看堆栈指针

    如果是由于堆栈不平衡导致的,可以看到retn前面是-04,修改pop

    选中它,快捷键 ait+k,修改为以下值

     再次F5

    进入加密函数sub_41112C()函数中

     1 char *__cdecl sub_411940(int a1, int a2)//a1,a2分别是数据Source,dword_418008=1Dh
     2 {
     3   char *result; // eax
     4   char v3; // [esp+D3h] [ebp-5h]
     5 
     6   v3 = *(_BYTE *)(a2 + a1);
     7   if ( (v3 < ‘a’ || v3 > 'z') && (v3 < 'A' || v3 > 'Z') )  //不是字母退出
     8     exit(0);
     9   if ( v3 < 'a' || v3 > 'z' ) //是大写字母与字符串进行替换并-38
    10   {
    11     result = off_418000[0];//off_418000=QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasd
    12     *(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 38];
    13   }
    14   else
    15   {
    16     result = off_418000[0];//是小写字母与字符串替换后-96
    17     *(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 96];
    18   }
    19   return result;
    20 }

    进入 ③sub_41119F()函数中

     1 void __stdcall sub_411B10(int a1)
     2 {
     3   while ( 1 )
     4   {
     5     WaitForSingleObject(hObject, 0xFFFFFFFF);
     6     if ( dword_418008 > -1 )
     7     {
     8       Sleep(0x64u);
     9       --dword_418008;
    10     }
    11     ReleaseMutex(hObject);
    12   }
    13 }

     进入④sub_411190()函数

     1 int sub_411880()
     2 {
     3   int i; // [esp+D0h] [ebp-8h]
     4 
     5   for ( i = 0; i < 29; ++i )
     6   {
     7     if ( Source[i] != off_418004[i] ) //off_418004[i]='TOiZiZtOrYaToUwPnToBsOaOapsyS'
     8       exit(0);                        //比较source[i]的值与off_418004[i]
     9   }
    10   return printf("
    flag{%s}
    
    ", Dest);
    11 }

    解题脚本:

    a='TOiZiZtOrYaToUwPnToBsOaOapsyS'
    b='QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasd'
    flag=''
    
    for i in range(len(a)):
        if i%2==0:
            flag+=a[i]
            continue
        for j,k in enumerate(b):#enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标j是数据项,k是下标项
            if a[i]==k:
                if chr(j+38).isupper():  # isupper() 检查所传的字符是否是大写字母
                    flag+=chr(j+38)
                else:
                    flag+=chr(j+96)
    print(flag)

    由于后面得出的flag函数只加密29个字母,但实际上你加密的有30个,所以最后一个在安恒赛里是可以随便填写的。

    30个这个点是在第二个线程里dword_418008初始值为1Dh,即10进制的29。它是从29开始-1,那么就是30位。

    但是BUU比较不智能,只能加E。

    四、flag

     flag{ThisisthreadofwindowshahasESqE}

    五、收获点

    解决不能F5的问题

    提示411A04:positive sp value has been found

    UPX脱壳

    多线程运行

  • 相关阅读:
    IOS Xcode编译项目-报错“ld: library not found for -XX”
    ios中关键词weak,assign,copy.strong等的区别
    iOS 控件
    iOS图片处理
    iOS 音频
    C语言文件操作
    iOS 删除相册中照片--来自简书
    ios sourecTree
    ios音频处理
    编码格式简介
  • 原文地址:https://www.cnblogs.com/Nickyl07/p/12716379.html
Copyright © 2011-2022 走看看