吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 430|回复: 26
上一主题 下一主题
收起左侧

[求助] 大佬们帮忙看下这个软件汇编的思路

[复制链接]
跳转到指定楼层
楼主
358059103 发表于 2025-3-3 21:18 回帖奖励
用动态X64DBG调试了几天,找不到思路,没有明码的字符串,感觉PY编写打包成EXE的程序是不是不能用X64DBG调试,请大佬们指导一下,需要什么工具或者调试思路,谢谢。

查壳2.png (33.75 KB, 下载次数: 0)

查壳2.png

窗口4.png (243.73 KB, 下载次数: 0)

窗口4.png

窗口2.png (83.24 KB, 下载次数: 0)

窗口2.png

窗口1.png (18.59 KB, 下载次数: 0)

窗口1.png

查壳3.png (41.98 KB, 下载次数: 0)

查壳3.png

查壳1.png (55.95 KB, 下载次数: 0)

查壳1.png

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

推荐
Jx29 发表于 2025-3-23 16:27
代码写完了,emmm......
python程序是动态的,如果没有运行到那个位置就找不到要修改的位置,所以每次运行还是需要手动输入注册码

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
358059103 + 1 + 1 热心回复!

查看全部评分

推荐
Jx29 发表于 2025-3-24 10:48
编译好的文件:https://gdjx.lanzoul.com/iZAxk2rgzdkj
放到AML.exe目录下,使用的私钥如下,你可以自己生成注册码
[Asm] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANH+NMtNRzjD0fB0
II3EDy0nnv165P+gNDFvJlra1D+MOjKcfY+s5Tk3zoodbmo7D4o/Im5L6iYh2vEs
NCTNQetHPfk5INe1dPJ4T4y9lCmbdIVXNObGCiSlbGQVf1+XnB9SQs4aTNgCAj13
AulWR23q1OQOBxhCxREPjFRyDRjdAgMBAAECgYEAk/0cY7IgYUbPay/LyVzEfUQQ
7f5v6B6U6cm1NA5HykkespBKhLiKCprjub4oFEFvIDSCJUzmxNzTGWfXj5//tXGb
/fvjALaczkgaQLgG2n2vJs9oRK0UISllSoxbyPd7mSwtIMn7RdKUT1DNWlHc4bJj
dS6MjRfxClWQxei7/8ECQQD+R6L7aMPktaCKUyFPPLlhFxGnkrWDb4tJunkfx52v
v9T9K4FXsc6+wP5yRQ/LJLMEb3HGG8nJGL5TRpcuCuAlAkEA02nflNXccebKewlO
wxfqO7VY0pHGMBj5Qy6kb2RA1wpenswtq4ORrAY0bPQm5zpu/WGlfD6mb9bmx8jD
V+K8WQJBAJFjpGzbmiZLM1/j6EfGELjS1+VYnTBpttqRJHBnUmIK7V1UYsAhinTH
JLVxh3Y/pZwDnKoJeXbiDvDOi+JnlYECQD0TSAEia2YIa5Rx0uwvm36WXEuwy1WX
0WLkNaLsjoLRPxaXG9aB0vKkdD7JpfeE/Q18SSeEneaPaepriGt6WDkCQQC55KyV
ZKMYJ0NObQJFd7xp56FaJZVdNYR6OoVo5TRewOOyLXjMRsuOUE03CTj4iJclqd66
3sGiTlxCKmI1kiJW
-----END PRIVATE KEY-----

源代码:
[C++] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <chrono>
#include <thread>
 
using namespace std;
 
