小白学习笔记(10)BUUCTF-re-Youngter-drive

新手一枚,如有错误(不足)请指正,谢谢!!
题目链接:Youngter-drive
参考资料:
1. IDA sp-analysis failed 不能F5的 解决方案之(一)-『软件逆向』-看雪安全论坛
2. IDA sp-analysis failed 不能F5的 解决方案之(二)-『软件逆向』-看雪安全论坛
3. ReleaseMutex 百度百科
4. WaitForSingleObject 百度百科
直接拖入IDA32,提示警告……
在这里插入图片描述
在这里插入图片描述
首先函数就俩,,,在UPX1,伪代码第一句是pusha,保存所有寄存器
而最上面的条也没被读取出来,显示灰色
在这里插入图片描述
exe文件,使用官网下载的upx进行脱壳进行脱壳
UPX-3.95-win64
在这里插入图片描述
脱壳之后成功加载
在这里插入图片描述
然后跳转到_main_0查看
F5伪代码
在这里插入图片描述
简单分析一下

在sub_411190()函数中
在这里插入图片描述
发现source存的和off_418004进行了一个比较
进入off_418004查看,可以看到里面存的啥
在这里插入图片描述
题不可能这么简单,所以source肯定经过处理了
点击source,x键进入交叉引用
在这里插入图片描述
挨个进去查看,发现第二个是对source进行处理的,也就是对main_0函数里的StartAddress函数进行分析
在这里插入图片描述

WaitForSingleObject
WaitForSingleObject是一种Windows API函数,当等待仍在挂起状态时,句柄被关闭,那么函数行为是未定义的。该句柄必须具有 SYNCHRONIZE 访问权限。
WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。
ReleaseMutex
ReleaseMutex是一种线性指令,具有释放线程拥有的互斥体的控制权。

线程也能告诉系统,它不想在某个时间段内被调度。这是通过调用Sleep函数来实现的:
VOID Sleep(DWORD dwMilliseconds);
该函数可使线程暂停自己的运行,直到dwMilliseconds过去为止。

另一个进程是sub_41119F
而这里面是没有操作的。
在这里插入图片描述
结合这两个进程,可以得到

当第一个进程执行到第10行时候,该线程被冻结,转向执行另一个线程,也就是函数sub_41119F,也就是说,dword_418008=29,执行循环,在第9行自减一,dword_418008=28 然后执行第十行sleep,线程被冻结,另一个函数sub_41119F开始执行,然后执行到sleep再冻结,再执行第一个进程(因为WaitForSingleObject函数在等着)
大概是这种变化……
在这里插入图片描述
可以发现,dword_418008=29,28,26,24,22的时候对字符串进行了处理,也就是说,当dword_418008为奇数的时候,对字符串进行处理。当下标为偶数的时候不进行处理。
然后进入线程1的sub_41112C()函数
在这里插入图片描述
提示了这个错误。。
然后查看参考资料1和2
先在菜单栏的Options→General,然后勾选stack pointer在这里插入图片描述
然后找到出问题的411A04
在View窗口里查看他的汇编代码
在这里插入图片描述
根据参考资料,我猜想是这里的跳转出现了问题
选中跳转那一行,然后Edit→
在这里插入图片描述
然后将其改成jmp跳转

然后F5试一下……
发现可以进行反编译了!
在这里插入图片描述
在这里插入图片描述
好了都分析清楚开始写代码

#include <stdio.h>
int main(void)
{
    char off1[] = "TOiZiZtOrYaToUwPnToBsOaOapsyS";
    char off2[] = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
    char flag[30]={0};
    int i,j;
    for(i=28;i>-1;i--)
    {
        if(i%2==0)
        {
            flag[i] = off1[i];
            continue;
        }
        for(j=0;j<52;j++)
        {
            if(off1[i] == off2[j])
            {
                flag[i] = j+38;
                if(!(flag[i]>=65 &&flag[i]<=90))
                    flag[i] = j+96;
                break;
            }
        }
    }
    puts(flag);
    return 0;
}

输出
在这里插入图片描述

往期回顾

小白学习笔记(0) CG-CTF-re-3 py交易
小白学习笔记(1) BUUCTF-re xor
小白学习笔记(2)BUUCTF-re-新年快乐
小白学习笔记(3) CG-CT re ReadAsm2
小白学习笔记(4)BUUCTF-re-reverse_1
小白学习笔记(5)BUUCTF-re-内涵软件
小白学习笔记(6)BUUCTF-re-SimpleRev
小白学习笔记(7)BUUCTF-re-rsa
小白学习笔记(8)BUUCTF-re-CrackRTF
小白学习笔记(9)BUUCTF-re-刮开有奖

posted @ 2019-11-17 20:39  Palmer0801  阅读(142)  评论(0编辑  收藏  举报