吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2111|回复: 46
上一主题 下一主题
收起左侧

[原创] 另类SE壳找私钥

  [复制链接]
跳转到指定楼层
楼主
deadash 发表于 2024-11-14 12:07 回帖奖励

SE壳破解已经有各种教程了,本文提供一个另类的思路来找公钥和随机key(下次发)。

公钥获取

可以确定的是SE壳的公钥和随机Key是直接在PE文件中的,并且找到了这两个就可以直接修改并通过修补最后两个字节来达到修改授权的目的,其他内容在网站都可以找到就不说了。

目的:存在a.exe或dll为目标PE,我们要修改公钥并解密a.key来达到修改成我们自己的授权。

步骤如下:

  1. 构建一个PE为b.exe,已知它的公钥和随机Key地址

  2. a.key拷贝成b.key,也就是b.exe可以加载a文件的key

  3. 解析a.exe,得到第一个节点 .sedata ,找到非0连续地址,然后读取指定大小后启动b.exe

  4. 内存修改b.exe对应公钥地址为上面猜解值,启动b.exe并拦截弹框

  5. 循环执行4,直到弹框报错 '该授权文件与本程序不匹配。', 这样就得到公钥地址+公钥。

参考代码如下

其中,PE解析代码例子如下

    // 读取输入文件
    let mut input_file = File::open(&cli.input)?;
    let mut buffer = Vec::new();
    input_file.read_to_end(&mut buffer)?;

    let pe = PE::parse(&buffer).map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Invalid PE file"))?;
    let (sedata_offset, sedata_size) = pe.sections.iter()
        .find(|s| s.name().unwrap_or("") == ".sedata")
        .map(|s| (s.pointer_to_raw_data, s.size_of_raw_data))
        .unwrap_or((0, 0));

    println!(".sedata Offset: 0x{:08X}, Size: 0x{:08X}", sedata_offset, sedata_size);

其中,拦截弹框并返回

// 添加新的窗口枚举回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
    DWORD processId;
    GetWindowThreadProcessId(hwnd, &processId);

    if (processId == GetCurrentProcessId()) {
        char title[256] = {0};

        GetWindowTextA(hwnd, title, sizeof(title));

        HWND child = GetWindow(hwnd, GW_CHILD);
        int controlIndex = 0;

        while (child && controlIndex < 2) {
            child = GetWindow(child, GW_HWNDNEXT);
            controlIndex++;
        }

        if (child) {
            int textLength = GetWindowTextLengthW(child) + 1;
            if (textLength > 1) {
                wchar_t* wideText = new wchar_t[textLength];
                GetWindowTextW(child, wideText, textLength);

                int mbLength = WideCharToMultiByte(CP_UTF8, 0, wideText, -1, NULL, 0, NULL, NULL);
                char* mbText = new char[mbLength];

                WideCharToMultiByte(CP_UTF8, 0, wideText, -1, mbText, mbLength, NULL, NULL);

                // 输出JSON格式
                printf("{\"title\": \"%s\", \"text\": \"%s\"}\n", title, mbText);
                delete[] wideText;
                delete[] mbText;

                // 退出进程
                ExitProcess(-1);
            }
        }
    }
    return TRUE;
}

// 添加新的监控线程函数
void WindowMonitorThread() {
    while (isMonitorRunning) {
        EnumWindows(EnumWindowsProc, 0);
        std::this_thread::sleep_for(std::chrono::milliseconds(30));
    }
}

判断返回

