吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1159|回复: 9
收起左侧

[求助] 如何获知【c#程序逆向调用dll导出接口的逻辑和传参】的思路

[复制链接]
284406022 发表于 2025-1-7 11:55
本帖最后由 284406022 于 2025-1-7 12:26 编辑

我是c++开发, 对c#并不熟悉,对c#逆向更是小白
目标:一个c#程序 调用 dll的导出函数, 我想让程序跑起来后触发功能,然后知道这个程序调用了哪些dll导出函数,具体参数是什么
这个c#加了壳:

image.png

保护器: Confuser(1.X)
(Heur)保护: Obfuscation[CLR constructor + Strange EP position + Strange sections + Anti-ILDASM + Ctrl flow + Watermark]
(Heur)保护: Anti analysis[Anti-debug + Anti-dump]
(Heur)打包工具: Compressed or packed data[Section 0 ("tE)EV+") compressed]


然后网上找了 Confuser脱壳工具,最后发现 【ConfuserEx-Unpacker-v2.0】是可以正常执行并输出成功的,脱完后:


image.png

(Heur)保护: Obfuscation[Modified EP + CLR constructor + Ctrl flow + Math mutations]
(Heur)保护: Anti analysis[Anti-debug]
脱完后运行不起来了,于是想dnspy单步走,但是发现能力不够,exe跑不起来

然后想着用劫持dll方法看是否可行, 于是就新建dll工程, 实现sdk.dll中的124个导出函数, 高高兴兴地把劫持dll和原始dll(改名:proxy.dll)放到exe目录下, 发现exe运行不起来,具体为什么跑不起来,dnspy单步走,有混淆也看不懂.
于是想问下c#大佬有没有其它方法, 打印出exe 调用这个sdk.dll 的调用顺序和参数, 真心求教, 不胜感激
image.png



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

ps122 发表于 2025-1-7 14:35
手动实现sdk.dll中的124个导出函数?工作量不小,程序发出来看看
abaooo 发表于 2025-1-7 14:31
是不是可以从dll库入手,逆向一下dll库,看这个库带哪些函数
 楼主| 284406022 发表于 2025-1-7 15:14
本帖最后由 284406022 于 2025-1-7 15:17 编辑
ps122 发表于 2025-1-7 14:35
手动实现sdk.dll中的124个导出函数?工作量不小,程序发出来看看

发不了截图, 可以说下我的方法, 函数原型直接copy IDA的,  代{过}{滤}理函数写法直接用宏来处理:
宏函数如下:
#define GET_FUNCTION_AND_DEBUG(dllHandle, funcName, funcType, funcPtr) \
    funcType funcPtr = (funcType)GetProcAddress(dllHandle, funcName); \
    OutputDebugStringA(funcName "\n"); \
    if (!funcPtr) { \
        OutputDebugStringA("get address " funcName " fail\n"); \
        return 0; \
    }

#define CALL_FUNCTION_FROM_DLL(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName();

