Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/loerting/threadtear
Analisi StaticaAnalisi del CodiceReverse EngineeringDebuggerAnalisi MalwareAnalisi di Binari
GitHubloerting/threadtear

threadtear

Suite di strumenti multifunzionale per la deofuscazione Java

Vedi Repository
9771325 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Threadtear Build Status Release Downloads

Threadtear è uno strumento di deofuscazione multifunzionale per Java. Il supporto per applicazioni Android è in arrivo (attualmente sto lavorando a un convertitore da Dalvik a Java). Adatto per un'analisi del codice più semplice senza preoccuparsi troppo dell'offuscamento. Sono inclusi anche gli offuscatori più costosi come ZKM o Stringer. Per un debug più semplice sono inclusi altri strumenti. Inserisci numeri di riga di debug per capire meglio da dove provengono le eccezioni, oppure aggiungi .printStackTrace() ai blocchi try-catch senza ricompilare il codice. La retrocompatibilità non è più un problema, se non vengono utilizzati metodi specifici di una versione. Analizza il flusso del codice in un grafico, per comprendere meglio gli algoritmi. Schermata 5 Schermata 1 Schermata 2 Schermata 3 Schermata 4

Esecuzioni

Una "esecuzione" è un'attività che viene eseguita e modifica tutti i file di classe caricati. Esistono vari tipi di esecuzioni, che vanno dalla pulizia del bytecode alla deofuscazione delle stringhe. Assicurati di averle nell'ordine giusto. Le esecuzioni di pulizia, ad esempio, dovrebbero essere eseguite per ultime, ma possono anche aiutare altre esecuzioni se eseguite per prime. Se sei pronto, clicca sul pulsante "Run" e verranno eseguite in ordine.

Avviso

Usa questo strumento a tuo rischio. Alcune esecuzioni utilizzano ClassLoader implementati per eseguire codice dal file jar. Un utente malintenzionato potrebbe modificare il bytecode in modo da eseguire codice dannoso. Le esecuzioni interessate usano la classe me.nov.threadtear.asm.vm.VM. Questo viene utilizzato principalmente per decifrare stringhe o offuscamento di risorse/accessi, poiché è molto più semplice eseguire i metodi di decifratura in remoto.

Sicurezza

Threadtear fa del suo meglio per proteggerti da chiamate dannose (esecuzioni di codice arbitrario) utilizzando un proprio SecurityManager, ma non c'è garanzia. Soprattutto con deoffuscatori come quelli per ZKM o Stringer bisogna stare molto attenti, poiché la riflessione deve essere consentita, altrimenti non funzionerebbero. Se scopri un ACE, per favore apri una segnalazione. Cercherò di risolverli il prima possibile.

Come compilare

Prima, esegui gradle build, poi gradle fatJar. Nella cartella builds/libs dovrebbe essere stato creato un jar eseguibile. Se non vuoi scaricare il repository, puoi usare l'ultima release.

Crea la tua esecuzione

Puoi creare facilmente la tua attività di esecuzione. Basta estendere me.nov.threadtear.execution.Execution:

root@kitploit:~
public class MyExecution extends Execution {
	public MyExecution() {
		super(ExecutionCategory.CLEANING /* categoria */, "My execution" /* nome */,
				"Executes something" /* descrizione, può usare html */);
	}
	/**
	* Questo metodo viene invocato quando l'utente clicca sul pulsante Run
	* @return true se successo, false se fallimento
	*/
	@Override
	public boolean execute(Map<String, Clazz> classes, boolean verbose) {
		classes.values().stream().map(c -> c.node).forEach(c -> {
			//trasforma qui le classi usando l'API tree di ASM
		});
		return false;
	}
}

Per caricare ClassNode a runtime, usa la classe me.nov.threadtear.asm.vm.VM e implementa me.nov.threadtear.asm.vm.IVMReferenceHandler:

