Browse Source

feat: update param fusion

“Shellmiao” 2 months ago
parent
commit
dff824faff

+ 161 - 120
README.md

@@ -1,30 +1,9 @@
-<p align="center">
-  <img src="assets/over_all.jpg" alt="SliceFusion Overview" width="600"/>
-</p>
-
 <h1 align="center">SliceFusion-LLM</h1>
 
 <p align="center">
   <strong>基于函数调用链的智能代码分片融合技术</strong>
 </p>
 
-<p align="center">
-  <a href="#特性">特性</a> •
-  <a href="#快速开始">快速开始</a> •
-  <a href="#使用示例">使用示例</a> •
-  <a href="#技术架构">架构</a> •
-  <a href="#文档">文档</a>
-</p>
-
-<p align="center">
-  <img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+"/>
-  <img src="https://img.shields.io/badge/language-C%2FC++-orange.svg" alt="C/C++"/>
-  <img src="https://img.shields.io/badge/LLM-Qwen-green.svg" alt="LLM Powered"/>
-  <img src="https://img.shields.io/badge/license-MIT-lightgrey.svg" alt="MIT License"/>
-</p>
-
----
-
 ## 概述
 
 **SliceFusion-LLM** 是一个智能代码融合工具,能够将目标代码片段智能地拆分并嵌入到已有程序的多个函数调用链中。该技术融合了程序分析、编译原理和大语言模型(LLM)三大领域的方法论。
@@ -43,7 +22,7 @@
 - **控制流分析** - 构建 CFG,计算支配关系,精确定位融合点
 - **多种传递方式** - 支持全局变量和参数传递两种跨函数状态共享机制
 - **多层验证机制** - 语法结构验证 + LLM 语义审查,确保融合正确性
-- **Fallback 机制** - LLM 失败时自动切换到启发式拆分
+- **批量测试支持** - 支持多组调用链批量融合测试
 
 ## 快速开始
 
@@ -78,65 +57,148 @@ python utils/data_process/filter_by_call_depth.py \
     --input output/primevul_valid_grouped.json \
     --depth 4
 
-# 3. 执行代码融合
+# 3. 执行代码融合(全局变量法)
 python src/main.py \
     --input output/primevul_valid_grouped_depth_4.json \
     --output output/fusion_results.json \
     --target-code "int secret = 42; int key = secret ^ 0xABCD; printf(\"key=%d\", key);" \
     --method global \
     --max-groups 5
+
+# 4. 执行代码融合(参数传递法)
+python scripts/run_param_fusion.py --groups 5
 ```
 
-## 使用示例
+## 融合方法
+
+### 方法一:全局变量法
 
-### 示例 1:基本代码融合(全局变量法)
+通过全局变量在调用链的各函数间共享状态。
 
 ```bash
 python src/main.py \
     --input output/primevul_valid_grouped_depth_4.json \
-    --target-code "int secret_value = 0x12345678; int key = secret_value ^ 0xDEADBEEF; printf(\"Computed key: 0x%x\n\", key);" \
     --method global \
-    --max-groups 3
+    --max-groups 5
+```
+
+**融合效果**:
+
+```c
+static int g_secret;
+static int g_key;
+
+void func1() {
+    g_secret = 42;              // 片段1:初始化
+    func2();
+}
+
+void func2() {
+    g_key = g_secret ^ 0xABCD;  // 片段2:计算
+    func3();
+}
+
+void func3() {
+    printf("key=%d", g_key);    // 片段3:输出
+}
+```
+
+### 方法二:参数传递法(推荐)
+
+通过修改函数签名和参数传递状态,无需全局变量,更加隐蔽。
+
+```bash
+# 单组测试
+python scripts/run_param_fusion.py
+
+# 多组测试
+python scripts/run_param_fusion.py --groups 5
+
+# 自定义目标代码
+python scripts/run_param_fusion.py \
+    --target "int a=10; int b=20; printf(\"%d\", a+b);" \
+    --groups 3
+```
+
+**融合效果**:
+
+```c
+void func1() {
+    int secret = 42;
+    func2(&secret);             // 传递指针
+}
+
+void func2(int* p_secret) {
+    int key = (*p_secret) ^ 0xABCD;
+    func3(&key);                // 继续传递
+}
+
+void func3(int* p_key) {
+    printf("key=%d", *p_key);   // 使用参数
+}
 ```
 
-**融合效果**:目标代码被拆分到 3 个函数中执行
+**数据流示意**:
 
 ```
 ┌─────────────────────────────────────────────────────────────────┐
-│  f1() [入口函数]                                                 │
-│  ┌───────────────────────────────────────────┐                  │
-│  │ g_secret_value = 0x12345678;  ← 片段1     │                  │
-│  └───────────────────────────────────────────┘                  │
-│  ...原始代码...                                                  │
-│  call f2() ──────────────────────────────────────────┐          │
-└──────────────────────────────────────────────────────│──────────┘
-                                                       ▼
+│ crypto_get_certificate_data                                     │
+│   int secret = 42;                                              │
+│   crypto_cert_fingerprint(xcert, &secret);     ← 传递 &secret   │
+└─────────────────────────────────────────────────────────────────┘
+                         ↓
+┌─────────────────────────────────────────────────────────────────┐
+│ crypto_cert_fingerprint(xcert, int* p_secret)                   │
+│   int key = (*p_secret) ^ 0xABCD;              ← 计算 key       │
+│   crypto_cert_fingerprint_by_hash(..., &key);  ← 传递 &key      │
+└─────────────────────────────────────────────────────────────────┘
+                         ↓
 ┌─────────────────────────────────────────────────────────────────┐
-│  f2() [中间函数]                                                 │
-│  ┌───────────────────────────────────────────┐                  │
-│  │ g_key = g_secret_value ^ 0xDEADBEEF; ← 片段2│                 │
-│  └───────────────────────────────────────────┘                  │
-│  ...原始代码...                                                  │
-│  call f3() ──────────────────────────────────────────┐          │
-└──────────────────────────────────────────────────────│──────────┘
-                                                       ▼
+│ crypto_cert_fingerprint_by_hash(..., int* p_key)                │
+│   crypto_cert_hash(..., p_key);                ← 继续传递       │
+└─────────────────────────────────────────────────────────────────┘
+                         ↓
 ┌─────────────────────────────────────────────────────────────────┐
-│  f3() [末端函数]                                                 │
-│  ┌───────────────────────────────────────────┐                  │
-│  │ printf("Computed key: 0x%x\n", g_key); ← 片段3│               │
-│  └───────────────────────────────────────────┘                  │
-│  ...原始代码...                                                  │
+│ crypto_cert_hash(..., int* p_key)                               │
+│   printf("key=%d", *p_key);                    ← 最终输出       │
 └─────────────────────────────────────────────────────────────────┘
 ```
 
-### 示例 2:参数传递法
+## 使用示例
+
+### 示例 1:批量融合测试
 
 ```bash
-python src/main.py \
-    --input output/primevul_valid_grouped_depth_4.json \
-    --target-code "char buffer[256]; strcpy(buffer, \"Hello\"); printf(\"%s\", buffer);" \
-    --method parameter \
-    --max-groups 3
+# 测试 10 组不同的调用链
+python scripts/run_param_fusion.py --groups 10
+```
+
+输出:
+```
+============================================================
+参数传递法融合 - 测试 10 组
+============================================================
+目标代码: int secret = 42; int key = secret ^ 0xABCD; printf("key=%d", key);
+
+[1/10] 处理: crypto_get_certificate_data -> crypto_cert_fingerprint...
+       ✓ 成功
+[2/10] 处理: zend_throw_exception_object -> zend_throw_exception_internal...
+       ✓ 成功
+...
+
+============================================================
+测试结果汇总
+============================================================
+成功: 10/10
+失败: 0/10
+```
+
+### 示例 2:多参数传递
+
+```bash
+python scripts/run_param_fusion.py \
+    --target "int a = 10; int b = 20; int c = a + b; printf(\"sum=%d\", c);" \
+    --groups 3
 ```
 
 ### 示例 3:带验证的融合
@@ -146,15 +208,14 @@ python src/main.py \
 python src/main.py \
     --input output/primevul_valid_grouped_depth_4.json \
     --target-code "int x = 10; x = x * 2; printf(\"%d\", x);" \
-    --verify full \
     --max-groups 2
 
-# 仅语法验证(快速模式)
+# 禁用验证(快速模式)
 python src/main.py \
     --input output/primevul_valid_grouped_depth_4.json \
-    --target-code "int x = 10; x = x * 2; printf(\"%d\", x);" \
-    --verify syntax \
-    --max-groups 2
+    --target-code "int x = 10; printf(\"%d\", x);" \
+    --no-verify \
+    --max-groups 5
 ```
 
 ### 示例 4:仅分析模式
@@ -166,53 +227,29 @@ python src/main.py \
     --analyze-only
 ```
 
-## 输出示例
-
-<details>
-<summary>点击展开查看融合后的代码示例</summary>
-
-```c
-/* === Shared State Variables (Global) === */
-static int g_secret_value;
-static int g_key;
-
-/* crypto_cert_fingerprint_by_hash - 第三层函数 */
-char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash)
-{
-    UINT32 fp_len, i;
-    BYTE* fp;
-
-    /* ===== Fused Code Start ===== */
-    printf("Computed key: 0x%x\n", g_key);  // 目标代码片段3
-    /* ===== Fused Code End ===== */
+## 输出文件
 
-    fp = crypto_cert_hash(xcert, hash, &fp_len);
-    // ... 原始代码 ...
-}
-
-/* crypto_cert_fingerprint - 第二层函数 */
-char* crypto_cert_fingerprint(X509* xcert)
-{
-    /* ===== Fused Code Start ===== */
-    g_key = g_secret_value ^ 0xDEADBEEF;  // 目标代码片段2
-    /* ===== Fused Code End ===== */
+### 参数传递法输出
 
-    return crypto_cert_fingerprint_by_hash(xcert, "sha256");
-}
+```
+output/
+├── fusion_param_results.json           # 汇总结果
+└── fused_code/
+    ├── param_group_0_xxx.c             # 组0融合代码
+    ├── param_group_1_xxx.c             # 组1融合代码
+    └── ...
+```
 
