-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathPE_RichSignatureDecode.asm
156 lines (130 loc) · 3.77 KB
/
PE_RichSignatureDecode.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
;==============================================================================
;
; PE Library
;
; Copyright (c) 2019 by fearless
;
; http://github.com/mrfearless
;
;==============================================================================
.686
.MMX
.XMM
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
include PE.inc
.CODE
PE_ALIGN
;------------------------------------------------------------------------------
; PE_RichSignatureDecode - Decodes rich signature and returns a block of
; memory, pointed to by the lpDecodedRichSignature parameter. lpdwSize var
; will contains size of decoded block on succesful return. Use GlobalFree
; once you have done with the decoded block.
;
; lpDecodedRichSignature can be null if you want to just return size of rich
; signature in lpdwSize
;
; Code adapted from Daniel Pistelli: https://ntcore.com/files/richsign.htm
;
; Returns: TRUE or FALSE
;------------------------------------------------------------------------------
PE_RichSignatureDecode PROC USES EBX ECX EDX hPE:DWORD, lpdwDecodedRichSignature:DWORD, lpdwSize:DWORD
LOCAL pHeaderRich:DWORD
LOCAL pRSEntry:DWORD
LOCAL pRSNewData:DWORD
LOCAL pRSNewEntry:DWORD
LOCAL nSignDwords:DWORD
LOCAL dwMask:DWORD
LOCAL dwSize:DWORD
LOCAL dwEndAddress:DWORD
.IF lpdwDecodedRichSignature == 0 && lpdwSize == 0
xor eax, eax
ret
.ENDIF
Invoke PE_HeaderRich, hPE
.IF eax == 0
ret
.ENDIF
mov pHeaderRich, eax
; Get address of PE in memory + filesize for max address
mov ebx, hPE
mov eax, [ebx].PEINFO.PEMemMapPtr
add eax, [ebx].PEINFO.PEFilesize
mov dwEndAddress, eax
; Loop through rich signature location
; count no of dwords till we hit max no
; or null, or 'Rich'.
mov ebx, pHeaderRich
mov nSignDwords, 0
mov ecx, 0
mov eax, 0
.WHILE eax < 100 && ebx < dwEndAddress
mov eax, [ebx]
.IF eax == 68636952h ; Rich
mov eax, ecx
mov nSignDwords, eax
.BREAK
.ELSEIF eax == 0 ; Null
.BREAK
.ENDIF
add ebx, SIZEOF DWORD
inc ecx
mov eax, ecx
.ENDW
; Check if we got anything
.IF nSignDwords == 0
xor eax, eax
ret
.ENDIF
; read xor mask
mov eax, dword ptr [ebx+4]
mov dwMask, eax
; alloc memory for decrypted block
mov eax, nSignDwords
inc eax
mov ebx, SIZEOF DWORD
mul ebx
mov dwSize, eax
.IF lpdwDecodedRichSignature != 0
Invoke GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, dwSize
mov pRSNewData, eax
mov pRSNewEntry, eax
mov edx, pRSNewEntry
; decrypt signature
mov ebx, pHeaderRich
mov pRSEntry, ebx
mov ecx, 0
mov eax, 0
.WHILE eax < nSignDwords && ebx < dwEndAddress
mov eax, [ebx] ; read pRSEntry DWORD
mov ebx, dwMask
xor eax, ebx ; decrypt (xor) with mask
mov [edx], eax ; store DWORD in pRSNewEntry
add pRSNewEntry, SIZEOF DWORD
add pRSEntry, SIZEOF DWORD
mov ebx, pRSEntry
mov edx, pRSNewEntry
inc ecx
mov eax, ecx
.ENDW
; write new mask for decrypted signature
mov dword ptr [edx+4], 0FFFFFFFFh
; return decrypted block and size
mov ebx, lpdwDecodedRichSignature
mov eax, pRSNewData
mov [ebx], eax
.ENDIF
.IF lpdwSize != NULL
mov ebx, lpdwSize
mov eax, dwSize
mov [ebx], eax
.ENDIF
mov eax, TRUE
ret
PE_RichSignatureDecode ENDP
PE_LIBEND