const wstring TARGET_EXE = L"AML.exe";
const string SEARCH_PATTERN = "32 44 32 44 32 44 32 44 32 44 34 32 34 35 34 37 34 39 34 45 32 30 35 30 35 35 34 32 34 43 34 39 34 33 32 30 34 42 34 35 35 39 32 44 32 44 32 44 32 44 32 44 30 41 34 44 34 39 34 37 36 36 34 44 34 31 33 30 34 37 34 33 35 33 37 31 34 37 35 33 34 39 36 32 33 33 34 34 35 31 34 35 34 32 34 31 35 31 35 35 34 31 34 31 33 34 34 37 34 45 34 31 34 34 34 33 34 32 36 39 35 31 34 42 34 32 36 37 35 31 34 33 35 36 34 44 36 43 33 39 36 45 36 33 35 36 35 39 33 39 35 41 36 31 36 32 35 39 34 39 36 44 33 38 36 32 35 38 33 32 36 38 37 35 36 46 35 30 34 46 36 32 30 41 34 42 36 31 37 39 35 30 33 33 34 31 36 35 37 30 34 41 34 37 33 35 35 37 37 34 37 36 35 41 35 34 34 46 36 43 34 31 36 46 33 38 35 39 33 30 34 37 33 37 36 36 35 41 36 35 34 31 36 39 33 39 34 31 36 33 36 41 34 37 34 35 36 39 36 41 34 41 36 33 35 34 37 41 34 36 35 39 33 32 37 37 33 39 37 37 33 34 37 30 33 33 34 35 34 41 35 36 37 36 37 36 37 39 33 39 34 36 34 39 37 37 37 34 34 44 34 41 30 41 33 34 35 35 33 35 33 31 35 37 36 31 33 33 33 34 36 34 37 36 35 33 35 32 34 46 36 38 33 36 37 33 33 35 36 43 35 39 35 37 34 42 34 46 35 39 37 31 36 41 32 46 37 34 34 31 34 38 36 38 36 32 34 41 35 30 37 36 35 30 37 30 35 38 37 33 36 31 32 46 35 38 34 31 36 31 33 39 34 36 37 41 33 37 36 41 37 35 36 39 37 33 35 37 36 39 37 37 32 42 35 32 37 32 35 34 35 38 35 36 34 41 34 41 37 34 34 43 30 41 36 43 37 36 35 32 35 31 34 46 35 30 34 34 34 34 33 34 36 31 36 42 34 34 35 39 32 42 33 34 37 39 36 46 35 31 34 39 34 34 34 31 35 31 34 31 34 32 30 41 32 44 32 44 32 44 32 44 32 44 34 35 34 45 34 34 32 30 35 30 35 35 34 32 34 43 34 39 34 33 32 30 34 42 34 35 35 39 32 44 32 44 32 44 32 44 32 44";    // 需要修改这些值
const string REPLACE_PATTERN = "32 44 32 44 32 44 32 44 32 44 34 32 34 35 34 37 34 39 34 45 32 30 35 30 35 35 34 32 34 43 34 39 34 33 32 30 34 42 34 35 35 39 32 44 32 44 32 44 32 44 32 44 30 41 34 44 34 39 34 37 36 36 34 44 34 31 33 30 34 37 34 33 35 33 37 31 34 37 35 33 34 39 36 32 33 33 34 34 35 31 34 35 34 32 34 31 35 31 35 35 34 31 34 31 33 34 34 37 34 45 34 31 34 34 34 33 34 32 36 39 35 31 34 42 34 32 36 37 35 31 34 34 35 32 32 46 36 41 35 34 34 43 35 34 35 35 36 33 33 34 37 37 33 39 34 38 37 37 36 34 34 33 34 33 34 45 37 38 34 31 33 38 37 34 34 41 33 35 33 37 33 39 30 41 36 35 37 35 35 34 32 46 36 46 34 34 35 31 37 38 36 32 37 39 35 41 36 31 33 32 37 34 35 31 32 46 36 41 34 34 36 46 37 39 36 45 34 38 33 32 35 30 37 32 34 46 35 35 33 35 34 45 33 38 33 36 34 42 34 38 35 37 33 35 37 31 34 46 37 37 32 42 34 42 35 30 37 39 34 41 37 35 35 33 32 42 36 46 36 44 34 39 36 34 37 32 37 38 34 43 34 34 35 31 36 42 37 41 35 35 34 38 37 32 35 32 37 41 33 33 33 35 30 41 34 46 35 33 34 34 35 38 37 34 35 38 35 34 37 39 36 35 34 35 32 42 34 44 37 36 35 41 35 31 37 30 36 44 33 33 35 33 34 36 35 36 37 41 35 34 36 44 37 38 36 37 36 46 36 42 37 30 35 37 37 38 36 42 34 36 35 38 33 39 36 36 36 43 33 35 37 37 36 36 35 35 36 42 34 43 34 46 34 37 36 42 37 41 35 39 34 31 36 37 34 39 33 39 36 34 37 37 34 43 37 30 35 36 36 42 36 34 37 34 33 36 37 34 35 34 36 42 30 41 34 34 36 37 36 33 35 39 35 31 37 33 35 35 35 32 34 34 33 34 37 38 35 35 36 33 36 37 33 30 35 39 33 33 35 31 34 39 34 34 34 31 35 31 34 31 34 32 30 41 32 44 32 44 32 44 32 44 32 44 34 35 34 45 34 34 32 30 35 30 35 35 34 32 34 43 34 39 34 33 32 30 34 42 34 35 35 39 32 44 32 44 32 44 32 44 32 44";   // 根据实际情况设置
 
