一個Java反彙編器的修改 (7千字)

看雪資料發表於2015-11-15

標 題:一個Java反彙編器的修改 (7千字)

發信人:slangmgh  [發短訊息]

時 間:2003-08-19 12:31:25

詳細資訊:




不知大家是否有用Java的,現在Java的反編譯器很多(當然Jad最牛,而且是用C寫的),而反彙編的不多,JCD version 2A是一個挺老的反彙編程式,不過我自己覺得挺好用(有的時候被擾碼後的.class不能反編譯,所以必須反彙編)。不過Jcd有一個問題,就是不能顯示位元組程式碼,並且在程式碼中的偏移也是相對的,而不是檔案偏移,這使得修改前還的自己計算,所以我們需要改進這些地方:
首先我們要找到反彙編Method的程式碼,用W32dasm的StringRef可以看到以下的程式碼:

* Possible StringData Ref from Data Obj ->"%8d%8caconst_null"
                                  |
:004144B2 68DE0B4200              push 00420BDE
:004144B7 E875D3FFFF              call 00411831
:004144BC 83C40C                  add esp, 0000000C
:004144BF E9F9250000              jmp 00416ABD
:004144C4 6A20                    push 00000020
:004144C6 8BC3                    mov eaxebx
:004144C8 43                      inc ebx
:004144C9 50                      push eax

再向前看,可以看到:

* Referenced by a CALL at Address:
|:00413395   
|
:00414063 55                      push ebp
:00414064 8BEC                    mov ebpesp
:00414066 81C4E0F3FFFF            add esp, FFFFF3E0
:0041406C 53                      push ebx
:0041406D 56                      push esi
:0041406E 57                      push edi
:0041406F 8B7D10                  mov edidword ptr [ebp+10] ; 程式碼偏移指標
:00414072 33F6                    xor esiesi
:00414074 8B1F                    mov ebxdword ptr [edi]
:00414076 8B4508                  mov eaxdword ptr [ebp+08] ;當前檔案
:00414079 8B550C                  mov edxdword ptr [ebp+0C] ;當前方法
:0041407C 03C2                    add eaxedx
:0041407E 0FB60418                movzx eaxbyte ptr [eax+ebx]
:00414082 3DFF000000              cmp eax, 000000FF
:00414087 0F871D2A0000            ja 00416AAA
:0041408D FF248594404100          jmp dword ptr [4*eax+00414094]

:00414094 94444100                DWORD 00414494
:00414098 AC444100                DWORD 004144AC

下面還有許多DWORD,明顯這是一個根據程式碼第一位元組的跳轉表。因而JCD的單條指令
的反編譯程式碼就是00414063。再看程式碼413395處:

:0041338D 8D45BC                  lea eaxdword ptr [ebp-44]
:00413390 50                      push eax ;程式碼偏移指標
:00413391 53                      push ebx ;當前方法
:00413392 57                      push edi ;當前檔案
:00413393 E8CB0C0000              call 00414063
:00413398 83C40C                  add esp, 0000000C
:0041339B 85C0                    test eaxeax ;程式碼正確
:0041339D 7522                    jne 004133C1
:0041339F 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"JCD"
                                  |
:004133A1 6870004200              push 00420070
:004133A6 8D8631080000            lea eaxdword ptr [esi+00000831]
:004133AC 50                      push eax
:004133AD FF7508                  push [ebp+08]

* Reference To: USER32.MessageBoxA, Ord:0000h
                                  |
:004133B0 E8EA9E0000              Call 0041D29F
:004133B5 33C0                    xor eaxeax
:004133B7 A374004200              mov dword ptr [00420074], eax
:004133BC E97F0C0000              jmp 00414040

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041339D(C)
|
:004133C1 8B45BC                  mov eaxdword ptr [ebp-44]
:004133C4 3B45D0                  cmp eaxdword ptr [ebp-30] ;當前方法的長度
:004133C7 7CC4                    jl 0041338D

這是一段迴圈直到改方法反彙編結束。再跟蹤進入方法414063,發現它將反編譯完成的字元
串放在[42008C]所指的DWORD所指的指標中。格式為"%8d%8c%s"。現在,一切都清楚了,以下
是我們所要做的。