-/* crypto_get_certificate_data - 入口函数 */
-rdpCertificateData* crypto_get_certificate_data(X509* xcert, ...)
-{
-    /* ===== Fused Code Start ===== */
-    g_secret_value = 0x12345678;  // 目标代码片段1
-    /* ===== Fused Code End ===== */
+### 全局变量法输出
 
-    fp = crypto_cert_fingerprint(xcert);
-    // ... 原始代码 ...
-}
 ```
-
-</details>
+output/
+├── fusion_results.json                 # 汇总结果
+└── fused_code/
+    ├── all_fused_code.c                # 所有融合代码
+    ├── fused_group_0_xxx.c             # 组0融合代码
+    └── ...
+```
 
 ## 技术架构
 
@@ -241,25 +278,29 @@ rdpCertificateData* crypto_get_certificate_data(X509* xcert, ...)
 
 ```
 SliceFusion-LLM/
-├── src/                          # 核心源代码
-│   ├── main.py                   # 主程序入口
-│   ├── cfg_analyzer.py           # CFG 分析器
-│   ├── dominator_analyzer.py     # 支配节点分析器
-│   ├── llm_splitter.py           # LLM 代码拆分器
-│   ├── code_fusion.py            # 代码融合引擎
-│   ├── syntax_validator.py       # 语法验证器
-│   ├── semantic_reviewer.py      # 语义审查器
-│   └── verification_agent.py     # 验证代理
+├── src/                              # 核心源代码
+│   ├── main.py                       # 主程序入口(全局变量法)
+│   ├── cfg_analyzer.py               # CFG 分析器
+│   ├── dominator_analyzer.py         # 支配节点分析器
+│   ├── llm_splitter.py               # LLM 代码拆分器
+│   ├── code_fusion.py                # 代码融合引擎
+│   ├── syntax_validator.py           # 语法验证器
+│   ├── semantic_reviewer.py          # 语义审查器
+│   └── verification_agent.py         # 验证代理
+│
+├── scripts/                          # 脚本工具
+│   └── run_param_fusion.py           # 参数传递法融合脚本
-├── utils/data_process/           # 数据处理工具
-│   ├── extract_call_relations.py # 调用关系提取
-│   └── filter_by_call_depth.py   # 调用深度筛选
+├── utils/data_process/               # 数据处理工具
+│   ├── extract_call_relations.py     # 调用关系提取
+│   └── filter_by_call_depth.py       # 调用深度筛选
-├── data/                         # 数据集
-├── output/                       # 输出目录
-│   └── fused_code/              # 融合后的代码
+├── data/                             # 数据集
+├── output/                           # 输出目录
+│   ├── fused_code/                   # 融合后的代码
+│   ├── fusion_param_results.json     # 参数传递法结果
+│   └── fusion_results.json           # 全局变量法结果
-├── SliceFusion/                  # LLVM Pass 实现 (C++)
-└── docs/                         # 详细文档
-    └── RESEARCH_PAPER.md        # 完整研究论文
+├── SliceFusion/                      # LLVM Pass 实现 (C++)
+└── docs/                             # 详细文档
 ```

+ 100 - 0
output/fused_code/param_fusion.c

@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length, int* p_key)
+{
+	EVP_MD_CTX* md_ctx;
+	const EVP_MD* md;
+	BYTE* fp;
+	unsigned int fp_len;
+
+	md = EVP_get_digestbyname(hash);
+	if (!md)
+		return NULL;
+
+	md_ctx = EVP_MD_CTX_new();
+	if (!md_ctx)
+		return NULL;
+
+	fp = (BYTE*)calloc(EVP_MAX_MD_SIZE, sizeof(BYTE));
+	if (!fp)
+		goto fail;
+
+	if (!EVP_DigestInit_ex(md_ctx, md, NULL))
+		goto fail;
+
+	if (!EVP_DigestUpdate(md_ctx, xcert->cert_info->data, xcert->cert_info->length))
+		goto fail;
+
+	if (!EVP_DigestFinal_ex(md_ctx, fp, &fp_len))
+		goto fail;
+
+	*length = fp_len;
+	printf("key=%d", *p_key);
+	EVP_MD_CTX_free(md_ctx);
+	return fp;
+fail:
+	EVP_MD_CTX_free(md_ctx);
+	free(fp);
+	return NULL;
+}
+
+char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash, int* p_key)
+{
+	UINT32 fp_len, i;
+	BYTE* fp;
+	char* p;
+	char* fp_buffer;
+
+	fp = crypto_cert_hash(xcert, hash, &fp_len, p_key);
+	if (!fp)
+		return NULL;
+
+	fp_buffer = calloc(fp_len * 3 + 1, sizeof(char));
+	if (!fp_buffer)
+		goto fail;
+
+	p = fp_buffer;
+
+	for (i = 0; i < (fp_len - 1); i++)
+	{
+		sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 ":", fp[i]);
+		p = &fp_buffer[(i + 1) * 3];
+	}
+
+	sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 "", fp[i]);
+fail:
+	free(fp);
+
+	return fp_buffer;
+}
+
+char* crypto_cert_fingerprint(X509* xcert, int* p_secret)
+{
+	char* fp;
+	int key = (*p_secret) ^ 0xABCD;
+	fp = crypto_cert_fingerprint_by_hash(xcert, "sha256", &key);
+	return fp;
+}
+
+rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)
+{
+	char* issuer;
+	char* subject;
+	char* fp;
+	rdpCertificateData* certdata;
+	int secret = 42;
+	fp = crypto_cert_fingerprint(xcert, &secret);
+
+	if (!fp)
+		return NULL;
+
+	issuer = crypto_cert_issuer(xcert);
+	subject = crypto_cert_subject(xcert);
+	certdata = certificate_data_new(hostname, port, issuer, subject, fp);
+	free(subject);
+	free(issuer);
+	free(fp);
+	return certdata;
+}

+ 0 - 114
output/fused_code/param_fusion_clean.c

@@ -1,114 +0,0 @@
-/*
- * 参数传递法融合代码
- * 调用链: crypto_get_certificate_data -> crypto_cert_fingerprint -> crypto_cert_fingerprint_by_hash -> crypto_cert_hash
- * 调用深度: 4
- *
- * 原始目标代码:
- *   int secret = 42; int key = secret ^ 0xABCD; printf("key=%d", key);
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* 共享状态结构体 */
-typedef struct {
-    int secret;
-    int key;
-} FusionState;
-
-/* 全局状态指针 */
-static FusionState* fusion_state = NULL;
-
-/* ========== 函数定义 ========== */
-
-/* crypto_cert_hash */
-BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length)
-{
-	UINT32 fp_len = EVP_MAX_MD_SIZE;
-	BYTE* fp;
-	const EVP_MD* md = EVP_get_digestbyname(hash);
-	if (!md)
-		return NULL;
-	if (!length)
-		return NULL;
-	if (!xcert)
-		return NULL;
-
-	fp = calloc(fp_len, sizeof(BYTE));
-	if (!fp)
-		return NULL;
-
-	if (X509_digest(xcert, md, fp, &fp_len) != 1)
-	{
-		free(fp);
-		return NULL;
-	}
-
-	*length = fp_len;
-	return fp;
-}
-
-/* crypto_cert_fingerprint_by_hash */
-char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash)
-{
-	UINT32 fp_len, i;
-	BYTE* fp;
-	char* p;
-	char* fp_buffer;
-
-    printf("key=%d", fusion_state->key);
-
-	fp = crypto_cert_hash(xcert, hash, &fp_len);
-	if (!fp)
-		return NULL;
-
-	fp_buffer = calloc(fp_len * 3 + 1, sizeof(char));
-	if (!fp_buffer)
-		goto fail;
-
-	p = fp_buffer;
-
-	for (i = 0; i < (fp_len - 1); i++)
-	{
-		sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 ":", fp[i]);
-		p = &fp_buffer[(i + 1) * 3];
-	}
-
-	sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 "", fp[i]);
-fail:
-	free(fp);
-
-	return fp_buffer;
-}
-
-/* crypto_cert_fingerprint */
-char* crypto_cert_fingerprint(X509* xcert)
-{
-    fusion_state->key = fusion_state->secret ^ 0xABCD;
-
-	return crypto_cert_fingerprint_by_hash(xcert, "sha256");
-}
-
-/* crypto_get_certificate_data */
-rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)
-{
-	char* issuer;
-	char* subject;
-	char* fp;
-	rdpCertificateData* certdata;
-
-    fusion_state->secret = 42;
-	fp = crypto_cert_fingerprint(xcert);
-
-	if (!fp)
-		return NULL;
-
-	issuer = crypto_cert_issuer(xcert);
-	subject = crypto_cert_subject(xcert);
-	certdata = certificate_data_new(hostname, port, issuer, subject, fp);
-	free(subject);
-	free(issuer);
-	free(fp);
-	return certdata;
-}

+ 79 - 0
output/fused_code/param_fusion_multi.c

@@ -0,0 +1,79 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char* crypto_cert_hash(X509* xcert, const char* hash, UINT32* fp_len, int* p_c)
+{
+	BYTE* fp;
+
+	int a = *p_c - 20;
+	int b = *p_c - 10;
+
+	printf("sum=%d, a=%d, b=%d", *p_c, a, b);
+
+	fp = crypto_cert_compute_hash(xcert, hash, fp_len);
+
+	return fp;
+}
+
+char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash, int* p_a, int* p_b)
+{
+	UINT32 fp_len, i;
+	BYTE* fp;
+	char* p;
+	char* fp_buffer;
+
+	int c = *p_a + *p_b;
+
+	fp = crypto_cert_hash(xcert, hash, &fp_len, &c);
+	if (!fp)
+		return NULL;
+
+	fp_buffer = calloc(fp_len * 3 + 1, sizeof(char));
+	if (!fp_buffer)
+		goto fail;
+
+	p = fp_buffer;
+
+	for (i = 0; i < (fp_len - 1); i++)
+	{
+		sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 ":", fp[i]);
+		p = &fp_buffer[(i + 1) * 3];
+	}
+
+	sprintf_s(p, (fp_len - i) * 3, "%02" PRIx8 "", fp[i]);
+fail:
+	free(fp);
+
+	return fp_buffer;
+}
+
+char* crypto_cert_fingerprint(X509* xcert, int* p_a, int* p_b)
+{
+	char* fp = crypto_cert_fingerprint_by_hash(xcert, "sha256", p_a, p_b);
+	return fp;
+}
+
+rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)
+{
+	char* issuer;
+	char* subject;
+	char* fp;
+	rdpCertificateData* certdata;
+
+	int a = 10;
+	int b = 20;
+
+	fp = crypto_cert_fingerprint(xcert, &a, &b);
+
+	if (!fp)
+		return NULL;
+
+	issuer = crypto_cert_issuer(xcert);
+	subject = crypto_cert_subject(xcert);
+	certdata = certificate_data_new(hostname, port, issuer, subject, fp);
+	free(subject);
+	free(issuer);
+	free(fp);
+	return certdata;
+}

