
最近在透過cli 全自動化開發
這次比較特別一次混合三種主題,主要最近還是探索怎麼用ai去改善,自己寫code的習慣 嘗試了google gemini pro,qwen,codex 其中兩個我有訂閱,直接長出三個分身 基本上只要遵守 規劃流程和驗證 讓他們自己去迭代就可以了,比如說驗證交易系統,自動化寫交易策略,比如說可以讓他們自己使用回測框架自我回測檢查績效,再反過來重複驗證他們的策略提升報酬率,目前弄下來寫了六百多隻策略想做策略共振,實驗下來還是算滿意,確實從共振回測可以觀察出一些提前的規律,最近也有聽演講這邊有看到自動化破解這部分我比較感興趣,看來離全自動化分析破解應該不遠了xd,不過目前好像只有靜態分析,只不過後面如果開發應該大家都要去完善 mcp server 用pyhton 寫一個然後用llm 當大腦,慢慢補足這些相關經驗讓他去呼叫這些tool 就可以。
策略共振
透過策略在不同時間框架下,量化成某格時間點的震盪指標
包括每日就可以增量回測近300根k
#!/usr/bin/env bash
# update_all.sh
# 一鍵更新 top_coins 資料、策略訊號、共振圖
# 使用: bash update_all.sh
set -e # 出錯就中斷
TOP_COINS=(
BTCUSDT ETHUSDT SOLUSDT XRPUSDT DOGEUSDT BNBUSDT ADAUSDT
)
END_UTC="$(date -u +%F)" # 例如 2025-08-31(UTC)
for sym in "${TOP_COINS[@]}"; do
echo "=== [SYNC] $sym ==="
python3 sync_and_aggregate.py \
--symbols "$sym" \
--mode update \
--start-date 2021-01-01 \
--end-date "$END_UTC" \
--csv-output "{symbol}_1m_2021_2025.csv" \
--parquet-output "{symbol}_1m_2021_2025.parquet" \
--threads 8 --drop-last-days 1\
--parquet
done
# ========== STEP 2: 產生/更新策略訊號 (增量模式) ==========
for sym in "${TOP_COINS[@]}"; do
echo "=== [SIGNALS] $sym ==="
python3 gen_recoardex_incre.py \
--symbols "$sym" \
--incremental \
--warmup-bars 300 \
--max-workers 8
done
# ========== STEP 3: 去重清理 ==========
for sym in "${TOP_COINS[@]}"; do
echo "=== [DEDUP] $sym ==="
python3 dedupe_lite.py \
--signals-root ./signals_raw \
--symbol "$sym"
done
# ========== STEP 4: 畫共振圖 ==========
for sym in "${TOP_COINS[@]}"; do
echo "=== [PLOT] $sym ==="
python3 plot_resonance_fast.py --view-resample 1h\
--symbol "$sym"
done
echo "✅ [DONE] 全部 top_coins 更新完成"
額外寫了一個ga 透過deap + vectorbt 透過基因演算法去組合目前策略作空作多最佳組合,
起始10000usdt,回測73407 20 min線,在套上以前的交易機器人基本上就是無腦操作了,每天有三個機器人一直幫你作研究
idapro mcp server
ida pro 沒有的話俄羅斯網站搞一套,網路上 llm 都是用 deepseek , claude 卻沒有人用google gemini 那這部分就用 gemini 來控制ida pro
那我在windows 那麼首先我在要安裝 ida mcp server https://github.com/mrexodia/ida-pro-mcp?tab=readme-ov-file 在這邊透過
pip uninstall ida-pro-mcp
pip install https://github.com/mrexodia/ida-pro-mcp/archive/refs/heads/main.zip
ida-pro-mcp --install
安裝
你就可以在這邊看到你的mcp server run 起來

windows 的port fording 給 wsl

REM 將 172.22.96.1:13337 轉到 127.0.0.1:13337
netsh interface portproxy add v4tov4 ^
listenaddress=172.22.96.1 listenport=13337 ^
connectaddress=127.0.0.1 connectport=13337
netsh advfirewall firewall add rule name="MCP proxy 13337 (WSL)" dir=in action=allow protocol=TCP localport=13337 remoteip=172.22.96.0/20
之後若要移除:
netsh interface portproxy delete v4tov4 listenaddress=172.22.96.1 listenport=13337
netstat -ano | findstr LISTENING | findstr :13337
run 起 sse server

