吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4491|回复: 17
收起左侧

[原创] 关于某个crackme的分析,以及编写的汇编转C语言程序

  [复制链接]
lizhirui 发表于 2018-10-15 20:50
本帖最后由 lizhirui 于 2018-10-15 20:51 编辑

本文主要突出解决问题的一个思路——自己写了一个汇编转C语言的程序。昨天我对某个crackme分析,打开之后就看到了以下的代码(这里只摘录一部分):
[Asm] 纯文本查看 复制代码
.text:00000000004005FE                 mov     cs:dword_694140, 9C06AA99h
.text:0000000000400608                 mov     cs:dword_694144, 0B4B2B03Fh
.text:0000000000400612                 mov     cs:dword_694148, 0C51F73CFh
.text:000000000040061C                 mov     cs:dword_69414C, 223520F8h
.text:0000000000400626                 mov     cs:dword_694150, 0C0C53B9h
.text:0000000000400630                 mov     cs:dword_694154, 0B59C78EAh
.text:000000000040063A                 mov     cs:dword_694158, 0F7DE2D34h
.text:0000000000400644                 mov     cs:dword_69415C, 0B27EEE2Ch
.text:000000000040064E                 movzx   eax, cs:byte_694117
.text:0000000000400655                 add     eax, 0Bh
.text:0000000000400658                 mov     cs:byte_694117, al
.text:000000000040065E                 movzx   eax, cs:byte_694103
.text:0000000000400665                 add     eax, 1Fh
.text:0000000000400668                 mov     cs:byte_694103, al
.text:000000000040066E                 mov     edx, cs:dword_694178
.text:0000000000400674                 mov     eax, cs:dword_69417C
.text:000000000040067A                 xor     eax, edx
.text:000000000040067C                 mov     cs:dword_69417C, eax
.text:0000000000400682                 mov     edx, cs:dword_69417C
.text:0000000000400688                 mov     eax, cs:dword_694180
.text:000000000040068E                 xor     eax, edx
.text:0000000000400690                 mov     cs:dword_694180, eax
.text:0000000000400696                 mov     edx, cs:dword_694180
.text:000000000040069C                 mov     eax, cs:dword_694184
.text:00000000004006A2                 xor     eax, edx
.text:00000000004006A4                 mov     cs:dword_694184, eax
.text:00000000004006AA                 mov     edx, cs:dword_694184
.text:00000000004006B0                 mov     eax, cs:dword_694188
.text:00000000004006B6                 xor     eax, edx
.text:00000000004006B8                 mov     cs:dword_694188, eax
.text:00000000004006BE                 mov     edx, cs:dword_694188
.text:00000000004006C4                 mov     eax, cs:dword_69418C
.text:00000000004006CA                 xor     eax, edx
.text:00000000004006CC                 mov     cs:dword_69418C, eax
.text:00000000004006D2                 mov     edx, cs:dword_69418C
.text:00000000004006D8                 mov     eax, cs:dword_694190