fn parse_execution_result(output: std::process::Output) -> ExecutionResult {
    match output.status.code().unwrap_or(-1) {
        -1073741819 => ExecutionResult::DecryptionFailed,
        -1 => {
            if let Ok(json_output) = serde_json::from_slice::<serde_json::Value>(&output.stdout) {
                if let Some(text) = json_output.get("text").and_then(|v| v.as_str()) {
                    match text {
                        "文件已损坏,无法运行。" => ExecutionResult::FileCorrupted,
                        "该授权文件与本程序不匹配。" => ExecutionResult::InvalidLicense,
                        _ => ExecutionResult::UnknownError(text.to_string()),
                    }
                } else {
                    ExecutionResult::UnknownError("无法解析 JSON 输出".to_string())
                }
            } else {
                ExecutionResult::UnknownError("标准输出无法解析为 JSON".to_string())
            }
        },
        0 | 1 => ExecutionResult::Success(
            String::from_utf8_lossy(&output.stdout).to_string(),
            String::from_utf8_lossy(&output.stderr).to_string()
        ),
        code => ExecutionResult::UnknownError(format!("未知错误码: {}", code)),
    }
}

结果

通过测试,所有的SE2加壳均可以快速(1-5分钟)找到key,并且测试在linux上可用,不需要启动目标程序就可以得到公钥。至于随机数,看这篇有没有人关注,多的话会发,大概原理采用数学统计原理找到目标区域。

思路可以推广到其他强壳。

免费评分

参与人数 20威望 +2 吾爱币 +125 热心值 +19 收起 理由
ioyr5995 + 1 + 1 我很赞同!
xiong9411 + 1 + 1 谢谢@Thanks!
qiaoyong + 1 + 1 热心回复!
pojiestudy + 1 + 1 谢谢@Thanks!
dream20241111 + 1 + 1 谢谢@Thanks!
jgs + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Hmily + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
HongHu106 + 1 + 1 谢谢@Thanks!
beatone + 1 谢谢@Thanks!
#917 + 1 我很赞同!
秋名山 + 1 + 1 希望能有详细的视频操作教程!太赞了 造福小白
610100 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
bh1783 + 1 热心回复!
逍遥枷锁 + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cylbgs + 1 + 1 谢谢@Thanks!
go2crack + 1 + 1 用心讨论,共获提升!
wtujoxk + 3 + 1 谢谢@Thanks!
xlazl + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
_Bitter + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
朱朱你堕落了 + 3 + 1 虽然不懂,但是支持一下。

查看全部评分

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

推荐
理想的海洋 发表于 2024-11-17 14:36
楼主详细讲解一下呗 原理懂了 获取到第一个节点 .sedata的偏移和大小  然后枚举窗口 需要指定进程吗 目标程序需要打开吗 测试了一天 不知道后面的步骤怎么实现的
推荐
理想的海洋 发表于 2024-11-18 17:11
deadash 发表于 2024-11-18 16:14
你需要启动b进程,然后注入b进程dll,让b进程自己找自己的进程pid的窗口。或者你也可以在父进程定时查找b ...

感谢回复  进程b是一个exe程序 打开就弹窗了  如何用代码拦截呢 可以贴个完整代码吗   爆破se真的太有魅力了 就是后面几部搞的不太明白
沙发
Awesomeme 发表于 2024-11-14 12:31
3#
flea033 发表于 2024-11-14 12:39
感谢分享!
4#
_Bitter 发表于 2024-11-14 13:11
感觉长了点知识,但是又有点不明白!找到.sedata的区段然后 枚举符合条件的窗口  -1073741819 是什么呢
5#
冰河洗剑 发表于 2024-11-14 13:23
本帖最后由 冰河洗剑 于 2024-11-14 13:28 编辑

不知道是BUG还是? 并不是所有SE都可以Keygen 有些样本无法正常解码       https://x.ws28.cn/f/fkf19l1quht
6#
mrruby10 发表于 2024-11-14 13:28
学习学习
7#
理想的海洋 发表于 2024-11-14 14:10
跟帖学习一下
8#
zyjust 发表于 2024-11-14 14:32
学到了 收藏一下
9#
随风起舞 发表于 2024-11-14 14:41
看看学习一下
头像被屏蔽
10#
zl1100 发表于 2024-11-14 15:17
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-22 21:11

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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