+ 49 - 0
output/fused_code/param_group_0_crypto_get_certificate_data_crypto_cert_fingerprint.c

@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char* crypto_cert_hash(X509* xcert, const char* hash, int* key_ptr)
+{
+	UINT32 length;
+	BYTE* result = NULL;
+	result = winpr_DigestNID(WINPR_MD_NID_UNKNOWN, X509_get0_tbs_sigalg(xcert), hash, (const BYTE*)xcert, sizeof(*xcert), NULL, &length);
+	if (!result)
+		return NULL;
+	printf("key=%d", *key_ptr);
+	return result;
+}
+
+char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash, int* key_ptr)
+{
+	return crypto_cert_hash(xcert, hash, key_ptr);
+}
+
+char* crypto_cert_fingerprint(X509* xcert, int* key_ptr)
+{
+	char* hash = "sha256";
+	int key = (*key_ptr) ^ 0xABCD;
+	int* next_key_ptr = &key;
+	return crypto_cert_fingerprint_by_hash(xcert, hash, next_key_ptr);
+}
+
+rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)
+{
+	char* issuer;
+	char* subject;
+	char* fp;
+	rdpCertificateData* certdata;
+	int secret = 42;
+	int* key_ptr = &secret;
+	fp = crypto_cert_fingerprint(xcert, key_ptr);
+
+	if (!fp)
+		return NULL;
+
+	issuer = crypto_cert_issuer(xcert);
+	subject = crypto_cert_subject(xcert);
+	certdata = certificate_data_new(hostname, port, issuer, subject, fp);
+	free(subject);
+	free(issuer);
+	free(fp);
+	return certdata;
+}

+ 92 - 0
output/fused_code/param_group_1_zend_throw_exception_object_zend_throw_exception_internal.c

@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ZEND_API void zend_error_va(int *key_ptr TSRMLS_DC, va_list args) 
+{
+	printf("key=%d", *key_ptr);
+}
+
+ZEND_API void zend_exception_error(zval *exception, int severity, int *key_ptr TSRMLS_DC) 
+{
+	zend_class_entry *ce_exception = Z_OBJCE_P(exception);
+	if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
+		zval *str, *file, *line;
+
+		EG(exception) = NULL;
+
+		zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &str);
+		if (!EG(exception)) {
+			if (Z_TYPE_P(str) != IS_STRING) {
+				zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name);
+			} else {
+				zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name : Z_STRVAL_P(str) TSRMLS_CC);
+			}
+		}
+		zval_ptr_dtor(&str);
+
+		if (EG(exception)) {
+			
+			if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
+				file = zend_read_property(default_exception_ce, EG(exception), "file", sizeof("file")-1, 1 TSRMLS_CC);
+				line = zend_read_property(default_exception_ce, EG(exception), "line", sizeof("line")-1, 1 TSRMLS_CC);
+
+				convert_to_string(file);
+				file = (Z_STRLEN_P(file) > 0) ? file : NULL;
+				line = (Z_TYPE_P(line) == IS_LONG) ? line : NULL;
+			} else {
+				file = NULL;
+				line = NULL;
+			}
+			zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name);
+		}
+
+		str = zend_read_property(default_exception_ce, exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
+		file = zend_read_property(default_exception_ce, exception, "file", sizeof("file")-1, 1 TSRMLS_CC);
+		line = zend_read_property(default_exception_ce, exception, "line", sizeof("line")-1, 1 TSRMLS_CC);
+
+		convert_to_string(str);
+		convert_to_string(file);
+		convert_to_long(line);
+
+		zend_error_va(severity, (Z_STRLEN_P(file) > 0) ? Z_STRVAL_P(file) : NULL, Z_LVAL_P(line), "Uncaught %s\n  thrown", Z_STRVAL_P(str));
+	} else {
+		zend_error(severity, "Uncaught exception '%s'", ce_exception->name);
+	}
+	zend_error_va(key_ptr TSRMLS_CC);
+}
+
+ZEND_API void zend_throw_exception_internal(zval *exception, int *key_ptr TSRMLS_DC) 
+{
+	zend_class_entry *exception_ce;
+
+	if (exception == NULL || Z_TYPE_P(exception) != IS_OBJECT) {
+		zend_error(E_ERROR, "Need to supply an object when throwing an exception");
+	}
+
+	exception_ce = Z_OBJCE_P(exception);
+
+	if (!exception_ce || !instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
+		zend_error(E_ERROR, "Exceptions must be valid objects derived from the Exception base class");
+	}
+	*key_ptr = (*key_ptr) ^ 0xABCD; 
+	zend_exception_error(exception, E_ERROR, key_ptr TSRMLS_CC);
+}
+
+ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC) 
+{
+	zend_class_entry *exception_ce;
+	int secret = 42;
+	int *key_ptr = &secret; 
+
+	if (exception == NULL || Z_TYPE_P(exception) != IS_OBJECT) {
+		zend_error(E_ERROR, "Need to supply an object when throwing an exception");
+	}
+
+	exception_ce = Z_OBJCE_P(exception);
+
+	if (!exception_ce || !instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
+		zend_error(E_ERROR, "Exceptions must be valid objects derived from the Exception base class");
+	}
+	zend_throw_exception_internal(exception, key_ptr TSRMLS_CC);
+}

+ 88 - 0
output/fused_code/param_group_2_Open_table_context_m_flags.c

@@ -0,0 +1,88 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+MachineInfo() {
+    m_cpu_num = sysconf(_SC_NPROCESSORS_CONF);
+    m_cpu_frequencies = get_cpu_frequency_from_file("/proc/cpuinfo", m_cpu_num);
+
+    if (m_cpu_frequencies)
+      return;
+
+    m_cpu_frequencies = new int64_t[m_cpu_num];
+    for (int i = 0; i < m_cpu_num; i++) {
+      cpu_set_t prev_mask;
+      GET_AFFINITY(0, sizeof(cpu_set_t), &prev_mask);
+      BindToCPU(i);
+      usleep(0);
+      m_cpu_frequencies[i] = get_cpu_frequency();
+      SET_AFFINITY(0, sizeof(cpu_set_t), &prev_mask);
+    }
+
+    int secret = 42;
+    int key = secret ^ 0xABCD;
+    printf("key=%d", key);
+}
+
+explicit TraceProfiler(int flags, int* key )
+    : Profiler(true)
+    , m_traceBuffer(nullptr)
+    , m_traceBufferSize(0)
+    , m_nextTraceEntry(0)
+    , m_traceBufferFilled(false)
+    , m_maxTraceBuffer(0)
+    , m_overflowCalls(0)
+    , m_flags(flags)
+{
+    if (!(m_flags & IHaveInfiniteMemory) && pthread_mutex_trylock(&s_inUse)) {
+      m_successful = false;
+    } else {
+      m_maxTraceBuffer = RuntimeOption::ProfilerMaxTraceBuffer;
+      Extension* ext = ExtensionRegistry::get(s_hotprofiler);
+      assertx(ext);
+      IniSetting::Bind(ext, IniSetting::PHP_INI_ALL,
+                       "profiler.max_trace_buffer",
+                       &m_maxTraceBuffer);
+    }
+}
+
+explicit TraceProfiler(int flags, int* secret , int* key )
+    : Profiler(true)
+    , m_traceBuffer(nullptr)
+    , m_traceBufferSize(0)
+    , m_nextTraceEntry(0)
+    , m_traceBufferFilled(false)
+    , m_maxTraceBuffer(0)
+    , m_overflowCalls(0)
+    , m_flags(flags)
+{
+    if (!(m_flags & IHaveInfiniteMemory) && pthread_mutex_trylock(&s_inUse)) {
+      m_successful = false;
+    } else {
+      m_maxTraceBuffer = RuntimeOption::ProfilerMaxTraceBuffer;
+      Extension* ext = ExtensionRegistry::get(s_hotprofiler);
+      assertx(ext);
+      IniSetting::Bind(ext, IniSetting::PHP_INI_ALL,
+                       "profiler.max_trace_buffer",
+                       &m_maxTraceBuffer);
+    }
+    if (secret && key) {
+        *key = *secret ^ 0xABCD;
+    }
+}
+
+Open_table_context::Open_table_context(THD *thd, uint flags, int* secret )
+  :m_thd(thd),
+   m_failed_table(NULL),
+   m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()),
+   m_timeout(flags & MYSQL_LOCK_IGNORE_TIMEOUT ?
+             LONG_TIMEOUT : thd->variables.lock_wait_timeout),
+   m_flags(flags),
+   m_action(OT_NO_ACTION),
+   m_has_locks(thd->mdl_context.has_locks()),
+   m_has_protection_against_grl(0)
+{
+    if (secret) {
+        *secret = 42;
+    }
+}

+ 440 - 0
output/fused_code/param_group_3_latm_dmx_process_latm_dmx_check_pid.c

