一、背景說明
在項目正常啓動後,運營一段時間後,發現java進程死掉JVM崩潰,在項目服務器中生成hs_err_pid.log 錯誤日誌,下面介紹一下hs_err_pid.log 日誌中的 Instructions 信息的解析。
二、解析 Instructions 信息中機器碼信息
將 Instructions 信息中的機器碼信息轉換爲彙編碼
其中Instructions信息如下所示:
Instructions: (pc=0x00007f029d015be0)
0x00007f029d015bc0: 00 00 00 e8 18 d3 83 15 48 8b 04 24 48 83 c4 10
0x00007f029d015bd0: c5 fb 10 04 24 48 83 c4 10 4c 8b 5d 18 41 ff d3
0x00007f029d015be0: 4c 8b 5d f8 c9 5f 49 8b e3 ff e7 be 00 00 00 00
0x00007f029d015bf0: e8 05 00 00 00 e9 7b 00 00 00 48 8d 44 24 08 4c
1、準備java capstone環境
引入Maven capstone jar包
<dependency>
<groupId>com.github.transcurity</groupId>
<artifactId>capstone</artifactId>
<version>3.0.5-rc2</version>
</dependency>
2、下載capstone.dll 文件
下載地址:https://github.com/aquynh/capstone/releases 下載版本:Version 3.0.5-rc2
3、將2位機器碼轉換爲4位機器碼
在2位機器碼之前統一添加0x 變爲4位機器碼,例如:
00 00 00 e8 18 d3 83 15 48 8b 04 24 48 83 c4 10 -> 0x00 0x00 0x00 0xe8 0x18 0xd3 0x83 0x15 0x48 0x8b 0x04 0x24 0x48 0x83 0xc4 0x10
4、編寫java 代碼解析將4位機器碼解析爲彙編碼
import capstone.Capstone;
public class Tests {
/**
* 線程隨機標識符
*/
private static long addr = 0x00007f029d015bc0L;
/**
* 四位機器碼
*/
private static byte[] hexCodes = {
0x00,0x00,0x00,(byte)0xe8,0x18,(byte)0xd3,(byte)0x83,0x15,0x48,(byte)0x8b,0x04,0x24,0x48,(byte)0x83,(byte)0xc4,0x10};
public static void main(String[] args) {
// 設置存放capstone.dll庫的路徑,需要注意跟jar包的版本保持一致
System.setProperty("jna.library.path","D:\\capstone-3.0.5-rc2-win64");
Capstone capstone = new Capstone(Capstone.CS_ARCH_X86, Capstone.CS_MODE_64);
Capstone.CsInsn[] allInsn = capstone.disasm(hexCodes, addr);
for (Capstone.CsInsn csInsn : allInsn) {
System.out.printf("0x%x:\t%s\t%s\n", csInsn.address,
csInsn.mnemonic, csInsn.opStr);
}
}
}
解析結果如下所示:
0x7f029d015bc0: add byte ptr [rax], al
0x7f029d015bc2: add al, ch
0x7f029d015bc4: sbb bl, dl
0x7f029d015bc6: adc dword ptr [rip + 0x24048b48], 0x48
0x7f029d015bcd: add esp, 0x10
接下來可以藉助反彙編工具將彙編碼反編譯成JVM 崩潰前執行的指令信息