:00413390 FF30                    push dword ptr [eax] ;我們需要儲存上次的偏移
:00413392 50                      push eax
:00413393 53                      push ebx
:00413394 57                      push edi
:00413395 E8C90C0000              call 00414063
:0041339A 83C40C                  add esp, 0000000C
:0041339D 85C0                    test eaxeax
:0041339F 0F849B0C0000            je 00414040
:004133A5 58                      pop eax ;上次的偏移
:004133A6 60                      pushad ;儲存暫存器
:004133A7 8B4DBC                  mov ecxdword ptr [ebp-44] ;這次的偏移
:004133AA BEF4D34100              mov esi, 0041D3F9 ;Format
:004133AF 2BC8                    sub ecxeax ;這條指令的位元組數
:004133B1 83F903                  cmp ecx, 00000003 ;我們只顯示三個位元組
:004133B4 7E05                    jle 004133BB
:004133B6 B903000000              mov ecx, 00000003

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004133B4(C)
|
:004133BB E99F9F0000              jmp 0041D35F ;程式碼在這裡寫不下
:004133C0 90                      nop


上面的程式碼跳到這裡

:0041D35F 03FB                    add ediebx
:0041D361 03F8                    add edieax ;EDI指向該指令的第一個位元組
:0041D363 33D2                    xor edxedx
:0041D365 890DE3D34100            mov dword ptr [0041D3E3], ecx ;儲存ECX的值,在呼叫函式wsprintf後清棧用

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D37B(U)
|
:0041D36B 49                      dec ecx
:0041D36C 740F                    je 0041D37D
:0041D36E 8A140F                  mov dlbyte ptr [edi+ecx]
:0041D371 52                      push edx ;將指令位元組推入棧
:0041D372 C70625303258            mov dword ptr [esi], 58323025 ;Format字串增加"%02X"
:0041D378 83C604                  add esi, 00000004
:0041D37B EBEE                    jmp 0041D36B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D36C(C)
|
:0041D37D 8A17                    mov dlbyte ptr [edi] ;該指令的第一個位元組入棧
:0041D37F 52                      push edx
:0041D380 90                      nop
:0041D381 90                      nop
:0041D382 90                      nop
:0041D383 50                      push eax
:0041D384 03C3                    add eaxebx ;當前指令偏移
:0041D386 50                      push eax
:0041D387 A18C004200              mov eaxdword ptr [0042008C]
:0041D38C 68EBD34100              push 0041D3EB ;Format字串(目前應為“%08X %02X[%02X...]”)
:0041D391 FF30                    push dword ptr [eax] ;目的字串
:0041D393 C60600                  mov byte ptr [esi], 00 ;Format字串最後一位為0

* Reference To: USER32.wsprintfA, Ord:0000h
                                  |
:0041D396 E8AAFEFFFF              Call 0041D245
:0041D39B 83C410                  add esp, 00000014 ;先清4個DWORD(buff,format,offset,offset, first byte
:0041D39E 8B0DE3D34100            mov ecxdword ptr [0041D3E3]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D3A8(U)
|
:0041D3A4 49                      dec ecx
:0041D3A5 7403                    je 0041D3AA
:0041D3A7 58                      pop eax ;根據ECX清除其他的棧中的資料
:0041D3A8 EBFA                    jmp 0041D3A4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0041D3A5(C)
|
:0041D3AA A18C004200              mov eaxdword ptr [0042008C]
:0041D3AF 8B10                    mov edxdword ptr [eax]
:0041D3B1 52                      push edx
:0041D3B2 52                      push edx

* Reference To: KERNEL32.lstrlenA, Ord:0000h
  |
:0041D3B3 E84FFDFFFF              Call 0041D107
:0041D3B8 5A                      pop edx
:0041D3B9 C6041020                mov byte ptr [eax+edx], 20 ;我們必須將空格改回來
:0041D3BD 61                      popad
:0041D3BE E9FE5FFFFF              jmp 004133C ;一切Over!

Format資料 "%04X:%03d %02X"
:0041D3EB 253034583A              and eax, 3A583430
:0041D3F0 2530336420              and eax, 20643330
:0041D3F5 2530325800              and eax, 00583230

相關文章