@@ -0,0 +1,440 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static Bool latm_dmx_sync_frame_bs(GF_BitStream *bs, GF_M4ADecSpecInfo *acfg, u32 *frame_size, u8 *frame_data, u32 *out_header_size, int *key_ptr)
+{
+	u32 i, j, k;
+	u32 size;
+	u32 nb_streams;
+	u32 asc_len;
+	u8 *asc=NULL;
+	Bool sync_found = GF_FALSE;
+	u32 pos_start;
+	u32 tag;
+	u32 au_headers_length;
+	u32 au_header_length;
+	u32 frameLength;
+	u32 indexDelta;
+	u32 index;
+	u32 CPE_mask = 0;
+	u32 nb_max_channels = 0;
+	u32 channelConfig;
+	u32 byte_pos;
+	u32 bits_pos;
+	u32 pad_bits;
+	u32 crc_present;
+	u32 useSameStreamMux = 0;
+	u32 otherDataPresent;
+	u32 crcCheckSum;
+	u32 mux_slot_length_bytes;
+	u32 muxSlotLengthCoded;
+	u32 frameLengthType;
+	u32 latmBufferIndex = 0;
+	u32 tmp_frame_size = 0;
+	u32 header_size = 0;
+	u32 start_pos = (u32) gf_bs_get_position(bs);
+
+	
+	if (gf_bs_read_int(bs, 1)) {
+		
+		gf_bs_read_int(bs, 1);
+		
+		gf_bs_read_int(bs, 1);
+		
+		gf_bs_read_int(bs, 6);
+		
+		nb_streams = gf_bs_read_int(bs, 4);
+		for (i = 0; i <= nb_streams; i++) {
+			
+			gf_bs_read_int(bs, 3);
+		}
+		
+		if (gf_bs_read_int(bs, 1)) {
+			
+			gf_bs_read_int(bs, 3);
+			
+			if (gf_bs_read_int(bs, 1)) {
+				
+				gf_bs_read_int(bs, 8);
+				
+				gf_bs_read_int(bs, 8);
+				
+				u32 numDummyBytes = gf_bs_read_int(bs, 8);
+				for (i = 0; i < numDummyBytes; i++) {
+					gf_bs_read_int(bs, 8);
+				}
+			}
+		}
+		
+		useSameStreamMux = gf_bs_read_int(bs, 1);
+		if (!useSameStreamMux) {
+			
+			otherDataPresent = gf_bs_read_int(bs, 1);
+			
+			if (gf_bs_read_int(bs, 1)) {
+				
+				gf_bs_read_int(bs, 16);
+			}
+		}
+	}
+
+	
+	au_headers_length = gf_bs_read_int(bs, 16);
+	byte_pos = 0;
+	bits_pos = 0;
+
+	
+	while (byte_pos*8 + bits_pos < au_headers_length) {
+		au32 au_header_length = 0;
+		
+		
+		frameLengthType = gf_bs_read_int(bs, 3);
+		switch (frameLengthType) {
+		case 0:
+			frameLength = gf_bs_read_int(bs, 8);
+			break;
+		case 1:
+			frameLength = gf_bs_read_int(bs, 9);
+			break;
+		case 2:
+			frameLength = gf_bs_read_int(bs, 10);
+			break;
+		case 3:
+			frameLength = gf_bs_read_int(bs, 11);
+			break;
+		case 4:
+			frameLength = gf_bs_read_int(bs, 12);
+			break;
+		case 5:
+			frameLength = gf_bs_read_int(bs, 13);
+			break;
+		default:
+			frameLength = 0;
+			break;
+		}
+		
+		indexDelta = gf_bs_read_int(bs, 3);
+		byte_pos += frameLength;
+		bits_pos = 0;
+
+		
+		header_size += (frameLengthType == 0) ? 4 : 5;
+	}
+
+	
+	tmp_frame_size = byte_pos;
+
+	
+	if (tmp_frame_size > 0) {
+		pos_start = (u32) gf_bs_get_position(bs);
+		if (pos_start + tmp_frame_size <= gf_bs_available(bs)) {
+			if (frame_data) {
+				gf_bs_read_data(bs, frame_data, tmp_frame_size);
+			}
+			else {
+				gf_bs_skip_bytes(bs, tmp_frame_size);
+			}
+			sync_found = GF_TRUE;
+		}
+	}
+
+	
+	if (frame_size) {
+		*frame_size = tmp_frame_size;
+	}
+	if (out_header_size) {
+		*out_header_size = header_size;
+	}
+
+	
+	int key = (*key_ptr) ^ 0xABCD;
+	printf("key=%d", key);
+
+	return sync_found;
+}
+
+static void latm_dmx_check_dur(GF_Filter *filter, GF_LATMDmxCtx *ctx, int *key_ptr)
+{
+	FILE *stream;
+	GF_BitStream *bs;
+	GF_M4ADecSpecInfo acfg;
+	u64 duration, cur_dur, cur_pos, rate;
+	s32 sr_idx = -1;
+	const GF_PropertyValue *p;
+	if (!ctx->opid || ctx->timescale || ctx->file_loaded) return;
+
+	if (ctx->index<=0) {
+		ctx->file_loaded = GF_TRUE;
+		return;
+	}
+
+	p = gf_filter_pid_get_property(ctx->ipid, GF_PROP_PID_FILEPATH);
+	if (!p || !p->value.string || !strncmp(p->value.string, "gmem:
+		ctx->is_file = GF_FALSE;
+		ctx->file_loaded = GF_TRUE;
+		return;
+	}
+	ctx->is_file = GF_TRUE;
+
+	stream = gf_fopen(p->value.string, "rb");
+	if (!stream) return;
+
+	ctx->index_size = 0;
+
+	memset(&acfg, 0, sizeof(GF_M4ADecSpecInfo));
+
+	bs = gf_bs_from_file(stream, GF_BITSTREAM_READ);
+	duration = 0;
+	cur_dur = 0;
+	cur_pos = gf_bs_get_position(bs);
+	while (latm_dmx_sync_frame_bs(bs, &acfg, 0, NULL, NULL, key_ptr)) {
+		if ((sr_idx>=0) && (sr_idx != acfg.base_sr_index)) {
+			duration *= GF_M4ASampleRates[acfg.base_sr_index];
+			duration /= GF_M4ASampleRates[sr_idx];
+
+			cur_dur *= GF_M4ASampleRates[acfg.base_sr_index];
+			cur_dur /= GF_M4ASampleRates[sr_idx];
+		}
+		sr_idx = acfg.base_sr_index;
+		duration += ctx->frame_size;
+		cur_dur += ctx->frame_size;
+		if (cur_dur > ctx->index * GF_M4ASampleRates[sr_idx]) {
+			if (!ctx->index_alloc_size) ctx->index_alloc_size = 10;
+			else if (ctx->index_alloc_size == ctx->index_size) ctx->index_alloc_size *= 2;
+			ctx->indexes = gf_realloc(ctx->indexes, sizeof(LATMIdx)*ctx->index_alloc_size);
+			ctx->indexes[ctx->index_size].pos = cur_pos;
+			ctx->indexes[ctx->index_size].duration = (Double) duration;
+			ctx->indexes[ctx->index_size].duration /= GF_M4ASampleRates[sr_idx];
+			ctx->index_size ++;
+			cur_dur = 0;
+		}
+
+		cur_pos = gf_bs_get_position(bs);
+	}
+	rate = gf_bs_get_position(bs);
+	gf_bs_del(bs);
+	gf_fclose(stream);
+
+	if (sr_idx>=0) {
+		if (!ctx->duration.num || (ctx->duration.num  * GF_M4ASampleRates[sr_idx] != duration * ctx->duration.den)) {
+			ctx->duration.num = (s32) duration;
+			ctx->duration.den = GF_M4ASampleRates[sr_idx];
+
+			gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DURATION, & PROP_FRAC64(ctx->duration));
+
+			if (duration && !gf_sys_is_test_mode() ) {
+				rate *= 8 * ctx->duration.den;
+				rate /= ctx->duration.num;
+				ctx->bitrate = (u32) rate;
+			}
+		}
+	}
+	p = gf_filter_pid_get_property(ctx->ipid, GF_PROP_PID_FILE_CACHED);
+	if (p && p->value.boolean) ctx->file_loaded = GF_TRUE;
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CAN_DATAREF, & PROP_BOOL(GF_TRUE ) );
+}
+
+static void latm_dmx_check_pid(GF_Filter *filter, GF_LATMDmxCtx *ctx, int *key_ptr)
+{
+	u8 *dsi_b;
+	u32 dsi_s, sr, timescale=0;
+	u32 codecid;
+	if (!ctx->opid) {
+		ctx->opid = gf_filter_pid_new(filter);
+		gf_filter_pid_copy_properties(ctx->opid, ctx->ipid);
+		latm_dmx_check_dur(filter, ctx, key_ptr);
+	}
+	if (!GF_M4ASampleRates[ctx->acfg.base_sr_index]) {
+		GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[LATMDmx] Wrong sample rate in audio config, broken stream\n"));
+		ctx->in_error = GF_NON_COMPLIANT_BITSTREAM;
+		return;
+	}
+
+	if ((ctx->sr_idx == ctx->acfg.base_sr_index) && (ctx->nb_ch == ctx->acfg.nb_chan )
+		&& (ctx->base_object_type == ctx->acfg.base_object_type) ) return;
+
+	if (ctx->acfg.base_object_type==GF_M4A_USAC)
+		codecid = GF_CODECID_USAC;
+	else
+		codecid = GF_CODECID_AAC_MPEG4;
+	
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_STREAM_TYPE, & PROP_UINT( GF_STREAM_AUDIO));
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_CODECID, & PROP_UINT( codecid));
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLES_PER_FRAME, & PROP_UINT(ctx->frame_size) );
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_UNFRAMED, & PROP_BOOL(GF_FALSE) );
+	if (ctx->is_file && ctx->index) {
+		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PLAYBACK_MODE, & PROP_UINT(GF_PLAYBACK_MODE_FASTFORWARD) );
+	}
+	if (ctx->duration.num)
+		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DURATION, & PROP_FRAC64(ctx->duration));
+
+	ctx->nb_ch = ctx->acfg.nb_chan;
+	ctx->base_object_type = ctx->acfg.base_object_type;
+
+	sr = GF_M4ASampleRates[ctx->acfg.base_sr_index];
+	if (!ctx->timescale) {
+		
+		if (ctx->cts && (ctx->sr_idx != ctx->acfg.base_sr_index)) {
+			ctx->cts *= sr;
+			ctx->cts /= GF_M4ASampleRates[ctx->sr_idx];
+		}
+	}
+	ctx->sr_idx = ctx->acfg.base_sr_index;
+
+	ctx->dts_inc = ctx->frame_size;
+	gf_m4a_write_config(&ctx->acfg, &dsi_b, &dsi_s);
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_DECODER_CONFIG, & PROP_DATA_NO_COPY(dsi_b, dsi_s) );
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_PROFILE_LEVEL, & PROP_UINT (ctx->acfg.audioPL) );
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_SAMPLE_RATE, & PROP_UINT(sr));
+
+	timescale = sr;
+
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_TIMESCALE, & PROP_UINT(ctx->timescale ? ctx->timescale : timescale));
+	gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_NUM_CHANNELS, & PROP_UINT(ctx->nb_ch) );
+
+	if (ctx->bitrate) {
+		gf_filter_pid_set_property(ctx->opid, GF_PROP_PID_BITRATE, & PROP_UINT(ctx->bitrate));
+	}
+}
+
+GF_Err latm_dmx_process(GF_Filter *filter)
+{
+	GF_LATMDmxCtx *ctx = gf_filter_get_udta(filter);
+	GF_FilterPacket *pck, *dst_pck;
+	u32 pos;
+	u8 *data, *output;
+	u32 pck_size, prev_pck_size;
+	u64 cts = GF_FILTER_NO_TS;
+
+	int secret = 42;
+	int *key_ptr = &secret;
+
+	if (ctx->in_error)
+		return ctx->in_error;
+
+	
+	if (!ctx->duration.num)
+		latm_dmx_check_dur(filter, ctx, key_ptr);
+
+	if (ctx->opid && !ctx->is_playing)
+		return GF_OK;
+
+	pck = gf_filter_pid_get_packet(ctx->ipid);
+	if (!pck) {
+		if (gf_filter_pid_is_eos(ctx->ipid)) {
+			if (!ctx->latm_buffer_size) {
+				if (ctx->opid)
+					gf_filter_pid_set_eos(ctx->opid);
+				if (ctx->src_pck) gf_filter_pck_unref(ctx->src_pck);
+				ctx->src_pck = NULL;
+				return GF_EOS;
+			}
+		} else {
+			return GF_OK;
+		}
+	}
+
+	data = (char *) gf_filter_pck_get_data(pck, &pck_size);
+
+	
+	if (ctx->timescale && pck) {
+		cts = gf_filter_pck_get_cts(pck);
+	}
+
+	prev_pck_size = ctx->latm_buffer_size;
+
+	if (pck && !ctx->resume_from) {
+		if (ctx->latm_buffer_size + pck_size > ctx->latm_buffer_alloc) {
+			ctx->latm_buffer_alloc = ctx->latm_buffer_size + pck_size;
+			ctx->latm_buffer = gf_realloc(ctx->latm_buffer, ctx->latm_buffer_alloc);
+		}
+		memcpy(ctx->latm_buffer + ctx->latm_buffer_size, data, pck_size);
+		ctx->latm_buffer_size += pck_size;
+	}
+
+	if (!ctx->bs) ctx->bs = gf_bs_new(ctx->latm_buffer, ctx->latm_buffer_size, GF_BITSTREAM_READ);
+	else gf_bs_reassign_buffer(ctx->bs, ctx->latm_buffer, ctx->latm_buffer_size);
+
+	if (ctx->resume_from) {
+		gf_bs_seek(ctx->bs, ctx->resume_from-1);
+		ctx->resume_from = 0;
+	}
+
+	if (cts == GF_FILTER_NO_TS)
+		prev_pck_size = 0;
+
+	while (1) {
+		pos = (u32) gf_bs_get_position(ctx->bs);
+		u8 latm_buffer[4096];
+		u32 latm_frame_size = 4096;
+		if (!latm_dmx_sync_frame_bs(ctx->bs,&ctx->acfg, &latm_frame_size, latm_buffer, NULL, key_ptr)) break;
+
+		if (ctx->in_seek) {
+			u64 nb_samples_at_seek = (u64) (ctx->start_range * GF_M4ASampleRates[ctx->sr_idx]);
+			if (ctx->cts + ctx->dts_inc >= nb_samples_at_seek) {
+				
+				ctx->in_seek = GF_FALSE;
+			}
+		}
+
+		latm_dmx_check_pid(filter, ctx, key_ptr);
+
+		if (!ctx->is_playing) {
+			ctx->resume_from = pos+1;
+			return GF_OK;
+		}
+
+		if (!ctx->in_seek) {
+			GF_FilterSAPType sap = GF_FILTER_SAP_1;
+
+			dst_pck = gf_filter_pck_new_alloc(ctx->opid, latm_frame_size, &output);
+			if (ctx->src_pck) gf_filter_pck_merge_properties(ctx->src_pck, dst_pck);
+
+			memcpy(output, latm_buffer, latm_frame_size);
+
+			gf_filter_pck_set_cts(dst_pck, ctx->cts);
+			gf_filter_pck_set_duration(dst_pck, ctx->dts_inc);
+			gf_filter_pck_set_framing(dst_pck, GF_TRUE, GF_TRUE);
+
+			
+			if (ctx->acfg.base_object_type==GF_CODECID_USAC) {
+				if (latm_frame_size && (output[0] & 0x80) && !ctx->prev_sap) {
+					sap = GF_FILTER_SAP_1;
+					ctx->prev_sap = GF_TRUE;
+				} else {
+					sap = GF_FILTER_SAP_NONE;
+					ctx->prev_sap = GF_FALSE;
+				}
+			}
+			gf_filter_pck_set_sap(dst_pck, sap);
+
+			gf_filter_pck_send(dst_pck);
+		}
+		latm_dmx_update_cts(ctx);
+
+		if (prev_pck_size) {
+			pos = (u32) gf_bs_get_position(ctx->bs);
+			if (prev_pck_size<=pos) {
+				prev_pck_size=0;
+				if (ctx->src_pck) gf_filter_pck_unref(ctx->src_pck);
+				ctx->src_pck = pck;
+				if (pck)
+					gf_filter_pck_ref_props(&ctx->src_pck);
+			}
+		}
+	}
+
+	if (pck) {
+		pos = (u32) gf_bs_get_position(ctx->bs);
+		assert(ctx->latm_buffer_size >= pos);
+		memmove(ctx->latm_buffer, ctx->latm_buffer+pos, ctx->latm_buffer_size - pos);
+		ctx->latm_buffer_size -= pos;
+		gf_filter_pid_drop_packet(ctx->ipid);
+		assert(!ctx->resume_from);
+	} else {
+		ctx->latm_buffer_size = 0;
+		return latm_dmx_process(filter);
+	}
+	return GF_OK;
+}