struct ProcessInfo {
    DWORD pid;
    FILETIME creationTime;
    bool isFirstInstance = false;
};
 
// 全局记录第一个进程信息
ProcessInfo g_firstProcess = { 0 };
 
vector<BYTE> ParseHexPattern(const string& patternStr) {
    vector<BYTE> result;
    stringstream ss(patternStr);
    string hexByte;
 
    while (ss >> hexByte) {
        try {
            int value = stoi(hexByte, nullptr, 16);
            result.push_back(static_cast<BYTE>(value));
        }
        catch (...) {
            cerr << "[ERROR] 无效的十六进制字节: " << hexByte << endl;
            exit(EXIT_FAILURE);
        }
    }
    return result;
}
 
bool StartAMLProcess() {
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi;
 
    // 获取当前目录
    wchar_t currentDir[MAX_PATH];
    GetCurrentDirectoryW(MAX_PATH, currentDir);
    wstring exePath = wstring(currentDir) + L"\\" + TARGET_EXE;
 
    if (!CreateProcessW(
        exePath.c_str(),
        NULL,
        NULL,
        NULL,
        FALSE,
        0,
        NULL,
        currentDir,
        &si,
        &pi
    )) {
        cerr << "[ERROR] 无法启动进程 (错误码: 0x"
            << hex << GetLastError() << ")" << endl;
        return false;
    }
 
    // 记录第一个进程信息
    FILETIME creationTime, exitTime, kernelTime, userTime;
    GetProcessTimes(pi.hProcess, &creationTime, &exitTime, &kernelTime, &userTime);
 
    g_firstProcess.pid = pi.dwProcessId;
    g_firstProcess.creationTime = creationTime;
    g_firstProcess.isFirstInstance = true;
 
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
 
    cout << "已成功启动初始进程 (PID: " << pi.dwProcessId << ")" << endl;
    return true;
}
 
vector<ProcessInfo> FindAMLProcesses() {
    vector<ProcessInfo> processes;
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 
    if (snapshot == INVALID_HANDLE_VALUE) {
        cerr << "[ERROR] 创建进程快照失败 (0x"
            << hex << GetLastError() << ")" << endl;
        return processes;
    }
 
    PROCESSENTRY32W pe = { sizeof(PROCESSENTRY32W) };
 
    if (!Process32FirstW(snapshot, &pe)) {
        CloseHandle(snapshot);
        return processes;
    }
 
    do {
        if (_wcsicmp(pe.szExeFile, TARGET_EXE.c_str()) == 0) {
            HANDLE hProcess = OpenProcess(
                PROCESS_QUERY_LIMITED_INFORMATION,
                FALSE,
                pe.th32ProcessID
            );
 
            if (hProcess) {
                FILETIME creationTime, exitTime, kernelTime, userTime;
                if (GetProcessTimes(hProcess, &creationTime, &exitTime, &kernelTime, &userTime)) {
                    ProcessInfo info;
                    info.pid = pe.th32ProcessID;
                    info.creationTime = creationTime;
 
                    // 标记是否是第一个进程
                    info.isFirstInstance = (pe.th32ProcessID == g_firstProcess.pid);
 
                    processes.push_back(info);
                }
                CloseHandle(hProcess);
            }
        }
    } while (Process32NextW(snapshot, &pe));
 
    CloseHandle(snapshot);
    return processes;
}
 