大篇的部分都是这样
因此我试图将其还原成C语言观其全貌:
使用了以下的程序(我简单写了个汇编翻译成C语言的翻译引擎,IDA翻译这一堆会卡死):
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 第六题求解程序
{
    class Program
    {
        enum CODE
        {
            mov = 0,
            movzx,
            add,
            sub,
            xor
        }

        enum ArgType
        {
            Register = 0,
            Variable,
            Imm,
        }

        enum ArgSize
        {
            _byte = 0,
            _dword,
        }

        enum Register
        {
            eax = 0,
            edx,
            al,
        }


        struct Arg
        {
            public ArgType Type;
            public ArgSize Size;
            public ulong VariableBaseAddr;
            public string VariableName;
            public ulong Offset;
            public ulong Index; 
            public ulong Number;
            public Register Reg;
        }

        struct Instruction
        {
            public ulong Addr;
            public CODE Code;
            public Arg[] Arg;
        }

        static string FormatLine(string line)
        {
            var r = new StringBuilder();

            for(var i = 0;i < line.Length;i++)
            {
                if(i == 0 || (line[i - 1] != ' ' && line[i - 1] != ',') || line[i] != ' ')
                {
                    r.Append(line[i]);
                }
            }

            return r.ToString();
        }

        static Instruction AnalysisInstruction(string line)
        {
            Instruction code = new Instruction();

            var seg = line.Split(' ');
            var addr = seg[0].Split(':');
            code.Addr = Convert.ToUInt64(addr[1],16);

            switch(seg[1])
            {
                case "mov":
                    code.Code = CODE.mov;
                    break;

                case "movzx":
                    code.Code = CODE.movzx;
                    break;

                case "add":
                    code.Code = CODE.add;
                    break;

                case "sub":
                    code.Code = CODE.sub;
                    break;

                case "xor":
                    code.Code = CODE.xor;
                    break;

                default:
                    throw new Exception("Unknown OpCode \"" + seg[1] + "\"");
            }

            var args = seg[2].Split(',');
            var arglist = new List<Arg>();

            foreach(var arg in args)
            {
                var targ = new Arg();

                if(arg.IndexOf('_') > 0)
                {
                    targ.Type = ArgType.Variable;
                    
                    var argaddr = arg.Split(':');

                    if(argaddr.Length > 1)
                    {
                        argaddr[0] = argaddr[1];
                    }

                    var msg = argaddr[0].Split('_');
                    var curaddr = Convert.ToUInt64(msg[1],16);

                    if(curaddr < 0x694140)
                    {
                        targ.VariableBaseAddr = 0x694100UL;
                        targ.VariableName = "InputBuf";
                    }
                    else
                    {
                        targ.VariableBaseAddr = 0x694140UL;
                        targ.VariableName = "EncodeFlag";
                    }

                    targ.Offset = curaddr - targ.VariableBaseAddr;

                    switch(msg[0])
                    {
                        case "byte":
                            targ.Size = ArgSize._byte;
                            targ.Index = targ.Offset;
                            break;

                        case "dword":
                            targ.Size = ArgSize._dword;
                            targ.Index = targ.Offset >> 2;
                            break;

                        default:
                            throw new Exception("Unknown Data Type \"" + msg[0] + "\"");
                    }
                }
                else
                {
                    switch(arg)
                    {
                        case "eax":
                            targ.Type = ArgType.Register;
                            targ.Reg = Register.eax;
                            break;

                        case "edx":
                            targ.Type = ArgType.Register;
                            targ.Reg = Register.edx;
                            break;

                        case "al":
                            targ.Type = ArgType.Register;
                            targ.Reg = Register.al;
                            break;

                        default:
                            if(arg[arg.Length - 1] == 'h')
                            {
                                targ.Type = ArgType.Imm;
                                targ.Number = Convert.ToUInt64(arg.Substring(0,arg.Length - 1),16);
                            }
                            else
                            {
                                try
                                {
                                    targ.Type = ArgType.Imm;
                                    targ.Number = Convert.ToUInt64(arg,16);
                                }
                                catch
                                {
                                    throw new Exception("Unknown Arg Type \"" + arg + "\"");
                                }
                            }

                            break;
                    }
                }

                arglist.Add(targ);
            }

            code.Arg = arglist.ToArray();
            return code;
        }

        static string GetArgString(Arg arg)
        {
            switch(arg.Type)
            {
                case ArgType.Imm:
                    return arg.Number + "";
                    
                case ArgType.Variable:
                    return arg.VariableName + "[" + arg.Index + "]";

                default:
                    throw new Exception("Error Type!");
            }
        }

        static void Main(string[] args)
        {
            var file = @"D:\exercise\XXXX\第六题待处理汇编.txt";

            var result = new StringBuilder();
            Stack<string> resultstack = new Stack<string>();

            var lines = File.ReadAllLines(file);
            var codes = new List<Instruction>();
            var eax = "";
            var edx = "";

            foreach(var line in lines)
            {
                var pline = FormatLine(line);
                codes.Add(AnalysisInstruction(pline));
            }

            for(var i = 0;i < codes.Count;i++)
            {
                var arg1str = "";

                switch(codes[i].Arg[1].Type)
                {
                    case ArgType.Variable:
                    case ArgType.Imm:
                        arg1str = GetArgString(codes[i].Arg[1]);
                        break;

                    case ArgType.Register:
                        
                        switch(codes[i].Arg[1].Reg)
                        {
                            case Register.eax:
                                arg1str = eax;
                                break;

                            case Register.edx:
                                arg1str = edx;
                                break;

                            case Register.al:
                                arg1str = "(" + eax + ") & 0xFF";
                                break;
                        }

                        break;
                }

                switch(codes[i].Code)
                {
                    case CODE.mov:
                    case CODE.movzx:
                        switch(codes[i].Arg[0].Type)
                        {
                            case ArgType.Register:

                                switch(codes[i].Arg[0].Reg)
                                {
                                    case Register.eax:
                                        eax = arg1str;
                                        break;

                                    case Register.edx:
                                        edx = arg1str;
                                        break;

                                    default:
                                        throw new Exception("Unknown Arg");
                                }

                                break;

                            case ArgType.Variable:
                                //Get InputBuf Code Only
                                if(codes[i].Arg[0].VariableName != "InputBuf")
                                {
                                    break;
                                }

                                result.Append(GetArgString(codes[i].Arg[0]));
                                result.Append(" = ");
                                result.Append(arg1str);
                                result.Append(";\n");
                                resultstack.Push(GetArgString(codes[i].Arg[0]) + " = " + arg1str + ";\n");

                                if((codes[i].Arg[0].VariableName == "EncodeFlag" && arg1str.IndexOf("InputBuf") > 0) || (codes[i].Arg[0].VariableName == "InputBuf" && arg1str.IndexOf("EncodeFlag") > 0))
                                {
                                    throw new Exception("Encode Flag is linked to InputBuf!");
                                }

                                break;

                            default:
                                throw new Exception("Unknown Arg");
                        }
                        
                        break;

                    case CODE.add:
                        switch(codes[i].Arg[0].Type)
                        {
                            case ArgType.Register:

                                switch(codes[i].Arg[0].Reg)
                                {
                                    case Register.eax:
                                        eax = "(" + eax + ") - (" + arg1str + ")";
                                        break;

                                    case Register.edx:
                                        edx = "(" + edx + ") - (" + arg1str + ")";
                                        break;

                                    default:
                                        throw new Exception("Unknown Arg");
                                }

                                break;

                            case ArgType.Variable:
                                result.Append(GetArgString(codes[i].Arg[0]));
                                result.Append(" -= ");
                                result.Append(arg1str);
                                result.Append(";\n");

                                if((codes[i].Arg[0].VariableName == "EncodeFlag" && arg1str.IndexOf("InputBuf") > 0) || (codes[i].Arg[0].VariableName == "InputBuf" && arg1str.IndexOf("EncodeFlag") > 0))
                                {
                                    throw new Exception("Encode Flag is linked to InputBuf!");
                                }

                                break;

                            default:
                                throw new Exception("Unknown Arg");
                        }
                        
                        break;

                    case CODE.sub:
                        switch(codes[i].Arg[0].Type)
                        {
                            case ArgType.Register:

                                switch(codes[i].Arg[0].Reg)
                                {
                                    case Register.eax:
                                        eax = "(" + eax + ") + (" + arg1str + ")";
                                        break;

                                    case Register.edx:
                                        edx = "(" + edx + ") + (" + arg1str + ")";
                                        break;

                                    default:
                                        throw new Exception("Unknown Arg");
                                }

                                break;

                            case ArgType.Variable:
                                result.Append(GetArgString(codes[i].Arg[0]));
                                result.Append(" += ");
                                result.Append(arg1str);
                                result.Append(";\n");

                                if((codes[i].Arg[0].VariableName == "EncodeFlag" && arg1str.IndexOf("InputBuf") > 0) || (codes[i].Arg[0].VariableName == "InputBuf" && arg1str.IndexOf("EncodeFlag") > 0))
                                {
                                    throw new Exception("Encode Flag is linked to InputBuf!");
                                }

                                break;

                            default:
                                throw new Exception("Unknown Arg");
                        }
                        
                        break;

                    case CODE.xor:
                        switch(codes[i].Arg[0].Type)
                        {
                            case ArgType.Register:

                                switch(codes[i].Arg[0].Reg)
                                {
                                    case Register.eax:
                                        eax = "(" + eax + ") ^ (" + arg1str + ")";
                                        break;

                                    case Register.edx:
                                        edx = "(" + edx + ") ^ (" + arg1str + ")";
                                        break;

                                    default:
                                        throw new Exception("Unknown Arg");
                                }

                                break;

                            case ArgType.Variable:
                                result.Append(GetArgString(codes[i].Arg[0]));
                                result.Append(" ^= ");
                                result.Append(arg1str);
                                result.Append(";\n");

                                if((codes[i].Arg[0].VariableName == "EncodeFlag" && arg1str.IndexOf("InputBuf") > 0) || (codes[i].Arg[0].VariableName == "InputBuf" && arg1str.IndexOf("EncodeFlag") > 0))
                                {
                                    throw new Exception("Encode Flag is linked to InputBuf!");
                                }

                                break;

                            default:
                                throw new Exception("Unknown Arg");
                        }
                        
                        break;
                }
            }

            result.Clear();

            while(resultstack.Count > 0)
            {
                result.Append(resultstack.Pop());
            }

            File.WriteAllText(@"D:\exercise\XXXX\第六题汇编处理结果_InputBuf_Only_Reverse.txt",result.ToString());
        }
    }
}