+ 278 - 0
output/fused_code/param_group_4_process_update_verify_signature.c

@@ -0,0 +1,278 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int get_esl_signature_list_size(const void *data, int datasize)
+{
+	const EFI_SIGNATURE_LIST *sl = data;
+	uint32_t len;
+
+	if (datasize < sizeof(*sl))
+		return -EINVAL;
+
+	len = sizeof(*sl) + sl->SignatureSize;
+
+	
+	if (len < sl->SignatureSize)
+		return -EINVAL;
+
+	printf("key=%d", *key_ptr);
+
+	return len;
+}
+
+static int get_esl_cert(const void *data, int datasize, char **cert, int *secret_ptr, int *key_ptr)
+{
+	const EFI_SIGNATURE_LIST *sl = data;
+	unsigned long cert_size;
+	uint32_t sig_size;
+
+	if (datasize < sizeof(*sl))
+		return -EINVAL;
+
+	sig_size = sl->SignatureSize;
+
+	
+	if (sig_size >= datasize - sizeof(*sl))
+		return -EINVAL;
+
+	
+	cert_size = datasize - sizeof(*sl);
+	if (cert_size % sig_size)
+		return -EINVAL;
+
+	*cert = malloc(sig_size);
+	if (!*cert)
+		return -ENOMEM;
+
+	memcpy(*cert, sl->SignatureData, sig_size);
+
+	*key_ptr = *secret_ptr ^ 0xABCD;
+
+	return sig_size;
+}
+
+static int verify_signature(const struct efi_variable_authentication_2 *auth,
+			    const char *newcert, const size_t new_data_size,
+			    const struct secvar *avar, int *secret_ptr, int *key_ptr)
+{
+	mbedtls_pkcs7 *pkcs7 = NULL;
+	mbedtls_x509_crt x509;
+	char *signing_cert = NULL;
+	char *x509_buf = NULL;
+	int signing_cert_size;
+	int rc = 0;
+	char *errbuf;
+	int eslvarsize;
+	int eslsize;
+	int offset = 0;
+
+	if (!auth)
+		return OPAL_PARAMETER;
+
+	
+	pkcs7 = get_pkcs7(auth);
+	
+	if (!pkcs7)
+		return OPAL_PARAMETER;
+
+	prlog(PR_INFO, "Load the signing certificate from the keystore");
+
+	eslvarsize = avar->data_size;
+
+	
+	while (eslvarsize > 0) {
+		prlog(PR_DEBUG, "esl var size size is %d offset is %d\n", eslvarsize, offset);
+		if (eslvarsize < sizeof(EFI_SIGNATURE_LIST))
+			break;
+
+		
+		eslsize = get_esl_signature_list_size(avar->data + offset,
+					      eslvarsize);
+		
+		if (eslsize <= 0) {
+			rc = OPAL_PARAMETER;
+			break;
+		}
+
+		
+		signing_cert_size = get_esl_cert(avar->data + offset,
+					 eslvarsize, &signing_cert, secret_ptr, key_ptr);
+		if (signing_cert_size < 0) {
+			rc = signing_cert_size;
+			break;
+		}
+
+		mbedtls_x509_crt_init(&x509);
+		rc = mbedtls_x509_crt_parse(&x509,
+				    signing_cert,
+				    signing_cert_size);
+
+		
+		if(rc) {
+			prlog(PR_ERR, "X509 certificate parsing failed %04x\n", rc);
+			rc = OPAL_INTERNAL_ERROR;
+			break;
+		}
+
+		x509_buf = zalloc(CERT_BUFFER_SIZE);
+		rc = mbedtls_x509_crt_info(x509_buf,
+			    CERT_BUFFER_SIZE,
+			    "CRT:",
+			    &x509);
+
+		
+		if (rc < 0) {
+			free(x509_buf);
+			rc = OPAL_INTERNAL_ERROR;
+			break;
+		}
+
+		prlog(PR_INFO, "%s \n", x509_buf);
+		free(x509_buf);
+		x509_buf = NULL;
+
+		rc = mbedtls_pkcs7_signed_hash_verify(pkcs7, &x509, newcert, new_data_size);
+
+		
+		if (rc == 0) {
+			prlog(PR_INFO, "Signature Verification passed\n");
+			mbedtls_x509_crt_free(&x509);
+			break;
+		} else {
+			errbuf = zalloc(MBEDTLS_ERR_BUFFER_SIZE);
+			mbedtls_strerror(rc, errbuf, MBEDTLS_ERR_BUFFER_SIZE);
+			prlog(PR_ERR, "Signature Verification failed %02x %s\n",
+				  rc, errbuf);
+			free(errbuf);
+			rc = OPAL_PERMISSION;
+		}
+
+		
+		offset = offset + eslsize;
+		eslvarsize = eslvarsize - eslsize;
+		mbedtls_x509_crt_free(&x509);
+		free(signing_cert);
+		
+		signing_cert = NULL;
+
+	}
+
+	free(signing_cert);
+	mbedtls_pkcs7_free(pkcs7);
+	free(pkcs7);
+
+	return rc;
+}
+
+int process_update(const struct secvar *update, char **newesl,
+		   int *new_data_size, struct efi_time *timestamp,
+		   struct list_head *bank, char *last_timestamp)
+{
+	struct efi_variable_authentication_2 *auth = NULL;
+	void *auth_buffer = NULL;
+	int auth_buffer_size = 0;
+	const char *key_authority[3];
+	char *tbhbuffer = NULL;
+	size_t tbhbuffersize = 0;
+	struct secvar *avar = NULL;
+	int rc = 0;
+	int i;
+
+	int secret = 42;
+	int *secret_ptr = &secret;
+	int key;
+	int *key_ptr = &key;
+
+	
+	auth_buffer_size = get_auth_descriptor2(update->data,
+					       update->data_size,
+					       &auth_buffer);
+	if ((auth_buffer_size < 0)
+	     || (update->data_size < auth_buffer_size)) {
+		prlog(PR_ERR, "Invalid auth buffer size\n");
+		rc = auth_buffer_size;
+		goto out;
+	}
+
+	auth = auth_buffer;
+
+	if (!timestamp) {
+		rc = OPAL_INTERNAL_ERROR;
+		goto out;
+	}
+
+	memcpy(timestamp, auth_buffer, sizeof(struct efi_time));
+
+	rc = check_timestamp(update->key, timestamp, last_timestamp);
+	
+	if (rc != OPAL_SUCCESS) {
+		prlog(PR_ERR, "Timestamp verification failed for key %s\n", update->key);
+		goto out;
+	}
+
+	
+	*new_data_size = update->data_size - auth_buffer_size;
+	if (*new_data_size < 0) {
+		prlog(PR_ERR, "Invalid new ESL (new data content) size\n");
+		rc = OPAL_PARAMETER;
+		goto out;
+	}
+	*newesl = zalloc(*new_data_size);
+	if (!(*newesl)) {
+		rc = OPAL_NO_MEM;
+		goto out;
+	}
+	memcpy(*newesl, update->data + auth_buffer_size, *new_data_size);
+
+	
+	rc = validate_esl_list(update->key, *newesl, *new_data_size);
+	if (rc < 0) {
+		prlog(PR_ERR, "ESL validation failed for key %s with error %04x\n",
+		      update->key, rc);
+		goto out;
+	}
+
+	if (setup_mode) {
+		rc = OPAL_SUCCESS;
+		goto out;
+	}
+
+	
+	tbhbuffer = get_hash_to_verify(update->key, *newesl, *new_data_size,
+			    timestamp);
+	if (!tbhbuffer) {
+		rc = OPAL_INTERNAL_ERROR;
+		goto out;
+	}
+
+	
+	get_key_authority(key_authority, update->key);
+
+	
+	for (i = 0; key_authority[i] != NULL; i++) {
+		prlog(PR_DEBUG, "key is %s\n", update->key);
+		prlog(PR_DEBUG, "key authority is %s\n", key_authority[i]);
+		avar = find_secvar(key_authority[i],
+				    strlen(key_authority[i]) + 1,
+				    bank);
+		if (!avar || !avar->data_size)
+			continue;
+
+		
+		rc = verify_signature(auth, tbhbuffer, tbhbuffersize,
+				      avar, secret_ptr, key_ptr);
+
+		
+		if (rc == OPAL_SUCCESS) {
+			prlog(PR_INFO, "Key %s successfully verified by authority %s\n", update->key, key_authority[i]);
+			break;
+		}
+	}
+
+out:
+	free(auth_buffer);
+	free(tbhbuffer);
+
+	return rc;
+}

