Full Code of jeremybeaume/tools for AI

master fb48c2dbb3d7 cached
19 files
51.2 KB
14.2k tokens
38 symbols
1 requests
Download .txt
Repository: jeremybeaume/tools
Branch: master
Commit: fb48c2dbb3d7
Files: 19
Total size: 51.2 KB

Directory structure:
gitextract_6wf3dbfx/

├── IDA_plugin/
│   └── param_enum.py
├── README.md
├── disable-defender.ps1
└── pin-unpacker/
    ├── .gitignore
    ├── IAT.cpp
    ├── IAT.h
    ├── IAT_repair.py
    ├── MyPinTool.vcxproj
    ├── MyPinTool.vcxproj.user
    ├── README.md
    ├── Unpacker.sln
    ├── Upacker.cpp
    ├── export.h
    ├── export_pin.cpp
    ├── export_windows.cpp
    ├── pin_utils.cpp
    ├── pin_utils.h
    ├── utils.cpp
    └── utils.h

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

================================================
FILE: IDA_plugin/param_enum.py
================================================
"""
Replace immediate values push before a call by enum value
"""

from idc import *
from idaapi import *
from idautils import *
from ida_enum import *

def replace_pushed_int(function_ea, target_push_n, target_enum_name, before_limit=0x30, int_type="hex"):
    """
    Replace the <target_push_n> last immediate value push before by enum value if possible

    function_ea : target function ea (will check Xref to this ea)
                  for structs use get_name_ea_simple
    target_push_n : how many push back we want, starts at 1
    target_enum_name : enum to target (created if doesn't exists)
    before_limit : how much back we agree to go
    str_type : "hex" or "dec", used for the enum value names (in hex or dec number)
    """

    target_enum = get_enum(target_enum_name)
    if target_enum == BADADDR:
        if int_type == "hex":
            target_enum = add_enum(0, target_enum_name, hex_flag())
        else:
            target_enum = add_enum(0, target_enum_name, dec_flag())

    for xref in XrefsTo(function_ea, 0):
        current_ea = xref.frm
        push_n = 0
        
        while current_ea != BADADDR:
            current_ea = prev_head(current_ea, xref.frm - before_limit)
            
            if print_insn_mnem(current_ea) == "push":
                push_n += 1

                if push_n == target_push_n: # that's the push we are looking for

                    type_n = get_operand_type(current_ea, 0)
                    if type_n == 5: # immediate value
                        value = get_operand_value(current_ea, 0)
                       
                        enum_value = get_enum_member(target_enum, value, 0, 0)
                        if enum_value == BADADDR:
                            # Create a new enum value
                            if int_type == "hex":
                                enum_val_name = "{:02X}".format(value)
                            else:
                                enum_val_name = str(value)

                            enum_value = add_enum_member(target_enum, get_enum_name(target_enum) + "_" + enum_val_name, value)

                        op_enum(current_ea, 0, target_enum, 0)

                    else: # not an immediate value
                        print(f"Help needed @ {hex(current_ea)}")
                    
                    break # Done here, break to the next Xref


================================================
FILE: README.md
================================================
Collection of tools developped by myself.

