2019
02
21

アセンブリからXORデコードの処理を読み取る

Practical Malware Analysis Lab 11-2 のサンプル・バイナリ Lab11-02.dllのXORデコーディングの処理内容について調べました。

本の中の解説ではXORデコーディングの部分については、XORデコードの関数のアドレスにブレークポイントを設定してデコードされたデータを確認するというもので、
XORデコードの処理の内容については触れられていなかったので、アセンブリから処理の内容を読み取ろうと思います。
以下がXORデコードの処理に関するコードです。(一部、関数名をわかりやすい名前に変更しています。)

.text:10001097 ; =============== S U B R O U T I N E =======================================
.text:10001097
.text:10001097 ; Attributes: bp-based frame
.text:10001097
.text:10001097 xor_decode proc near ; CODE XREF: decoder+32↓p
.text:10001097
.text:10001097 arg_0 = byte ptr 8
.text:10001097 arg_4 = dword ptr 0Ch
.text:10001097
.text:10001097 push ebp
.text:10001098 mov ebp, esp
.text:1000109A mov eax, [ebp+arg_4]
.text:1000109D and eax, 0FFh
.text:100010A2 imul eax, 29Ah
.text:100010A8 sar eax, 4
.text:100010AB movsx ecx, [ebp+arg_0]
.text:100010AF xor eax, ecx
.text:100010B1 pop ebp
.text:100010B2 retn
.text:100010B2 xor_decode endp
.text:100010B2
.text:100010B3
.text:100010B3 ; =============== S U B R O U T I N E =======================================
.text:100010B3
.text:100010B3 ; Attributes: bp-based frame
.text:100010B3
.text:100010B3 decoder proc near ; CODE XREF: sub_10001610+BA↓p
.text:100010B3
.text:100010B3 var_4 = dword ptr -4
.text:100010B3 arg_0 = dword ptr 8
.text:100010B3
.text:100010B3 push ebp
.text:100010B4 mov ebp, esp
.text:100010B6 push ecx
.text:100010B7 mov eax, [ebp+arg_0]
.text:100010BA mov [ebp+var_4], eax
.text:100010BD
.text:100010BD loc_100010BD: ; CODE XREF: decoder+48↓j
.text:100010BD mov ecx, [ebp+arg_0]
.text:100010C0 movsx edx, byte ptr [ecx]
.text:100010C3 test edx, edx
.text:100010C5 jz short loc_100010FD
.text:100010C7 mov eax, [ebp+arg_0]
.text:100010CA movsx ecx, byte ptr [eax]
.text:100010CD cmp ecx, 0Dh
.text:100010D0 jz short loc_100010FD
.text:100010D2 mov edx, [ebp+arg_0]
.text:100010D5 movsx eax, byte ptr [edx]
.text:100010D8 cmp eax, 0Ah
.text:100010DB jz short loc_100010FD
.text:100010DD push 32h
.text:100010DF mov ecx, [ebp+arg_0]
.text:100010E2 mov dl, [ecx]
.text:100010E4 push edx
.text:100010E5 call xor_decode
.text:100010EA add esp, 8
.text:100010ED mov ecx, [ebp+arg_0]
.text:100010F0 mov [ecx], al
.text:100010F2 mov edx, [ebp+arg_0]
.text:100010F5 add edx, 1
.text:100010F8 mov [ebp+arg_0], edx
.text:100010FB jmp short loc_100010BD
.text:100010FD ; ---------------------------------------------------------------------------
.text:100010FD
.text:100010FD loc_100010FD: ; CODE XREF: decoder+12↑j
.text:100010FD ; decoder+1D↑j ...
.text:100010FD mov eax, [ebp+var_4]
.text:10001100 mov esp, ebp
.text:10001102 pop ebp
.text:10001103 retn
.text:10001103 decoder endp


decoder関数はループの中で、xor_decode関数を実行します。xor_decode関数は、XORエンコードされたデータ (0x43484d4d58614c404d56405344404f404d58524852434e4e4a0f424e4c) 1バイトずつ と0x32という値を引数として受け取ります。

.text:100010DD push 32h
.text:100010DF mov ecx, [ebp+arg_0]
.text:100010E2 mov dl, [ecx]
.text:100010E4 push edx
.text:100010E5 call xor_decode


xor_decode関数の中では以下の処理が行われます。

and     eax, 0FFh

0x32と0x00ffのAND演算を行う。オール1ビットとのAND演算なので0x32の値は変化しない。

imul    eax, 29Ah

0x32と0x029aの掛け算を行う。結果はeaxに格納

sar     eax, 4

eaxの値を右へ4シフト


movsx ecx, [ebp+arg_0]
xor eax, ecx

eaxの値とecxの値 (arg_0)のXOR演算を行う。

上記の内容をPythonで表すと以下のようになる。

>>> (((0x32 & 0x00ff) * 0x029a) >> 4) ^ 0x43
2146
>>> bin(2146).replace('0b', '')
'100001100010'

さて、ここで処理がxor_decode関数からdecoder関数に戻ります。

call xor_decode
add esp, 8
mov ecx, [ebp+arg_0]
mov [ecx], al


xor_decode関数の演算結果から下位8ビット (100001100010) がecxが指すアドレスにコピーされます。(mov [ecx], al)
この下位8ビットがXORデコードされたデータになります。

Pythonで表すと以下のようになります。

下位8ビットの値
>>> bin(2146).replace('0b', '')[-8:]
'01100010'

下位8ビットを10進数に変換
>>> int(bin(2146).replace('0b', '')[-8:], 2)
98

98をASCIIデコードするとアルファベットの'b'になります。
>>> chr(int(bin(2146).replace('0b', '')[-8:], 2))
'b'

これらのXORデコーディングの処理をPythonで書くと以下のようになります。

#!/usr/bin/env python

import binascii

enc = '43484d4d58614c404d56405344404f404d58524852434e4e4a0f424e4c'
dec = ''
cnt = len(enc)
n = 2

for i in range(0, cnt, 2):
j = (((0x32 & 0x00ff) * 0x029a) >> 4) ^ ord(binascii.unhexlify(enc[i:i+n]))
j = bin(j).replace('0b', '')[-8:]
dec += chr(int(j, 2))

print(dec)


上記スクリプトの実行結果。

$ python Lab11-02-decoder.py
billy@malwareanalysisbook.com


以上。
Comment



Only the blog author may view the comment.


Trackback
Trackback URL

«  | HOME |  »

奇妙な風景 Unique Scene
<< >>

プロフィール


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


スポンサード リンク


FC2カウンター


検索フォーム


RSSリンクの表示


リンク


ブロとも申請フォーム


QRコード