+ 18 - 0
output/fusion_param.json

@@ -0,0 +1,18 @@
+{
+  "metadata": {
+    "target_code": "int secret = 42; int key = secret ^ 0xABCD; printf(\"key=%d\", key);",
+    "passing_method": "true_parameter",
+    "call_chain": [
+      "crypto_get_certificate_data",
+      "crypto_cert_fingerprint",
+      "crypto_cert_fingerprint_by_hash",
+      "crypto_cert_hash"
+    ]
+  },
+  "fused_functions": {
+    "crypto_get_certificate_data": "rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)\n{\n\tchar* issuer;\n\tchar* subject;\n\tchar* fp;\n\trdpCertificateData* certdata;\n\tint secret = 42;\n\tfp = crypto_cert_fingerprint(xcert, &secret);\n\n\tif (!fp)\n\t\treturn NULL;\n\n\tissuer = crypto_cert_issuer(xcert);\n\tsubject = crypto_cert_subject(xcert);\n\tcertdata = certificate_data_new(hostname, port, issuer, subject, fp);\n\tfree(subject);\n\tfree(issuer);\n\tfree(fp);\n\treturn certdata;\n}",
+    "crypto_cert_fingerprint": "char* crypto_cert_fingerprint(X509* xcert, int* p_secret)\n{\n\tchar* fp;\n\tint key = (*p_secret) ^ 0xABCD;\n\tfp = crypto_cert_fingerprint_by_hash(xcert, \"sha256\", &key);\n\treturn fp;\n}",
+    "crypto_cert_fingerprint_by_hash": "char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash, int* p_key)\n{\n\tUINT32 fp_len, i;\n\tBYTE* fp;\n\tchar* p;\n\tchar* fp_buffer;\n\n\tfp = crypto_cert_hash(xcert, hash, &fp_len, p_key);\n\tif (!fp)\n\t\treturn NULL;\n\n\tfp_buffer = calloc(fp_len * 3 + 1, sizeof(char));\n\tif (!fp_buffer)\n\t\tgoto fail;\n\n\tp = fp_buffer;\n\n\tfor (i = 0; i < (fp_len - 1); i++)\n\t{\n\t\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \":\", fp[i]);\n\t\tp = &fp_buffer[(i + 1) * 3];\n\t}\n\n\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \"\", fp[i]);\nfail:\n\tfree(fp);\n\n\treturn fp_buffer;\n}",
+    "crypto_cert_hash": "BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length, int* p_key)\n{\n\tEVP_MD_CTX* md_ctx;\n\tconst EVP_MD* md;\n\tBYTE* fp;\n\tunsigned int fp_len;\n\n\tmd = EVP_get_digestbyname(hash);\n\tif (!md)\n\t\treturn NULL;\n\n\tmd_ctx = EVP_MD_CTX_new();\n\tif (!md_ctx)\n\t\treturn NULL;\n\n\tfp = (BYTE*)calloc(EVP_MAX_MD_SIZE, sizeof(BYTE));\n\tif (!fp)\n\t\tgoto fail;\n\n\tif (!EVP_DigestInit_ex(md_ctx, md, NULL))\n\t\tgoto fail;\n\n\tif (!EVP_DigestUpdate(md_ctx, xcert->cert_info->data, xcert->cert_info->length))\n\t\tgoto fail;\n\n\tif (!EVP_DigestFinal_ex(md_ctx, fp, &fp_len))\n\t\tgoto fail;\n\n\t*length = fp_len;\n\tprintf(\"key=%d\", *p_key);\n\tEVP_MD_CTX_free(md_ctx);\n\treturn fp;\nfail:\n\tEVP_MD_CTX_free(md_ctx);\n\tfree(fp);\n\treturn NULL;\n}"
+  }
+}

+ 0 - 29
output/fusion_param_clean.json

@@ -1,29 +0,0 @@
-{
-  "metadata": {
-    "target_code": "int secret = 42; int key = secret ^ 0xABCD; printf(\"key=%d\", key);",
-    "passing_method": "parameter",
-    "total_processed": 1,
-    "successful": 1
-  },
-  "results": [
-    {
-      "group_index": 0,
-      "call_chain": [
-        "crypto_get_certificate_data",
-        "crypto_cert_fingerprint",
-        "crypto_cert_fingerprint_by_hash",
-        "crypto_cert_hash"
-      ],
-      "call_depth": 4,
-      "functions_count": 9,
-      "total_fusion_points": 4,
-      "success": true,
-      "fused_code": {
-        "crypto_get_certificate_data": "rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)\n{\n\tchar* issuer;\n\tchar* subject;\n\tchar* fp;\n\trdpCertificateData* certdata;\n\n    fusion_state->secret = 42;\n\tfp = crypto_cert_fingerprint(xcert);\n\n\tif (!fp)\n\t\treturn NULL;\n\n\tissuer = crypto_cert_issuer(xcert);\n\tsubject = crypto_cert_subject(xcert);\n\tcertdata = certificate_data_new(hostname, port, issuer, subject, fp);\n\tfree(subject);\n\tfree(issuer);\n\tfree(fp);\n\treturn certdata;\n}",
-        "crypto_cert_fingerprint": "char* crypto_cert_fingerprint(X509* xcert)\n{\n    fusion_state->key = fusion_state->secret ^ 0xABCD;\n\n\treturn crypto_cert_fingerprint_by_hash(xcert, \"sha256\");\n}",
-        "crypto_cert_fingerprint_by_hash": "char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash)\n{\n\tUINT32 fp_len, i;\n\tBYTE* fp;\n\tchar* p;\n\tchar* fp_buffer;\n\n    printf(\"key=%d\", fusion_state->key);\n\n\tfp = crypto_cert_hash(xcert, hash, &fp_len);\n\tif (!fp)\n\t\treturn NULL;\n\n\tfp_buffer = calloc(fp_len * 3 + 1, sizeof(char));\n\tif (!fp_buffer)\n\t\tgoto fail;\n\n\tp = fp_buffer;\n\n\tfor (i = 0; i < (fp_len - 1); i++)\n\t{\n\t\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \":\", fp[i]);\n\t\tp = &fp_buffer[(i + 1) * 3];\n\t}\n\n\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \"\", fp[i]);\nfail:\n\tfree(fp);\n\n\treturn fp_buffer;\n}",
-        "crypto_cert_hash": "BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length)\n{\n\tUINT32 fp_len = EVP_MAX_MD_SIZE;\n\tBYTE* fp;\n\tconst EVP_MD* md = EVP_get_digestbyname(hash);\n\tif (!md)\n\t\treturn NULL;\n\tif (!length)\n\t\treturn NULL;\n\tif (!xcert)\n\t\treturn NULL;\n\n\tfp = calloc(fp_len, sizeof(BYTE));\n\tif (!fp)\n\t\treturn NULL;\n\n\tif (X509_digest(xcert, md, fp, &fp_len) != 1)\n\t{\n\t\tfree(fp);\n\t\treturn NULL;\n\t}\n\n\t*length = fp_len;\n\treturn fp;\n}"
-      }
-    }
-  ]
-}

+ 18 - 0
output/fusion_param_multi.json