root@kitploit:~
public class MyExecution extends Execution implements IVMReferenceHandler {
	public MyExecution() {
		super(ExecutionCategory.GENERIC, "My execution", "Carica ClassNode a runtime");
	}
	@Override
	public boolean execute(Map<String, Clazz> classes, boolean verbose) {
		classes.values().stream().map(c -> c.node).forEach(c -> {
			VM vm = VM.constructVM(this);
			//trasforma bytecode in java.lang.Class
			Class<?> loadedClass = vm.loadClass(c.name.replace('/', '.'), true);
			//fai cose con la tua classe qui
			loadedClass.getMethods()[0].invoke(...);
			return true;
		});
	}
	/**
	* Verrà invocato da VM, quando viene chiamato VM.loadClass
	*/
	@Override
	public ClassNode tryClassLoad(String name) {
		//prova a trovare la classe da caricare nell'archivio jar aperto
		return classes.containsKey(name) ? classes.get(name).node : null;
	}
}

Usando ConstantTracker (me.nov.threadtear.analysis.stack.ConstantTracker) puoi analizzare i metodi e tenere traccia dei valori dello stack non variabili. Se ad esempio iconst_0 viene spinto nello stack, il valore stesso non viene perso come nell'analizzatore ASM di base, e puoi usarlo per prevedere cose più avanti nel codice.

root@kitploit:~
public class MyExecution extends Execution implements IConstantReferenceHandler {
	public MyExecution() {
		super(ExecutionCategory.GENERIC, "My execution", "Esegue analisi dello stack e sostituisce il codice.");
	}
	@Override
	public boolean execute(Map<String, Clazz> classes, boolean verbose) {
		classes.values().stream().map(c -> c.node).forEach(this::analyzeAndRewrite);
		return true;
	}
	public void analyzeAndRewrite(ClassNode cn) {
		cn.methods.forEach(m -> {
			// questo analizzatore mantiene i valori dello stack noti, ad esempio utili per la previsione dei salti
			Analyzer<ConstantValue> a = new Analyzer<ConstantValue>(new ConstantTracker(this, Access.isStatic(m.access), m.maxLocals, m.desc, new Object[0]));
			try {
				a.analyze(cn.name, m);
			} catch (AnalyzerException e) {
				logger.severe("Analisi dello stack fallita in " + cn.name + "." + m.name + ":" + e.getMessage());
				return;
			}
			Frame<ConstantValue>[] frames = a.getFrames();
			InsnList rewrittenCode = new InsnList();
			Map<LabelNode, LabelNode> labels = Instructions.cloneLabels(m.instructions);

			// riscrivi le istruzioni del metodo
			for (int i = 0; i < m.instructions.size(); i++) {
				AbstractInsnNode ain = m.instructions.get(i);
				Frame<ConstantValue> frame = frames[i];
				// sostituisci / modifica istruzioni, ecc...
				if (frame.getStackSize() > 0) {
					ConstantValue top = frame.getStack(frame.getStackSize() - 1);
					if (top.isKnown() && top.isInteger()) {
						int knownTopStackValue = top.getInteger();
						// usa lo stack noto per rimuovere salti, semplificare codice, ecc...
						// if(...) { rewrittenCode.add(...); }
						continue;
					}
				}
				rewrittenCode.add(ain.clone(labels));
			}
			// aggiorna istruzioni e correggi blocchi try-catch, variabili locali, ecc...
			Instructions.updateInstructions(m, labels, rewrittenCode);
		});
	}
	/**
	 * Usa questo metodo per prevedere i valori dello stack se vengono caricati i campi
	 */
	@Override
	public Object getFieldValueOrNull(BasicValue v, String owner, String name, String desc) {
		return null;
	}
	/**
	 * Usa questo metodo per prevedere i valori dello stack se vengono invocati metodi su oggetti noti
	 */
	@Override
	public Object getMethodReturnOrNull(BasicValue v, String owner, String name, String desc, List<? extends ConstantValue> values) {
		if (name.equals("toCharArray") && owner.equals("java/lang/String")) {
			if (!values.get(0).isKnown()) {
				// il target dell'invocazione non è noto, non possiamo calcolare il ritorno
				return null;
			}
			return ((String) values.get(0).getValue()).toCharArray();
		}
		return null;
	}
}