uv run ida-pro-mcp --transport http://172.22.96.1:8744/sse
gemini add mcp server
gemini mcp add --transport sse ida-ida http://172.22.96.1:8744/sse
gemini mcp list
ctrl + t就可以顯示 mcp server tool有哪些可以呼叫了

這邊嘗試了兩題
Wyvern CTF Challenge Write-up
This document details the reverse engineering process used to find the password for the Wyvern CTF challenge.
1. Initial Analysis
The target file, wyvern_c85f1be480808a9da350faaa6104a19b.exe, is a Linux ELF executable despite its .exe extension, a common trick in CTF challenges. The program prompts the user for a "dragon's secret" and validates it. The goal is to find the correct secret.
2. Decompiling main
The analysis began with the main function to understand the program's overall structure.
/* line: 0, address: 0x40e120 */ int __fastcall main(int argc, const char **argv, const char **envp)
/* line: 1 */ {
/* line: 2 */ __int64 v3; // rdx
/* line: 3 */ int started; // [rsp+24h] [rbp-19Ch] BYREF
/* line: 4 */ _BYTE v6[8]; // [rsp+80h] [rbp-140h] BYREF
/* line: 5 */ _BYTE v7[12]; // [rsp+88h] [rbp-138h] BYREF
/* line: 6 */ _BYTE v8[8]; // [rsp+A0h] [rbp-120h] BYREF
/* line: 7 */ _BYTE v9[8]; // [rsp+A8h] [rbp-118h] BYREF
/* line: 8 */ char s[268]; // [rsp+B0h] [rbp-110h] BYREF
/* line: 9 */ int v11; // [rsp+1BCh] [rbp-4h]
/* line: 10 */
/* line: 11, address: 0x40e12b */ v11 = 0;
/* line: 12, address: 0x40e14a */ std::operator<<<std::char_traits<char>>(&std::cout, (unsigned int)\n+-----------------------+\n, envp);
/* line: 13, address: 0x40e164 */ std::operator<<<std::char_traits<char>>(...);
/* line: 29 */ std::operator<<<std::char_traits<char>>(&std::cout, (unsigned int)"Enter the dragon's secret: ", ...);
/* line: 33, address: 0x40e1f5 */ fgets(s, 257, stdin);
/* line: 34, address: 0x40e212 */ std::allocator<char>::allocator(v8);
/* line: 35, address: 0x40e22c */ std::string::string(v9, s, v8);
/* line: 36, address: 0x40e23d */ std::allocator<char>::~allocator(v8);
/* line: 37, address: 0x40e250 */ std::string::string((std::string *)v7, (const std::string *)v9);
/* line: 38, address: 0x40e266 */ started = start_quest(v7);
/* line: 39, address: 0x40e292 */ std::string::~string((std::string *)v7);
/* line: 40, address: 0x40e2a4 */ if ( started == 4919 )
/* line: 41 */ {
/* line: 42, address: 0x40e2bd */ std::string::string((std::string *)v6, (const std::string *)v9);
/* line: 43, address: 0x40e2ce */ reward_strength(v6);
/* line: 44, address: 0x40e2df */ std::string::~string((std::string *)v6);
/* line: 45 */ }
/* line: 46 */ else
/* line: 47 */ {
/* line: 48, address: 0x40e37a */ std::operator<<<std::char_traits<char>>(&std::cout, (unsigned int)"\n[-] You have failed...\n", v3);
/* line: 52 */ }
/* line: 53, address: 0x40e397 */ v11 = 0;
/* line: 54, address: 0x40e3a8 */ std::string::~string((std::string *)v9);
/* line: 55, address: 0x40e3b0 */ return v11;
/* line: 56 */ }
Finding: The program reads user input, passes it to start_quest, and checks if the return value is exactly 4919. This is the main bypass condition.
3. Analyzing start_quest
The next step was to decompile start_quest to understand how it generates its return value.
/* line: 0, address: 0x404350 */ __int64 __fastcall start_quest(std::string *a1)
{
// ... heavily obfuscated code ...
/* line: 49 */ v5 = std::string::length(v10) - 1LL != legend >> 2;
// ...
/* line: 83 */ if ( v5 ) // This is the WRONG length path
/* line: 84 */ {
// ... returns a failure value
/* line: 95 */ }
/* line: 96 */ else // This is the CORRECT length path
/* line: 97 */ {
// ...
/* line: 108 */ v4 = sanitize_input(v6);
// ...
/* line: 125 */ return v3; // v3 eventually gets the value from v4
/* line: 126 */ }
}
Findings:
- Length Check: The function first checks if the input length (minus the newline character) is equal to
legend >> 2. - Content Check: If the length is correct, the input is passed to another function,
sanitize_input, whose return value becomes the return value ofstart_quest.
4. Finding the Password Length
To pass the length check, the value of the global variable legend was needed. Reading it by name or address failed, but reading the raw memory at its address (0x610138) succeeded.
- Memory at
0x610138:0x73 0x0 0x0 0x0 0x64 0x0 0x0 0x0 - This was interpreted as two 32-bit integers:
115and100. - The code for populating the
heroarray (see below) contained 28 elements. This confirmed the correctlegendvalue was115. - Calculation:
115 >> 2(115 divided by 4) is28. The required password length is 28.
5. The Core Algorithm: transform_input and sanitize_input
Decompiling sanitize_input revealed a loop that called transform_input on an ever-growing prefix of the user's input and compared it to values from a hero array.
Decompiling transform_input revealed its simple purpose:
/* line: 0, address: 0x4014b0 */ __int64 __fastcall transform_input(__int64 a1)
{
// ... obfuscated loop ...
/* line: 71 */ *v15 += *v2; // *v15 is the accumulator, *v2 is the character
// ...
/* line: 126 */ return v7; // returns the final sum
}
Finding: transform_input simply returns the sum of the ASCII values of the characters it receives.
This leads to the central validation logic in sanitize_input:
sum(password[0...i]) == hero[i] for i in 0..27.
6. Deriving the Solution
The validation logic can be reversed to solve for each character of the password:
password[0]=hero[0]password[1]=hero[1] - hero[0]password[2]=hero[2] - hero[1]- General Formula:
password[i] = hero[i] - hero[i-1]
7. Finding the hero Array
Reading the hero global variable from memory failed, showing it was uninitialized. Analysis of start_quest showed that it builds the hero vector at runtime by pushing a series of hardcoded values.
/* line: 21, address: 0x4043f0 */ std::vector<int>::push_back(&hero, &secret_100);
/* line: 22, address: 0x404409 */ std::vector<int>::push_back(&hero, &secret_214);
/* line: 23, address: 0x404422 */ std::vector<int>::push_back(&hero, &secret_266);
// ... and so on
The values of the hero array were extracted directly from these variable names:
[100, 214, 266, 369, 417, 527, 622, 733, 847, 942, 1054, 1106, 1222, 1336, 1441, 1540, 1589, 1686, 1796, 1891, 1996, 2112, 2165, 2260, 2336, 2412, 2498, 2575]
8. Final Password Calculation
Applying the formula password[i] = hero[i] - hero[i-1] to the hero array:
p[0] = 100-> 'd'p[1] = 214 - 100 = 114-> 'r'p[2] = 266 - 214 = 52-> '4'p[3] = 369 - 266 = 103-> 'g'p[4] = 417 - 369 = 48-> '0'p[5] = 527 - 417 = 110-> 'n'p[6] = 622 - 527 = 95-> '_'p[7] = 733 - 622 = 111-> 'o'p[8] = 847 - 733 = 114-> 'r'p[9] = 942 - 847 = 95-> '_'p[10] = 1054 - 942 = 112-> 'p'p[11] = 1106 - 1054 = 52-> '4'p[12] = 1222 - 1106 = 116-> 't'p[13] = 1336 - 1222 = 114-> 'r'p[14] = 1441 - 1336 = 105-> 'i'p[15] = 1540 - 1441 = 99-> 'c'p[16] = 1589 - 1540 = 49-> '1'p[17] = 1686 - 1589 = 97-> 'a'p[18] = 1796 - 1686 = 110-> 'n'p[19] = 1891 - 1796 = 95-> '_'p[20] = 1996 - 1891 = 105-> 'i'p[21] = 2112 - 1996 = 116-> 't'p[22] = 2165 - 2112 = 53-> '5'p[23] = 2260 - 2165 = 95-> '_'p[24] = 2336 - 2260 = 76-> 'L'p[25] = 2412 - 2336 = 76-> 'L'p[26] = 2498 - 2412 = 86-> 'V'p[27] = 2575 - 2498 = 77-> 'M'
Final Password
dr4g0n_or_p4tric1an_it5_LLVM
Baby Rev CTF Challenge Write-up
This document details the process used to solve the baby_rev CTF challenge.
1. Challenge Description
The goal of this challenge is to decompile the binary and inspect the code to find a Base64 encoded flag.
2. Solution Process
The analysis followed the provided solution steps, which proved to be a direct path to the flag.
Step 1: Locating the init Function
Following the provided hints, the analysis focused on the init function, which was suspected of initializing the flag variable. The function's address was found using get_function_by_name.
- Tool:
get_function_by_name(name = "init") - Result: The address of
initwas found to be0x1276.
Step 2: Decompiling init and Finding the Encoded Flag
The decompile_function tool was used on the address 0x1276. The decompiled code immediately revealed a qmemcpy operation containing a long, suspicious string ending in ==.
/* line: 0, address: 0x1276 */ __int64 init()
{
__int64 result; // rax
_QWORD v1[16]; // [rsp+0h] [rbp-90h] BYREF
int j; // [rsp+88h] [rbp-8h]
int i; // [rsp+8Ch] [rbp-4h]
__int64 savedregs; // [rsp+90h] [rbp+0h] BYREF
/* line: 8, address: 0x1288 */ qmemcpy(
v1,
"Y3Nhd2N0ZntOM3Yzcl9wcjA3M2M3X3MzbnMxNzF2M18xbmYwcm00NzEwbl91czFuZ19qdXM3XzNuYzBkMW5nIV8jM25jMGQxbmdfMXNfbjB0XzNuY3J5cDcxMG4hfQ==",
sizeof(v1));
/* line: 12, address: 0x1356 */ result = 0x3D3D51666834474DLL;
/* line: 13, address: 0x1364 */ for ( i = 0; i <= 15; ++i )
{
/* line: 15, address: 0x136d */ for ( j = 0; j <= 7; ++j )
{
/* line: 17, address: 0x13af */ result = (__int64)&flag + 8 * i + j;
/* line: 18, address: 0x13b2 */ *(_BYTE *)result = *((_BYTE *)&savedregs + 8 * i + j - 144);
}
}
/* line: 21, address: 0x13ca */ return result;
}
The string Y3Nhd2N0ZntOM3Yzcl9wcjA3M2M3X3MzbnMxNzF2M18xbmYwcm00NzEwbl91czFuZ19qdXM3XzNuYzBkMW5nIV8jM25jMGQxbmdfMXNfbjB0XzNuY3J5cDcxMG4hfQ== was identified as the Base64 encoded flag.
Step 3: Decoding the Flag
The final step was to decode the Base64 string. This was done using a simple Python command via the run_shell_command tool.
- Command:
python3 -c 'import base64; print(base64.b64decode("Y3Nhd2N0ZntOM3Yzcl9wcjA3M2M3X3MzbnMxNzF2M18xbmYwcm00NzEwbl91czFuZ19qdXM3XzNuYzBkMW5nIV8jM25jMGQxbmdfMXNfbjB0XzNuY3J5cDcxMG4hfQ==").decode("utf-8"))'
3. Conclusion
The decoded string revealed the final flag.
Flag: csawctf{N3v3r_pr073c7_s3ns171v3_1nf0rm4710n_us1ng_jus7_3nc0d1ng!_#3nc0d1ng_1s_n0t_3ncryp710n!}
The challenge serves as a reminder that encoding is not a form of security and can be easily reversed.
兩題ctf 都可以找到正解並且把步驟都列出來。還蠻扯,不知道是不是上網找解答哈哈,第二題也還好,定位到那一個function 按f5就可以轉成偽ccode 看到那串後在
python3 -c 'import base64; print(base64.b64decode("Y3Nhd2N0ZntOM3Yzcl9wcjA3M2M3X3MzbnMxNzF2M18xbmYwcm00NzEwb… csawctf{N3v3r_pr073c7_s3ns171v3_1nf0rm4710n_us1ng_jus7_3nc0d1ng!_#3nc0d1ng_1s_n0t_3ncryp710n!}

Comments