GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

软件研发 --- AI应用研发 之 提炼提示词

这是我的经验

先写简单的提示词比如

 给我生成一个关于安卓逆向简介的PPT格式的网站页面,同时支持导出为pptx格式

我们发现效果不满意,有很明显的AI味道,用黑色和渐变色背景,五颜六色的文字,表情图标,不美观

image

依据上述缺点精细设计提示词

 给我生成一个关于安卓逆向简介的PPT格式的网站页面,同时支持导出为pptx格式

请美化样式,显示为简洁,清爽,大方,整个背景用白色,不要使用渐变色,不要使用浅色而是用正色,颜色和样式要统一

image

我们发现效果不错。我们再设计一个,基于以上设计一个更加复杂的提示词

给我生成一个关于安卓逆向简介的PPT格式的网站页面,同时支持导出为pptx格式。

工具采用

const CDN_URLS = ['https://unpkg.com/pptxgenjs@4.0.1/dist/pptxgen.bundle.js'];

内容方面

1.文字内容要充实可行,拒绝空话套话抽象的话,用通俗语言解释

2.能用工具和数字证实的地方就快要尽可能用实用工具

样式方面

我的ppt要求如下 样式方面 请美化样式,显示为简洁,清爽,大方

ppt整体的设计界面尺寸应模拟苹果的MACbook的pc的大小布局设计

ppt整体的设计界面风格应该采用苹果电脑的ui设计规范,组件用透明玻璃效果,要充分展示ppt高级美感

ppt整体的设计使用真实的 UI 图片,而非占位符图片(可从 Unsplash、Pexels、Apple 官方 UI 资源中选择)。

ppt整体的设计不要使用任何渐变色,杂色,用正色,体现商务,正式,简约风格

ppt整体的设计风格应该统一、美观

ppt的背景不要使用深色这样不美观
效果非常惊艳

image

 我们为了将整个优秀的作品下次仍然保留下来,我们上claude生成的代码再发给claude生成极其专业的提示词