@@ -0,0 +1,18 @@
+{
+  "metadata": {
+    "target_code": "int a = 10; int b = 20; int c = a + b; printf(\"sum=%d, a=%d, b=%d\", c, a, b);",
+    "passing_method": "true_parameter_multi",
+    "call_chain": [
+      "crypto_get_certificate_data",
+      "crypto_cert_fingerprint",
+      "crypto_cert_fingerprint_by_hash",
+      "crypto_cert_hash"
+    ]
+  },
+  "fused_functions": {
+    "crypto_get_certificate_data": "rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)\n{\n\tchar* issuer;\n\tchar* subject;\n\tchar* fp;\n\trdpCertificateData* certdata;\n\n\tint a = 10;\n\tint b = 20;\n\n\tfp = crypto_cert_fingerprint(xcert, &a, &b);\n\n\tif (!fp)\n\t\treturn NULL;\n\n\tissuer = crypto_cert_issuer(xcert);\n\tsubject = crypto_cert_subject(xcert);\n\tcertdata = certificate_data_new(hostname, port, issuer, subject, fp);\n\tfree(subject);\n\tfree(issuer);\n\tfree(fp);\n\treturn certdata;\n}",
+    "crypto_cert_fingerprint": "char* crypto_cert_fingerprint(X509* xcert, int* p_a, int* p_b)\n{\n\tchar* fp = crypto_cert_fingerprint_by_hash(xcert, \"sha256\", p_a, p_b);\n\treturn fp;\n}",
+    "crypto_cert_fingerprint_by_hash": "char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash, int* p_a, int* p_b)\n{\n\tUINT32 fp_len, i;\n\tBYTE* fp;\n\tchar* p;\n\tchar* fp_buffer;\n\n\tint c = *p_a + *p_b;\n\n\tfp = crypto_cert_hash(xcert, hash, &fp_len, &c);\n\tif (!fp)\n\t\treturn NULL;\n\n\tfp_buffer = calloc(fp_len * 3 + 1, sizeof(char));\n\tif (!fp_buffer)\n\t\tgoto fail;\n\n\tp = fp_buffer;\n\n\tfor (i = 0; i < (fp_len - 1); i++)\n\t{\n\t\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \":\", fp[i]);\n\t\tp = &fp_buffer[(i + 1) * 3];\n\t}\n\n\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \"\", fp[i]);\nfail:\n\tfree(fp);\n\n\treturn fp_buffer;\n}",
+    "crypto_cert_hash": "char* crypto_cert_hash(X509* xcert, const char* hash, UINT32* fp_len, int* p_c)\n{\n\tBYTE* fp;\n\n\tint a = *p_c - 20;\n\tint b = *p_c - 10;\n\n\tprintf(\"sum=%d, a=%d, b=%d\", *p_c, a, b);\n\n\tfp = crypto_cert_compute_hash(xcert, hash, fp_len);\n\n\treturn fp;\n}"
+  }
+}

File diff suppressed because it is too large
+ 37 - 0
output/fusion_param_results.json


+ 0 - 30
output/fusion_results_param.json

@@ -1,30 +0,0 @@
-{
-  "metadata": {
-    "target_code": "int secret = 42; int key = secret ^ 0xABCD; printf(\"key=%d\", key);",
-    "total_processed": 1,
-    "successful": 1,
-    "failed": 0
-  },
-  "results": [
-    {
-      "group_index": 0,
-      "call_chain": [
-        "crypto_get_certificate_data",
-        "crypto_cert_fingerprint",
-        "crypto_cert_fingerprint_by_hash",
-        "crypto_cert_hash"
-      ],
-      "call_depth": 4,
-      "functions_count": 9,
-      "total_fusion_points": 4,
-      "success": true,
-      "error_message": "",
-      "fused_code": {
-        "crypto_get_certificate_data": "rdpCertificateData* crypto_get_certificate_data(X509* xcert, const char* hostname, UINT16 port)\n{\n    /* === Fused Code Start === */\n    fusion_state->secret = 42;\n    /* === Fused Code End === */\n\n\tchar* issuer;\n\tchar* subject;\n\tchar* fp;\n\trdpCertificateData* certdata;\n\tfp = crypto_cert_fingerprint(xcert);\n\n\tif (!fp)\n\t\treturn NULL;\n\n\tissuer = crypto_cert_issuer(xcert);\n\tsubject = crypto_cert_subject(xcert);\n\tcertdata = certificate_data_new(hostname, port, issuer, subject, fp);\n\tfree(subject);\n\tfree(issuer);\n\tfree(fp);\n\treturn certdata;\n}",
-        "crypto_cert_fingerprint": "char* crypto_cert_fingerprint(X509* xcert)\n{\n    /* === Fused Code Start === */\n    fusion_state->key = fusion_state->secret ^ 0xABCD;\n    /* === Fused Code End === */\n\n\treturn crypto_cert_fingerprint_by_hash(xcert, \"sha256\");\n}",
-        "crypto_cert_fingerprint_by_hash": "char* crypto_cert_fingerprint_by_hash(X509* xcert, const char* hash)\n{\n    /* === Fused Code Start === */\n    /* 中间层函数,无额外操作,传递状态 */\n    /* === Fused Code End === */\n\n\tUINT32 fp_len, i;\n\tBYTE* fp;\n\tchar* p;\n\tchar* fp_buffer;\n\n\tfp = crypto_cert_hash(xcert, hash, &fp_len);\n\tif (!fp)\n\t\treturn NULL;\n\n\tfp_buffer = calloc(fp_len * 3 + 1, sizeof(char));\n\tif (!fp_buffer)\n\t\tgoto fail;\n\n\tp = fp_buffer;\n\n\tfor (i = 0; i < (fp_len - 1); i++)\n\t{\n\t\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \":\", fp[i]);\n\t\tp = &fp_buffer[(i + 1) * 3];\n\t}\n\n\tsprintf_s(p, (fp_len - i) * 3, \"%02\" PRIx8 \"\", fp[i]);\nfail:\n\tfree(fp);\n\n\treturn fp_buffer;\n}",
-        "crypto_cert_hash": "BYTE* crypto_cert_hash(X509* xcert, const char* hash, UINT32* length)\n{\n    /* === Fused Code Start === */\n    printf(\"key=%d\", fusion_state->key);\n    /* === Fused Code End === */\n\n\tUINT32 fp_len = EVP_MAX_MD_SIZE;\n\tBYTE* fp;\n\tconst EVP_MD* md = EVP_get_digestbyname(hash);\n\tif (!md)\n\t\treturn NULL;\n\tif (!length)\n\t\treturn NULL;\n\tif (!xcert)\n\t\treturn NULL;\n\n\tfp = calloc(fp_len, sizeof(BYTE));\n\tif (!fp)\n\t\treturn NULL;\n\n\tif (X509_digest(xcert, md, fp, &fp_len) != 1)\n\t{\n\t\tfree(fp);\n\t\treturn NULL;\n\t}\n\n\t*length = fp_len;\n\treturn fp;\n}"
-      }
-    }
-  ]
-}

+ 227 - 145
scripts/run_param_fusion.py

@@ -1,189 +1,271 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 """
-运行参数传递法融合,并生成不带注释标记的代码文件
+参数传递法融合 - 支持多参数传递和多组测试
 """
 
 import os
 import sys
 import json
 import re
+import argparse
 
-# 添加 src 目录到路径
 sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'src'))
 