#define CALL_FUNCTION_FROM_DLL1(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName(a1);
#define CALL_FUNCTION_FROM_DLL2(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName(a1,a2);
#define CALL_FUNCTION_FROM_DLL3(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName(a1,a2,a3);
#define CALL_FUNCTION_FROM_DLL4(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName(a1,a2,a3,a4);
#define CALL_FUNCTION_FROM_DLL5(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName(a1,a2,a3,a4,a5);
#define CALL_FUNCTION_FROM_DLL6(dllHandle, functionName) \
    GET_FUNCTION_AND_DEBUG(dllHandle, #functionName, Fn_##functionName, _##functionName); \
    return _##functionName(a1,a2,a3,a4,a5,a6);

先简单打印 调用的函数名,
宏调用如下:
DLL_EXPORT int __fastcall SystemPeakLevel(int a1, float* a2)
{
        CALL_FUNCTION_FROM_DLL2(g_hDll, SystemPeakLevel);
}

DLL_EXPORT __int64 __fastcall TestDriver(int a1, int a2, unsigned __int8 a3, char a4)
{
        CALL_FUNCTION_FROM_DLL4(g_hDll, TestDriver);
}

DLL_EXPORT __int64 UpdateSoundboardSoundVolume()
{
        CALL_FUNCTION_FROM_DLL(g_hDll, UpdateSoundboardSoundVolume);
}

DLL_EXPORT __int64 UpdateSoundboardSoundsVolume()
{
        CALL_FUNCTION_FROM_DLL(g_hDll, UpdateSoundboardSoundsVolume);
}

DLL_EXPORT __int64 VoiceSize()
{
        CALL_FUNCTION_FROM_DLL(g_hDll, VoiceSize);
}

DLL_EXPORT __int64 __fastcall WriteWordExtractorBuffer(__int64 a1, unsigned int a2)
{
        CALL_FUNCTION_FROM_DLL2(g_hDll, WriteWordExtractorBuffer);
}
不过, 这第一步劫持就失败了, 浪费我大半天时间弄这些导出函数, 这些宏的展开效果在帖子最后一张截图效果一样的

 楼主| 284406022 发表于 2025-1-7 17:16
我用dnspy单步走, 发现了一个 校验exe和dll 签名返回false的地方,导致进程退出, 我想把函数开头直接返回true, 但是修改代码, 点击编译就报错, 修改不了, 有什么方法可以像 x86汇编或者smali 那样直接改函数返回值
        public static bool _UgOo3GutCHKdOZjtrzDLr427UzN(IEnumerable<string> A_0, string A_1 = null, string A_2 = null, string A_3 = null)
        {
                bool result = false;
                try
                {
                        foreach (string text in A_0)
                        {
                                using (X509Certificate x509Certificate = X509Certificate.CreateFromSignedFile(text))
                                {
                                        using (_nPR2UNNzWoTGU2VRdhJTOa9BgOf nPR2UNNzWoTGU2VRdhJTOa9BgOf = _RtxcMfzpKqJ2UEPBseofHns6ATA._maWq1ZMBG13hEDYILKdgAQy7yJDA._nXKflPva7Xa6cghik8LxrUbC9oy())
                                        {
                                                new X509Certificate2(x509Certificate);
                                                if (!(result = ((result = (x509Certificate.GetCertHashString().ToLowerInvariant() == nPR2UNNzWoTGU2VRdhJTOa9BgOf._3QucTL3NM0MhdugbP0LmWmIF5vj)) && _RtxcMfzpKqJ2UEPBseofHns6ATA._CyIkY2yA6Ktag9KiKaIzYpQAk8kA._vQTg02HDOlcpvuOdJHql0CBERfh(text))))
                                                {
                                                        break;
                                                }
                                        }
                                }
                        }
                }
                catch (Exception)
                {
                        result = false;
                }
                return result;
        }
Raohz520 发表于 2025-1-7 17:58
284406022 发表于 2025-1-7 17:16
我用dnspy单步走, 发现了一个 校验exe和dll 签名返回false的地方,导致进程退出, 我想把函数开头直接返回tru ...

这不是混淆过的代码吗。
 楼主| 284406022 发表于 2025-1-7 18:12
Raohz520 发表于 2025-1-7 17:58
这不是混淆过的代码吗。

应该是吧, 有什么方法反混淆吗?
ps122 发表于 2025-1-7 19:50
284406022 发表于 2025-1-7 17:16
我用dnspy单步走, 发现了一个 校验exe和dll 签名返回false的地方,导致进程退出, 我想把函数开头直接返回tru ...

直接IL修改,返回true
 楼主| 284406022 发表于 2025-1-8 09:30
本帖最后由 284406022 于 2025-1-8 09:33 编辑
ps122 发表于 2025-1-7 19:50
直接IL修改,返回true

已经改好, 并正常走过, 现在发现一处自动升级的地方,老是调用就会进入函数内的catch (Exception ex2)处死循环, 代码如下:
[C#] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
public void _YXoXA4Ptrjnx6H9Dzi7nLZ8N7BE(bool A_1, _78lbTE42EQhhbP2MUqOVSspWXhQ A_2, _VkUZu7rbnYT3IBJdaaHARhaX8iv A_3)
        {
                AutoUpdater.LetUserSelectRemindLater = false;
                AutoUpdater.ShowRemindLaterButton = false;
                AutoUpdater.ShowSkipButton = false;
                AutoUpdater.AppTitle = "Voicemod Desktop";
                AutoUpdater.RunUpdateAsAdmin = false;
                try
                {
                        Version version = _PMiGMU2LppngXtWaoKTaKmf0kf1._56Uc3RjeLcTHMAc4dfiaF6luQWMb();
                        string text = Environment.Is64BitOperatingSystem ? "x64" : "x86";
                        string text2 = _PMiGMU2LppngXtWaoKTaKmf0kf1._yAgXeiwDbgNO9vBLuf6pCXf4YfJ(new _sowhdfJLBbkaVDttgLkNeicIPK0());
                        _X6dZdcZAKumQIXn9jm2nJBaeusm x6dZdcZAKumQIXn9jm2nJBaeusm = new _X6dZdcZAKumQIXn9jm2nJBaeusm(this._lvK8k7vAtFb7HNlPxIfVkMhemHL(A_1), new _yPLBe45UhZloUfmvwcQ2JIYJJ5Z(A_2, this._al8CbAnWhb9VbZ3dvWknsXxCMQdA, A_3), A_2, A_3);
                        x6dZdcZAKumQIXn9jm2nJBaeusm._h66A1Xp2Rh8DWtFZUfwC6X29DMd = new _yPfzJfH9RhYVfL9cGVoDDDMZprF();
                        x6dZdcZAKumQIXn9jm2nJBaeusm._xEW6gPiy87tc2x9IeSQbfGm7OeF = new _KiBApumkl3oqwuHQZuenjJ8fPDt();
                        _jlrzNDPayCP7Iz0C3H9DMWWET4t jlrzNDPayCP7Iz0C3H9DMWWET4t = new _jlrzNDPayCP7Iz0C3H9DMWWET4t
                        {
                                _jZSRq4xIgYv1IsFRVnaMW1ZkLQA = text2,
                                _NJl2fee1JEhjRHojc8yM8ISGIje = version.ToString(),
                                _UKhc76HD4cSNJbR4EKX0MlhrT3u = text
                        };
                        _224RjEAeRhOCNhNSzCxD6qJKaPI<_lAqO8rZBCgBo0XgluC9bSvAFGzib> result = x6dZdcZAKumQIXn9jm2nJBaeusm._kBFvM9WzFbL1hQTwjP5BYaIqbWB<_jlrzNDPayCP7Iz0C3H9DMWWET4t, _lAqO8rZBCgBo0XgluC9bSvAFGzib>(jlrzNDPayCP7Iz0C3H9DMWWET4t).ConfigureAwait(true).GetAwaiter().GetResult();
                        if (result._XX1uH8AzsyqQnZ3D2ejfJJwRgrB == ServiceCode.OK)
                        {
                                this._vjTYFxD7R5dz6MqqbOlhtBxcssg = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
                                File.WriteAllText(this._vjTYFxD7R5dz6MqqbOlhtBxcssg, JsonConvert.SerializeObject(result._uy9Id6Ha1B3pxlOwFhDIhoyj4fo._6c3B34hIQycuECKrdcgV9pbwdJd));
                                AutoUpdater.Start(this._vjTYFxD7R5dz6MqqbOlhtBxcssg, null);
                        }
                        else
                        {
                                this._ic43xghxorLmqPeDetqZ0l4OzXh = _Drbll29VUExLXa3SZbK3dcCtOpc.SERVER_ERROR;
                                EventHandler e9ZGS7ILKd8Y3YUUE1X0K29qvlE = this._e9ZGS7ILKd8Y3YUUE1X0K29qvlE;
                                if (e9ZGS7ILKd8Y3YUUE1X0K29qvlE != null)
                                {
                                        e9ZGS7ILKd8Y3YUUE1X0K29qvlE(null, null);
                                }
                        }
                        if (!A_1)
                        {
                                _mbTRbzTa6RlSnKzDn7d5gVdkQYQ._ztvTfDRMCk4P22w849rawN8AMko();
                        }
                }
                catch (ServerInMaintenanceModeException ex)
                {
                        MessageBox.Show(this._JE3ceNpxgCV1QsiaqHGWC0AS5TE._yLcSE6yw175Q1Be7ip9mj4lzyAH("autoupdater_maintenance_mode_description"), this._JE3ceNpxgCV1QsiaqHGWC0AS5TE._yLcSE6yw175Q1Be7ip9mj4lzyAH("autoupdater_maintenance_mode_title"), MessageBoxButton.OK, MessageBoxImage.Hand);
                        this._odmddiCZiVoIP0CoxkdPV4ZxODF._eEl6aEJeKaOu6cRw8Gs2FromujJ(ex, "AutoUpdater failed");
                        throw;
                }
                catch (Exception ex2)
                {
                        for (;;)
                        {
                                IL_1DF:
                                _KairoKYg9HtwqYVZWd8RxWWS1E kairoKYg9HtwqYVZWd8RxWWS1E = new _KairoKYg9HtwqYVZWd8RxWWS1E("VoicemodUpdater: AutoUpdater failed - " + ex2.Message, ex2);
                                for (;;)
                                {
                                        IL_1D0:
                                        A_2._r9snxfJAHq6EW6KHhqZygG4rQ8V(kairoKYg9HtwqYVZWd8RxWWS1E, "voicemod-updater-error");
                                        for (;;)
                                        {
                                                IL_1C1:
                                                this._odmddiCZiVoIP0CoxkdPV4ZxODF._eEl6aEJeKaOu6cRw8Gs2FromujJ<_KairoKYg9HtwqYVZWd8RxWWS1E>(kairoKYg9HtwqYVZWd8RxWWS1E);
                                                for (;;)
                                                {
                                                        IL_1B8:
                                                        this._ic43xghxorLmqPeDetqZ0l4OzXh = _Drbll29VUExLXa3SZbK3dcCtOpc.SERVER_ERROR;
                                                        for (;;)
                                                        {
                                                                EventHandler e9ZGS7ILKd8Y3YUUE1X0K29qvlE2 = this._e9ZGS7ILKd8Y3YUUE1X0K29qvlE;
                                                                if (e9ZGS7ILKd8Y3YUUE1X0K29qvlE2 == null)
                                                                {
                                                                        goto Block_10;
                                                                }
                                                                e9ZGS7ILKd8Y3YUUE1X0K29qvlE2(null, null);
                                                                uint num;
                                                                switch ((num = (num * 3933880144U ^ 1832400596U ^ 3756516255U)) % 7U)
                                                                {
                                                                case 0U:
                                                                        continue;
                                                                case 1U:
                                                                case 2U:
                                                                        goto IL_1DF;
                                                                case 3U:
                                                                        goto IL_1B8;
                                                                case 4U:
                                                                        goto IL_1D0;

跳转到catch的是执行 这句代码:   _224RjEAeRhOCNhNSzCxD6qJKaPI<_lAqO8rZBCgBo0XgluC9bSvAFGzib> result = x6dZdcZAKumQIXn9jm2nJBaeusm._kBFvM9WzFbL1hQTwjP5BYaIqbWB<_jlrzNDPayCP7Iz0C3H9DMWWET4t, _lAqO8rZBCgBo0XgluC9bSvAFGzib>(jlrzNDPayCP7Iz0C3H9DMWWET4t).ConfigureAwait(true).GetAwaiter().GetResult();  
看起来有点像http网络请求, 我想去掉这个函数,因为我不用自动更新功能
 楼主| 284406022 发表于 2025-1-8 09:52
改了_YXoXA4Ptrjnx6H9Dzi7nLZ8N7BE 这个函数 ,在函数开头IL指令改成: nop , ret , 但是一执行就报异常
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-25 08:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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