请给我依据下面的类似ppt的html可以导出pptx文件,请总结特征出一个精炼的ai提示词,可以下次在使用

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>安卓逆向工程简介</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Arial, sans-serif;
            background: #f5f5f7;
            min-height: 100vh;
            color: #1d1d1f;
        }

        /* 顶部控制栏 */
        .top-bar {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            z-index: 1000;
            height: 52px;
            background: rgba(255, 255, 255, 0.85);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border-bottom: 1px solid rgba(0, 0, 0, 0.08);
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 24px;
        }

        .top-bar-left {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        .app-icon {
            width: 28px;
            height: 28px;
            background: #000;
            border-radius: 7px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 14px;
            font-weight: 700;
        }

        .app-title {
            font-size: 14px;
            font-weight: 600;
            color: #1d1d1f;
            letter-spacing: -0.2px;
        }

        .top-bar-center {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .slide-indicator {
            font-size: 13px;
            color: #6e6e73;
            font-weight: 500;
        }

        .nav-btn {
            width: 28px;
            height: 28px;
            border: none;
            background: rgba(0, 0, 0, 0.06);
            border-radius: 6px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #1d1d1f;
            font-size: 12px;
            transition: all 0.2s;
        }

        .nav-btn:hover {
            background: rgba(0, 0, 0, 0.12);
        }

        .export-btn {
            height: 32px;
            padding: 0 16px;
            background: #000;
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 13px;
            font-weight: 600;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 6px;
            transition: all 0.2s;
            letter-spacing: -0.2px;
        }

        .export-btn:hover {
            background: #333;
            transform: translateY(-1px);
        }

        .export-btn:active {
            transform: translateY(0);
        }

        /* 左侧缩略图栏 */
        .sidebar {
            position: fixed;
            left: 0;
            top: 52px;
            bottom: 0;
            width: 180px;
            background: rgba(255, 255, 255, 0.7);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border-right: 1px solid rgba(0, 0, 0, 0.08);
            overflow-y: auto;
            padding: 16px 12px;
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .sidebar::-webkit-scrollbar {
            width: 4px;
        }

        .sidebar::-webkit-scrollbar-track {
            background: transparent;
        }

        .sidebar::-webkit-scrollbar-thumb {
            background: rgba(0, 0, 0, 0.15);
            border-radius: 2px;
        }

        .thumb-item {
            cursor: pointer;
            border-radius: 8px;
            overflow: hidden;
            border: 2px solid transparent;
            transition: all 0.2s;
            background: white;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
        }

        .thumb-item:hover {
            border-color: rgba(0, 0, 0, 0.2);
        }

        .thumb-item.active {
            border-color: #000;
            box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
        }

        .thumb-inner {
            width: 100%;
            aspect-ratio: 16/9;
            padding: 6px;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: flex-start;
            position: relative;
            overflow: hidden;
        }

        .thumb-num {
            position: absolute;
            bottom: 4px;
            right: 6px;
            font-size: 9px;
            color: #6e6e73;
            font-weight: 600;
        }

        .thumb-title {
            font-size: 7px;
            font-weight: 700;
            color: #1d1d1f;
            line-height: 1.2;
            max-width: 100%;
            overflow: hidden;
        }

        .thumb-subtitle {
            font-size: 5px;
            color: #6e6e73;
            margin-top: 2px;
        }

        /* 主内容区 */
        .main-content {
            margin-left: 180px;
            margin-top: 52px;
            padding: 40px;
            display: flex;
            flex-direction: column;
            align-items: center;
            min-height: calc(100vh - 52px);
        }

        /* PPT 幻灯片容器 */
        .slide-wrapper {
            width: 100%;
            max-width: 960px;
            position: relative;
        }

        .slide {
            display: none;
            width: 100%;
            aspect-ratio: 16/9;
            background: white;
            border-radius: 16px;
            box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.04);
            overflow: hidden;
            position: relative;
            animation: slideIn 0.3s ease;
        }

        .slide.active {
            display: block;
        }

        @keyframes slideIn {
            from {
                opacity: 0;
                transform: translateY(8px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        /* ============================================
           幻灯片内部样式
        ============================================ */

        /* 通用布局 */
        .slide-content {
            width: 100%;
            height: 100%;
            padding: 48px 56px;
            display: flex;
            flex-direction: column;
            position: relative;
        }

        /* 装饰线条 */
        .accent-line {
            width: 40px;
            height: 3px;
            background: #000;
            border-radius: 2px;
            margin-bottom: 16px;
        }

        /* 标题幻灯片 - Slide 1 */
        .slide-1 {
            background: #ffffff;
        }

        .slide-1 .content-area {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            padding: 48px 56px;
            position: relative;
        }

        .slide-1 .bg-shape {
            position: absolute;
            top: -60px;
            right: -60px;
            width: 400px;
            height: 400px;
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.03);
            pointer-events: none;
        }

        .slide-1 .bg-shape-2 {
            position: absolute;
            bottom: -80px;
            left: 40%;
            width: 300px;
            height: 300px;
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.02);
            pointer-events: none;
        }

        .tag-badge {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            background: #f5f5f7;
            border: 1px solid rgba(0, 0, 0, 0.08);
            border-radius: 20px;
            padding: 4px 12px;
            font-size: 11px;
            font-weight: 600;
            color: #6e6e73;
            letter-spacing: 0.4px;
            text-transform: uppercase;
            margin-bottom: 20px;
            width: fit-content;
        }

        .main-heading {
            font-size: 52px;
            font-weight: 700;
            color: #1d1d1f;
            letter-spacing: -2px;
            line-height: 1.05;
            margin-bottom: 16px;
        }

        .main-heading span {
            color: #6e6e73;
        }

        .sub-heading {
            font-size: 18px;
            color: #6e6e73;
            font-weight: 400;
            line-height: 1.5;
            max-width: 480px;
            letter-spacing: -0.3px;
        }

        .slide-1 .meta-row {
            position: absolute;
            bottom: 40px;
            left: 56px;
            display: flex;
            align-items: center;
            gap: 20px;
        }

        .meta-item {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 12px;
            color: #6e6e73;
            font-weight: 500;
        }

        .meta-dot {
            width: 4px;
            height: 4px;
            border-radius: 50%;
            background: #d2d2d7;
        }

        .slide-1 .right-visual {
            position: absolute;
            right: 56px;
            top: 50%;
            transform: translateY(-50%);
            width: 280px;
        }

        .glass-card {
            background: rgba(255, 255, 255, 0.7);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border: 1px solid rgba(0, 0, 0, 0.08);
            border-radius: 16px;
            padding: 20px;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06);
        }

        .code-block {
            background: #f5f5f7;
            border-radius: 10px;
            padding: 14px;
            font-family: 'SF Mono', 'Fira Code', monospace;
            font-size: 11px;
            line-height: 1.6;
            color: #1d1d1f;
            border: 1px solid rgba(0, 0, 0, 0.06);
        }

        .code-line {
            display: block;
        }

        .code-comment {
            color: #6e6e73;
        }

        .code-keyword {
            color: #bf5af2;
        }

        .code-string {
            color: #34c759;
        }

        .code-function {
            color: #007aff;
        }

        /* 通用章节标题 */
        .section-header {
            margin-bottom: 32px;
        }

        .section-label {
            font-size: 11px;
            font-weight: 700;
            color: #6e6e73;
            letter-spacing: 1px;
            text-transform: uppercase;
            margin-bottom: 8px;
        }

        .section-title {
            font-size: 32px;
            font-weight: 700;
            color: #1d1d1f;
            letter-spacing: -1px;
            line-height: 1.1;
        }

        /* 卡片网格 */
        .card-grid {
            display: grid;
            gap: 16px;
        }

        .card-grid-2 {
            grid-template-columns: 1fr 1fr;
        }

        .card-grid-3 {
            grid-template-columns: 1fr 1fr 1fr;
        }

        .info-card {
            background: #f5f5f7;
            border-radius: 12px;
            padding: 20px;
            border: 1px solid rgba(0, 0, 0, 0.05);
            position: relative;
            overflow: hidden;
        }

        .info-card.glass {
            background: rgba(255, 255, 255, 0.6);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border: 1px solid rgba(0, 0, 0, 0.08);
            box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
        }

        .card-icon {
            width: 36px;
            height: 36px;
            background: white;
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 18px;
            margin-bottom: 12px;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
        }

        .card-title {
            font-size: 14px;
            font-weight: 700;
            color: #1d1d1f;
            margin-bottom: 6px;
            letter-spacing: -0.3px;
        }

        .card-desc {
            font-size: 12px;
            color: #6e6e73;
            line-height: 1.5;
            letter-spacing: -0.1px;
        }

        /* 工具列表 */
        .tool-list {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }

        .tool-item {
            display: flex;
            align-items: center;
            gap: 14px;
            padding: 14px 16px;
            background: #f5f5f7;
            border-radius: 10px;
            border: 1px solid rgba(0, 0, 0, 0.05);
        }

        .tool-item.glass {
            background: rgba(255, 255, 255, 0.6);
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
            border: 1px solid rgba(0, 0, 0, 0.08);
        }

        .tool-icon-box {
            width: 32px;
            height: 32px;
            background: white;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 16px;
            flex-shrink: 0;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }

        .tool-info {
            flex: 1;
        }

        .tool-name {
            font-size: 13px;
            font-weight: 700;
            color: #1d1d1f;
            letter-spacing: -0.2px;
        }

        .tool-desc {
            font-size: 11px;
            color: #6e6e73;
            margin-top: 2px;
        }

        .tool-tag {
            font-size: 10px;
            font-weight: 600;
            color: #6e6e73;
            background: rgba(0, 0, 0, 0.06);
            padding: 2px 8px;
            border-radius: 4px;
            white-space: nowrap;
        }

        /* 流程步骤 */
        .step-flow {
            display: flex;
            align-items: flex-start;
            gap: 0;
            position: relative;
        }

        .step-item {
            flex: 1;
            display: flex;
            flex-direction: column;
            align-items: center;
            position: relative;
        }

        .step-connector {
            position: absolute;
            top: 18px;
            left: 50%;
            right: -50%;
            height: 1px;
            background: rgba(0, 0, 0, 0.1);
        }

        .step-num {
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background: #1d1d1f;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            font-weight: 700;
            position: relative;
            z-index: 1;
            margin-bottom: 10px;
        }

        .step-title {
            font-size: 12px;
            font-weight: 700;
            color: #1d1d1f;
            text-align: center;
            margin-bottom: 4px;
        }

        .step-desc {
            font-size: 10px;
            color: #6e6e73;
            text-align: center;
            line-height: 1.4;
            padding: 0 4px;
        }

        /* 数据统计 */
        .stat-grid {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 16px;
        }

        .stat-card {
            background: #f5f5f7;
            border-radius: 12px;
            padding: 20px;
            text-align: center;
            border: 1px solid rgba(0, 0, 0, 0.05);
        }

        .stat-num {
            font-size: 32px;
            font-weight: 700;
            color: #1d1d1f;
            letter-spacing: -1px;
            line-height: 1;
            margin-bottom: 4px;
        }

        .stat-label {
            font-size: 11px;
            color: #6e6e73;
            font-weight: 500;
        }

        /* 对比表格 */
        .compare-table {
            width: 100%;
            border-collapse: separate;
            border-spacing: 0;
            font-size: 12px;
        }

        .compare-table th {
            background: #f5f5f7;
            padding: 10px 14px;
            font-weight: 700;
            color: #1d1d1f;
            text-align: left;
            border-bottom: 1px solid rgba(0, 0, 0, 0.08);
        }

        .compare-table th:first-child {
            border-radius: 8px 0 0 0;
        }

        .compare-table th:last-child {
            border-radius: 0 8px 0 0;
        }

        .compare-table td {
            padding: 10px 14px;
            color: #6e6e73;
            border-bottom: 1px solid rgba(0, 0, 0, 0.05);
        }

        .compare-table tr:last-child td {
            border-bottom: none;
        }

        .compare-table tr:nth-child(even) td {
            background: rgba(0, 0, 0, 0.01);
        }

        .tag-pill {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 4px;
            font-size: 10px;
            font-weight: 600;
            background: rgba(0, 0, 0, 0.06);
            color: #6e6e73;
        }

        .tag-pill.highlight {
            background: #1d1d1f;
            color: white;
        }

        /* 底部页码 */
        .slide-footer {
            position: absolute;
            bottom: 24px;
            left: 56px;
            right: 56px;
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .footer-brand {
            font-size: 11px;
            font-weight: 700;
            color: #d2d2d7;
            letter-spacing: 0.5px;
        }

        .footer-page {
            font-size: 11px;
            color: #d2d2d7;
            font-weight: 500;
        }

        .footer-line {
            flex: 1;
            height: 1px;
            background: rgba(0, 0, 0, 0.06);
            margin: 0 16px;
        }

        /* 进度指示器 */
        .slide-progress {
            display: flex;
            justify-content: center;
            gap: 6px;
            margin-top: 20px;
            flex-wrap: wrap;
        }

        .progress-dot {
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.15);
            cursor: pointer;
            transition: all 0.2s;
        }

        .progress-dot.active {
            background: #000;
            transform: scale(1.3);
        }

        /* 键盘快捷键提示 */
        .keyboard-hint {
            text-align: center;
            margin-top: 12px;
            font-size: 11px;
            color: #6e6e73;
        }

        .kbd {
            display: inline-block;
            padding: 1px 6px;
            background: rgba(0, 0, 0, 0.06);
            border-radius: 4px;
            font-size: 10px;
            font-weight: 600;
            border: 1px solid rgba(0, 0, 0, 0.1);
        }

        /* 右侧面板 (for 2-col layouts) */
        .two-col {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 24px;
            flex: 1;
        }

        .col-left, .col-right {
            display: flex;
            flex-direction: column;
            gap: 12px;
        }

        /* 时间线 */
        .timeline {
            display: flex;
            flex-direction: column;
            gap: 0;
            position: relative;
        }

        .timeline::before {
            content: '';
            position: absolute;
            left: 15px;
            top: 16px;
            bottom: 16px;
            width: 1px;
            background: rgba(0, 0, 0, 0.1);
        }

        .timeline-item {
            display: flex;
            gap: 16px;
            padding: 8px 0;
            position: relative;
        }

        .timeline-dot {
            width: 31px;
            height: 31px;
            border-radius: 50%;
            background: white;
            border: 2px solid rgba(0, 0, 0, 0.15);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            flex-shrink: 0;
            position: relative;
            z-index: 1;
        }

        .timeline-dot.active-dot {
            border-color: #000;
            background: #000;
            color: white;
        }

        .timeline-content {
            flex: 1;
            padding-top: 4px;
        }

        .timeline-title {
            font-size: 13px;
            font-weight: 700;
            color: #1d1d1f;
        }

        .timeline-desc {
            font-size: 11px;
            color: #6e6e73;
            margin-top: 2px;
            line-height: 1.4;
        }

        /* 警告/提示框 */
        .alert-box {
            background: #fff8e1;
            border: 1px solid rgba(0, 0, 0, 0.08);
            border-radius: 10px;
            padding: 14px 16px;
            display: flex;
            gap: 10px;
            align-items: flex-start;
        }

        .alert-icon {
            font-size: 16px;
            flex-shrink: 0;
        }

        .alert-text {
            font-size: 12px;
            color: #6e6e73;
            line-height: 1.5;
        }

        .alert-text strong {
            color: #1d1d1f;
        }

        /* 大图片区 */
        .visual-panel {
            border-radius: 12px;
            overflow: hidden;
            position: relative;
            background: #f5f5f7;
        }

        .visual-panel img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .visual-overlay {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(10px);
            padding: 12px 16px;
        }

        .visual-overlay-title {
            font-size: 12px;
            font-weight: 700;
            color: #1d1d1f;
        }

        .visual-overlay-desc {
            font-size: 10px;
            color: #6e6e73;
        }

        /* 导出加载 */
        .export-loading {
            position: fixed;
            inset: 0;
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(10px);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 9999;
            gap: 16px;
        }

        .export-loading.hidden {
            display: none;
        }

        .loading-spinner {
            width: 40px;
            height: 40px;
            border: 3px solid rgba(0, 0, 0, 0.1);
            border-top-color: #000;
            border-radius: 50%;
            animation: spin 0.8s linear infinite;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .loading-text {
            font-size: 16px;
            font-weight: 600;
            color: #1d1d1f;
        }

        .loading-sub {
            font-size: 13px;
            color: #6e6e73;
        }

        /* 响应式 */
        @media (max-width: 768px) {
            .sidebar { display: none; }
            .main-content { margin-left: 0; padding: 60px 16px 20px; }
        }
    </style>
</head>
<body>

<!-- 导出加载提示 -->
<div class="export-loading hidden" id="exportLoading">
    <div class="loading-spinner"></div>
    <div class="loading-text">正在生成 PPTX 文件</div>
    <div class="loading-sub">请稍候,这可能需要几秒钟...</div>
</div>

<!-- 顶部控制栏 -->
<div class="top-bar">
    <div class="top-bar-left">
        <div class="app-icon">AR</div>
        <div class="app-title">安卓逆向工程简介</div>
    </div>
    <div class="top-bar-center">
        <button class="nav-btn" onclick="prevSlide()" title="上一页">←</button>
        <span class="slide-indicator" id="slideIndicator">1 / 10</span>
        <button class="nav-btn" onclick="nextSlide()" title="下一页">→</button>
    </div>
    <button class="export-btn" onclick="exportPPTX()">
        ↓ 导出 PPTX
    </button>
</div>

<!-- 左侧缩略图 -->
<div class="sidebar" id="sidebar">
    <!-- 由 JS 生成 -->
</div>

<!-- 主内容区 -->
<div class="main-content">
    <div class="slide-wrapper">

        <!-- ======= SLIDE 1: 封面 ======= -->
        <div class="slide slide-1 active" id="slide-1">
            <div class="bg-shape"></div>
            <div class="bg-shape-2"></div>
            <div class="content-area">
                <div class="tag-badge">🔍 技术入门指南 · 2024</div>
                <div class="main-heading">安卓逆向<br><span>工程简介</span></div>
                <div class="sub-heading">了解 Android APK 如何被分析、解构与研究——从工具到流程,系统性入门</div>
                <div class="meta-row">
                    <div class="meta-item">🎯 适合初学者</div>
                    <div class="meta-dot"></div>
                    <div class="meta-item">📱 Android 平台</div>
                    <div class="meta-dot"></div>
                    <div class="meta-item">⏱ 预计阅读 15 分钟</div>
                </div>
            </div>
            <div class="right-visual">
                <div class="glass-card">
                    <div style="font-size:11px;font-weight:700;color:#1d1d1f;margin-bottom:10px;">📄 APK 结构</div>
                    <div class="code-block">
                        <span class="code-line"><span class="code-comment"># APK 本质是 ZIP 文件</span></span>
                        <span class="code-line">app.apk/</span>
                        <span class="code-line">├── <span class="code-function">classes.dex</span>   <span class="code-comment"># 代码</span></span>
                        <span class="code-line">├── <span class="code-string">res/</span>          <span class="code-comment"># 资源</span></span>
                        <span class="code-line">├── <span class="code-keyword">lib/</span>          <span class="code-comment"># SO库</span></span>
                        <span class="code-line">└── AndroidManifest.xml</span>
                    </div>
                </div>
            </div>
            <div class="slide-footer">
                <div class="footer-brand">ANDROID REVERSE</div>
                <div class="footer-line"></div>
                <div class="footer-page">01 / 10</div>
            </div>
        </div>

        <!-- ======= SLIDE 2: 什么是逆向工程 ======= -->
        <div class="slide" id="slide-2">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 01</div>
                    <div class="accent-line"></div>
                    <div class="section-title">什么是安卓逆向工程?</div>
                </div>
                <div class="two-col" style="flex:1;">
                    <div class="col-left">
                        <div class="info-card glass" style="flex:1;">
                            <div class="card-icon">🔧</div>
                            <div class="card-title">通俗理解</div>
                            <div class="card-desc">
                                你下载了一个 APP,但没有源代码。逆向工程就是把这个 APP 的 <strong style="color:#1d1d1f">classes.dex(编译后的代码文件)</strong> 还原回你能读懂的 Java/Smali 代码,就像把熟食还原成菜谱。
                            </div>
                        </div>
                        <div class="info-card glass" style="flex:1;">
                            <div class="card-icon">⚖️</div>
                            <div class="card-title">合法场景</div>
                            <div class="card-desc">
                                • 安全研究:发现 APP 漏洞并上报<br>
                                • 恶意软件分析:看病毒干了什么<br>
                                • 兼容性测试:协议分析<br>
                                • 自己的 APP:忘记源码时恢复
                            </div>
                        </div>
                    </div>
                    <div class="col-right">
                        <div class="info-card" style="background:#f5f5f7;flex:1;">
                            <div style="font-size:12px;font-weight:700;color:#1d1d1f;margin-bottom:12px;">📦 Android 代码编译链</div>
                            <div style="display:flex;flex-direction:column;gap:6px;">
                                <div style="background:white;border-radius:8px;padding:10px 14px;border:1px solid rgba(0,0,0,0.06);">
                                    <div style="font-size:11px;font-weight:700;color:#1d1d1f;">.java / .kt 源码</div>
                                    <div style="font-size:10px;color:#6e6e73;">开发者写的代码</div>
                                </div>
                                <div style="text-align:center;font-size:11px;color:#6e6e73;">↓ javac / kotlinc 编译</div>
                                <div style="background:white;border-radius:8px;padding:10px 14px;border:1px solid rgba(0,0,0,0.06);">
                                    <div style="font-size:11px;font-weight:700;color:#1d1d1f;">.class 字节码</div>
                                    <div style="font-size:10px;color:#6e6e73;">JVM 字节码</div>
                                </div>
                                <div style="text-align:center;font-size:11px;color:#6e6e73;">↓ d8 / dx 转换</div>
                                <div style="background:#1d1d1f;border-radius:8px;padding:10px 14px;">
                                    <div style="font-size:11px;font-weight:700;color:white;">classes.dex</div>
                                    <div style="font-size:10px;color:rgba(255,255,255,0.5);">Dalvik 字节码 — 逆向目标</div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">02 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 3: 核心工具 ======= -->
        <div class="slide" id="slide-3">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 02</div>
                    <div class="accent-line"></div>
                    <div class="section-title">必备逆向工具全景</div>
                </div>
                <div class="tool-list" style="flex:1;justify-content:center;gap:8px;">
                    <div class="tool-item glass">
                        <div class="tool-icon-box">🔓</div>
                        <div class="tool-info">
                            <div class="tool-name">jadx</div>
                            <div class="tool-desc">把 APK/dex 直接反编译成可读的 Java 代码,带 GUI 界面,是新手首选工具</div>
                        </div>
                        <div class="tool-tag">反编译</div>
                    </div>
                    <div class="tool-item glass">
                        <div class="tool-icon-box">🔨</div>
                        <div class="tool-info">
                            <div class="tool-name">apktool</div>
                            <div class="tool-desc">解包 APK → 修改 Smali 代码 → 重新打包。版本 v2.9.3,用于修改和回编译</div>
                        </div>
                        <div class="tool-tag">重打包</div>
                    </div>
                    <div class="tool-item glass">
                        <div class="tool-icon-box">🕵️</div>
                        <div class="tool-info">
                            <div class="tool-name">Frida</div>
                            <div class="tool-desc">动态插桩框架,用 JS 脚本在运行中 hook 任意函数,实时修改返回值,最强动态分析工具</div>
                        </div>
                        <div class="tool-tag">动态分析</div>
                    </div>
                    <div class="tool-item glass">
                        <div class="tool-icon-box">🌐</div>
                        <div class="tool-info">
                            <div class="tool-name">Charles / mitmproxy</div>
                            <div class="tool-desc">抓取 APP 的 HTTPS 网络请求,看它偷偷发了什么数据到服务器</div>
                        </div>
                        <div class="tool-tag">流量分析</div>
                    </div>
                    <div class="tool-item glass">
                        <div class="tool-icon-box">🏗️</div>
                        <div class="tool-info">
                            <div class="tool-name">IDA Pro / Ghidra</div>
                            <div class="tool-desc">分析 .so 原生库(C/C++ 编译的 ARM 代码),Ghidra 免费开源,NSA 出品</div>
                        </div>
                        <div class="tool-tag">Native 分析</div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">03 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 4: 逆向工作流 ======= -->
        <div class="slide" id="slide-4">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 03</div>
                    <div class="accent-line"></div>
                    <div class="section-title">标准逆向分析流程</div>
                </div>
                <div class="step-flow" style="margin-bottom:24px;">
                    <div class="step-item">
                        <div class="step-num">1</div>
                        <div class="step-connector"></div>
                        <div class="step-title">获取 APK</div>
                        <div class="step-desc">adb pull 或从手机提取,使用 APKPure 等平台</div>
                    </div>
                    <div class="step-item">
                        <div class="step-num">2</div>
                        <div class="step-connector"></div>
                        <div class="step-title">静态分析</div>
                        <div class="step-desc">用 jadx 查看代码结构、权限声明、关键类</div>
                    </div>
                    <div class="step-item">
                        <div class="step-num">3</div>
                        <div class="step-connector"></div>
                        <div class="step-title">定位目标</div>
                        <div class="step-desc">搜索关键词如 "login" "check" "encrypt"</div>
                    </div>
                    <div class="step-item">
                        <div class="step-num">4</div>
                        <div class="step-connector"></div>
                        <div class="step-title">动态验证</div>
                        <div class="step-desc">Frida hook 目标函数,打印实参和返回值</div>
                    </div>
                    <div class="step-item">
                        <div class="step-num">5</div>
                        <div style="display:none" class="step-connector"></div>
                        <div class="step-title">整理结论</div>
                        <div class="step-desc">记录发现的逻辑、接口、加密算法</div>
                    </div>
                </div>
                <div class="card-grid card-grid-3" style="flex:1;align-content:start;gap:12px;">
                    <div class="info-card glass">
                        <div class="card-title">🔍 常用 adb 命令</div>
                        <div class="code-block" style="font-size:10px;">
                            <span class="code-line"><span class="code-comment"># 列出设备包名</span></span>
                            <span class="code-line">adb shell pm list packages</span>
                            <span class="code-line"></span>
                            <span class="code-line"><span class="code-comment"># 提取 APK</span></span>
                            <span class="code-line">adb pull /data/app/xxx/base.apk</span>
                        </div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-title">🪝 Frida Hook 模板</div>
                        <div class="code-block" style="font-size:10px;">
                            <span class="code-line">Java.perform(<span class="code-keyword">function</span>() {</span>
                            <span class="code-line">  <span class="code-keyword">var</span> Cls = Java.use(<span class="code-string">"com.app.Login"</span>);</span>
                            <span class="code-line">  Cls.check.implementation = <span class="code-keyword">function</span>() {</span>
                            <span class="code-line">    <span class="code-keyword">return</span> <span class="code-function">true</span>; <span class="code-comment">// 绕过</span></span>
                            <span class="code-line">  };</span>
                            <span class="code-line">});</span>
                        </div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-title">📋 分析清单</div>
                        <div style="display:flex;flex-direction:column;gap:4px;">
                            <div style="font-size:11px;color:#6e6e73;display:flex;gap:6px;align-items:center;"><span>☑</span> AndroidManifest 权限</div>
                            <div style="font-size:11px;color:#6e6e73;display:flex;gap:6px;align-items:center;"><span>☑</span> 网络请求地址</div>
                            <div style="font-size:11px;color:#6e6e73;display:flex;gap:6px;align-items:center;"><span>☑</span> 本地存储内容</div>
                            <div style="font-size:11px;color:#6e6e73;display:flex;gap:6px;align-items:center;"><span>☑</span> 加密算法类型</div>
                            <div style="font-size:11px;color:#6e6e73;display:flex;gap:6px;align-items:center;"><span>☑</span> 混淆程度评估</div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">04 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 5: Smali 语言 ======= -->
        <div class="slide" id="slide-5">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 04</div>
                    <div class="accent-line"></div>
                    <div class="section-title">读懂 Smali —— 安卓汇编语言</div>
                </div>
                <div class="two-col" style="flex:1;">
                    <div>
                        <div style="font-size:12px;font-weight:700;color:#6e6e73;margin-bottom:8px;">原始 Java 代码</div>
                        <div class="code-block" style="font-size:11px;line-height:1.7;">
                            <span class="code-line"><span class="code-keyword">public boolean</span> <span class="code-function">isVip</span>(String uid) {</span>
                            <span class="code-line">  <span class="code-keyword">if</span> (uid.equals(<span class="code-string">"admin"</span>)) {</span>
                            <span class="code-line">    <span class="code-keyword">return true</span>;</span>
                            <span class="code-line">  }</span>
                            <span class="code-line">  <span class="code-keyword">return false</span>;</span>
                            <span class="code-line">}</span>
                        </div>
                        <div style="margin-top:16px;font-size:12px;font-weight:700;color:#6e6e73;margin-bottom:8px;">关键寄存器规则</div>
                        <div style="display:flex;flex-direction:column;gap:6px;">
                            <div style="background:#f5f5f7;border-radius:8px;padding:8px 12px;font-size:11px;display:flex;gap:12px;">
                                <span style="font-family:monospace;font-weight:700;color:#1d1d1f;min-width:32px;">v0</span>
                                <span style="color:#6e6e73;">本地变量寄存器,从 v0 开始编号</span>
                            </div>
                            <div style="background:#f5f5f7;border-radius:8px;padding:8px 12px;font-size:11px;display:flex;gap:12px;">
                                <span style="font-family:monospace;font-weight:700;color:#1d1d1f;min-width:32px;">p0</span>
                                <span style="color:#6e6e73;">参数寄存器,p0 = this(对象方法)</span>
                            </div>
                            <div style="background:#f5f5f7;border-radius:8px;padding:8px 12px;font-size:11px;display:flex;gap:12px;">
                                <span style="font-family:monospace;font-weight:700;color:#1d1d1f;min-width:32px;">p1</span>
                                <span style="color:#6e6e73;">第一个参数,上例中 p1 = uid</span>
                            </div>
                        </div>
                    </div>
                    <div>
                        <div style="font-size:12px;font-weight:700;color:#6e6e73;margin-bottom:8px;">对应 Smali 代码</div>
                        <div class="code-block" style="font-size:10px;line-height:1.7;">
                            <span class="code-line"><span class="code-comment">.method public isVip(Ljava/lang/String;)Z</span></span>
                            <span class="code-line">  .registers 3 <span class="code-comment"># v0, p0(this), p1(uid)</span></span>
                            <span class="code-line"></span>
                            <span class="code-line">  const-string v0, <span class="code-string">"admin"</span></span>
                            <span class="code-line">  invoke-virtual {p1, v0},</span>
                            <span class="code-line">    Ljava/lang/String;->equals(Ljava/lang/Object;)Z</span>
                            <span class="code-line">  move-result v0</span>
                            <span class="code-line">  <span class="code-keyword">if-eqz</span> v0, :cond_0 <span class="code-comment"># 若不等则跳转</span></span>
                            <span class="code-line"></span>
                            <span class="code-line">  const/4 v0, <span class="code-function">0x1</span>  <span class="code-comment"># true</span></span>
                            <span class="code-line">  return v0</span>
                            <span class="code-line"></span>
                            <span class="code-line">  :cond_0</span>
                            <span class="code-line">  const/4 v0, <span class="code-function">0x0</span>  <span class="code-comment"># false</span></span>
                            <span class="code-line">  return v0</span>
                            <span class="code-line">.end method</span>
                        </div>
                        <div style="margin-top:10px;" class="alert-box">
                            <div class="alert-icon">💡</div>
                            <div class="alert-text">把 <strong>if-eqz 改成 if-nez</strong>,或直接把 const/4 v0, 0x0 改成 0x1,即可绕过验证</div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">05 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 6: 常见保护手段 ======= -->
        <div class="slide" id="slide-6">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 05</div>
                    <div class="accent-line"></div>
                    <div class="section-title">APP 的 6 大保护机制</div>
                </div>
                <div class="card-grid card-grid-3" style="flex:1;gap:12px;align-content:start;">
                    <div class="info-card glass">
                        <div class="card-icon">🌫️</div>
                        <div class="card-title">代码混淆 (ProGuard)</div>
                        <div class="card-desc">把 <code style="font-size:10px;background:#f0f0f0;padding:1px 4px;border-radius:3px;">LoginActivity</code> 改成 <code style="font-size:10px;background:#f0f0f0;padding:1px 4px;border-radius:3px;">a.b.c</code>,增加阅读难度,但逻辑不变,jadx 仍可反编译</div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-icon">📦</div>
                        <div class="card-title">加壳 (Packing)</div>
                        <div class="card-desc">把真正的 dex 加密后隐藏,运行时再解密。常见壳:梆梆、360加固、腾讯乐固。需要先脱壳再分析</div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-icon">🔐</div>
                        <div class="card-title">SSL Pinning</div>
                        <div class="card-desc">APP 内置证书指纹,只接受特定证书,阻止中间人抓包。可用 Frida 脚本或 TrustMeAlready 模块绕过</div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-icon">🔍</div>
                        <div class="card-title">Root / 调试检测</div>
                        <div class="card-desc">检测 /system/bin/su 文件是否存在、是否可被调试。可用 Magisk DenyList 或 RootBeer 绕过模块对抗</div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-icon">⚡</div>
                        <div class="card-title">VMP 虚拟机保护</div>
                        <div class="card-desc">核心算法被自定义虚拟机解释执行,指令集完全私有,是目前最难破解的保护方式</div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-icon">✅</div>
                        <div class="card-title">签名校验</div>
                        <div class="card-desc">APP 运行时校验自身签名,修改 smali 重打包后签名变了会直接闪退。需 hook <code style="font-size:10px;background:#f0f0f0;padding:1px 4px;border-radius:3px;">getSignatures</code> 返回原始值</div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">06 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 7: 动态分析 Frida ======= -->
        <div class="slide" id="slide-7">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 06</div>
                    <div class="accent-line"></div>
                    <div class="section-title">Frida 动态分析实战</div>
                </div>
                <div class="two-col" style="flex:1;">
                    <div style="display:flex;flex-direction:column;gap:12px;">
                        <div class="info-card" style="background:#f5f5f7;">
                            <div style="font-size:12px;font-weight:700;color:#1d1d1f;margin-bottom:8px;">① 环境搭建</div>
                            <div class="code-block" style="font-size:10px;line-height:1.7;">
                                <span class="code-line"><span class="code-comment"># 安装 frida 工具</span></span>
                                <span class="code-line">pip install frida-tools</span>
                                <span class="code-line"></span>
                                <span class="code-line"><span class="code-comment"># 推送 frida-server 到手机</span></span>
                                <span class="code-line">adb push frida-server /data/local/tmp/</span>
                                <span class="code-line">adb shell "chmod 755 /data/local/tmp/frida-server"</span>
                                <span class="code-line">adb shell "/data/local/tmp/frida-server &"</span>
                            </div>
                        </div>
                        <div class="info-card" style="background:#f5f5f7;">
                            <div style="font-size:12px;font-weight:700;color:#1d1d1f;margin-bottom:8px;">② 注入脚本</div>
                            <div class="code-block" style="font-size:10px;line-height:1.7;">
                                <span class="code-line"><span class="code-comment"># 对目标包名注入脚本</span></span>
                                <span class="code-line">frida -U -f <span class="code-string">com.target.app</span> \</span>
                                <span class="code-line">  -l <span class="code-string">hook.js</span> --no-pause</span>
                            </div>
                        </div>
                    </div>
                    <div style="display:flex;flex-direction:column;gap:12px;">
                        <div class="info-card" style="background:#f5f5f7;flex:1;">
                            <div style="font-size:12px;font-weight:700;color:#1d1d1f;margin-bottom:8px;">③ Hook 实战脚本:追踪加密函数</div>
                            <div class="code-block" style="font-size:10px;line-height:1.7;">
                                <span class="code-line">Java.perform(<span class="code-keyword">function</span>() {</span>
                                <span class="code-line">  <span class="code-comment">// Hook MessageDigest (MD5/SHA)</span></span>
                                <span class="code-line">  <span class="code-keyword">var</span> MD = Java.use(<span class="code-string">"java.security.MessageDigest"</span>);</span>
                                <span class="code-line">  MD.update.overload(<span class="code-string">"[B"</span>).implementation = <span class="code-keyword">function</span>(b) {</span>
                                <span class="code-line">    console.log(<span class="code-string">"[*] MD input: "</span> + Java.use(<span class="code-string">"java.lang.String"</span>)</span>
                                <span class="code-line">      .$new(b));</span>
                                <span class="code-line">    <span class="code-keyword">return</span> <span class="code-function">this</span>.update(b);</span>
                                <span class="code-line">  };</span>
                                <span class="code-line"></span>
                                <span class="code-line">  <span class="code-comment">// 查看调用栈,定位代码位置</span></span>
                                <span class="code-line">  console.log(Java.use(<span class="code-string">"android.util.Log"</span>)</span>
                                <span class="code-line">    .getStackTraceString(</span>
                                <span class="code-line">      Java.use(<span class="code-string">"java.lang.Exception"</span>).$new()));</span>
                                <span class="code-line">});</span>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">07 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 8: 数据与行业现状 ======= -->
        <div class="slide" id="slide-8">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 07</div>
                    <div class="accent-line"></div>
                    <div class="section-title">行业数据与应用现状</div>
                </div>
                <div class="stat-grid" style="margin-bottom:20px;">
                    <div class="stat-card">
                        <div class="stat-num">35%</div>
                        <div class="stat-label">Google Play 上架 APP 使用了 ProGuard 混淆<br><span style="font-size:10px;color:#aaa;">(NowSecure 2023 报告)</span></div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-num">73%</div>
                        <div class="stat-label">金融类 APP 存在至少一个高危安全漏洞<br><span style="font-size:10px;color:#aaa;">(OWASP Mobile Top 10 统计)</span></div>
                    </div>
                    <div class="stat-card">
                        <div class="stat-num">$38K</div>
                        <div class="stat-label">Google 安卓漏洞最高 Bug Bounty 奖励<br><span style="font-size:10px;color:#aaa;">(Google VRP 2023)</span></div>
                    </div>
                </div>
                <div class="two-col" style="flex:1;gap:16px;">
                    <div class="info-card glass">
                        <div class="card-title">📊 逆向工程主要应用场景</div>
                        <div style="margin-top:10px;display:flex;flex-direction:column;gap:8px;">
                            <div>
                                <div style="display:flex;justify-content:space-between;font-size:11px;margin-bottom:3px;">
                                    <span style="color:#1d1d1f;font-weight:600;">安全漏洞研究</span>
                                    <span style="color:#6e6e73;">45%</span>
                                </div>
                                <div style="height:4px;background:#f0f0f0;border-radius:2px;overflow:hidden;">
                                    <div style="width:45%;height:100%;background:#1d1d1f;border-radius:2px;"></div>
                                </div>
                            </div>
                            <div>
                                <div style="display:flex;justify-content:space-between;font-size:11px;margin-bottom:3px;">
                                    <span style="color:#1d1d1f;font-weight:600;">恶意软件分析</span>
                                    <span style="color:#6e6e73;">30%</span>
                                </div>
                                <div style="height:4px;background:#f0f0f0;border-radius:2px;overflow:hidden;">
                                    <div style="width:30%;height:100%;background:#1d1d1f;border-radius:2px;"></div>
                                </div>
                            </div>
                            <div>
                                <div style="display:flex;justify-content:space-between;font-size:11px;margin-bottom:3px;">
                                    <span style="color:#1d1d1f;font-weight:600;">协议还原分析</span>
                                    <span style="color:#6e6e73;">15%</span>
                                </div>
                                <div style="height:4px;background:#f0f0f0;border-radius:2px;overflow:hidden;">
                                    <div style="width:15%;height:100%;background:#1d1d1f;border-radius:2px;"></div>
                                </div>
                            </div>
                            <div>
                                <div style="display:flex;justify-content:space-between;font-size:11px;margin-bottom:3px;">
                                    <span style="color:#1d1d1f;font-weight:600;">其他(兼容/测试)</span>
                                    <span style="color:#6e6e73;">10%</span>
                                </div>
                                <div style="height:4px;background:#f0f0f0;border-radius:2px;overflow:hidden;">
                                    <div style="width:10%;height:100%;background:#1d1d1f;border-radius:2px;"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="info-card glass">
                        <div class="card-title">🏆 学习资源推荐</div>
                        <div style="margin-top:10px;display:flex;flex-direction:column;gap:8px;">
                            <div style="padding:8px 12px;background:#f5f5f7;border-radius:8px;font-size:11px;">
                                <div style="font-weight:700;color:#1d1d1f;">CTF 平台</div>
                                <div style="color:#6e6e73;margin-top:2px;">BUUCTF、攻防世界均有专项 Android 题目</div>
                            </div>
                            <div style="padding:8px 12px;background:#f5f5f7;border-radius:8px;font-size:11px;">
                                <div style="font-weight:700;color:#1d1d1f;">OWASP MASTG</div>
                                <div style="color:#6e6e73;margin-top:2px;">移动安全测试指南,官方免费 PDF,系统性最强</div>
                            </div>
                            <div style="padding:8px 12px;background:#f5f5f7;border-radius:8px;font-size:11px;">
                                <div style="font-weight:700;color:#1d1d1f;">看雪论坛 / 52pojie</div>
                                <div style="color:#6e6e73;margin-top:2px;">国内最活跃的逆向社区,有大量实战案例</div>
                            </div>
                            <div style="padding:8px 12px;background:#f5f5f7;border-radius:8px;font-size:11px;">
                                <div style="font-weight:700;color:#1d1d1f;">Android Internals(书)</div>
                                <div style="color:#6e6e73;margin-top:2px;">Jonathan Levin 著,深入 Android 系统底层原理</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">08 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 9: 法律与道德 ======= -->
        <div class="slide" id="slide-9">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 08</div>
                    <div class="accent-line"></div>
                    <div class="section-title">法律红线与职业道德</div>
                </div>
                <div style="flex:1;display:flex;flex-direction:column;gap:14px;">
                    <table class="compare-table" style="background:white;border-radius:10px;overflow:hidden;border:1px solid rgba(0,0,0,0.06);">
                        <thead>
                            <tr>
                                <th style="width:30%">行为</th>
                                <th style="width:25%">法律依据(中国)</th>
                                <th style="width:20%">风险等级</th>
                                <th style="width:25%">建议</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>分析自己的 APP / 授权安全测试</td>
                                <td>合法行为</td>
                                <td><span class="tag-pill highlight">✓ 安全</span></td>
                                <td>推荐练习方式</td>
                            </tr>
                            <tr>
                                <td>CTF 竞赛逆向题</td>
                                <td>合法行为</td>
                                <td><span class="tag-pill highlight">✓ 安全</span></td>
                                <td>最佳入门途径</td>
                            </tr>
                            <tr>
                                <td>发现漏洞后负责任披露</td>
                                <td>《网络安全法》鼓励</td>
                                <td><span class="tag-pill highlight">✓ 鼓励</span></td>
                                <td>可获 Bug Bounty 奖励</td>
                            </tr>
                            <tr>
                                <td>破解商业软件版权保护</td>
                                <td>《著作权法》第 48 条</td>
                                <td><span class="tag-pill">⚠ 违法</span></td>
                                <td>可能面临民事赔偿</td>
                            </tr>
                            <tr>
                                <td>未授权入侵、窃取数据</td>
                                <td>《刑法》285/286 条</td>
                                <td><span class="tag-pill">🚫 刑事</span></td>
                                <td>最高 7 年有期徒刑</td>
                            </tr>
                        </tbody>
                    </table>
                    <div class="alert-box" style="background:#f0f8ff;border-color:rgba(0,0,0,0.08);">
                        <div class="alert-icon">⚖️</div>
                        <div class="alert-text">
                            <strong>核心原则:</strong>只在你有权限的环境内操作。拿到认证(OSCE、BSCP)比非法操作更能体现技术价值。Bug Bounty 平台(HackerOne、SRC)提供了合法赚钱的渠道。
                        </div>
                    </div>
                    <div class="card-grid card-grid-3" style="gap:10px;">
                        <div class="info-card glass" style="padding:14px;">
                            <div style="font-size:20px;margin-bottom:6px;">🎓</div>
                            <div class="card-title" style="font-size:12px;">先从 CTF 开始</div>
                            <div class="card-desc">攻防世界、BUUCTF 有大量合法练习题,从 Easy 难度起步</div>
                        </div>
                        <div class="info-card glass" style="padding:14px;">
                            <div style="font-size:20px;margin-bottom:6px;">🏅</div>
                            <div class="card-title" style="font-size:12px;">参与 Bug Bounty</div>
                            <div class="card-desc">各大厂均有 SRC 漏洞奖励,报告漏洞合法且有收益</div>
                        </div>
                        <div class="info-card glass" style="padding:14px;">
                            <div style="font-size:20px;margin-bottom:6px;">📝</div>
                            <div class="card-title" style="font-size:12px;">签署授权协议</div>
                            <div class="card-desc">渗透测试前务必签书面授权,保护自己和委托方</div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">09 / 10</div>
                </div>
            </div>
        </div>

        <!-- ======= SLIDE 10: 学习路线 ======= -->
        <div class="slide" id="slide-10">
            <div class="slide-content">
                <div class="section-header">
                    <div class="section-label">Chapter 09</div>
                    <div class="accent-line"></div>
                    <div class="section-title">从零到实战:学习路线图</div>
                </div>
                <div class="two-col" style="flex:1;gap:20px;">
                    <div>
                        <div class="timeline">
                            <div class="timeline-item">
                                <div class="timeline-dot active-dot">1</div>
                                <div class="timeline-content">
                                    <div class="timeline-title">第 1-2 周:基础准备</div>
                                    <div class="timeline-desc">学 Java 基础语法 → 了解 Android 开发结构 → 搭建 Android Studio 环境,写一个简单 APP</div>
                                </div>
                            </div>
                            <div class="timeline-item">
                                <div class="timeline-dot active-dot">2</div>
                                <div class="timeline-content">
                                    <div class="timeline-title">第 3-4 周:静态分析入门</div>
                                    <div class="timeline-desc">安装 jadx,解析开源 APK(如 GadgetBridge),读懂类结构和方法调用关系</div>
                                </div>
                            </div>
                            <div class="timeline-item">
                                <div class="timeline-dot active-dot">3</div>
                                <div class="timeline-content">
                                    <div class="timeline-title">第 5-6 周:Smali 与重打包</div>
                                    <div class="timeline-desc">用 apktool 解包 → 修改 Smali → 重打包签名 → 安装验证,完成第一次 patch</div>
                                </div>
                            </div>
                            <div class="timeline-item">
                                <div class="timeline-dot active-dot">4</div>
                                <div class="timeline-content">
                                    <div class="timeline-title">第 7-8 周:动态分析 Frida</div>
                                    <div class="timeline-desc">配置 Frida 环境 → 完成基本 hook → 追踪加密函数 → 打印调用栈定位逻辑</div>
                                </div>
                            </div>
                            <div class="timeline-item">
                                <div class="timeline-dot">5</div>
                                <div class="timeline-content">
                                    <div class="timeline-title">第 2-3 月:CTF 实战</div>
                                    <div class="timeline-desc">在 CTF 平台做 Android 题,解决真实混淆/加壳场景,积累解题经验</div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div style="display:flex;flex-direction:column;gap:12px;">
                        <div class="info-card glass">
                            <div class="card-title">🛠 推荐练习 APK</div>
                            <div style="margin-top:10px;display:flex;flex-direction:column;gap:6px;">
                                <div style="font-size:11px;color:#6e6e73;display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid rgba(0,0,0,0.04);">
                                    <span style="font-weight:600;color:#1d1d1f;">InsecureBank v2</span>
                                    <span class="tag-pill">入门</span>
                                </div>
                                <div style="font-size:11px;color:#6e6e73;display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid rgba(0,0,0,0.04);">
                                    <span style="font-weight:600;color:#1d1d1f;">DIVA Android</span>
                                    <span class="tag-pill">入门</span>
                                </div>
                                <div style="font-size:11px;color:#6e6e73;display:flex;justify-content:space-between;padding:6px 0;border-bottom:1px solid rgba(0,0,0,0.04);">
                                    <span style="font-weight:600;color:#1d1d1f;">UnCrackable Level 1-3</span>
                                    <span class="tag-pill">进阶</span>
                                </div>
                                <div style="font-size:11px;color:#6e6e73;display:flex;justify-content:space-between;padding:6px 0;">
                                    <span style="font-weight:600;color:#1d1d1f;">OWASP GoatDroid</span>
                                    <span class="tag-pill">综合</span>
                                </div>
                            </div>
                        </div>
                        <div class="info-card glass" style="flex:1;">
                            <div class="card-title">🎯 技能树总览</div>
                            <div style="margin-top:10px;display:grid;grid-template-columns:1fr 1fr;gap:6px;">
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#1d1d1f;">Java/Kotlin</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#1d1d1f;">Smali 语法</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#1d1d1f;">jadx 使用</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#1d1d1f;">apktool 重打包</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#1d1d1f;">Frida 插桩</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#1d1d1f;">抓包分析</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#6e6e73;">ARM 汇编</div>
                                <div style="background:#f5f5f7;border-radius:6px;padding:6px 8px;font-size:10px;font-weight:600;color:#6e6e73;">脱壳技术</div>
                            </div>
                            <div style="margin-top:8px;font-size:10px;color:#6e6e73;">灰色 = 高级阶段学习</div>
                        </div>
                    </div>
                </div>
                <div class="slide-footer">
                    <div class="footer-brand">ANDROID REVERSE</div>
                    <div class="footer-line"></div>
                    <div class="footer-page">10 / 10</div>
                </div>
            </div>
        </div>

    </div>

    <!-- 进度点 -->
    <div class="slide-progress" id="slideProgress"></div>
    <div class="keyboard-hint">使用 <span class="kbd">←</span> <span class="kbd">→</span> 方向键或点击缩略图切换幻灯片</div>
</div>

<script>
    // ============================================
    // 幻灯片数据
    // ============================================
    const slidesData = [
        { num: 1, title: '安卓逆向工程简介', subtitle: '入门指南' },
        { num: 2, title: '什么是逆向工程', subtitle: 'APK 结构与原理' },
        { num: 3, title: '必备工具全景', subtitle: 'jadx / Frida / apktool' },
        { num: 4, title: '标准分析流程', subtitle: '5步法' },
        { num: 5, title: 'Smali 语言', subtitle: '安卓汇编基础' },
        { num: 6, title: '6大保护机制', subtitle: '混淆/加壳/SSL Pinning' },
        { num: 7, title: 'Frida 动态分析', subtitle: '实战脚本' },
        { num: 8, title: '行业数据', subtitle: '现状与资源' },
        { num: 9, title: '法律与道德', subtitle: '合规边界' },
        { num: 10, title: '学习路线图', subtitle: '从零到实战' },
    ];

    const totalSlides = slidesData.length;
    let currentSlide = 1;

    // ============================================
    // 初始化缩略图
    // ============================================
    function initSidebar() {
        const sidebar = document.getElementById('sidebar');
        slidesData.forEach((data, index) => {
            const item = document.createElement('div');
            item.className = 'thumb-item' + (index === 0 ? ' active' : '');
            item.id = 'thumb-' + (index + 1);
            item.onclick = () => goToSlide(index + 1);
            item.innerHTML = `
                <div class="thumb-inner" style="background:${index === 0 ? '#fff' : '#f8f8f8'};">
                    <div class="thumb-title">${data.title}</div>
                    <div class="thumb-subtitle">${data.subtitle}</div>
                    <div class="thumb-num">${String(index + 1).padStart(2, '0')}</div>
                </div>
            `;
            sidebar.appendChild(item);
        });
    }

    // ============================================
    // 初始化进度点
    // ============================================
    function initProgress() {
        const container = document.getElementById('slideProgress');
        slidesData.forEach((_, index) => {
            const dot = document.createElement('div');
            dot.className = 'progress-dot' + (index === 0 ? ' active' : '');
            dot.id = 'dot-' + (index + 1);
            dot.onclick = () => goToSlide(index + 1);
            container.appendChild(dot);
        });
    }

    // ============================================
    // 切换幻灯片
    // ============================================
    function goToSlide(num) {
        if (num < 1 || num > totalSlides) return;

        // 隐藏当前
        document.getElementById('slide-' + currentSlide).classList.remove('active');
        document.getElementById('thumb-' + currentSlide).classList.remove('active');
        document.getElementById('dot-' + currentSlide).classList.remove('active');

        currentSlide = num;

        // 显示新的
        document.getElementById('slide-' + currentSlide).classList.add('active');
        document.getElementById('thumb-' + currentSlide).classList.add('active');
        document.getElementById('dot-' + currentSlide).classList.add('active');

        // 更新指示器
        document.getElementById('slideIndicator').textContent = `${currentSlide} / ${totalSlides}`;

        // 滚动缩略图到可见
        const thumb = document.getElementById('thumb-' + currentSlide);
        thumb.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
    }

    function nextSlide() { goToSlide(currentSlide + 1); }
    function prevSlide() { goToSlide(currentSlide - 1); }

    // 键盘事件
    document.addEventListener('keydown', (e) => {
        if (e.key === 'ArrowRight' || e.key === 'ArrowDown') nextSlide();
        if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') prevSlide();
    });

    // ============================================
    // 导出 PPTX
    // ============================================
    async function exportPPTX() {
        const loading = document.getElementById('exportLoading');
        loading.classList.remove('hidden');

        try {
            // 动态加载 pptxgenjs
            await loadScript('https://unpkg.com/pptxgenjs@4.0.1/dist/pptxgen.bundle.js');

            const pptx = new PptxGenJS();

            // 幻灯片尺寸 16:9
            pptx.layout = 'LAYOUT_WIDE';
            pptx.author = 'Android Reverse Engineering';
            pptx.company = 'Security Research';
            pptx.subject = '安卓逆向工程简介';
            pptx.title = '安卓逆向工程简介';

            // 定义主题色
            const C = {
                black: '1d1d1f',
                gray: '6e6e73',
                lightGray: 'f5f5f7',
                border: 'd2d2d7',
                white: 'ffffff',
                bgLight: 'fafafa',
            };

            // ──────────────────────────────
            // SLIDE 1: 封面
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                // 左侧装饰块
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });

                // 标签
                slide.addText('🔍  技术入门指南 · 2024', {
                    x: 0.5, y: 1.0, w: 5, h: 0.35,
                    fontSize: 10, color: C.gray, bold: true,
                    fontFace: 'Arial'
                });

                // 主标题
                slide.addText('安卓逆向工程简介', {
                    x: 0.5, y: 1.5, w: 6.5, h: 1.4,
                    fontSize: 46, color: C.black, bold: true,
                    fontFace: 'Arial', charSpacing: -1
                });

                // 副标题
                slide.addText('了解 Android APK 如何被分析、解构与研究\n从工具到流程,系统性入门指南', {
                    x: 0.5, y: 3.1, w: 5.5, h: 0.9,
                    fontSize: 14, color: C.gray,
                    fontFace: 'Arial', lineSpacingMultiple: 1.4
                });

                // 分割线
                slide.addShape(pptx.ShapeType.line, {
                    x: 0.5, y: 4.2, w: 5.5, h: 0,
                    line: { color: C.border, width: 1 }
                });

                // Meta 信息
                slide.addText('🎯 适合初学者  ·  📱 Android 平台  ·  ⏱ 预计阅读 15 分钟', {
                    x: 0.5, y: 4.35, w: 6, h: 0.3,
                    fontSize: 10, color: C.gray, fontFace: 'Arial'
                });

                // 右侧代码卡片背景
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 7.2, y: 1.2, w: 5.5, h: 3.8,
                    fill: { color: C.lightGray },
                    line: { color: 'e0e0e5', width: 1 },
                    rectRadius: 0.15
                });

                slide.addText('📄  APK 结构示意', {
                    x: 7.5, y: 1.45, w: 4.5, h: 0.3,
                    fontSize: 11, color: C.black, bold: true, fontFace: 'Courier New'
                });

                const codeLines = [
                    '# APK 本质是 ZIP 压缩文件',
                    'app.apk/',
                    '├── classes.dex    # 代码(逆向目标)',
                    '├── res/           # 图片/布局资源',
                    '├── lib/           # Native SO 库',
                    '├── assets/        # 原始资源文件',
                    '└── AndroidManifest.xml',
                ];

                codeLines.forEach((line, i) => {
                    slide.addText(line, {
                        x: 7.5, y: 1.9 + i * 0.3, w: 4.8, h: 0.28,
                        fontSize: 10, color: line.startsWith('#') ? C.gray : C.black,
                        fontFace: 'Courier New', bold: line.includes('classes.dex')
                    });
                });

                // 页脚
                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('01 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 2: 什么是逆向工程
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });

                // 章节标签
                slide.addText('CHAPTER 01', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });

                // 装饰线
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });

                slide.addText('什么是安卓逆向工程?', {
                    x: 0.5, y: 0.95, w: 11, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial', charSpacing: -0.5
                });

                // 左列:通俗理解卡片
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 1.85, w: 5.8, h: 1.7,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('🔧 通俗理解', {
                    x: 0.75, y: 1.98, w: 5, h: 0.3,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                slide.addText('你下载了一个 APP,但没有源代码。逆向工程就是把这个 APP 的 classes.dex(编译后的代码文件)还原回你能读懂的 Java 代码,就像把熟食还原成菜谱。', {
                    x: 0.75, y: 2.32, w: 5.3, h: 1.0,
                    fontSize: 11, color: C.gray, fontFace: 'Arial', lineSpacingMultiple: 1.3
                });

                // 左列:合法场景卡片
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 3.7, w: 5.8, h: 2.5,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('⚖️ 合法应用场景', {
                    x: 0.75, y: 3.83, w: 5, h: 0.3,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                const legalCases = [
                    '• 安全研究:发现 APP 漏洞并向厂商上报',
                    '• 恶意软件分析:分析病毒/木马行为',
                    '• 协议还原:分析 APP 通信协议',
                    '• 自己的代码:忘记源码时恢复逻辑',
                ];
                legalCases.forEach((text, i) => {
                    slide.addText(text, {
                        x: 0.75, y: 4.18 + i * 0.45, w: 5.3, h: 0.38,
                        fontSize: 11, color: C.gray, fontFace: 'Arial'
                    });
                });

                // 右列:编译链
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 6.7, y: 1.85, w: 5.8, h: 4.35,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('📦 Android 代码编译链', {
                    x: 6.95, y: 1.98, w: 5, h: 0.3,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });

                const chain = [
                    { title: '.java / .kt 源码', desc: '开发者编写的代码', dark: false },
                    { title: '↓ javac / kotlinc 编译', desc: '', dark: false, arrow: true },
                    { title: '.class 字节码', desc: 'JVM 字节码格式', dark: false },
                    { title: '↓ d8 / dx 工具转换', desc: '', dark: false, arrow: true },
                    { title: 'classes.dex', desc: 'Dalvik 字节码 — 逆向分析的目标', dark: true },
                ];

                let yPos = 2.35;
                chain.forEach(item => {
                    if (item.arrow) {
                        slide.addText(item.title, {
                            x: 6.95, y: yPos, w: 5.3, h: 0.3,
                            fontSize: 10, color: C.gray, fontFace: 'Arial', align: 'center'
                        });
                        yPos += 0.32;
                    } else {
                        slide.addShape(pptx.ShapeType.roundRect, {
                            x: 6.95, y: yPos, w: 5.3, h: 0.65,
                            fill: { color: item.dark ? C.black : C.white },
                            line: { color: item.dark ? C.black : 'e0e0e5', width: 1 },
                            rectRadius: 0.08
                        });
                        slide.addText(item.title, {
                            x: 7.1, y: yPos + 0.08, w: 5, h: 0.28,
                            fontSize: 12, color: item.dark ? C.white : C.black,
                            bold: true, fontFace: 'Arial'
                        });
                        if (item.desc) {
                            slide.addText(item.desc, {
                                x: 7.1, y: yPos + 0.35, w: 5, h: 0.22,
                                fontSize: 9, color: item.dark ? 'aaaaaa' : C.gray, fontFace: 'Arial'
                            });
                        }
                        yPos += 0.72;
                    }
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('02 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 3: 核心工具
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 02', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('必备逆向工具全景', {
                    x: 0.5, y: 0.95, w: 11, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                const tools = [
                    { icon: '🔓', name: 'jadx', tag: '反编译', desc: '把 APK/dex 直接反编译成可读的 Java 代码,带 GUI 界面,新手首选工具,支持搜索、交叉引用等功能' },
                    { icon: '🔨', name: 'apktool v2.9.3', tag: '重打包', desc: '解包 APK → 修改 Smali 代码 → 重新打包。适合需要修改代码后重新安装的场景' },
                    { icon: '🕵️', name: 'Frida 16.x', tag: '动态分析', desc: '动态插桩框架,用 JavaScript 脚本在运行中 hook 任意函数,实时修改参数和返回值' },
                    { icon: '🌐', name: 'Charles / mitmproxy', tag: '流量分析', desc: '抓取 APP 的 HTTPS 网络请求,查看 APP 发送的数据、API 接口格式与参数结构' },
                    { icon: '🏗️', name: 'IDA Pro / Ghidra', tag: 'Native 分析', desc: '分析 .so 原生库(C/C++ 编译的 ARM 代码),Ghidra 免费开源,NSA 出品,功能完备' },
                ];

                tools.forEach((tool, i) => {
                    const y = 1.9 + i * 1.02;
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x: 0.5, y, w: 12.2, h: 0.88,
                        fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                        rectRadius: 0.1
                    });
                    slide.addText(tool.icon, {
                        x: 0.65, y: y + 0.22, w: 0.5, h: 0.45,
                        fontSize: 20, fontFace: 'Arial'
                    });
                    slide.addText(tool.name, {
                        x: 1.3, y: y + 0.12, w: 3, h: 0.3,
                        fontSize: 13, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    slide.addText(tool.desc, {
                        x: 1.3, y: y + 0.45, w: 9.3, h: 0.28,
                        fontSize: 10, color: C.gray, fontFace: 'Arial'
                    });
                    // 标签
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x: 11.1, y: y + 0.22, w: 1.3, h: 0.32,
                        fill: { color: 'ebebf0' }, line: { color: 'e0e0e5', width: 1 },
                        rectRadius: 0.04
                    });
                    slide.addText(tool.tag, {
                        x: 11.1, y: y + 0.24, w: 1.3, h: 0.28,
                        fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', align: 'center'
                    });
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('03 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 4: 逆向工作流
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 03', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('标准逆向分析流程', {
                    x: 0.5, y: 0.95, w: 11, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                // 流程步骤
                const steps = [
                    { num: '1', title: '获取 APK', desc: 'adb pull 或\nAPKPure 下载' },
                    { num: '2', title: '静态分析', desc: 'jadx 查看代码\n结构与权限' },
                    { num: '3', title: '定位目标', desc: '搜索 login/check\n/encrypt 等关键词' },
                    { num: '4', title: '动态验证', desc: 'Frida hook\n打印参数返回值' },
                    { num: '5', title: '整理结论', desc: '记录逻辑接口\n和加密算法' },
                ];

                steps.forEach((step, i) => {
                    const x = 0.5 + i * 2.42;
                    // 圆圈
                    slide.addShape(pptx.ShapeType.ellipse, {
                        x: x + 0.7, y: 1.95, w: 0.8, h: 0.8,
                        fill: { color: C.black }
                    });
                    slide.addText(step.num, {
                        x: x + 0.7, y: 1.97, w: 0.8, h: 0.76,
                        fontSize: 14, color: C.white, bold: true,
                        fontFace: 'Arial', align: 'center', valign: 'middle'
                    });
                    // 连接线
                    if (i < 4) {
                        slide.addShape(pptx.ShapeType.line, {
                            x: x + 1.52, y: 2.35, w: 0.88, h: 0,
                            line: { color: C.border, width: 1 }
                        });
                    }
                    slide.addText(step.title, {
                        x, y: 2.88, w: 2.2, h: 0.3,
                        fontSize: 11, color: C.black, bold: true,
                        fontFace: 'Arial', align: 'center'
                    });
                    slide.addText(step.desc, {
                        x, y: 3.2, w: 2.2, h: 0.5,
                        fontSize: 9, color: C.gray,
                        fontFace: 'Arial', align: 'center', lineSpacingMultiple: 1.3
                    });
                });

                // 底部三列代码/提示
                const cols = [
                    {
                        title: '🔍 常用 adb 命令',
                        lines: ['# 列出所有已安装包名', 'adb shell pm list packages', '', '# 提取 APK 文件', 'adb pull \\', '  /data/app/xxx/base.apk .']
                    },
                    {
                        title: '🪝 Frida Hook 模板',
                        lines: ['Java.perform(function() {', '  var Cls = Java.use(', '    "com.app.Login");', '  Cls.check.implementation', '    = function() {', '    return true; // 绕过', '  };', '});']
                    },
                    {
                        title: '📋 静态分析清单',
                        lines: ['☑ AndroidManifest 权限声明', '☑ 网络请求域名和接口', '☑ 本地 SharedPrefs 存储', '☑ 加密算法调用位置', '☑ 混淆程度和命名规则', '☑ 第三方 SDK 引入情况']
                    },
                ];

                cols.forEach((col, i) => {
                    const x = 0.5 + i * 4.1;
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x, y: 3.9, w: 3.85, h: 2.7,
                        fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                        rectRadius: 0.1
                    });
                    slide.addText(col.title, {
                        x: x + 0.15, y: 4.03, w: 3.55, h: 0.28,
                        fontSize: 11, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    col.lines.forEach((line, j) => {
                        slide.addText(line, {
                            x: x + 0.15, y: 4.38 + j * 0.33, w: 3.55, h: 0.28,
                            fontSize: 9,
                            color: line.startsWith('#') || line.startsWith('') ? C.gray : C.black,
                            fontFace: line.startsWith('') ? 'Arial' : 'Courier New'
                        });
                    });
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('04 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 5: Smali
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 04', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('读懂 Smali —— 安卓汇编语言', {
                    x: 0.5, y: 0.95, w: 12, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                // 左:Java 代码
                slide.addText('原始 Java 代码', {
                    x: 0.5, y: 1.85, w: 5.5, h: 0.28,
                    fontSize: 11, color: C.gray, bold: true, fontFace: 'Arial'
                });
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 2.15, w: 5.5, h: 2.4,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.1
                });
                const javaCode = [
                    'public boolean isVip(String uid) {',
                    '  if (uid.equals("admin")) {',
                    '    return true;',
                    '  }',
                    '  return false;',
                    '}',
                ];
                javaCode.forEach((line, i) => {
                    slide.addText(line, {
                        x: 0.7, y: 2.28 + i * 0.34, w: 5.1, h: 0.3,
                        fontSize: 11, color: C.black, fontFace: 'Courier New'
                    });
                });

                // 寄存器规则
                slide.addText('关键寄存器规则', {
                    x: 0.5, y: 4.7, w: 5.5, h: 0.28,
                    fontSize: 11, color: C.gray, bold: true, fontFace: 'Arial'
                });
                const regs = [
                    { reg: 'v0', desc: '本地变量寄存器,从 v0 开始编号' },
                    { reg: 'p0', desc: '参数寄存器,p0 = this(实例方法)' },
                    { reg: 'p1', desc: '第一个参数,此例中 p1 = uid' },
                ];
                regs.forEach((r, i) => {
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x: 0.5, y: 5.02 + i * 0.52, w: 5.5, h: 0.42,
                        fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                        rectRadius: 0.06
                    });
                    slide.addText(r.reg, {
                        x: 0.65, y: 5.05 + i * 0.52, w: 0.5, h: 0.36,
                        fontSize: 12, color: C.black, bold: true, fontFace: 'Courier New'
                    });
                    slide.addText(r.desc, {
                        x: 1.3, y: 5.07 + i * 0.52, w: 4.5, h: 0.32,
                        fontSize: 10, color: C.gray, fontFace: 'Arial'
                    });
                });

                // 右:Smali 代码
                slide.addText('对应 Smali 代码(逆向后看到的)', {
                    x: 6.5, y: 1.85, w: 6.2, h: 0.28,
                    fontSize: 11, color: C.gray, bold: true, fontFace: 'Arial'
                });
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 6.5, y: 2.15, w: 6.2, h: 3.5,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.1
                });
                const smaliCode = [
                    '.method public isVip(Ljava/lang/String;)Z',
                    '  .registers 3   # v0, p0(this), p1(uid)',
                    '',
                    '  const-string v0, "admin"',
                    '  invoke-virtual {p1, v0},',
                    '    Ljava/lang/String;->equals(Ljava/lang/Object;)Z',
                    '  move-result v0',
                    '  if-eqz v0, :cond_0   # 若不等则跳转',
                    '',
                    '  const/4 v0, 0x1      # true',
                    '  return v0',
                    '',
                    '  :cond_0',
                    '  const/4 v0, 0x0      # false',
                    '  return v0',
                    '.end method',
                ];
                smaliCode.forEach((line, i) => {
                    slide.addText(line, {
                        x: 6.65, y: 2.28 + i * 0.195, w: 5.9, h: 0.19,
                        fontSize: 9,
                        color: line.includes('#') ? C.gray : C.black,
                        fontFace: 'Courier New'
                    });
                });

                // 提示
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 6.5, y: 5.78, w: 6.2, h: 0.75,
                    fill: { color: 'fff8e1' }, line: { color: 'ffe082', width: 1 },
                    rectRadius: 0.08
                });
                slide.addText('💡  逆向修改技巧:将 if-eqz 改成 if-nez,或直接将 const/4 v0, 0x0 改成 0x1,即可绕过 isVip 验证,让所有用户都返回 true。', {
                    x: 6.65, y: 5.85, w: 5.9, h: 0.6,
                    fontSize: 10, color: '795548', fontFace: 'Arial', lineSpacingMultiple: 1.3
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('05 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 6: 保护机制
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 05', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('APP 的 6 大保护机制', {
                    x: 0.5, y: 0.95, w: 12, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                const protections = [
                    { icon: '🌫️', title: '代码混淆 (ProGuard)', desc: '把 LoginActivity 改成 a.b.c,增加阅读难度,但逻辑不变,jadx 仍可反编译读取' },
                    { icon: '📦', title: '加壳 (Packing)', desc: '把真正的 dex 加密后隐藏,运行时再解密。常见:梆梆、360加固、腾讯乐固,需先脱壳' },
                    { icon: '🔐', title: 'SSL Pinning', desc: 'APP 内置证书指纹,只接受特定证书,阻止抓包。可用 Frida 脚本或 TrustMeAlready 绕过' },
                    { icon: '🔍', title: 'Root / 调试检测', desc: '检测 /system/bin/su 是否存在。可用 Magisk DenyList、RootBeer 模块进行对抗' },
                    { icon: '', title: 'VMP 虚拟机保护', desc: '核心算法被自定义虚拟机解释执行,指令集完全私有,是目前最难逆向的保护方式' },
                    { icon: '', title: '签名校验', desc: '运行时校验自身签名,重打包后签名变化会闪退。需 hook getSignatures() 返回原始签名' },
                ];

                protections.forEach((item, i) => {
                    const col = i % 3;
                    const row = Math.floor(i / 3);
                    const x = 0.5 + col * 4.1;
                    const y = 2.0 + row * 2.4;
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x, y, w: 3.85, h: 2.1,
                        fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                        rectRadius: 0.12
                    });
                    slide.addText(item.icon, {
                        x: x + 0.15, y: y + 0.18, w: 0.5, h: 0.5,
                        fontSize: 22, fontFace: 'Arial'
                    });
                    slide.addText(item.title, {
                        x: x + 0.15, y: y + 0.72, w: 3.5, h: 0.32,
                        fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    slide.addText(item.desc, {
                        x: x + 0.15, y: y + 1.08, w: 3.55, h: 0.85,
                        fontSize: 10, color: C.gray, fontFace: 'Arial', lineSpacingMultiple: 1.3
                    });
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('06 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 7: Frida 动态分析
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 06', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('Frida 动态分析实战', {
                    x: 0.5, y: 0.95, w: 12, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                // 左侧:环境搭建
                slide.addText('① 环境搭建', {
                    x: 0.5, y: 1.85, w: 5.8, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 2.15, w: 5.8, h: 2.2,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.1
                });
                const setupCode = [
                    '# 安装 frida 命令行工具',
                    'pip install frida-tools',
                    '',
                    '# 推送 frida-server 到手机',
                    'adb push frida-server /data/local/tmp/',
                    'adb shell "chmod 755 /data/local/tmp/frida-server"',
                    'adb shell "/data/local/tmp/frida-server &"',
                ];
                setupCode.forEach((line, i) => {
                    slide.addText(line, {
                        x: 0.7, y: 2.28 + i * 0.27, w: 5.4, h: 0.24,
                        fontSize: 9.5, color: line.startsWith('#') ? C.gray : C.black,
                        fontFace: 'Courier New'
                    });
                });

                // 注入命令
                slide.addText('② 注入脚本到目标 APP', {
                    x: 0.5, y: 4.5, w: 5.8, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 4.82, w: 5.8, h: 1.0,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.1
                });
                const injectCode = [
                    '# 对目标包名注入脚本并启动',
                    'frida -U -f com.target.app \\',
                    '  -l hook.js --no-pause',
                ];
                injectCode.forEach((line, i) => {
                    slide.addText(line, {
                        x: 0.7, y: 4.95 + i * 0.27, w: 5.4, h: 0.24,
                        fontSize: 9.5, color: line.startsWith('#') ? C.gray : C.black,
                        fontFace: 'Courier New'
                    });
                });

                // 右侧:Hook 脚本
                slide.addText('③ Hook 实战脚本:追踪 MessageDigest 加密输入', {
                    x: 6.7, y: 1.85, w: 6, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 6.7, y: 2.15, w: 5.8, h: 3.65,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.1
                });
                const hookCode = [
                    'Java.perform(function() {',
                    '  // Hook MessageDigest (MD5/SHA)',
                    '  var MD = Java.use(',
                    '    "java.security.MessageDigest");',
                    '',
                    '  MD.update.overload("[B")',
                    '    .implementation = function(b) {',
                    '    // 打印传入的原文数据',
                    '    var str = Java.use("java.lang.String").$new(b);',
                    '    console.log("[*] MD input: " + str);',
                    '',
                    '    // 打印调用栈,定位代码位置',
                    '    console.log(Java.use("android.util.Log")',
                    '      .getStackTraceString(',
                    '        Java.use("java.lang.Exception").$new()));',
                    '',
                    '    return this.update(b);  // 继续执行原函数',
                    '  };',
                    '});',
                ];
                hookCode.forEach((line, i) => {
                    slide.addText(line, {
                        x: 6.85, y: 2.28 + i * 0.175, w: 5.5, h: 0.17,
                        fontSize: 8.5,
                        color: line.includes('//') ? C.gray : C.black,
                        fontFace: 'Courier New'
                    });
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('07 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 8: 行业数据
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 07', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('行业数据与应用现状', {
                    x: 0.5, y: 0.95, w: 12, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                // 三个统计数字
                const stats = [
                    { num: '35%', label: 'Google Play APP\n使用了代码混淆', src: 'NowSecure 2023' },
                    { num: '73%', label: '金融类 APP 存在\n高危安全漏洞', src: 'OWASP Mobile Top 10' },
                    { num: '$38K', label: 'Google 安卓漏洞\n最高 Bug Bounty 奖励', src: 'Google VRP 2023' },
                ];
                stats.forEach((s, i) => {
                    const x = 0.5 + i * 4.1;
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x, y: 1.95, w: 3.85, h: 1.7,
                        fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                        rectRadius: 0.12
                    });
                    slide.addText(s.num, {
                        x, y: 2.05, w: 3.85, h: 0.75,
                        fontSize: 36, color: C.black, bold: true,
                        fontFace: 'Arial', align: 'center', charSpacing: -1
                    });
                    slide.addText(s.label, {
                        x, y: 2.82, w: 3.85, h: 0.45,
                        fontSize: 10, color: C.gray,
                        fontFace: 'Arial', align: 'center', lineSpacingMultiple: 1.3
                    });
                    slide.addText(s.src, {
                        x, y: 3.3, w: 3.85, h: 0.25,
                        fontSize: 8, color: C.border,
                        fontFace: 'Arial', align: 'center'
                    });
                });

                // 应用场景条形图
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 3.9, w: 5.8, h: 2.65,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('📊 逆向工程主要应用场景', {
                    x: 0.7, y: 4.03, w: 5.3, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                const bars = [
                    { label: '安全漏洞研究', pct: 45 },
                    { label: '恶意软件分析', pct: 30 },
                    { label: '协议还原分析', pct: 15 },
                    { label: '其他(兼容/测试)', pct: 10 },
                ];
                bars.forEach((bar, i) => {
                    const y = 4.45 + i * 0.52;
                    slide.addText(bar.label, {
                        x: 0.7, y, w: 2.5, h: 0.25,
                        fontSize: 10, color: C.black, fontFace: 'Arial', bold: true
                    });
                    slide.addText(`${bar.pct}%`, {
                        x: 5.6, y, w: 0.5, h: 0.25,
                        fontSize: 10, color: C.gray, fontFace: 'Arial', align: 'right'
                    });
                    // 背景条
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x: 0.7, y: y + 0.27, w: 5.1, h: 0.1,
                        fill: { color: 'e0e0e5' }, rectRadius: 0.05
                    });
                    // 进度条
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x: 0.7, y: y + 0.27, w: 5.1 * bar.pct / 100, h: 0.1,
                        fill: { color: C.black }, rectRadius: 0.05
                    });
                });

                // 学习资源
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 6.7, y: 3.9, w: 5.8, h: 2.65,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('🏆 推荐学习资源', {
                    x: 6.9, y: 4.03, w: 5.3, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                const resources = [
                    { name: 'CTF 平台', desc: 'BUUCTF、攻防世界均有专项 Android 题' },
                    { name: 'OWASP MASTG', desc: '移动安全测试指南,官方免费 PDF' },
                    { name: '看雪论坛 / 52pojie', desc: '国内最活跃逆向社区,大量实战案例' },
                    { name: 'Android Internals', desc: 'Jonathan Levin 著,深入系统底层原理' },
                ];
                resources.forEach((r, i) => {
                    slide.addShape(pptx.ShapeType.roundRect, {
                        x: 6.9, y: 4.43 + i * 0.52, w: 5.3, h: 0.42,
                        fill: { color: C.white }, line: { color: 'e8e8ed', width: 1 },
                        rectRadius: 0.06
                    });
                    slide.addText(r.name, {
                        x: 7.1, y: 4.46 + i * 0.52, w: 2.5, h: 0.22,
                        fontSize: 10, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    slide.addText(r.desc, {
                        x: 7.1, y: 4.67 + i * 0.52, w: 5, h: 0.18,
                        fontSize: 9, color: C.gray, fontFace: 'Arial'
                    });
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('08 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 9: 法律
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 08', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('法律红线与职业道德', {
                    x: 0.5, y: 0.95, w: 12, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                // 表格头
                const tableHeaders = ['行为', '法律依据(中国)', '风险等级', '建议'];
                const tableWidths = [3.5, 3.0, 2.0, 4.2];
                let xOff = 0.5;
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 1.85, w: 12.2, h: 0.38,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.06
                });
                tableHeaders.forEach((h, i) => {
                    slide.addText(h, {
                        x: xOff + 0.1, y: 1.88, w: tableWidths[i] - 0.1, h: 0.32,
                        fontSize: 11, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    xOff += tableWidths[i];
                });

                const rows = [
                    ['分析自己的 APP / 授权安全测试', '合法行为', '✓ 安全', '推荐练习方式'],
                    ['CTF 竞赛逆向题', '合法行为', '✓ 安全', '最佳入门途径'],
                    ['发现漏洞后负责任披露', '《网络安全法》鼓励', '✓ 鼓励', '可获 Bug Bounty 奖励'],
                    ['破解商业软件版权保护', '《著作权法》第 48 条', '⚠ 违法', '可能面临民事赔偿'],
                    ['未授权入侵、窃取数据', '《刑法》285/286 条', '🚫 刑事', '最高 7 年有期徒刑'],
                ];

                rows.forEach((row, ri) => {
                    const y = 2.28 + ri * 0.72;
                    const isOdd = ri % 2 === 0;
                    slide.addShape(pptx.ShapeType.rect, {
                        x: 0.5, y, w: 12.2, h: 0.68,
                        fill: { color: isOdd ? C.white : 'fafafa' }
                    });
                    // 底部分割线
                    slide.addShape(pptx.ShapeType.line, {
                        x: 0.5, y: y + 0.68, w: 12.2, h: 0,
                        line: { color: 'f0f0f0', width: 1 }
                    });
                    xOff = 0.5;
                    row.forEach((cell, ci) => {
                        const isDanger = ri >= 3;
                        const isRisk = ci === 2;
                        slide.addText(cell, {
                            x: xOff + 0.1, y: y + 0.2, w: tableWidths[ci] - 0.1, h: 0.28,
                            fontSize: 10,
                            color: isRisk && isDanger ? 'c0392b' : isRisk ? '27ae60' : C.gray,
                            bold: isRisk,
                            fontFace: 'Arial'
                        });
                        xOff += tableWidths[ci];
                    });
                });

                // 提示框
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 0.5, y: 5.95, w: 12.2, h: 0.75,
                    fill: { color: 'f0f8ff' }, line: { color: 'b3d9f7', width: 1 },
                    rectRadius: 0.08
                });
                slide.addText('⚖️  核心原则:只在你有权限的环境内操作。拿到认证(OSCE、BSCP)比非法操作更能体现技术价值。Bug Bounty 平台(HackerOne、各厂商 SRC)提供了合法赚钱的渠道,最高单漏洞奖励可达数万元。', {
                    x: 0.7, y: 6.02, w: 11.8, h: 0.6,
                    fontSize: 10, color: '1a4a7a', fontFace: 'Arial', lineSpacingMultiple: 1.3
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('09 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // ──────────────────────────────
            // SLIDE 10: 学习路线
            // ──────────────────────────────
            {
                const slide = pptx.addSlide();
                slide.background = { color: C.white };

                slide.addShape(pptx.ShapeType.rect, {
                    x: 0, y: 0, w: 0.06, h: 7.5,
                    fill: { color: C.black }
                });
                slide.addText('CHAPTER 09', {
                    x: 0.5, y: 0.5, w: 4, h: 0.25,
                    fontSize: 9, color: C.gray, bold: true, fontFace: 'Arial', charSpacing: 1
                });
                slide.addShape(pptx.ShapeType.rect, {
                    x: 0.5, y: 0.82, w: 0.5, h: 0.04,
                    fill: { color: C.black }
                });
                slide.addText('从零到实战:学习路线图', {
                    x: 0.5, y: 0.95, w: 12, h: 0.7,
                    fontSize: 28, color: C.black, bold: true, fontFace: 'Arial'
                });

                // 时间线
                const timeline = [
                    { phase: '第 1-2 周:基础准备', desc: '学 Java 基础语法 → 了解 Android 开发结构 → 搭建 Android Studio 环境,写一个简单 APP', done: true },
                    { phase: '第 3-4 周:静态分析入门', desc: '安装 jadx,解析开源 APK(如 GadgetBridge),读懂类结构和方法调用关系', done: true },
                    { phase: '第 5-6 周:Smali 与重打包', desc: '用 apktool 解包 → 修改 Smali → 重打包签名 → 安装验证,完成第一次 patch', done: true },
                    { phase: '第 7-8 周:动态分析 Frida', desc: '配置 Frida 环境 → 完成基本 hook → 追踪加密函数 → 打印调用栈定位逻辑', done: true },
                    { phase: '第 2-3 月:CTF 实战', desc: '在 CTF 平台做 Android 题,解决真实混淆/加壳场景,积累实战解题经验', done: false },
                ];

                // 竖线
                slide.addShape(pptx.ShapeType.line, {
                    x: 0.9, y: 2.1, w: 0, h: 4.4,
                    line: { color: C.border, width: 1 }
                });

                timeline.forEach((item, i) => {
                    const y = 2.0 + i * 0.9;
                    // 圆点
                    slide.addShape(pptx.ShapeType.ellipse, {
                        x: 0.65, y: y + 0.02, w: 0.5, h: 0.5,
                        fill: { color: item.done ? C.black : C.white },
                        line: { color: item.done ? C.black : C.border, width: 2 }
                    });
                    if (item.done) {
                        slide.addText(String(i + 1), {
                            x: 0.65, y: y + 0.02, w: 0.5, h: 0.5,
                            fontSize: 11, color: C.white, bold: true,
                            fontFace: 'Arial', align: 'center', valign: 'middle'
                        });
                    }
                    slide.addText(item.phase, {
                        x: 1.3, y: y + 0.02, w: 5.1, h: 0.28,
                        fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    slide.addText(item.desc, {
                        x: 1.3, y: y + 0.32, w: 5.3, h: 0.45,
                        fontSize: 10, color: C.gray, fontFace: 'Arial', lineSpacingMultiple: 1.3
                    });
                });

                // 右侧:练习 APK + 技能树
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 7.1, y: 2.0, w: 5.6, h: 2.0,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('🛠 推荐练习 APK', {
                    x: 7.3, y: 2.12, w: 5, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                const apks = [
                    { name: 'InsecureBank v2', level: '入门' },
                    { name: 'DIVA Android', level: '入门' },
                    { name: 'UnCrackable Level 1-3', level: '进阶' },
                    { name: 'OWASP GoatDroid', level: '综合' },
                ];
                apks.forEach((apk, i) => {
                    slide.addShape(pptx.ShapeType.line, {
                        x: 7.3, y: 2.52 + i * 0.33, w: 5.1, h: 0,
                        line: { color: 'f0f0f0', width: 1 }
                    });
                    slide.addText(apk.name, {
                        x: 7.3, y: 2.55 + i * 0.33, w: 3.5, h: 0.25,
                        fontSize: 10, color: C.black, bold: true, fontFace: 'Arial'
                    });
                    slide.addText(apk.level, {
                        x: 11.2, y: 2.55 + i * 0.33, w: 1.2, h: 0.25,
                        fontSize: 9, color: C.gray, fontFace: 'Arial', align: 'right'
                    });
                });

                // 技能树
                slide.addShape(pptx.ShapeType.roundRect, {
                    x: 7.1, y: 4.15, w: 5.6, h: 2.4,
                    fill: { color: C.lightGray }, line: { color: 'e8e8ed', width: 1 },
                    rectRadius: 0.12
                });
                slide.addText('🎯 技能树总览', {
                    x: 7.3, y: 4.28, w: 5, h: 0.28,
                    fontSize: 12, color: C.black, bold: true, fontFace: 'Arial'
                });
                const skills = [
                    ['Java/Kotlin', 'Smali 语法'],
                    ['jadx 使用', 'apktool 重打包'],
                    ['Frida 插桩', '抓包分析'],
                    ['ARM 汇编 (进阶)', '脱壳技术 (进阶)'],
                ];
                skills.forEach((row, ri) => {
                    row.forEach((skill, ci) => {
                        const isAdv = skill.includes('进阶');
                        slide.addShape(pptx.ShapeType.roundRect, {
                            x: 7.3 + ci * 2.75, y: 4.68 + ri * 0.43, w: 2.55, h: 0.34,
                            fill: { color: isAdv ? 'f0f0f0' : C.white },
                            line: { color: 'e8e8ed', width: 1 },
                            rectRadius: 0.06
                        });
                        slide.addText(skill, {
                            x: 7.35 + ci * 2.75, y: 4.7 + ri * 0.43, w: 2.45, h: 0.3,
                            fontSize: 9.5,
                            color: isAdv ? C.gray : C.black,
                            bold: !isAdv,
                            fontFace: 'Arial', align: 'center'
                        });
                    });
                });

                slide.addText('ANDROID REVERSE ENGINEERING', {
                    x: 0.5, y: 7.0, w: 5, h: 0.25,
                    fontSize: 8, color: C.border, bold: true, fontFace: 'Arial'
                });
                slide.addText('10 / 10', {
                    x: 11.5, y: 7.0, w: 1.2, h: 0.25,
                    fontSize: 8, color: C.border, fontFace: 'Arial', align: 'right'
                });
            }

            // 保存文件
            await pptx.writeFile({ fileName: '安卓逆向工程简介.pptx' });

        } catch (error) {
            console.error('导出失败:', error);
            alert('导出失败: ' + error.message);
        } finally {
            loading.classList.add('hidden');
        }
    }

    function loadScript(src) {
        return new Promise((resolve, reject) => {
            if (window.PptxGenJS) {
                resolve();
                return;
            }
            const script = document.createElement('script');
            script.src = src;
            script.onload = resolve;
            script.onerror = reject;
            document.head.appendChild(script);
        });
    }

    // ============================================
    // 初始化
    // ============================================
    initSidebar();
    initProgress();
</script>
</body>
</html>

结果如下,

我已经充分了解了这个文件的结构和特征。现在为你总结一个精炼的AI提示词,方便下次复用。

---

# 📋 精炼AI提示词(可复用)

````markdown
# 角色
你是一位资深的 PPT 设计师 + 前端工程师,擅长 Apple 风格极简设计和 pptxgenjs 库。

# 任务
生成一个**单文件 HTML**,主题是「{{在此填写主题}}」,共 {{N}} 页幻灯片。
该 HTML 在浏览器中是一个交互式 PPT 预览器,并且带有一键「导出 PPTX」按钮,点击后通过 pptxgenjs 生成一份**视觉上与 HTML 完全一致的 .pptx 文件**。

# 一、整体架构(必须严格遵守)
1. **单个 .html 文件**,内联 CSS + JS,零外部依赖(pptxgenjs 在点击导出时动态 CDN 加载:`https://unpkg.com/pptxgenjs@4.0.1/dist/pptxgen.bundle.js`)。
2. 页面布局三区:
- **顶部固定栏**(高52px,毛玻璃 `backdrop-filter: blur(20px)`):左侧 app 图标+标题,中间「← 页码 →」导航,右侧黑色「↓ 导出 PPTX」按钮。
- **左侧缩略图栏**(宽180px,毛玻璃):由 JS 根据 `slidesData` 数组动态生成,包含页码、标题、副标题,点击可跳转,当前页高亮。
- **主内容区**:单张 `.slide` 容器,`aspect-ratio:16/9`,`max-width:960px`,白底、圆角16px、柔和阴影;通过 `.active` 类切换显示。
3. 交互:左右方向键翻页、点击缩略图跳转、点击进度点跳转,切换有 `slideIn` 淡入动画。
4. 导出加载遮罩:点击导出时显示「正在生成 PPTX 文件」loading 层。

# 二、视觉设计系统(Apple 极简风)
- **调色板**(HTML 与 PPTX 必须同色):
```
黑 #1d1d1f | 灰 #6e6e73 | 浅灰背景 #f5f5f7 | 边框 #d2d2d7 | 白 #ffffff
```
- **字体**:`-apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Helvetica Neue', Arial`;PPTX 中用 `Arial`,代码用 `Courier New`。
- **字号规范**:主标题 46-52px、章节标题 28px、卡片标题 12-14px、正文 10-12px、页脚 8-9px。
- **元素规范**:
- 每页左边缘 0.06"宽纯黑装饰竖条
- 章节标签用大写英文「CHAPTER 0X」+ 字距 1px,下方一条 40px 黑色 `accent-line`
- 卡片统一 `border-radius: 12-16px`、浅灰背景 `#f5f5f7`、1px 细边框
- 首页可用毛玻璃 `.glass-card` 作右侧视觉元素(代码块 / 图示卡)
- 页脚统一:左「ANDROID REVERSE」品牌字 + 中间细线 + 右「0X / XX」页码

# 三、HTML 页面结构(关键类名保持一致)
```
.top-bar / .sidebar .thumb-item / .slide-wrapper > .slide.slide-N
每张 .slide 内:.slide-content > .section-header (.section-label + .accent-line + .section-title) + 主体区 + .slide-footer
```
- 布局模式可选:**首页左右分栏**、**two-col 双列卡片**、**tool-list 列表**、**5步时间线(圆圈+连接线)**、**三/四列卡片网格**、**数据统计大数字**。
- JS 中维护 `slidesData = [{num, title, subtitle}, ...]` 用于生成缩略图。

# 四、PPTX 导出(核心 —— 必须逐页 1:1 还原)
```js
const pptx = new PptxGenJS();
pptx.layout = 'LAYOUT_WIDE'; // 13.33 x 7.5 英寸 16:9
pptx.author/company/subject/title = '...';
const C = { black:'1d1d1f', gray:'6e6e73', lightGray:'f5f5f7', border:'d2d2d7', white:'ffffff' };
```
**每一页都用独立 `{ ... }` 块**构建,顺序复刻 HTML:
1. `slide.background = { color: C.white }`
2. 左边缘装饰条 `addShape(rect, {x:0,y:0,w:0.06,h:7.5, fill:{color:C.black}})`
3. `CHAPTER 0X` 标签 + 装饰短线 + 章节大标题
4. 卡片用 `addShape(roundRect, {... rectRadius:0.12, fill:{color:C.lightGray}, line:{color:'e8e8ed',width:1}})`,再在其上用 `addText` 叠加文字
5. 强调块用反色(黑底白字)
6. 图标用 Emoji 直接写在文字里(`🔧 通俗理解`)
7. 页脚品牌字 + 页码(`0.5" / 11.5"` 两端对齐)

**坐标单位为英寸**,常用基准:
- 页面 13.33" × 7.5"
- 左右留白 0.5"、内容宽度 12.3"
- 左右两栏:每栏 5.8" 宽,间距 0.4"
- 章节标题 y=0.95、主体区从 y=1.85 开始、页脚 y=7.0

# 五、内容要求
- {{N}} 页大纲由你根据主题自行合理设计,但需包含:封面页 + 章节页 + 总结/路线图页。
- 文案中文为主,数据/代码/术语用英文,保持信息密度适中,不堆砌。
- 所有可视化元素(图表、流程链、对比卡)在 HTML 和 PPTX 中都用**原生形状 + 文字**绘制,不引入图片。

# 六、交付
直接输出完整 `.html` 文件代码(一个代码块,无多余解释)。确保:
- 浏览器打开即可预览、键盘可翻页;
- 点击「导出 PPTX」成功下载 `{{主题}}.pptx`,打开后每一页视觉与 HTML 一致。
````

---

## 💡 使用说明

下次只需把这段提示词发给 AI,并在以下位置填空:
- `{{在此填写主题}}` → 例如:"React 19 新特性"、"区块链入门" 等
- `{{N}}` → 页数,例如 10

AI 就能生成一份**同款 Apple 极简风 + 可导出 PPTX** 的 HTML 幻灯片文件。

### 这个提示词的关键特征总结
| 维度 | 特征 |
|---|---|
| 形态 | 单 HTML 文件,内含预览器 + PPTX 导出 |
| 技术 | 纯原生 CSS/JS + pptxgenjs@4.0.1 CDN |
| 风格 | Apple 极简(黑白灰 + 毛玻璃 + 圆角) |
| 尺寸 | 16:9 / LAYOUT_WIDE / 13.33×7.5 英寸 |
| 导出核心 | 用 `addShape` + `addText` 逐页 1:1 还原,不截图 |
| 一致性 | HTML 与 PPTX **同色号、同字号、同布局** |

posted on 2026-04-25 11:39  GKLBB  阅读(3)  评论(0)    收藏  举报