该程序证明了一大堆代码中的一个dword数组和另一个输入缓冲数组并没有任何的关联,且一大堆代码之后的代码也没有使用到那个dword的代码,因此上面的代码同时进行了过滤操作,仅仅过滤出了输入缓冲区的操作代码,并且进行了代码反转,输出的是Flag解密代码(源代码是加密输入缓冲区内容然后与已有数据进行比较)
详情文件由于太长都在附件中,crackme(6-WxyVM2)也在,工程代码也都在(VS2017),crackme附带IDA x64的数据库。

求解.rar (2.22 MB, 下载次数: 47)

免费评分

参与人数 5威望 +1 吾爱币 +12 热心值 +5 收起 理由
小俊 + 2 + 1 谢谢@Thanks!
Anonymous、 + 2 + 1 我很赞同!
冼星海ksv + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
voyage1969 + 1 + 1 我很赞同!
Sound + 1 + 6 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Sound 发表于 2018-10-15 21:36
不错,感谢分享。
hzyh 发表于 2018-10-15 21:42
voyage1969 发表于 2018-10-15 21:55
心病 发表于 2018-10-15 22:06
楼主真的厉害
copit 发表于 2018-10-15 23:42
感谢分享,学习了
cwz 发表于 2018-10-16 09:03
谢谢,楼主厉害。
shaunkelly 发表于 2018-10-16 10:04
楼主是一个爱钻研的人啊
xiaowanzi52 发表于 2018-10-16 10:11
非常感谢分享呢 好东西值得收藏呢
i-ii 发表于 2018-10-16 10:25
学习了,感谢分享!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表