DWORD WaitForSecondProcess() {
    cout << "等待第二个AML.exe进程启动..." << endl;
 
    const int maxWaitSeconds = 30;
    auto startTime = chrono::steady_clock::now();
 
    while (true) {
        auto elapsed = chrono::duration_cast<chrono::seconds>(
            chrono::steady_clock::now() - startTime).count();
        if (elapsed > maxWaitSeconds) {
            cerr << "[ERROR] 等待超时,未检测到第二个进程" << endl;
            exit(EXIT_FAILURE);
        }
 
        auto processes = FindAMLProcesses();
 
        // 过滤掉第一个进程
        vector<ProcessInfo> newProcesses;
        copy_if(processes.begin(), processes.end(), back_inserter(newProcesses),
            [](const ProcessInfo& pi) { return !pi.isFirstInstance; });
 
        // 找到最新创建的进程
        if (!newProcesses.empty()) {
            sort(newProcesses.begin(), newProcesses.end(),
                [](const ProcessInfo& a, const ProcessInfo& b) {
                    return CompareFileTime(&a.creationTime, &b.creationTime) < 0;
                });
 
            cout << "发现目标进程 (PID: " << newProcesses[0].pid << ")" << endl;
            return newProcesses[0].pid;
        }
 
        this_thread::sleep_for(chrono::seconds(1));
    }
}
 
bool MemoryOperation(HANDLE hProcess,
    const vector<BYTE>& searchPattern,
    const vector<BYTE>& replacePattern) {
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
 
    uintptr_t minAddr = (uintptr_t)sysInfo.lpMinimumApplicationAddress;
    uintptr_t maxAddr = (uintptr_t)sysInfo.lpMaximumApplicationAddress;
 
    MEMORY_BASIC_INFORMATION memInfo;
    vector<BYTE> buffer;
    size_t replaceCount = 0;
 
    for (uintptr_t addr = minAddr; addr < maxAddr; ) {
        if (!VirtualQueryEx(hProcess, (LPCVOID)addr, &memInfo, sizeof(memInfo))) {
            addr += sysInfo.dwPageSize;
            continue;
        }
 
        addr = (uintptr_t)memInfo.BaseAddress + memInfo.RegionSize;
        if (memInfo.State != MEM_COMMIT ||
            memInfo.Protect == PAGE_NOACCESS ||
            (memInfo.Protect & PAGE_GUARD)) {
            continue;
        }
 
        // 读取内存数据
        vector<BYTE> chunk(memInfo.RegionSize);
        SIZE_T bytesRead;
        if (ReadProcessMemory(hProcess, memInfo.BaseAddress,
            chunk.data(), memInfo.RegionSize, &bytesRead)) {
 
            for (size_t i = 0; i + searchPattern.size() <= bytesRead; ++i) {
                if (memcmp(chunk.data() + i,
                    searchPattern.data(),
                    searchPattern.size()) == 0) {
                    // 计算实际地址
                    uintptr_t targetAddr = (uintptr_t)memInfo.BaseAddress + i;
 
                    // 修改内存
                    DWORD oldProtect;
                    if (VirtualProtectEx(hProcess, (LPVOID)targetAddr,
                        searchPattern.size(),
                        PAGE_EXECUTE_READWRITE, &oldProtect)) {
                        SIZE_T written;
                        if (WriteProcessMemory(hProcess, (LPVOID)targetAddr,
                            replacePattern.data(),
                            replacePattern.size(), &written)) {
                            replaceCount++;
                            cout << "成功修改地址: 0x" << hex << targetAddr << endl;
                        }
                        VirtualProtectEx(hProcess, (LPVOID)targetAddr,
                            searchPattern.size(), oldProtect, &oldProtect);
                    }
                }
            }
        }
    }
 
    cout << "\n共完成 " << dec << replaceCount << " 处修改" << endl;
    return replaceCount > 0;
}
 