Some of them may have articles describing them on my [blog](https://bidouillesecurity.com)

================================================
FILE: disable-defender.ps1
================================================
# Disable Windows Defender

<#
                           _               _ 
 __      ____ _ _ __ _ __ (_)_ __   __ _  | |
 \ \ /\ / / _` | '__| '_ \| | '_ \ / _` | | |
  \ V  V / (_| | |  | | | | | | | | (_| | |_|
   \_/\_/ \__,_|_|  |_| |_|_|_| |_|\__, | (_)
                                   |___/     

This script is NOT a disable/enable solution, I'm a malware analyst, I use it for malware analysis.
It can completely DELETE Defender, and it is NOT REVERSIBLE (that's what I need).
Once you have run it, you will no longer have any sort of antivirus protection, and WILL NOT BE ABLE to reactivate it.

Think twice before running it, or read the blog post to understand and modify it to suit **your** needs.

THIS IS NOT A JOKE.
YOU HAVE BEEN WARNED.
#>

<#
Options :

-Delete : delete the defender related files (services, drivers, executables, ....) 

Source :  https://bidouillesecurity.com/disable-windows-defender-in-powershell

#>

Write-Host "[+] Disable Windows Defender (as $(whoami))"


## STEP 0 : elevate if needed


if(-Not $($(whoami) -eq "nt authority\system")) {
    $IsSystem = $false

    # Elevate to admin (needed when called after reboot)
    if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
        Write-Host "    [i] Elevate to Administrator"
        $CommandLine = "-ExecutionPolicy Bypass `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
        Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
        Exit
    }

    # Elevate to SYSTEM if psexec is available
    $psexec_path = $(Get-Command PsExec -ErrorAction 'ignore').Source 
    if($psexec_path) {
        Write-Host "    [i] Elevate to SYSTEM"
        $CommandLine = " -i -s powershell.exe -ExecutionPolicy Bypass `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments 
        Start-Process -WindowStyle Hidden -FilePath $psexec_path -ArgumentList $CommandLine
        exit
    } else {
        Write-Host "    [i] PsExec not found, will continue as Administrator"
    }

} else {
    $IsSystem = $true
}


## STEP 1 : Disable everything we can with immediate effect


Write-Host "    [+] Add exclusions"

# Add the whole system in Defender exclusions

67..90|foreach-object{
    $drive = [char]$_
    Add-MpPreference -ExclusionPath "$($drive):\" -ErrorAction SilentlyContinue
    Add-MpPreference -ExclusionProcess "$($drive):\*" -ErrorAction SilentlyContinue
}

Write-Host "    [+] Disable scanning engines (Set-MpPreference)"

Set-MpPreference -DisableArchiveScanning 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableBehaviorMonitoring 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableIntrusionPreventionSystem 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableIOAVProtection 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableRemovableDriveScanning 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableBlockAtFirstSeen 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableScanningMappedNetworkDrivesForFullScan 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableScanningNetworkFiles 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableScriptScanning 1 -ErrorAction SilentlyContinue
Set-MpPreference -DisableRealtimeMonitoring 1 -ErrorAction SilentlyContinue

Write-Host "    [+] Set default actions to Allow (Set-MpPreference)"

Set-MpPreference -LowThreatDefaultAction Allow -ErrorAction SilentlyContinue
Set-MpPreference -ModerateThreatDefaultAction Allow -ErrorAction SilentlyContinue
Set-MpPreference -HighThreatDefaultAction Allow -ErrorAction SilentlyContinue


## STEP 2 : Disable services, we cannot stop them, but we can disable them (they won't start next reboot)


Write-Host "    [+] Disable services"

$need_reboot = $false

# WdNisSvc Network Inspection Service 
# WinDefend Antivirus Service
# Sense : Advanced Protection Service

$svc_list = @("WdNisSvc", "WinDefend", "Sense")
foreach($svc in $svc_list) {
    if($(Test-Path "HKLM:\SYSTEM\CurrentControlSet\Services\$svc")) {
        if( $(Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$svc").Start -eq 4) {
            Write-Host "        [i] Service $svc already disabled"
        } else {
            Write-Host "        [i] Disable service $svc (next reboot)"
            Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$svc" -Name Start -Value 4
            $need_reboot = $true
        }
    } else {
        Write-Host "        [i] Service $svc already deleted"
    }
}

Write-Host "    [+] Disable drivers"

# WdnisDrv : Network Inspection System Driver
# wdfilter : Mini-Filter Driver
# wdboot : Boot Driver

$drv_list = @("WdnisDrv", "wdfilter", "wdboot")
foreach($drv in $drv_list) {
    if($(Test-Path "HKLM:\SYSTEM\CurrentControlSet\Services\$drv")) {
        if( $(Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$drv").Start -eq 4) {
            Write-Host "        [i] Driver $drv already disabled"
        } else {
            Write-Host "        [i] Disable driver $drv (next reboot)"
            Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$drv" -Name Start -Value 4
            $need_reboot = $true
        }
    } else {
        Write-Host "        [i] Driver $drv already deleted"
    }
}

# Check if service running or not
if($(GET-Service -Name WinDefend).Status -eq "Running") {   
    Write-Host "    [+] WinDefend Service still running (reboot required)"
    $need_reboot = $true
} else {
    Write-Host "    [+] WinDefend Service not running"
}


## STEP 3 : Reboot if needed, add a link to the script to Startup (will be runned again after reboot)


$link_reboot = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\disable-defender.lnk"
Remove-Item -Force "$link_reboot" -ErrorAction 'ignore' # Remove the link (only execute once after reboot)

if($need_reboot) {
    Write-Host "    [+] This script will be started again after reboot." -BackgroundColor DarkRed -ForegroundColor White
    
    $powershell_path = '"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"'
    $cmdargs = "-ExecutionPolicy Bypass `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
    
    $res = New-Item $(Split-Path -Path $link_reboot -Parent) -ItemType Directory -Force
    $WshShell = New-Object -comObject WScript.Shell
    $shortcut = $WshShell.CreateShortcut($link_reboot)
    $shortcut.TargetPath = $powershell_path
    $shortcut.Arguments = $cmdargs
    $shortcut.WorkingDirectory = "$(Split-Path -Path $PSScriptRoot -Parent)"
    $shortcut.Save()

} else {


    ## STEP 4 : After reboot (we checked that everything was successfully disabled), make sure it doesn't come up again !


    if($IsSystem) {

        # Configure the Defender registry to disable it (and the TamperProtection)
        # editing HKLM:\SOFTWARE\Microsoft\Windows Defender\ requires to be SYSTEM

        Write-Host "    [+] Disable all functionnalities with registry keys (SYSTEM privilege)"

        # Cloud-delivered protection:
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender\Real-Time Protection" -Name SpyNetReporting -Value 0
        # Automatic Sample submission
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender\Real-Time Protection" -Name SubmitSamplesConsent -Value 0
        # Tamper protection
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender\Features" -Name TamperProtection -Value 4
        
        # Disable in registry
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows Defender" -Name DisableAntiSpyware -Value 1
        Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows Defender" -Name DisableAntiSpyware -Value 1

    } else {
        Write-Host "    [W] (Optional) Cannot configure registry (not SYSTEM)"
    }


    if($MyInvocation.UnboundArguments -And $($MyInvocation.UnboundArguments.tolower().Contains("-delete"))) {
        
        # Delete Defender files

        function Delete-Show-Error {
            $path_exists = Test-Path $args[0]
            if($path_exists) {
                Remove-Item -Recurse -Force -Path $args[0]
            } else {
                Write-Host "    [i] $($args[0]) already deleted"
            }
        }

        Write-Host ""
        Write-Host "[+] Delete Windows Defender (files, services, drivers)"

        # Delete files
        Delete-Show-Error "C:\ProgramData\Windows\Windows Defender\"
        Delete-Show-Error "C:\ProgramData\Windows\Windows Defender Advanced Threat Protection\"

        # Delete drivers
        Delete-Show-Error "C:\Windows\System32\drivers\wd\"

        # Delete service registry entries
        foreach($svc in $svc_list) {
            Delete-Show-Error "HKLM:\SYSTEM\CurrentControlSet\Services\$svc"
        }

        # Delete drivers registry entries
        foreach($drv in $drv_list) {
            Delete-Show-Error "HKLM:\SYSTEM\CurrentControlSet\Services\$drv"
        }
    }
}

Write-Host ""
Read-Host -Prompt "Press any key to continue"


================================================
FILE: pin-unpacker/.gitignore
================================================
test/
x64/
x86/
IAT.json
*.exe
*.dll
.vs/

================================================
FILE: pin-unpacker/IAT.cpp
================================================
#include <iostream>
#include <fstream>

#include "IAT.h"
#include "utils.h"

using std::endl;

void IAT_add_library(IAT_table& table, char* DLL_Name, ADDRINT LoadLibrary_addr)
{
	struct IAT_DLL_entry& funct_entry = table[std::string(DLL_Name)];
	if (funct_entry.LoadLibrary_addr != 0) {
		funct_entry.LoadLibrary_addr = LoadLibrary_addr;
	}
}

void IAT_add_function(IAT_table& table, char* DLL_Name, char* function_name, ADDRINT function_addr, ADDRINT GetProcAddress_addr)
{
	struct IAT_Func_entry entry;
	entry.Function_name = std::string(function_name);
	entry.IAT_RVA = function_addr;
	entry.GetProcAddress_addr = GetProcAddress_addr;

	struct IAT_DLL_entry& funct_entry = table[std::string(DLL_Name)];
	funct_entry.functions.push_back(entry);
}

void IAT_print(const IAT_table& table, std::ostream* out)
{
	*out << "=== IAT ===" << endl;
	for (std::pair<std::string, struct IAT_DLL_entry> element : table)
	{
		*out << element.first << " (Loaded @ " << int_to_hex(element.second.LoadLibrary_addr) << ")" << endl;
		for (struct IAT_Func_entry entry : element.second.functions)
		{
			*out << "    " << entry.Function_name << " @ " << int_to_hex(entry.IAT_RVA) << " (Loaded @ " << int_to_hex(entry.GetProcAddress_addr) << ")" << endl;
		}
	}
}

void IAT_json_save(const IAT_table& table, const std::string& path)
{
	std::ofstream outFile;
	outFile.open(path.c_str());

	outFile << "{\n  \"DLL\":{\n";

	bool first_DLL = true;
	for (std::pair<std::string, struct IAT_DLL_entry> element : table)
	{
		if (!first_DLL) {
			outFile << ",\n";
		}
		first_DLL = false;
		outFile << "    \"" << element.first << "\":{\n";
		outFile << "      \"LoadLibrary_RVA\":\"" << int_to_hex(element.second.LoadLibrary_addr) << "\",\n";
		outFile << "      \"functions\":{\n";

		bool first_function = true;
		for (struct IAT_Func_entry entry : element.second.functions)
		{
			if (!first_function) {
				outFile << ",\n";
			}
			first_function = false;
			outFile << "        \"" << entry.Function_name << "\":{\n";
			outFile << "          \"IAT_RVA\":\"" << int_to_hex(entry.IAT_RVA) <<"\",\n";
			outFile << "          \"GetProcAddress_RVA\":\"" << int_to_hex(entry.GetProcAddress_addr) << "\"\n";
			outFile << "        }";
		}
		outFile << "\n      }\n";
		outFile << "    }";
	}
	outFile << "\n  }\n}\n";

	outFile.close();
	std::cerr << "IAT saved in " << path << endl;
}

================================================
FILE: pin-unpacker/IAT.h
================================================
#pragma once

#include <iostream>
#include <vector>

#include "pin.H"

struct IAT_Func_entry {
	std::string Function_name;
	ADDRINT IAT_RVA;
	ADDRINT GetProcAddress_addr;
};

struct IAT_DLL_entry {
	ADDRINT LoadLibrary_addr;
	std::vector<struct IAT_Func_entry> functions;
};

typedef std::map<std::string, struct IAT_DLL_entry> IAT_table;

void IAT_add_library(IAT_table& table, char* DLL_Name, ADDRINT LoadLibrary_addr);

void IAT_add_function(IAT_table& table, char* DLL_Name, char* function_name, ADDRINT function_addr, ADDRINT GetProcAddress_addr);

void IAT_print(const IAT_table& table, std::ostream* out);

void IAT_json_save(const IAT_table& table, const std::string& path);

================================================
FILE: pin-unpacker/IAT_repair.py
================================================
import argparse
import lief
import os
import json

def align(x, al):
    """ return <x> aligned to <al> """
    if x % al == 0:
        return x
    else:
        return x - (x % al) + al


def pad_data(data, al):
    """ return <data> padded with 0 to a size aligned with <al> """
    return data + ([0] * (align(len(data), al) - len(data)))


class ImportTableBuilder:

    def __init__(self, baseoffset, ptr_size):
        self.data = b""
        self.hint_name_RVA_dict = {}
        self.name_thunk_RVA_dict = {}
        self.baseoffset = baseoffset
        self.IDT_RVA = 0
        self.ptr_size = ptr_size


    def _add_name(self, name, hint=0):
        self.hint_name_RVA_dict[name] = self.baseoffset + len(self.data)
        self.data += b"\x00\x00" # hint field, added even for DLL names
        self.data += name.encode("ASCII") + b'\x00'


    def _add_thunk_list(self, dllname, name_list):
        self.name_thunk_RVA_dict[dllname] = self.baseoffset + len(self.data)
        for n in name_list:
            self._push(self.hint_name_RVA_dict[n], self.ptr_size)
        self._push(0, self.ptr_size) #end of the array


    def _add_import_descriptor(self, dllname, IAT_RVA):
        if(self.IDT_RVA ==0):
            self.IDT_RVA = self.baseoffset + len(self.data)
        self._push(self.name_thunk_RVA_dict[dllname], 4) #OriginalFirstThunk
        self._push(0, 4) #TimeDateStamp
        self._push(0, 4) #ForwarderChain
        self._push(self.hint_name_RVA_dict[dllname] + 2, 4) #DLLname, + 2 to ignore hint field
        self._push(IAT_RVA, 4) #FirstThunk


    def _push(self, val, size):
        self.data += val.to_bytes(size, "little")


    def _init_IAT(self, input_PE, base_IAT_addr, name_list):
        """
        Init the IAT to point to the functions names we created
        """
        rva = base_IAT_addr
        for n in name_list:
            data = list(self.hint_name_RVA_dict[n].to_bytes(self.ptr_size, "little"))
            input_PE.patch_address(rva, data, lief.Binary.VA_TYPES.RVA)
            rva += self.ptr_size


    def build(self, imports_names, IAT_locations, input_PE):
        """
            import_names = {
                'DLL_name':['functions_names']
            }

            IAT_locations = {'DLL_name':RVA}
        """

        for dll_name, func_names_list in imports_names.items():
            self._add_name(dll_name)  
            for fun_name in func_names_list:
                self._add_name(fun_name)

            self._add_thunk_list(dll_name, func_names_list)
            self._init_IAT(input_PE, IAT_locations[dll_name], func_names_list)

        for dll_name in imports_names.keys():
            self._add_import_descriptor(dll_name, IAT_locations[dll_name])
        self._push(0, 20) # empty import_descriptor to finish the array


if __name__ =="__main__" :

    parser = argparse.ArgumentParser(description='Pack PE binary')
    parser.add_argument('input', metavar="FILE", help='input PE file')
    parser.add_argument('iat_file', metavar="IAT FILE", help='input IAT json file')
    parser.add_argument('-o', metavar="FILE", help='output', default="IAT_corrected.exe")

    args = parser.parse_args()

    with open(args.iat_file, "r") as f:
        IAT_data = json.load(f)

    input_PE = lief.PE.parse(args.input)

    # get RVA for new section
    max_RVA = max([x.virtual_address + x.size for x in input_PE.sections])
    max_RVA = align(max_RVA, input_PE.optional_header.section_alignment)

    import_names = {}
    IAT_locations = {}

    for dll_name in IAT_data["DLL"].keys():
        import_names[dll_name] = []
        IAT_locations[dll_name] = 0

        func_dict = IAT_data["DLL"][dll_name]["functions"]

        for fun_name in func_dict.keys():
            import_names[dll_name] += [fun_name]

        IAT_loc = min([int(infos["IAT_RVA"], 16) for (name, infos) in func_dict.items()])

        IAT_locations[dll_name] = IAT_loc

    builder = ImportTableBuilder(max_RVA, 8)

    builder.build(import_names, IAT_locations, input_PE)

    import_data = pad_data(list(builder.data), input_PE.optional_header.file_alignment)
    import_section = lief.PE.Section(name=".imp")
    import_section.content = import_data
    import_section.size = len(import_data)
    import_section.virtual_address = max_RVA
    import_section.characteristics = (lief.PE.SECTION_CHARACTERISTICS.MEM_READ
                                        | lief.PE.SECTION_CHARACTERISTICS.MEM_WRITE)

    input_PE.add_section(import_section)

    # change the file ehaders

    # make lief compute the new sizeof_image
    input_PE.optional_header.sizeof_image = 0

    # chagne the Import table to point to ours
    import_data_dir = input_PE.data_directory(lief.PE.DATA_DIRECTORY.IMPORT_TABLE)
    import_data_dir.rva = builder.IDT_RVA
    import_data_dir.size = len(builder.data)

    # not supposed to move (no reloctions table)
    input_PE.optional_header.dll_characteristics = 0

    # make all sections writable (make sur the IAT is writable)
    for s in input_PE.sections:
        s.characteristics = s.characteristics | lief.PE.SECTION_CHARACTERISTICS.MEM_WRITE


    # save the resulting PE
    if(os.path.exists(args.o)):
        # little trick here : lief emits no warning when it cannot write because the output
        # file is already opened. Using this function ensure we fail in this case (avoid errors).
        os.remove(args.o)

    builder = lief.PE.Builder(input_PE)
    builder.build()
    builder.write(args.o)

    print(f"Output saved in {args.o}")







================================================
FILE: pin-unpacker/MyPinTool.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{639EF517-FCFC-408E-9500-71F0DC0458DB}</ProjectGuid>
    <RootNamespace>MyPinTool</RootNamespace>
    <Keyword>Win32Proj</Keyword>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
    <ProjectName>Unpacker</ProjectName>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>MultiByte</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <PlatformToolset>v142</PlatformToolset>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>MultiByte</CharacterSet>
    <PlatformToolset>v142</PlatformToolset>
    <PreferredToolArchitecture>x86</PreferredToolArchitecture>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>MultiByte</CharacterSet>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <PlatformToolset>v142</PlatformToolset>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>DynamicLibrary</ConfigurationType>
    <CharacterSet>MultiByte</CharacterSet>
    <PlatformToolset>v142</PlatformToolset>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <AdditionalOptions>/GR- /GS- /EHs- /EHa- /Oi- /FIinclude/msvc_compat.h %(AdditionalOptions)</AdditionalOptions>
      <Optimization>Disabled</Optimization>
      <AdditionalIncludeDirectories>$(PINTOOLS_DIR)\source\include\pin;$(PINTOOLS_DIR)\source\include\pin\gen;$(PINTOOLS_DIR)\source\toolsInstLib;$(PINTOOLS_DIR)\extras\xed-ia32\include\xed;$(PINTOOLS_DIR)\extras\components\include;$(PINTOOLS_DIR)\extras\stlport\include;$(PINTOOLS_DIR)\extras;$(PINTOOLS_DIR)\extras\libstdc++\include;$(PINTOOLS_DIR)\extras\crt\include;$(PINTOOLS_DIR)\extras\crt;$(PINTOOLS_DIR)\extras\crt\include\arch-x86;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi\asm-x86;%(AdditionalIncludeDirectories);$(WindowsSdkDir)\include</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>TARGET_IA32;HOST_IA32;TARGET_WINDOWS;__PIN__=1;PIN_CRT=1;__i386__;_WINDOWS_H_PATH_=$(WIN10SDK_INCLUDE)/um</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <ExceptionHandling>
      </ExceptionHandling>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <BufferSecurityCheck>false</BufferSecurityCheck>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <DisableSpecificWarnings>4530;5208;%(DisableSpecificWarnings)</DisableSpecificWarnings>
      <LanguageStandard>stdcpp17</LanguageStandard>
      <LanguageStandard_C>stdc17</LanguageStandard_C>
    </ClCompile>
    <Link>
      <AdditionalOptions>/export:main /ignore:4210 /ignore:4281 %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>pin.lib;xed.lib;pinvm.lib;pincrt.lib;ntdll-32.lib;kernel32.lib;crtbeginS.obj</AdditionalDependencies>
      <AdditionalLibraryDirectories>$(PINTOOLS_DIR)\ia32\lib;$(PINTOOLS_DIR)\ia32\lib-ext;$(PINTOOLS_DIR)\extras\xed-ia32\lib;$(PINTOOLS_DIR)\ia32\runtime\pincrt;%(AdditionalLibraryDirectories);$(WindowsSdkDir)\lib</AdditionalLibraryDirectories>
      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
      <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <SubSystem>NotSet</SubSystem>
      <OptimizeReferences>false</OptimizeReferences>
      <EntryPointSymbol>Ptrace_DllMainCRTStartup%4012</EntryPointSymbol>
      <BaseAddress>0x55000000</BaseAddress>
      <TargetMachine>MachineX86</TargetMachine>
      <AllowIsolation>true</AllowIsolation>
      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Midl>
      <TargetEnvironment>X64</TargetEnvironment>
    </Midl>
    <ClCompile>
      <AdditionalOptions>/GR- /GS- /EHs- /EHa- /Oi- /FIinclude/msvc_compat.h %(AdditionalOptions)</AdditionalOptions>
      <Optimization>Disabled</Optimization>
      <AdditionalIncludeDirectories>$(PINTOOLS_DIR)\source\include\pin;$(PINTOOLS_DIR)\source\include\pin\gen;$(PINTOOLS_DIR)\source\toolsInstLib;$(PINTOOLS_DIR)\extras\xed-intel64\include\xed;$(PINTOOLS_DIR)\extras\components\include;$(PINTOOLS_DIR)\extras\stlport\include;$(PINTOOLS_DIR)\extras;$(PINTOOLS_DIR)\extras\libstdc++\include;$(PINTOOLS_DIR)\extras\crt\include;$(PINTOOLS_DIR)\extras\crt;$(PINTOOLS_DIR)\extras\crt\include\arch-x86_64;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi\asm-x86;$(WindowsSdkDir)\include;%(AdditionalIncludeDirectories);$(WindowsSdkDir)\include</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>TARGET_IA32E;HOST_IA32E;TARGET_WINDOWS;__PIN__=1;PIN_CRT=1;__LP64__;_WINDOWS_H_PATH_=$(WIN10SDK_INCLUDE)/um</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <ExceptionHandling>
      </ExceptionHandling>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
      <BufferSecurityCheck>false</BufferSecurityCheck>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
      <DisableSpecificWarnings>4530;5208;%(DisableSpecificWarnings)</DisableSpecificWarnings>
      <LanguageStandard>stdcpp17</LanguageStandard>
      <LanguageStandard_C>stdc17</LanguageStandard_C>
    </ClCompile>
    <Link>
      <AdditionalOptions>/export:main /ignore:4210 /ignore:4281 %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>pin.lib;xed.lib;pinvm.lib;pincrt.lib;ntdll-64.lib;kernel32.lib;crtbeginS.obj</AdditionalDependencies>
      <AdditionalLibraryDirectories>$(PINTOOLS_DIR)\intel64\lib;$(PINTOOLS_DIR)\intel64\lib-ext;$(PINTOOLS_DIR)\extras\xed-intel64\lib;$(PINTOOLS_DIR)\intel64\runtime\pincrt;$(WindowsSdkDir)\lib;%(AdditionalLibraryDirectories);$(WindowsSdkDir)\lib</AdditionalLibraryDirectories>
      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
      <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <SubSystem>NotSet</SubSystem>
      <OptimizeReferences>false</OptimizeReferences>
      <EntryPointSymbol>Ptrace_DllMainCRTStartup</EntryPointSymbol>
      <BaseAddress>0xC5000000</BaseAddress>
      <TargetMachine>MachineX64</TargetMachine>
      <AllowIsolation>true</AllowIsolation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <AdditionalOptions>/GR- /GS- /EHs- /EHa- /Oi- /FIinclude/msvc_compat.h %(AdditionalOptions)</AdditionalOptions>
      <IntrinsicFunctions>false</IntrinsicFunctions>
      <WholeProgramOptimization>false</WholeProgramOptimization>
      <AdditionalIncludeDirectories>$(PINTOOLS_DIR)\source\include\pin;$(PINTOOLS_DIR)\source\include\pin\gen;$(PINTOOLS_DIR)\source\toolsInstLib;$(PINTOOLS_DIR)\extras\xed-ia32\include\xed;$(PINTOOLS_DIR)\extras\components\include;$(PINTOOLS_DIR)\extras\stlport\include;$(PINTOOLS_DIR)\extras;$(PINTOOLS_DIR)\extras\libstdc++\include;$(PINTOOLS_DIR)\extras\crt\include;$(PINTOOLS_DIR)\extras\crt;$(PINTOOLS_DIR)\extras\crt\include\arch-x86;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi\asm-x86;%(AdditionalIncludeDirectories);$(WindowsSdkDir)\include</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>TARGET_IA32;HOST_IA32;TARGET_WINDOWS;__PIN__=1;PIN_CRT=1;__i386__;_WINDOWS_H_PATH_=$(WIN10SDK_INCLUDE)/um</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <ExceptionHandling>
      </ExceptionHandling>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <BufferSecurityCheck>false</BufferSecurityCheck>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>
      </DebugInformationFormat>
      <DisableSpecificWarnings>4530;5208;%(DisableSpecificWarnings)</DisableSpecificWarnings>
      <LanguageStandard>stdcpp17</LanguageStandard>
      <LanguageStandard_C>stdc17</LanguageStandard_C>
    </ClCompile>
    <Link>
      <AdditionalOptions>/export:main /ignore:4210 /ignore:4281 %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>pin.lib;xed.lib;pinvm.lib;pincrt.lib;ntdll-32.lib;kernel32.lib;crtbeginS.obj</AdditionalDependencies>
      <AdditionalLibraryDirectories>$(PINTOOLS_DIR)\ia32\lib;$(PINTOOLS_DIR)\ia32\lib-ext;$(PINTOOLS_DIR)\extras\xed-ia32\lib;$(PINTOOLS_DIR)\ia32\runtime\pincrt;%(AdditionalLibraryDirectories);$(WindowsSdkDir)\lib</AdditionalLibraryDirectories>
      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
      <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <SubSystem>NotSet</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>
      </EnableCOMDATFolding>
      <LinkTimeCodeGeneration>
      </LinkTimeCodeGeneration>
      <EntryPointSymbol>Ptrace_DllMainCRTStartup%4012</EntryPointSymbol>
      <BaseAddress>0x55000000</BaseAddress>
      <TargetMachine>MachineX86</TargetMachine>
      <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Midl>
      <TargetEnvironment>X64</TargetEnvironment>
    </Midl>
    <ClCompile>
      <AdditionalOptions>/GR- /GS- /EHs- /EHa- /Oi- /FIinclude/msvc_compat.h %(AdditionalOptions)</AdditionalOptions>
      <IntrinsicFunctions>false</IntrinsicFunctions>
      <WholeProgramOptimization>false</WholeProgramOptimization>
      <AdditionalIncludeDirectories>$(PINTOOLS_DIR)\source\include\pin;$(PINTOOLS_DIR)\source\include\pin\gen;$(PINTOOLS_DIR)\source\toolsInstLib;$(PINTOOLS_DIR)\extras\xed-intel64\include\xed;$(PINTOOLS_DIR)\extras\components\include;$(PINTOOLS_DIR)\extras\stlport\include;$(PINTOOLS_DIR)\extras;$(PINTOOLS_DIR)\extras\libstdc++\include;$(PINTOOLS_DIR)\extras\crt\include;$(PINTOOLS_DIR)\extras\crt;$(PINTOOLS_DIR)\extras\crt\include\arch-x86_64;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi;$(PINTOOLS_DIR)\extras\crt\include\kernel\uapi\asm-x86;$(WindowsSdkDir)\include;%(AdditionalIncludeDirectories);$(WindowsSdkDir)\include</AdditionalIncludeDirectories>
      <PreprocessorDefinitions>TARGET_IA32E;HOST_IA32E;TARGET_WINDOWS;__PIN__=1;PIN_CRT=1;__LP64__;_WINDOWS_H_PATH_=$(WIN10SDK_INCLUDE)/um</PreprocessorDefinitions>
      <MinimalRebuild>false</MinimalRebuild>
      <ExceptionHandling>
      </ExceptionHandling>
      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
      <BufferSecurityCheck>false</BufferSecurityCheck>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
      <PrecompiledHeader>
      </PrecompiledHeader>
      <WarningLevel>Level3</WarningLevel>
      <DebugInformationFormat>
      </DebugInformationFormat>
      <DisableSpecificWarnings>4530;5208;%(DisableSpecificWarnings)</DisableSpecificWarnings>
      <LanguageStandard>stdcpp17</LanguageStandard>
      <LanguageStandard_C>stdc17</LanguageStandard_C>
    </ClCompile>
    <Link>
      <AdditionalOptions>/export:main /ignore:4210 /ignore:4281 %(AdditionalOptions)</AdditionalOptions>
      <AdditionalDependencies>pin.lib;xed.lib;pinvm.lib;pincrt.lib;ntdll-64.lib;kernel32.lib;crtbeginS.obj</AdditionalDependencies>
      <AdditionalLibraryDirectories>$(PINTOOLS_DIR)\intel64\lib;$(PINTOOLS_DIR)\intel64\lib-ext;$(PINTOOLS_DIR)\extras\xed-intel64\lib;$(PINTOOLS_DIR)\intel64\runtime\pincrt;$(WindowsSdkDir)\lib;%(AdditionalLibraryDirectories);$(WindowsSdkDir)\lib</AdditionalLibraryDirectories>
      <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
      <IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
      <GenerateDebugInformation>true</GenerateDebugInformation>
      <SubSystem>NotSet</SubSystem>
      <OptimizeReferences>true</OptimizeReferences>
      <EnableCOMDATFolding>
      </EnableCOMDATFolding>
      <LinkTimeCodeGeneration>
      </LinkTimeCodeGeneration>
      <EntryPointSymbol>Ptrace_DllMainCRTStartup</EntryPointSymbol>
      <BaseAddress>0xC5000000</BaseAddress>
      <TargetMachine>MachineX64</TargetMachine>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="export_pin.cpp" />
    <ClCompile Include="IAT.cpp" />
    <ClCompile Include="export_windows.cpp" />
    <ClCompile Include="pin_utils.cpp" />
    <ClCompile Include="utils.cpp" />
    <ClCompile Include="Upacker.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="export.h" />
    <ClInclude Include="pin_utils.h" />
    <ClInclude Include="utils.h" />
    <ClInclude Include="IAT.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

================================================
FILE: pin-unpacker/MyPinTool.vcxproj.user
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup />
</Project>

================================================
FILE: pin-unpacker/README.md
================================================

# Compilation configuration

## Environment variables

2 environment variables needed :

  * `PINTOOL_DIR` : pintool installation, so folder `$(PINTOOL_DIR)/source/include/pin` exists
  * `WIN10SDK_INCLUDE` : SDK installation dir, so `$(WIN10SDK_INCLUDE)/um/windows.h`  exists (should me something like `C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0`)

Add them through `sysdm.cpl` > Advanced > Envrionment Variables

================================================
FILE: pin-unpacker/Unpacker.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31105.61
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyPinTool", "MyPinTool.vcxproj", "{639EF517-FCFC-408E-9500-71F0DC0458DB}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|x64 = Debug|x64
		Debug|x86 = Debug|x86
		Release|x64 = Release|x64
		Release|x86 = Release|x86
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x64.ActiveCfg = Debug|x64
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x64.Build.0 = Debug|x64
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x86.ActiveCfg = Debug|Win32
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x86.Build.0 = Debug|Win32
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x64.ActiveCfg = Release|x64
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x64.Build.0 = Release|x64
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x86.ActiveCfg = Release|Win32
		{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x86.Build.0 = Release|Win32
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {2F8ECBE6-FF9D-4D3D-B2AB-EC87B9F25AAB}
	EndGlobalSection
EndGlobal


================================================
FILE: pin-unpacker/Upacker.cpp
================================================
#include <iostream>
#include <fstream>
#include <string.h>

#include "pin.H"
#include "utils.h" 
#include "pin_utils.h" 
#include "IAT.h"
#include "export.h"

using std::endl;

std::ostream * out = &std::cerr;

/*
    GLOBAL VARIABLES
*/

IAT_table iat_table;
char* last_LoadLibrary = NULL;

VOID save_results(ADDRINT OEP) {
    //IAT_print(iat_table, out);
    export_image(get_main_IMG(), OEP, "export.exe");
    IAT_json_save(iat_table, "IAT.json");

    exit(0); //FIXME better solution ? continue and do multiple exports (TLS) ?
}

VOID Fini(INT32 code, VOID *v)
{
    IAT_print(iat_table, out);
    *out << "DONE" << std::endl;
}

/*  Finds a function RTN object
    RTN must be closed after use
*/
RTN FindRoutine(IMG image, std::string name) {
    for (SYM sym = IMG_RegsymHead(image); SYM_Valid(sym); sym = SYM_Next(sym))
    {
        std::string fname = PIN_UndecorateSymbolName(SYM_Name(sym), UNDECORATION_NAME_ONLY);
        if (fname == name)
        {
            RTN rtn = RTN_FindByAddress(IMG_LowAddress(image) + SYM_Value(sym));
            if (RTN_Valid(rtn))
            {
                return rtn;
            }
        }
    }
    return RTN_Invalid();
}

VOID Callback_LoadLibrary(const CONTEXT* ctx, char* lib_name)
{
    ADDRINT saved_EIP = get_stack(ctx, 0);
    if (in_main_module(saved_EIP))
    {
       // *out << "Callback : LoadLibrary(" << lib_name << ") @ " << int_to_hex(saved_EIP) << endl;
        last_LoadLibrary = lib_name;
        IAT_add_library(iat_table, lib_name, get_RVA(saved_EIP));
    }
}

VOID Callback_GetProcAddress(const CONTEXT* ctx, char* funct_name)
{
    ADDRINT RBX = (ADDRINT)PIN_GetContextReg(ctx, REG_RBX);
    ADDRINT saved_EIP = get_stack(ctx, 0);
    if (in_main_module(saved_EIP))
    {
        //*out << "Callback : GetProcAddress(" << last_LoadLibrary << ", " << funct_name << ") @ " << int_to_hex(saved_EIP) << endl;
        //*out << "    RBX=" << int_to_hex(RBX) << " (" << int_to_hex(get_RVA(RBX)) << ")" << endl;
        IAT_add_function(iat_table, last_LoadLibrary, funct_name, get_RVA(RBX), get_RVA(saved_EIP)); //FIXME
    }
}

/* Called on DLL loaded by the Application */
VOID Callback_ImageLoad(IMG image, VOID* v)
{
    //*out << "Loading " << IMG_Name(image) << endl;
    RTN funct_rtn = FindRoutine(image, "LoadLibraryA");
    if (RTN_Valid(funct_rtn))
    {
        //*out << "Instrumenting LoadLibraryA in " << IMG_Name(image) << endl;
        RTN_Open(funct_rtn);
        RTN_InsertCall(funct_rtn, IPOINT_BEFORE, (AFUNPTR)Callback_LoadLibrary, IARG_CONTEXT, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END);
        RTN_Close(funct_rtn);
    }

    funct_rtn = FindRoutine(image, "GetProcAddress");
    if (RTN_Valid(funct_rtn))
    {
        //*out << "Instrumenting GetProcAddress in " << IMG_Name(image) << endl;
        RTN_Open(funct_rtn);
        RTN_InsertCall(funct_rtn, IPOINT_BEFORE, (AFUNPTR)Callback_GetProcAddress, IARG_CONTEXT, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_END);
        RTN_Close(funct_rtn);
    }
}

ADDRINT main_exec_section = 0;
bool last_in_exec_section = true;
ADDRINT last_ins = 0;

VOID Callback_Instruction(INS ins, VOID*) {
    // check instruction in main module
    ADDRINT ins_addr = INS_Address(ins);

    if (in_main_module(ins_addr)) { //FIXME : VirtualAlloc ?
        SEC ins_sec = Find_Section(ins_addr);
        if (!SEC_Valid(ins_sec)) {
            // should never happen inside a module !
            *out << "ERROR : instruction in main module, but not in a section ? (" << int_to_hex(ins_addr) << ")" << endl;
        }
        else {
            ADDRINT ins_secaddr = SEC_Address(ins_sec);
            if (main_exec_section == 0) {
                main_exec_section = ins_secaddr; //base section address for EntryPoint
            }
            else{
                if (main_exec_section != ins_secaddr) {
                    if (last_in_exec_section) {
                        *out << "Inter section jump found : RVA " << int_to_hex(get_RVA(ins_addr)) << " called from RVA " << int_to_hex(get_RVA(last_ins)) << endl;
                        save_results(ins_addr);
                    }
                    last_in_exec_section = false;
                }
                else {
                    last_in_exec_section = true;
                }
            }
        }
    }

    last_ins = ins_addr;
}

VOID Callback_AppStart(void* )
{
    //*out << "AppStart callback\n";
}

int main(int argc, char *argv[])
{
    // Initialize PIN library. Print help message if -h(elp) is specified
    // in the command line or the command line is invalid 
    if( PIN_Init(argc,argv) )
    {
        return 0;
    }

    PIN_InitSymbols();

    IMG_AddInstrumentFunction(Callback_ImageLoad, NULL);
    INS_AddInstrumentFunction(Callback_Instruction, NULL);

    PIN_AddApplicationStartFunction(Callback_AppStart, NULL);
    PIN_AddFiniFunction(Fini, NULL);
  
    // Start the program, never returns
    PIN_StartProgram();
    
    return 0;
}

================================================
FILE: pin-unpacker/export.h
================================================
#pragma once

#include <iostream>
#include "pin.H"

void export_image(IMG img, ADDRINT OEP, const std::string& path);

void export_image_buffer(void* data, size_t size, void* ImageBase, void* RVA_OEP, const std::string& path);



================================================
FILE: pin-unpacker/export_pin.cpp
================================================
/*
	Pin side for the exports
	windows.h and pin.H cannot be included simultaneously
*/

#include <iostream>
#include <string>

#include "pin.H"

#include "export.h"
#include "utils.h"

using std::endl;

void export_image(IMG img, ADDRINT OEP, const std::string& path) {
	size_t size = IMG_HighAddress(img) - IMG_LowAddress(img) + 1;
	char* buffer = (char*) malloc(size);

	PIN_SafeCopy(buffer, (void*) IMG_LowAddress(img), size);

	export_image_buffer(buffer, size, (void*)IMG_LowAddress(img), (void*) (OEP - IMG_LowAddress(img)), path);

	free(buffer);

	std::cerr << "Module " << IMG_Name(img) << " saved at " << path << endl;
}

================================================
FILE: pin-unpacker/export_windows.cpp
================================================
/*
	Functions of export.h that needs Windows.h included
	windows.h and pin.H cannot be included simultaneously
*/

#include <iostream>
#include <string>

#include <windows.h>
#include <winnt.h>


//#include "export.h" // this one includes pin, do NOT IMPORT
#include "utils.h"

using std::endl;

size_t pad_size(size_t data, size_t align)
{
	if (data % align == 0) {
		return 0;
	}
	else {
		return align - (data % align);
	}
}

size_t align(size_t data, size_t align)
{
	return data + pad_size(data, align);
}

/*
	Saves the sections of a IMG object to a file
*/
void export_image_buffer(void* data, size_t size, void* ImageBase, void* RVA_OEP, const std::string& path)
{
	IMAGE_DOS_HEADER* p_DOS_HDR = (IMAGE_DOS_HEADER*) data;
	IMAGE_NT_HEADERS* p_NT_HDR = (IMAGE_NT_HEADERS*)(((char*)p_DOS_HDR) + p_DOS_HDR->e_lfanew);
	IMAGE_SECTION_HEADER* sections = (IMAGE_SECTION_HEADER*)(p_NT_HDR + 1);
	
	//Change Optional Header, disable int size warnings
	#pragma warning(suppress: 4311)
	#pragma warning(suppress: 4302)
	p_NT_HDR->OptionalHeader.ImageBase = (ULONGLONG) ImageBase; // #FIXME : 64 bits ....
	
	#pragma warning(suppress: 4311)
	#pragma warning(suppress: 4302)
	p_NT_HDR->OptionalHeader.AddressOfEntryPoint = (DWORD) RVA_OEP;

	//Change sections :
	//	all sections have RawSize = VirtualSize
	//  and RawAddress = VirtualAddress

	for (int i = 0; i < p_NT_HDR->FileHeader.NumberOfSections; ++i) {
		sections[i].SizeOfRawData = sections[i].Misc.VirtualSize;
		sections[i].PointerToRawData = sections[i].VirtualAddress;
	}

	// Save the result

	FILE* file = fopen(path.c_str(), "wb");
	if (!file) {
		std::cerr << "ERROR opening output file " << int_to_hex(GetLastError()) << endl;
		return;
	}

	fwrite(data, size, 1, file);

	fclose(file);
}

================================================
FILE: pin-unpacker/pin_utils.cpp
================================================
#include <iostream>

#include "pin_utils.h"
#include "utils.h"

using std::endl;

SEC Find_Section(ADDRINT addr)
{
    //List images loaded in memory
    IMG img = IMG_FindByAddress(addr);
    if (IMG_Valid(img))
    {
        for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
        {
            ADDRINT sec_addr = SEC_Address(sec);
            USIZE sec_size = SEC_Size(sec);
            if (addr >= sec_addr && addr <= sec_addr + sec_size)
            {
                return sec;
            }
        }
    }
    return SEC_Invalid();
}

bool in_main_module(ADDRINT addr)
{
    PIN_LockClient();
    IMG img = IMG_FindByAddress(addr);
    PIN_UnlockClient();

    if (!IMG_Valid(img))
    {
        return false;
    }
    return IMG_IsMainExecutable(img);
}

ADDRINT get_RVA(ADDRINT addr)
{
    PIN_LockClient();
    IMG img = IMG_FindByAddress(addr);
    PIN_UnlockClient();

    if (!IMG_Valid(img))
    {
        std::cerr << "WARNING : No module found for address " << int_to_hex(addr) << endl;
        return addr;
    }
    return addr - IMG_LowAddress(img);
}

ADDRINT get_stack(const CONTEXT* ctx, ADDRINT offset)
{
    ADDRINT RSP = (ADDRINT)PIN_GetContextReg(ctx, REG_STACK_PTR);
    ADDRINT data;
    PIN_SafeCopy(&data, (void*)(RSP + offset), sizeof(ADDRINT));
    return data;
}

void print_call_stack(const CONTEXT* ctx, std::ostream* out) {
    ADDRINT RBP = (ADDRINT)PIN_GetContextReg(ctx, REG_RBP);
    ADDRINT EIP_saved;
    while (RBP != 0) {
        PIN_SafeCopy(&EIP_saved, (void*)(RBP + sizeof(ADDRINT)), sizeof(ADDRINT));
        *out << " " << int_to_hex(EIP_saved) << endl;
        PIN_SafeCopy(&RBP, (void*)(RBP), sizeof(ADDRINT));
    }
}

static IMG _main_img = IMG_Invalid();

IMG get_main_IMG()
{
    if (IMG_Valid(_main_img)) {
        return _main_img;
    }
    else {
        for (IMG img = APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) {
            if (IMG_IsMainExecutable(img)) {
                _main_img = img;
                return _main_img;
            }
        }
    }
    return IMG_Invalid();

}

================================================
FILE: pin-unpacker/pin_utils.h
================================================
#pragma once

#include "pin.H"

SEC Find_Section(ADDRINT addr);
bool in_main_module(ADDRINT addr);
ADDRINT get_RVA(ADDRINT addr);

ADDRINT get_stack(const CONTEXT* ctx, ADDRINT offset);

IMG get_main_IMG();

================================================
FILE: pin-unpacker/utils.cpp
================================================
#include <iostream>
#include <strings.h>

using std::endl;

std::string int_to_hex(ADDRINT val)
{
    char buff[33];
    sprintf(buff, "0x%llx", val);
    return std::string(buff);
}


================================================
FILE: pin-unpacker/utils.h
================================================
#pragma once

#include <iostream>
#include <string>

std::string int_to_hex(unsigned long long int val);
Download .txt
gitextract_6wf3dbfx/

├── IDA_plugin/
│   └── param_enum.py
├── README.md
├── disable-defender.ps1
└── pin-unpacker/
    ├── .gitignore
    ├── IAT.cpp
    ├── IAT.h
    ├── IAT_repair.py
    ├── MyPinTool.vcxproj
    ├── MyPinTool.vcxproj.user
    ├── README.md
    ├── Unpacker.sln
    ├── Upacker.cpp
    ├── export.h
    ├── export_pin.cpp
    ├── export_windows.cpp
    ├── pin_utils.cpp
    ├── pin_utils.h
    ├── utils.cpp
    └── utils.h
Download .txt
SYMBOL INDEX (38 symbols across 9 files)

FILE: IDA_plugin/param_enum.py
  function replace_pushed_int (line 10) | def replace_pushed_int(function_ea, target_push_n, target_enum_name, bef...

FILE: pin-unpacker/IAT.cpp
  function IAT_add_library (line 9) | void IAT_add_library(IAT_table& table, char* DLL_Name, ADDRINT LoadLibra...
  function IAT_add_function (line 17) | void IAT_add_function(IAT_table& table, char* DLL_Name, char* function_n...
  function IAT_print (line 28) | void IAT_print(const IAT_table& table, std::ostream* out)
  function IAT_json_save (line 41) | void IAT_json_save(const IAT_table& table, const std::string& path)

FILE: pin-unpacker/IAT.h
  type IAT_Func_entry (line 8) | struct IAT_Func_entry {
  type IAT_DLL_entry (line 14) | struct IAT_DLL_entry {
  type std (line 19) | typedef std::map<std::string, struct

FILE: pin-unpacker/IAT_repair.py
  function align (line 6) | def align(x, al):
  function pad_data (line 14) | def pad_data(data, al):
  class ImportTableBuilder (line 19) | class ImportTableBuilder:
    method __init__ (line 21) | def __init__(self, baseoffset, ptr_size):
    method _add_name (line 30) | def _add_name(self, name, hint=0):
    method _add_thunk_list (line 36) | def _add_thunk_list(self, dllname, name_list):
    method _add_import_descriptor (line 43) | def _add_import_descriptor(self, dllname, IAT_RVA):
    method _push (line 53) | def _push(self, val, size):
    method _init_IAT (line 57) | def _init_IAT(self, input_PE, base_IAT_addr, name_list):
    method build (line 68) | def build(self, imports_names, IAT_locations, input_PE):

FILE: pin-unpacker/Upacker.cpp
  function VOID (line 22) | VOID save_results(ADDRINT OEP) {
  function VOID (line 30) | VOID Fini(INT32 code, VOID *v)
  function RTN (line 39) | RTN FindRoutine(IMG image, std::string name) {
  function VOID (line 55) | VOID Callback_LoadLibrary(const CONTEXT* ctx, char* lib_name)
  function VOID (line 66) | VOID Callback_GetProcAddress(const CONTEXT* ctx, char* funct_name)
  function VOID (line 79) | VOID Callback_ImageLoad(IMG image, VOID* v)
  function VOID (line 105) | VOID Callback_Instruction(INS ins, VOID*) {
  function VOID (line 138) | VOID Callback_AppStart(void* )
  function main (line 143) | int main(int argc, char *argv[])

FILE: pin-unpacker/export_pin.cpp
  function export_image (line 16) | void export_image(IMG img, ADDRINT OEP, const std::string& path) {

FILE: pin-unpacker/export_windows.cpp
  function pad_size (line 18) | size_t pad_size(size_t data, size_t align)
  function align (line 28) | size_t align(size_t data, size_t align)
  function export_image_buffer (line 36) | void export_image_buffer(void* data, size_t size, void* ImageBase, void*...

FILE: pin-unpacker/pin_utils.cpp
  function SEC (line 8) | SEC Find_Section(ADDRINT addr)
  function in_main_module (line 27) | bool in_main_module(ADDRINT addr)
  function ADDRINT (line 40) | ADDRINT get_RVA(ADDRINT addr)
  function ADDRINT (line 54) | ADDRINT get_stack(const CONTEXT* ctx, ADDRINT offset)
  function print_call_stack (line 62) | void print_call_stack(const CONTEXT* ctx, std::ostream* out) {
  function IMG (line 74) | IMG get_main_IMG()

FILE: pin-unpacker/utils.cpp
  function int_to_hex (line 6) | std::string int_to_hex(ADDRINT val)
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (56K chars).
[
  {
    "path": "IDA_plugin/param_enum.py",
    "chars": 2381,
    "preview": "\"\"\"\nReplace immediate values push before a call by enum value\n\"\"\"\n\nfrom idc import *\nfrom idaapi import *\nfrom idautils "
  },
  {
    "path": "README.md",
    "chars": 133,
    "preview": "Collection of tools developped by myself.\n\nSome of them may have articles describing them on my [blog](https://bidouille"
  },
  {
    "path": "disable-defender.ps1",
    "chars": 9405,
    "preview": "# Disable Windows Defender\r\n\r\n<#\r\n                           _               _ \r\n __      ____ _ _ __ _ __ (_)_ __   __ "
  },
  {
    "path": "pin-unpacker/.gitignore",
    "chars": 41,
    "preview": "test/\nx64/\nx86/\nIAT.json\n*.exe\n*.dll\n.vs/"
  },
  {
    "path": "pin-unpacker/IAT.cpp",
    "chars": 2363,
    "preview": "#include <iostream>\n#include <fstream>\n\n#include \"IAT.h\"\n#include \"utils.h\"\n\nusing std::endl;\n\nvoid IAT_add_library(IAT_"
  },
  {
    "path": "pin-unpacker/IAT.h",
    "chars": 682,
    "preview": "#pragma once\n\n#include <iostream>\n#include <vector>\n\n#include \"pin.H\"\n\nstruct IAT_Func_entry {\n\tstd::string Function_nam"
  },
  {
    "path": "pin-unpacker/IAT_repair.py",
    "chars": 5538,
    "preview": "import argparse\nimport lief\nimport os\nimport json\n\ndef align(x, al):\n    \"\"\" return <x> aligned to <al> \"\"\"\n    if x % a"
  },
  {
    "path": "pin-unpacker/MyPinTool.vcxproj",
    "chars": 19729,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microso"
  },
  {
    "path": "pin-unpacker/MyPinTool.vcxproj.user",
    "chars": 163,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"Current\" xmlns=\"http://schemas.microsoft.com/developer/ms"
  },
  {
    "path": "pin-unpacker/README.md",
    "chars": 431,
    "preview": "\n# Compilation configuration\n\n## Environment variables\n\n2 environment variables needed :\n\n  * `PINTOOL_DIR` : pintool in"
  },
  {
    "path": "pin-unpacker/Unpacker.sln",
    "chars": 1404,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3110"
  },
  {
    "path": "pin-unpacker/Upacker.cpp",
    "chars": 4965,
    "preview": "#include <iostream>\n#include <fstream>\n#include <string.h>\n\n#include \"pin.H\"\n#include \"utils.h\" \n#include \"pin_utils.h\" "
  },
  {
    "path": "pin-unpacker/export.h",
    "chars": 228,
    "preview": "#pragma once\n\n#include <iostream>\n#include \"pin.H\"\n\nvoid export_image(IMG img, ADDRINT OEP, const std::string& path);\n\nv"
  },
  {
    "path": "pin-unpacker/export_pin.cpp",
    "chars": 630,
    "preview": "/*\n\tPin side for the exports\n\twindows.h and pin.H cannot be included simultaneously\n*/\n\n#include <iostream>\n#include <st"
  },
  {
    "path": "pin-unpacker/export_windows.cpp",
    "chars": 1752,
    "preview": "/*\n\tFunctions of export.h that needs Windows.h included\n\twindows.h and pin.H cannot be included simultaneously\n*/\n\n#incl"
  },
  {
    "path": "pin-unpacker/pin_utils.cpp",
    "chars": 2078,
    "preview": "#include <iostream>\n\n#include \"pin_utils.h\"\n#include \"utils.h\"\n\nusing std::endl;\n\nSEC Find_Section(ADDRINT addr)\n{\n    /"
  },
  {
    "path": "pin-unpacker/pin_utils.h",
    "chars": 206,
    "preview": "#pragma once\n\n#include \"pin.H\"\n\nSEC Find_Section(ADDRINT addr);\nbool in_main_module(ADDRINT addr);\nADDRINT get_RVA(ADDRI"
  },
  {
    "path": "pin-unpacker/utils.cpp",
    "chars": 183,
    "preview": "#include <iostream>\n#include <strings.h>\n\nusing std::endl;\n\nstd::string int_to_hex(ADDRINT val)\n{\n    char buff[33];\n   "
  },
  {
    "path": "pin-unpacker/utils.h",
    "chars": 105,
    "preview": "#pragma once\n\n#include <iostream>\n#include <string>\n\nstd::string int_to_hex(unsigned long long int val);\n"
  }
]

About this extraction

This page contains the full source code of the jeremybeaume/tools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (51.2 KB), approximately 14.2k tokens, and a symbol index with 38 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!