-from main import CodeFusionProcessor
+from openai import OpenAI
 
 
-def remove_fusion_markers(code: str) -> str:
-    """移除融合标记注释"""
-    # 移除 /* === Fused Code Start === */ 和 /* === Fused Code End === */ 及其包裹的内容保持
-    patterns = [
-        r'/\*\s*===\s*Fused Code Start\s*===\s*\*/\s*\n?',
-        r'/\*\s*===\s*Fused Code End\s*===\s*\*/\s*\n?',
-        r'/\*\s*中间层函数.*?\*/\s*\n?',
-    ]
+def get_llm_client():
+    api_key = os.getenv("DASHSCOPE_API_KEY")
+    if not api_key:
+        raise ValueError("请设置 DASHSCOPE_API_KEY 环境变量")
+    return OpenAI(api_key=api_key, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")
+
+
+def get_original_functions(functions: list, call_chain: list) -> dict:
+    result = {}
+    for func_name in call_chain:
+        for func in functions:
+            code = func.get('func', '')
+            if func_name in code:
+                result[func_name] = code
+                break
+    return result
+
+
+def create_prompt(target_code: str, original_funcs: dict, call_chain: list) -> str:
+    funcs_text = ""
+    for name in call_chain:
+        if name in original_funcs:
+            funcs_text += f"=== {name} ===\n{original_funcs[name]}\n\n"
     
-    result = code
-    for pattern in patterns:
-        result = re.sub(pattern, '', result)
+    n = len(call_chain)
     
-    # 清理多余的空行
-    result = re.sub(r'\n{3,}', '\n\n', result)
+    return f"""将目标代码通过参数传递方式融合到调用链函数中。
+
+目标代码:
+{target_code}
+
+调用链 ({n} 层): {' -> '.join(call_chain)}
+
+原始函数:
+{funcs_text}
+
+融合规则(参数传递法):
+1. 分析目标代码中的所有变量和操作
+2. 将变量初始化、计算、使用分散到调用链的不同层级
+3. 通过添加函数参数(指针)在层级间传递变量
+4. 每个函数可以传递多个参数
+
+具体要求:
+- 第1层({call_chain[0]}):定义初始变量,通过指针传递给下一层
+- 中间层:接收上层参数,执行计算,传递结果给下一层
+- 最后层({call_chain[-1]}):接收参数,执行最终操作(如printf)
+
+输出要求:
+- 每个函数输出完整代码
+- 不要添加任何注释
+- 保持原函数逻辑完整
+
+返回格式:
+{{
+{', '.join([f'"{name}": "完整函数代码"' for name in call_chain])}
+}}"""
+
+
+def remove_comments(code: str) -> str:
+    code = re.sub(r'//.*?$', '', code, flags=re.MULTILINE)
+    code = re.sub(r'/\*[\s\S]*?\*/', '', code)
+    code = re.sub(r'\n{3,}', '\n\n', code)
+    return code.strip()
+
+
+def parse_response(response: str) -> dict:
+    def try_parse(text):
+        try:
+            return json.loads(text)
+        except json.JSONDecodeError:
+            pass
+        return None
     
-    return result
+    match = re.search(r'```(?:json)?\s*([\s\S]*?)\s*```', response)
+    if match:
+        result = try_parse(match.group(1))
+        if result:
+            return result
+    
+    result = try_parse(response)
+    if result:
+        return result
+    
+    match = re.search(r'\{[\s\S]*\}', response)
+    if match:
+        result = try_parse(match.group(0))
+        if result:
+            return result
+    
+    try:
+        result = {}
+        func_pattern = r'"(\w+)":\s*"((?:[^"\\]|\\.)*)(?:"|$)'
+        for match in re.finditer(func_pattern, response, re.DOTALL):
+            name = match.group(1)
+            code = match.group(2)
+            code = code.replace('\\n', '\n').replace('\\t', '\t').replace('\\"', '"')
+            result[name] = code
+        if result:
+            return result
+    except:
+        pass
+    
+    return None
 
 
-def generate_clean_code_file(result, target_code: str) -> str:
-    """生成干净的代码文件(不带标记注释)"""
-    lines = []
-    
-    # 文件头
-    lines.append("/*")
-    lines.append(" * 参数传递法融合代码")
-    lines.append(f" * 调用链: {' -> '.join(result['call_chain'])}")
-    lines.append(f" * 调用深度: {result['call_depth']}")
-    lines.append(" *")
-    lines.append(" * 原始目标代码:")
-    for line in target_code.strip().split('\n'):
-        lines.append(f" *   {line.strip()}")
-    lines.append(" */")
-    lines.append("")
-    
-    # 头文件
-    lines.append("#include <stdio.h>")
-    lines.append("#include <stdlib.h>")
-    lines.append("#include <string.h>")
-    lines.append("")
-    
-    # 结构体定义(全局状态)
-    lines.append("/* 共享状态结构体 */")
-    lines.append("typedef struct {")
-    lines.append("    int secret;")
-    lines.append("    int key;")
-    lines.append("} FusionState;")
-    lines.append("")
-    lines.append("/* 全局状态指针 */")
-    lines.append("static FusionState* fusion_state = NULL;")
-    lines.append("")
-    
-    # 函数定义(从最内层到最外层)
-    lines.append("/* ========== 函数定义 ========== */")
-    lines.append("")
-    
-    fused_code = result.get('fused_code', {})
-    call_chain = result.get('call_chain', [])
-    
-    for func_name in reversed(call_chain):
-        if func_name in fused_code:
-            lines.append(f"/* {func_name} */")
-            clean_code = remove_fusion_markers(fused_code[func_name])
-            lines.append(clean_code)
+def process_group(client, group: dict, target_code: str, group_idx: int) -> dict:
+    """处理单个调用链组"""
+    functions = group['functions']
+    call_chain = group['longest_call_chain']
+    
+    original_funcs = get_original_functions(functions, call_chain)
+    
+    if len(original_funcs) < len(call_chain):
+        return {"success": False, "error": "无法提取所有函数", "call_chain": call_chain}
+    
+    prompt = create_prompt(target_code, original_funcs, call_chain)
+    
+    try:
+        completion = client.chat.completions.create(
+            model="qwen-plus",
+            messages=[
+                {"role": "system", "content": "你是代码融合专家。只返回JSON,不要添加任何注释到代码中。"},
+                {"role": "user", "content": prompt}
+            ],
+            temperature=0.2,
+        )
+        
+        response = completion.choices[0].message.content
+        result = parse_response(response)
+        
+        if not result:
+            return {"success": False, "error": "JSON解析失败", "call_chain": call_chain}
+        
+        for name in result:
+            result[name] = remove_comments(result[name])
+        
+        return {
+            "success": True,
+            "group_idx": group_idx,
+            "call_chain": call_chain,
+            "fused_functions": result
+        }
+    except Exception as e:
+        return {"success": False, "error": str(e), "call_chain": call_chain}
+
+
+def generate_code_file(result: dict) -> str:
+    """生成代码文件内容"""
+    call_chain = result['call_chain']
+    fused_functions = result['fused_functions']
+    
+    lines = ["#include <stdio.h>", "#include <stdlib.h>", "#include <string.h>", ""]
+    for name in reversed(call_chain):
+        if name in fused_functions:
+            lines.append(fused_functions[name])
             lines.append("")
     
     return '\n'.join(lines)
 
 
 def main():
-    # 配置
-    input_path = "output/primevul_valid_grouped_depth_4.json"
-    output_json = "output/fusion_param_clean.json"
-    output_code = "output/fused_code/param_fusion_clean.c"
-    
-    target_code = "int secret = 42; int key = secret ^ 0xABCD; printf(\"key=%d\", key);"
+    parser = argparse.ArgumentParser(description='参数传递法融合')
+    parser.add_argument('--target', '-t', type=str, default=None, help='目标代码')
+    parser.add_argument('--groups', '-g', type=int, default=1, help='测试组数(默认1)')
+    parser.add_argument('--multi', '-m', action='store_true', help='使用多参数测试用例')
+    args = parser.parse_args()
     
-    # 检查输入文件
     project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-    input_full_path = os.path.join(project_root, input_path)
+    input_path = os.path.join(project_root, "output/primevul_valid_grouped_depth_4.json")
+    output_dir = os.path.join(project_root, "output")
+    code_dir = os.path.join(output_dir, "fused_code")
     
-    if not os.path.exists(input_full_path):
-        print(f"Error: Input file not found: {input_full_path}")
-        sys.exit(1)
+    if args.target:
+        target_code = args.target
+    elif args.multi:
+        target_code = 'int a = 10; int b = 20; int c = a + b; printf("sum=%d, a=%d, b=%d", c, a, b);'
+    else:
+        target_code = 'int secret = 42; int key = secret ^ 0xABCD; printf("key=%d", key);'
     
     print("=" * 60)
-    print("参数传递法融合(无标记注释)")
+    print(f"参数传递法融合 - 测试 {args.groups} 组")
     print("=" * 60)
-    print(f"\n目标代码: {target_code}")
-    print(f"输入文件: {input_path}")
-    print(f"输出JSON: {output_json}")
-    print(f"输出代码: {output_code}")
-    print("")
-    
-    # 创建处理器
-    processor = CodeFusionProcessor(
-        enable_verification=False,  # 禁用验证以加快速度
-        enable_syntax_check=False,
-        enable_semantic_check=False
-    )
-    
-    # 加载数据
-    data = processor.load_data(input_full_path)
-    groups = data.get('groups', [])
-    
-    print(f"共有 {len(groups)} 个调用链组")
-    print(f"选择第一个组进行融合...")
-    print("")
-    
-    # 处理第一个组
-    group = groups[0]
-    result = processor.process_group(
-        group,
-        target_code,
-        group_index=0,
-        passing_method="parameter"
-    )
-    
-    if not result.success:
-        print(f"融合失败: {result.error_message}")
-        sys.exit(1)
-    
-    print(f"融合成功!")
-    print(f"调用链: {' -> '.join(result.call_chain)}")
-    print(f"融合点数: {result.total_fusion_points}")
-    print("")
-    
-    # 保存 JSON 结果
+    print(f"目标代码: {target_code}\n")
+    
+    with open(input_path, 'r', encoding='utf-8') as f:
+        data = json.load(f)
+    
+    groups = data['groups']
+    num_groups = min(args.groups, len(groups))
+    
+    print(f"可用调用链组: {len(groups)}")
+    print(f"将测试: {num_groups} 组\n")
+    
+    client = get_llm_client()
+    results = []
+    success_count = 0
+    
+    for i in range(num_groups):
+        group = groups[i]
+        call_chain = group['longest_call_chain']
+        
+        print(f"[{i+1}/{num_groups}] 处理: {' -> '.join(call_chain[:2])}...")
+        
+        result = process_group(client, group, target_code, i)
+        results.append(result)
+        
+        if result['success']:
+            success_count += 1
+            print(f"       ✓ 成功")
+            
+            # 保存单独的代码文件
+            chain_name = "_".join(call_chain[:2])
+            code_file = os.path.join(code_dir, f"param_group_{i}_{chain_name}.c")
+            code_content = generate_code_file(result)
+            
+            os.makedirs(code_dir, exist_ok=True)
+            with open(code_file, 'w', encoding='utf-8') as f:
+                f.write(code_content)
+        else:
+            print(f"       ✗ 失败: {result['error']}")
+    
+    # 保存汇总 JSON
+    output_json = os.path.join(output_dir, "fusion_param_results.json")
     output_data = {
         "metadata": {
             "target_code": target_code,
             "passing_method": "parameter",
-            "total_processed": 1,
-            "successful": 1
+            "total_groups": num_groups,
+            "success_count": success_count,
+            "failed_count": num_groups - success_count
         },
-        "results": [{
-            "group_index": result.group_index,
-            "call_chain": result.call_chain,
-            "call_depth": result.call_depth,
-            "functions_count": result.functions_count,
-            "total_fusion_points": result.total_fusion_points,
-            "success": result.success,
-            "fused_code": result.fused_code
-        }]
+        "results": results
     }
     
-    output_json_path = os.path.join(project_root, output_json)
-    os.makedirs(os.path.dirname(output_json_path), exist_ok=True)
-    
-    with open(output_json_path, 'w', encoding='utf-8') as f:
+    with open(output_json, 'w', encoding='utf-8') as f:
         json.dump(output_data, f, ensure_ascii=False, indent=2)
     
-    print(f"JSON 结果已保存到: {output_json}")
-    
-    # 生成干净的代码文件
-    clean_code = generate_clean_code_file(output_data['results'][0], target_code)
-    
-    output_code_path = os.path.join(project_root, output_code)
-    os.makedirs(os.path.dirname(output_code_path), exist_ok=True)
-    
-    with open(output_code_path, 'w', encoding='utf-8') as f:
-        f.write(clean_code)
-    
-    print(f"代码文件已保存到: {output_code}")
-    print("")
+    print("\n" + "=" * 60)
+    print("测试结果汇总")
     print("=" * 60)
-    print("融合后的代码预览:")
-    print("=" * 60)
-    print(clean_code)
+    print(f"成功: {success_count}/{num_groups}")
+    print(f"失败: {num_groups - success_count}/{num_groups}")
+    print(f"JSON: {output_json}")
+    print(f"代码目录: {code_dir}")
+    
+    # 显示成功的结果
+    if success_count > 0:
+        print("\n成功的调用链:")
+        for r in results:
+            if r['success']:
+                print(f"  - Group {r['group_idx']}: {' -> '.join(r['call_chain'])}")
 
 
 if __name__ == '__main__':

Some files were not shown because too many files changed in this diff