本項目不再維護
建議使用新版Jar Analyzer V2 https://github.com/jar-analyzer/jar-analyzer
Jar-Analyzer 命令行版本
Jar-Analyzer Cli Version
簡單的介紹:https://mp.weixin.qq.com/s/Rrx6x5M_28YRcQQCdxuEeQ
沒有英文文檔,老外請自行翻譯
一個用於分析jar包的GUI工具,尤其適合從事代碼安全審計。可以在同時分析多個jar文件,可以輕易地搜索目標方法。 支持反編譯字節碼並自動構建類和方法之間的關係,幫助Java安全研究員更高效地工作。
注意:請勿分析過大或過多的的Jar包,建議最大不超過300M
前往下載
可以精確定位方法的位置(左側灰色游標高亮顯示)

可以直接定位字符串(分析常量池相關指令實現精確定位)

可以直接分析Spring框架編寫的項目

為什麼不選擇IDEA分析:因為IDEA不支持分析無源碼的Jar包
支持六種搜索方式:
LDC指令找到精確位置)LDC指令找到精確位置)支持選擇三項反編譯方式:
使用類定制化的JSyntaxPane組件(非官方)來展示Java代碼
(在該庫https://code.google.com/archive/p/jsyntaxpane的基礎上加了很多黑科技)
支持一種超強的表達式搜索,可以隨意組合以搜索你想要的信息
| 表達式 | 參數 | 作用 |
|---|---|---|
| nameContains | String | 方法名包含 |
| startWith | String | 方法前綴 |
| endWith | String | 方法後綴 |
| classNameContains | String | 類名包含 |
| returnType | String | 方法返回類型 |
| paramTypeMap | int String | 方法參數對應關係 |
| paramsNum | int | 方法參數個數 |
| isStatic | boolean | 方法是否靜態 |
| isSubClassOf | String | 是誰的子類 |
| isSuperClassOf | String | 是誰的父類 |
| hasAnno | String | 方法的註解 |
| hasClassAnno | String | 類的註解 |
| hasField | String | 類字段 |
注意:
returnType和paramTypeMap要求類似是完整類名,例如java.lang.String ,基礎類型直接寫即可例如intisSubClassOf和isSuperClassOf要求完整類名,例如java.awt.ComponenthasAnno和hasClassAnno不要求完整類名,直接寫即可例如Controller 
搜索的基礎是方法,你希望搜索怎樣的方法
例如我希望搜索方法名以set開頭並以value結尾的方法
# method
. startWith ( "set" )
. endWith ( "value" )例如我希望搜索類名包含Context且方法名包含lookup的方法
# method
. nameContains ( "lookup" )
. classNameContains ( "Context" )例如我希望搜索返回Process類型共3個參數且第二個參數為String的方法
# method
. returnType ( "java.lang.Process" )
. paramsNum ( 3 )
. paramTypeMap ( 1 , "java.lang.String" )比如我們想找javax.naming.spi.ObjectFactory的所有子類(包括子類的子類等)
編寫以下規則即可,程序內部會遞歸地尋找所有的父類
# method
. isSubClassOf ( "javax.naming.spi.ObjectFactory" )如果想找某個類的所有父類,使用isSuperClassOf即可(注意全類名)
注意以上會直接找到所有符合條件類的所有方法,所以我建議再加一些過濾
例如
# method
. isSubClassOf ( "javax.naming.spi.ObjectFactory" )
. startWith ( "xxx" )
. paramsNum ( 0 )比如我們想找@Controller註解的所有類的所有方法
編寫以下規則
# method
. hasClassAnno ( "Controller" )比如想找@RequestMapping註解的所有方法
# method
. hasAnno ( "RequestMapping" )同樣地由於找到的是所有符合條件類的所有方法,所以我建議再加一些過濾
根據網上師傅提供的Swing RCE條件:
Component子類(包括間接子類)因此我們編寫一條規則
# method
. startWith ( "set" )
. paramsNum ( 1 )
. paramTypeMap ( 0 , "java.lang.String" )
. isSubClassOf ( "java.awt.Component" )搜索結果

重要:請使用Java 8+運行(推薦11並已提供內置Java 11 JRE的EXE版本)
(在Java 11中使用了一種更好的字體,其他版本使用默認字體)
(1) 第一步:添加jar文件(支持單個jar文件和jar目錄)
Select Jar File打開jar文件請不要著急,分析jar文件需要花費少量的時間
注意:請等到進度條滿時分析完成
(2) 第二步:輸入你搜索的信息
我們支持三種格式的輸入:
javax.naming.Context (例如)javax/naming/ContextContext (會搜索所有*.Context類)提供了一種快速輸入的方式

注意:這裡的常見搜索內容可以自定義補充
在當前目錄新建search.txt文件,一行一個以#分割類名和方法,例如
java.lang.Runtime#getRuntime
java.lang.String#equals
二進制搜索只會返回是否存在,不會返回具體信息

(3) 第三步:你可以雙擊進行反編譯
游標將會精確地指向方法調用的位置
當反編譯的過程中,方法之間的關係會被構建
在面板上的任何地方都可以雙擊進行反編譯,並構建新的方法調用關係和展示
請注意:如果你遇到無法反編譯的情況,你需要加載正確的jar文件
例如,我無法反編譯javax.naming.Context因為我沒有加入rt.jar文件,如果你加入了它,就可以正常反編譯了
你可以使用Ctrl+F搜索代碼和編輯
你可以單擊任何一個選項,接下來將會顯示方法的詳細信息
你可以右鍵將選項發送到鏈中。你可以把鏈理解為一個收藏夾或記錄。在鏈中你同樣可以雙擊反編譯,然後展示新的方法調用關係,或單機顯示詳情如果鏈中某個選項是你不想要的,可以右鍵把該選項從鏈中刪除
因此你可以構建出一個只屬於你的調用鏈
谁调用了当前方法和当前方法调用了谁中的所有方法調用關係同樣可以雙擊反編譯,單擊看詳情,右鍵加入鏈
可以一鍵查看當前類字節碼

(1) 什麼是方法之間的關係
class Test {
void a (){
new Test (). b ();
}
void b (){
Test . c ();
}
static void c (){
// code
}
}如果當前方法是b
誰調用了當前方法: Test class a method
當前方法調用了誰: Test class c method
(2) 如何解決接口實現的問題
class Demo {
void demo (){
new Test (). test ();
}
}
interface Test {
void test ();
}
class Test1Impl implements Test {
@ Override
public void test () {
// code
}
}
class Test2Impl implements Test {
@ Override
public void test () {
// code
}
}現在我們有Demo.demo -> Test.test數據, 但實際上它是Demo.demo -> TestImpl.test .
因此我們添加了新的規則: Test.test -> Test1Impl.test和Test.test -> Test2Impl.test .
首先確保數據不會丟失,然後我們可以自行手動分析反編譯的代碼
Demo.demo -> Test.testTest.test -> Test1Impl.test / Test.test -> Test2Impl.test(3) 如何解決繼承關係
class Zoo {
void run (){
Animal dog = new Dog ();
dog . eat ();
}
}
class Animal {
void eat () {
// code
}
}
class Dog extends Animal {
@ Override
void eat () {
// code
}
}
class Cat extends Animal {
@ Override
void eat () {
// code
}
} Zoo.run -> dog.cat的字節碼是INVOKEVIRTUAL Animal.eat ()V , 但我們只有這條規則Zoo.run -> Animal.eat , 丟失了Zoo.run -> Dog.eat規則
這種情況下我們添加了新規則: Animal.eat -> Dog.eat和Animal.eat -> Cat.eat
首先確保數據不會丟失,然後我們可以自行手動分析反編譯的代碼
Zoo.run -> Animal.eatAnimal.eat -> Dog.eat / Animal.eat -> Cat.eat This project is developed using JetBrains IDEA. Thanks to JetBrains for providing me with a free license, which is a strong support for me.