首页
社区
课程
招聘
[求助].net编写的DLL(混合了托管代码及非托管代码)怎么破解
发表于: 2016-9-28 16:25 7916

[求助].net编写的DLL(混合了托管代码及非托管代码)怎么破解

2016-9-28 16:25
7916
我对C++反编译这一块纯属小白,希望大神们提供一下思路及方法。谢谢。

我做了一个小工具,应用了此思路(将所有核心的东西全部放进了非托管代码里面),主要是想了解清楚这样做到底有没有用,以及作用到底是多大(是不是轻松就让人破解了)

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 23
活跃值: (1401)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
getcode 暴露了.

代码就不全贴了.
    private readonly string aesKey = "94<E2Q3Si<^E[yT%";

当然都是建立在你公开的已知信息下 才弄出来的,不然从0开始 还是挺不好弄的.
2016-9-29 01:47
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你说的这个我早已经发现了(我是通过.net reflector的调试功能)。

如果是这样,破起来是不是特别费事呢,如果是的话,那么这种手段还是可行的吧。
2016-9-29 08:33
0
雪    币: 23
活跃值: (1401)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Windows.Forms;
internal class Invoker
{
    private bool CheckDLLsIsLegal(string invokerFileName, string binDir)
    {
        Dictionary<string, string> allowDLLs = new Dictionary<string, string>();
        allowDLLs.Add("netprotect.blldemo.dll", "39A880A46960FB4E80763B4F74024DF6");
        allowDLLs.Add("netprotect.consoleapplication1.exe", "5E9B932FF7CC0AA61A47DDAA394C0BDE");
        if (allowDLLs == null || allowDLLs.Count == 0)
        {
            return true;
        }
        else
        {
            if (!allowDLLs.ContainsKey(invokerFileName))
            {
                return false;
            }
            foreach (var item in allowDLLs)
            {
                string filePath = Path.Combine(binDir, item.Key);
                if (!File.Exists(filePath))
                {
                    return false;
                }
                string invokerHash = HashFile(filePath);
                if (invokerHash != item.Value)
                {
                    return false;
                }
            }
            return true;
        }
    }
    internal Invoker()
    {
        Assembly assembly = GetInvokerAssembly();
        if (assembly == null)
        {
            throw new Exception("The caller is null(0x00000000).");
        }
        string invokerFileName = Path.GetFileName(assembly.Location).ToLower();
        string binDir = Path.GetDirectoryName(new Uri(assembly.CodeBase).LocalPath);
        if (!CheckDLLsIsLegal(invokerFileName, binDir))
        {
            throw new Exception("The caller is unauthorized(0x11111111).");
        }
    }
    private Assembly GetInvokerAssembly()
    {
        if ((HttpContext.Current == null) || (HttpContext.Current.Handler == null))
        {
            return Assembly.GetEntryAssembly();
        }
        else
        {
            var type = System.Web.HttpContext.Current.ApplicationInstance.GetType();
            while (type != null && type.Namespace.ToUpper() == "ASP")
            {
                type = type.BaseType;
            }
            return type == null ? null : type.Assembly;
        }
    }
    private string HashFile(string file)
    {
        if (!File.Exists(file))
        {
            return string.Empty;
        }
        using (HashAlgorithm algorithm = MD5.Create())
        {
            using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read))
            {
                byte[] hashBytes = algorithm.ComputeHash(stream);
                return BitConverter.ToString(hashBytes).Replace("-", "");
            }
        }
    }
}
public class Core
{
    public Core()
    {
        Invoker myInvoker = new Invoker();
    }
    public string Encrypt(string toEncrypt)
    {
        string aesKey = "wg.MtbH&zvqS^!(k";
        try
        {
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes(aesKey);
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = rDel.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }
        catch
        {
            return null;
        }
    }
    public string Decrypt(string toDecrypt)
    {
        string aesKey = "wg.MtbH&zvqS^!(k";
        if (string.IsNullOrEmpty(toDecrypt))
        {
            return string.Empty;
        }
        try
        {
            if (string.IsNullOrEmpty(toDecrypt.Trim()))
            {
                return string.Empty;
            }
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes(aesKey);
            byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = rDel.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            return Encoding.UTF8.GetString(resultArray);
        }
        catch (Exception)
        {
            throw;
        }
    }
    private static readonly string dbPath = Path.Combine(Application.StartupPath, "share.db");
    public int ExecuteNonQuery(string cmdText, List<SQLiteParameter> commandParameters)
    {
        string connectionString = string.Format("Data Source={1};Version=3;Password={0};", "Bhp?lYjm]w*E[e|O", dbPath);
        using (SQLiteConnection conn = new SQLiteConnection(connectionString))
        {
            using (SQLiteCommand cmd = new SQLiteCommand())
            {
                PrepareCommand(cmd, conn, null, cmdText, commandParameters);
                int val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
        }
    }
    public SQLiteDataReader ExecuteReader(string cmdText, List<SQLiteParameter> commandParameters)
    {
        string connectionString = string.Format("Data Source={1};Version=3;Password={0};", "Bhp?lYjm]w*E[e|O", dbPath);
        SQLiteConnection conn = new SQLiteConnection(connectionString);
        using (SQLiteCommand cmd = new SQLiteCommand())
        {
            PrepareCommand(cmd, conn, null, cmdText, commandParameters);
            SQLiteDataReader rdr = cmd.ExecuteReader();
            cmd.Parameters.Clear();
            return rdr;
        }
    }
    public object ExecuteScalar(string cmdText, List<SQLiteParameter> commandParameters)
    {
        string connectionString = string.Format("Data Source={1};Version=3;Password={0};", "Bhp?lYjm]w*E[e|O", dbPath);
        using (SQLiteConnection connection = new SQLiteConnection(connectionString))
        {
            using (SQLiteCommand cmd = new SQLiteCommand())
            {
                PrepareCommand(cmd, connection, null, cmdText, commandParameters);
                object val = cmd.ExecuteScalar();
                cmd.Parameters.Clear();
                return val;
            }
        }
    }
    private void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, SQLiteTransaction trans, string cmdText, List<SQLiteParameter> cmdParms)
    {
        if (conn.State != ConnectionState.Open)
            conn.Open();
        cmd.Connection = conn;
        cmd.CommandText = cmdText;
        if (trans != null)
            cmd.Transaction = trans;
        if (cmdParms != null && cmdParms.Count > 0)
        {
            foreach (SQLiteParameter parm in cmdParms)
                cmd.Parameters.Add(parm);
        }
    }
}
2016-9-29 11:10
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
sealmoon,请问是怎么做的呢,谢谢。怎么防范呢?
2016-9-29 11:37
0
雪    币: 23
活跃值: (1401)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
核心是.net的动态编译,其中的方法CompileAssemblyFromSource 中的参数就是你要编译的 明文代码,HOOK这里就找到了.
2016-9-29 14:19
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
好。谢谢。我知道了。
2016-9-29 14:26
0
雪    币: 159
活跃值: (24)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我采用的是C++/CLR的方式
.net 可以识别调用.
实现在C++中.

而且..最重要一点.是可以实现DllMain功能.

哦.原来楼主采用的方式就是C++/Clr
话说.楼主是如何实现

二、不能调:我们在非托管代码中加入验证调用者来源功能,判断调用者的HASH值是不是与在非托管代码中约定的HASH值(发布时需要提前生成相关引用者的HASH值存于非托管代码,最后生成非托管代码的DLL放于安装包中)一致,如一致则通过执行返回结果,不一致则返回空。这样就解决了非合法来源不能调的问题。

这个的?能说明一下如何判断调用试用装的HASH吗?
2016-9-29 20:17
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
上面的代码有啊,判断调用者的HASH值就可以了
2016-10-18 09:37
0
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
学习中
2019-7-27 10:01
0
游客
登录 | 注册 方可回帖
返回
//