Non dimenticare di aggiungere la tua esecuzione all'albero in me.nov.threadtear.execution.ExecutionLink!

Suggerimenti e trucchi

Ci sono alcuni trucchi che possono aiutarti a identificare e deoffuscare con successo i file jar. Prima di eseguire le esecuzioni, decompila il codice per scoprire cosa deve essere usato. Puoi usare il decompilatore integrato per questo.

Ordine di deofuscazione

L'ordine migliore per una deofuscazione è: esecuzioni generiche > deofuscazione degli accessi > deofuscazione delle stringhe > esecuzioni di pulizia.

Identificazione

Gli offuscatori mostrano schemi che puoi usare per identificarli. Il modo più semplice per identificare un offuscatore è scorrere il file META-INF/MANIFEST.MF. È possibile che ci sia un attributo Obfuscated-By: XXX o Protected-By: XXX.

ZKM

Codice estremamente offuscato (nel flusso), spesso riconoscibile da un metodo di decifratura delle stringhe nell'inizializzatore statico contenente switch, o metodi di decifratura delle stringhe con un blocco switch molto lungo (circa 250 casi). ZKM è uno dei migliori (e più vecchi) offuscatori per Java, ed è molto costoso. Antico quanto l'offuscatore è il loro sito web. ZKM

Stringer

Se il tuo file jar contiene alcune classi speciali con enormi algoritmi di decifratura utilizzati per l'offuscamento delle stringhe e degli accessi, probabilmente è Stringer. La protezione non è male e Stringer è uno degli offuscatori più costosi. A differenza degli offuscatori normali, non include l'offuscamento dei nomi. Viene piuttosto usato come "secondo strato". Probabilmente il 90% delle persone che usano questo offuscatore utilizza una crack, poiché costa più di un'auto. Se il tuo file è stato offuscato con più offuscatori, e Stringer è uno di questi, dovresti iniziare la deofuscazione con Stringer, poiché l'offuscamento di Stringer non può essere sovrascritto. (A causa della firma JAR personalizzata e dell'uso dei nomi dei metodi durante la decifratura delle stringhe) Stringer Stringer 2

Allatori

Nomi di classe come IiIlIlIiIl o aUx, cOn, PrX indicano l'offuscamento con Allatori. Allatori è molto comune tra i file jar offuscati, perché offre una demo gratuita accessibile con pochi clic. L'offuscamento non è così difficile da invertire. Allatori

Paramorphism

Paramorphism è come il fratello minore di Stringer, poiché sembra simile, ma non è altrettanto buono. Ha anche alcune caratteristiche interessanti che mirano a far crashare gli strumenti di reverse engineering, ma possono essere rimosse facilmente. La forza dell'offuscamento è paragonabile ad Allatori. Paramorphism

Altri offuscatori

Per altri offuscatori puoi provare esecuzioni generiche o aprire una segnalazione, e vedrò cosa posso fare.

Descrizione e tag

Prima di selezionare un'esecuzione, controlla i testi dei suggerimenti che appaiono al passaggio del mouse. Contengono una breve descrizione di ciò che fanno, ma anche tag che ti aiutano a capire come il comportamento del tuo file JAR verrà modificato.

Licenza

Threadtear è concesso in licenza sotto la GNU General Public License 3.0

Dona

Questo strumento è stato un'enorme mole di lavoro. Se ti ho fatto risparmiare tempo e vuoi offrirmi un caffè, puoi farlo qui: Dona con Bitcoin

Avviso

Utilizza Threadtear solo per scopi legali. Threadtear non mira ad essere uno strumento di cracking, ma piuttosto un toolkit per l'analisi di malware. Per favore apri una segnalazione o inviami un'email se un trasformatore non funziona correttamente e allega il log.
Nota che i file di output molto probabilmente non sono eseguibili. Se vuoi comunque provare ad eseguirli, usa -noverify come argomento JVM!
Questo strumento è pensato per essere utilizzato con Java 8, ma probabilmente funzionerà anche su versioni successive.

Scarica lo strumento