int main() {
    if (!StartAMLProcess()) {
        return EXIT_FAILURE;
    }
 
    DWORD targetPid = WaitForSecondProcess();
    HANDLE hTarget = OpenProcess(
        PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION,
        FALSE, targetPid);
 
    if (!hTarget) {
        DWORD err = GetLastError();
        cerr << "[ERROR] 无法打开目标进程 (0x" << hex << err << ")" << endl;
        return EXIT_FAILURE;
    }
 
    auto searchBytes = ParseHexPattern(SEARCH_PATTERN);
    auto replaceBytes = ParseHexPattern(REPLACE_PATTERN);
 
    if (searchBytes.size() != replaceBytes.size()) {
        cerr << "[ERROR] 搜索模式和替换模式长度不一致" << endl;
        CloseHandle(hTarget);
        return EXIT_FAILURE;
    }
 
    cout << "\n开始内存修改操作..." << endl;
    Sleep(1100);
    MemoryOperation(hTarget, searchBytes, replaceBytes);
 
    CloseHandle(hTarget);
    cout << "操作已完成" << endl;
    return EXIT_SUCCESS;
}
沙发
shaokui123 发表于 2025-3-4 09:54
3#
 楼主| 358059103 发表于 2025-3-4 12:34 |楼主
shaokui123 发表于 2025-3-4 09:54
字符串不是找到了吗

PY程序跟其它不同,上面没有可以跳转的代码,请指导一下,谢谢。
4#
shaokui123 发表于 2025-3-4 12:55
你程序得发出来啊,不然画饼交流啊?
5#
 楼主| 358059103 发表于 2025-3-4 13:30 |楼主
shaokui123 发表于 2025-3-4 12:55
你程序得发出来啊,不然画饼交流啊?

https://www.123912.com/s/oTbLVv-YJrSv?提取码:Tlj6
请大佬指导一下,研究一下思路,谢谢。
6#
 楼主| 358059103 发表于 2025-3-6 13:09 |楼主
shaokui123 发表于 2025-3-4 12:55
你程序得发出来啊,不然画饼交流啊?

老师,寻找到思路了没,要使用什么工具来针对这个问题呢,请指导一下,谢谢。
7#
Jx29 发表于 2025-3-16 01:07
解包后的文件
https://gdjx.lanzoul.com/iPCAc2qpt3de
不懂python,pyc文件自己找工具转,看了下核心文件好像少了个库
8#
 楼主| 358059103 发表于 2025-3-16 08:24 |楼主
Jx29 发表于 2025-3-16 01:07
解包后的文件
https://gdjx.lanzoul.com/iPCAc2qpt3de
不懂python,pyc文件自己找工具转,看了下核心文件 ...

这个只能解包调试吗,老师,谢谢了,
9#
Jx29 发表于 2025-3-16 13:31
本帖最后由 Jx29 于 2025-3-16 13:49 编辑
358059103 发表于 2025-3-16 08:24
这个只能解包调试吗,老师,谢谢了,

网上逆向python的教程太少,都是反编译pyc,直接用x64dbg爆破的似乎没有
反编译后,注册验证部分用的rsa算法,没私钥不可能算出注册码。程序效验逻辑很简单,不过我不知道改了后怎么打包回去
10#
 楼主| 358059103 发表于 2025-3-17 12:44 |楼主
Jx29 发表于 2025-3-16 13:31
网上逆向python的教程太少,都是反编译pyc,直接用x64dbg爆破的似乎没有
反编译后,注册验证部分用的rsa ...

老师说得对,这方面的教程太难找了,不过能算出算法后写个内存注册机重新打包回去,
将Python代码打包成exe文件可以通过多种工具实现,其中最常用的工具是PyInstaller、cx_Freeze和Py2exe。&#8204;

PyInstaller
PyInstaller是一个流行的Python打包工具,支持Windows、Linux和MacOS平台。使用PyInstaller打包Python代码
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-3-27 08:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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